public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
blob f2a7377da0151c9a99865537553c658c6a917cce 2811 bytes (raw)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
 
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright Red Hat
 * Author: David Gibson <david@gibson.dropbear.id.au>
 *
 * Tracking for logical "flows" of packets.
 */

#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>

#include "util.h"
#include "passt.h"
#include "inany.h"
#include "siphash.h"
#include "flow.h"
#include "tcp_conn.h"
#include "flow_table.h"

const char *flow_type_str[] = {
	[FLOW_NONE]		= "<none>",
	[FLOW_TCP]		= "TCP connection",
	[FLOW_TCP_SPLICE]	= "TCP connection (spliced)",
};

/* Global Flow Table */
union flow flowtab[FLOW_MAX];

/** flowside_fmt - Format a flowside as a string
 * @fs:		flowside to format
 * @buf:	Buffer into which to store the formatted version
 * @size:	Size of @buf
 *
 * Return: pointer to formatted string describing @fs, or NULL on error
 */
const char *flowside_fmt(const struct flowside *fs, char *buf, size_t size)
{
	char ebuf[INET6_ADDRSTRLEN], fbuf[INET6_ADDRSTRLEN];

	if (!inet_ntop(AF_INET6, &fs->eaddr, ebuf, sizeof(ebuf))
	    || !inet_ntop(AF_INET6, &fs->faddr, fbuf, sizeof(fbuf)))
		return NULL;

	snprintf(buf, size, "[%s]:%hu <-> [%s]:%hu", fbuf, fs->fport,
		 ebuf, fs->eport);
	return (const char *)buf;
}

/**
 * flow_table_compact() - Perform compaction on flow table
 * @c:		Execution context
 * @hole:	Pointer to recently closed flow
 */
void flow_table_compact(struct ctx *c, union flow *hole)
{
	union flow *from;

	if (FLOW_IDX(hole) == --c->flow_count) {
		debug("flow: table compaction: maximum index was %li (%p)",
		      FLOW_IDX(hole), hole);
		memset(hole, 0, sizeof(*hole));
		return;
	}

	from = flowtab + c->flow_count;
	memcpy(hole, from, sizeof(*hole));

	switch (from->f.type) {
	case FLOW_TCP:
		tcp_tap_conn_update(c, &from->tcp, &hole->tcp);
		break;
	case FLOW_TCP_SPLICE:
		tcp_splice_conn_update(c, &hole->tcp_splice);
		break;
	default:
		die("Unexpected %s in tcp_table_compact()",
		    FLOW_TYPE(&from->f));
	}

	debug("flow: table compaction (%s): old index %li, new index %li, "
	      "from: %p, to: %p",
	      FLOW_TYPE(&from->f), FLOW_IDX(from), FLOW_IDX(hole), from, hole);

	memset(from, 0, sizeof(*from));
}

/** flowside_getsockname - Initialize flowside f{addr,port} from a bound socket
 * @fs:		flowside to initialize
 * @s:		bound socket
 *
 * #syscalls getsockname
 */
int flowside_getsockname(struct flowside *fs, int s)
{
	struct sockaddr_storage sa;
	socklen_t sl = sizeof(sa);

	/* FIXME: Workaround clang-tidy not realizing that getsockname() writes
	 * the socket address.  See
	 * https://github.com/llvm/llvm-project/issues/58992
	 */
	memset(&sa, 0, sizeof(struct sockaddr_in6));
	if (getsockname(s, (struct sockaddr *)&sa, &sl) < 0)
		return -errno;

	inany_from_sockaddr(&fs->faddr, &fs->fport,
			    (const struct sockaddr *)&sa);

	return 0;
}

debug log:

solving f2a7377 ...
found f2a7377 in https://archives.passt.top/passt-dev/20230828054146.48673-10-david@gibson.dropbear.id.au/
found 4521a43 in https://archives.passt.top/passt-dev/20230828054146.48673-8-david@gibson.dropbear.id.au/
found d7264f8 in https://archives.passt.top/passt-dev/20230828054146.48673-7-david@gibson.dropbear.id.au/
found a93cf8c in https://archives.passt.top/passt-dev/20230828054146.48673-6-david@gibson.dropbear.id.au/
found 12ca8db in https://archives.passt.top/passt-dev/20230828054146.48673-5-david@gibson.dropbear.id.au/
found 864158a in https://archives.passt.top/passt-dev/20230828054146.48673-3-david@gibson.dropbear.id.au/
found c3802ce in https://archives.passt.top/passt-dev/20230828054146.48673-2-david@gibson.dropbear.id.au/

applying [1/7] https://archives.passt.top/passt-dev/20230828054146.48673-2-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
new file mode 100644
index 0000000..c3802ce


applying [2/7] https://archives.passt.top/passt-dev/20230828054146.48673-3-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
index c3802ce..864158a 100644


applying [3/7] https://archives.passt.top/passt-dev/20230828054146.48673-5-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
index 864158a..12ca8db 100644


applying [4/7] https://archives.passt.top/passt-dev/20230828054146.48673-6-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
index 12ca8db..a93cf8c 100644


applying [5/7] https://archives.passt.top/passt-dev/20230828054146.48673-7-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
index a93cf8c..d7264f8 100644


applying [6/7] https://archives.passt.top/passt-dev/20230828054146.48673-8-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
index d7264f8..4521a43 100644


applying [7/7] https://archives.passt.top/passt-dev/20230828054146.48673-10-david@gibson.dropbear.id.au/
diff --git a/flow.c b/flow.c
index 4521a43..f2a7377 100644

Checking patch flow.c...
Applied patch flow.c cleanly.
Checking patch flow.c...
Applied patch flow.c cleanly.
Checking patch flow.c...
Applied patch flow.c cleanly.
Checking patch flow.c...
Applied patch flow.c cleanly.
Checking patch flow.c...
Applied patch flow.c cleanly.
Checking patch flow.c...
Applied patch flow.c cleanly.
Checking patch flow.c...
Applied patch flow.c cleanly.

index at:
100644 f2a7377da0151c9a99865537553c658c6a917cce	flow.c

Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).