public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
blob d5d5d064f5abe48d8280c135029cb85cc0b3b882 5818 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
 
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright (c) 2021 Red Hat GmbH
 * Author: Stefano Brivio <sbrivio@redhat.com>
 */

#ifndef TCP_INTERNAL_H
#define TCP_INTERNAL_H

#define MAX_WS				8
#define MAX_WINDOW			(1 << (16 + (MAX_WS)))

#define MSS4				ROUND_DOWN(IP_MAX_MTU -		   \
						   sizeof(struct tcphdr) - \
						   sizeof(struct iphdr),   \
						   sizeof(uint32_t))
#define MSS6				ROUND_DOWN(IP_MAX_MTU -		   \
						   sizeof(struct tcphdr) - \
						   sizeof(struct ipv6hdr), \
						   sizeof(uint32_t))

#define SEQ_LE(a, b)			((b) - (a) < MAX_WINDOW)
#define SEQ_LT(a, b)			((b) - (a) - 1 < MAX_WINDOW)
#define SEQ_GE(a, b)			((a) - (b) < MAX_WINDOW)
#define SEQ_GT(a, b)			((a) - (b) - 1 < MAX_WINDOW)

#define FIN		(1 << 0)
#define SYN		(1 << 1)
#define RST		(1 << 2)
#define ACK		(1 << 4)

/* Flags for internal usage */
#define DUP_ACK		(1 << 5)
#define OPT_EOL		0
#define OPT_NOP		1
#define OPT_MSS		2
#define OPT_WS		3
#define OPT_SACKP	4
#define OPT_SACK	5
#define OPT_TS		8

#define TAPSIDE(conn_)	((conn_)->f.pif[1] == PIF_TAP)
#define TAPFLOW(conn_)	(&((conn_)->f.side[TAPSIDE(conn_)]))
#define TAP_SIDX(conn_)	(FLOW_SIDX((conn_), TAPSIDE(conn_)))

#define CONN_V4(conn)		(!!inany_v4(&TAPFLOW(conn)->oaddr))
#define CONN_V6(conn)		(!CONN_V4(conn))

/*
 * enum tcp_iov_parts - I/O vector parts for one TCP frame
 * @TCP_IOV_TAP		tap backend specific header
 * @TCP_IOV_ETH		Ethernet header
 * @TCP_IOV_IP		IP (v4/v6) header
 * @TCP_IOV_PAYLOAD	IP payload (TCP header + data)
 * @TCP_NUM_IOVS 	the number of entries in the iovec array
 */
enum tcp_iov_parts {
	TCP_IOV_TAP	= 0,
	TCP_IOV_ETH	= 1,
	TCP_IOV_IP	= 2,
	TCP_IOV_PAYLOAD	= 3,
	TCP_NUM_IOVS
};

/**
 * struct tcp_payload_t - TCP header and data to send segments with payload
 * @th:		TCP header
 * @data:	TCP data
 */
struct tcp_payload_t {
	struct tcphdr th;
	uint8_t data[IP_MAX_MTU - sizeof(struct tcphdr)];
#ifdef __AVX2__
} __attribute__ ((packed, aligned(32)));    /* For AVX2 checksum routines */
#else
} __attribute__ ((packed, aligned(__alignof__(unsigned int))));
#endif

/** struct tcp_opt_nop - TCP NOP option
 * @kind:	Option kind (OPT_NOP = 1)
 */
struct tcp_opt_nop {
	uint8_t kind;
} __attribute__ ((packed));
#define TCP_OPT_NOP		((struct tcp_opt_nop){ .kind = OPT_NOP, })

/** struct tcp_opt_mss - TCP MSS option
 * @kind:	Option kind (OPT_MSS == 2)
 * @len:	Option length (4)
 * @mss:	Maximum Segment Size
 */
struct tcp_opt_mss {
	uint8_t kind;
	uint8_t len;
	uint16_t mss;
} __attribute__ ((packed));
#define TCP_OPT_MSS(mss_)				\
	((struct tcp_opt_mss) {				\
		.kind = OPT_MSS,			\
		.len = sizeof(struct tcp_opt_mss),	\
		.mss = htons(mss_),			\
	})

/** struct tcp_opt_ws - TCP Window Scaling option
 * @kind:	Option kind (OPT_WS == 3)
 * @len:	Option length (3)
 * @shift:	Window scaling shift
 */
struct tcp_opt_ws {
	uint8_t kind;
	uint8_t len;
	uint8_t shift;
} __attribute__ ((packed));
#define TCP_OPT_WS(shift_)				\
	((struct tcp_opt_ws) {				\
		.kind = OPT_WS,				\
		.len = sizeof(struct tcp_opt_ws),	\
		.shift = (shift_),			\
	})

/** struct tcp_syn_opts - TCP options we apply to SYN packets
 * @mss:	Maximum Segment Size (MSS) option
 * @nop:	NOP opt (for alignment)
 * @ws:		Window Scaling (WS) option
 */
struct tcp_syn_opts {
	struct tcp_opt_mss mss;
	struct tcp_opt_nop nop;
	struct tcp_opt_ws ws;
} __attribute__ ((packed));
#define TCP_SYN_OPTS(mss_, ws_)				\
	((struct tcp_syn_opts){				\
		.mss = TCP_OPT_MSS(mss_),		\
		.nop = TCP_OPT_NOP,			\
		.ws = TCP_OPT_WS(ws_),			\
	})

/**
 * struct tcp_flags_t - TCP header and data to send zero-length
 *                      segments (flags)
 * @th:		TCP header
 * @opts	TCP options
 */
struct tcp_flags_t {
	struct tcphdr th;
	struct tcp_syn_opts opts;
#ifdef __AVX2__
} __attribute__ ((packed, aligned(32)));
#else
} __attribute__ ((packed, aligned(__alignof__(unsigned int))));
#endif

extern char tcp_buf_discard [MAX_WINDOW];

void conn_flag_do(const struct ctx *c, struct tcp_tap_conn *conn,
		  unsigned long flag);
#define conn_flag(c, conn, flag)					\
	do {								\
		flow_trace(conn, "flag at %s:%i", __func__, __LINE__);	\
		conn_flag_do(c, conn, flag);				\
	} while (0)


void conn_event_do(const struct ctx *c, struct tcp_tap_conn *conn,
		   unsigned long event);
#define conn_event(c, conn, event)					\
	do {								\
		flow_trace(conn, "event at %s:%i", __func__, __LINE__);	\
		conn_event_do(c, conn, event);				\
	} while (0)

void tcp_rst_do(const struct ctx *c, struct tcp_tap_conn *conn);
#define tcp_rst(c, conn)						\
	do {								\
		flow_dbg((conn), "TCP reset at %s:%i", __func__, __LINE__); \
		tcp_rst_do(c, conn);					\
	} while (0)

struct tcp_info_linux;

void tcp_update_check_tcp4(const struct iphdr *iph,
			   const struct iovec *iov, int iov_cnt,
			   size_t l4offset);
void tcp_update_check_tcp6(const struct ipv6hdr *ip6h,
			   const struct iovec *iov, int iov_cnt,
			   size_t l4offset);
size_t tcp_fill_headers4(const struct tcp_tap_conn *conn,
			 struct tap_hdr *taph,
			 struct iphdr *iph, struct tcp_payload_t *bp,
			 size_t dlen, const uint16_t *check,
			 uint32_t seq, bool no_tcp_csum);
size_t tcp_fill_headers6(const struct tcp_tap_conn *conn,
			 struct tap_hdr *taph,
			 struct ipv6hdr *ip6h, struct tcp_payload_t *bp,
			 size_t dlen, uint32_t seq, bool no_tcp_csum);
size_t tcp_l2_buf_fill_headers(const struct tcp_tap_conn *conn,
			       struct iovec *iov, size_t dlen,
			       const uint16_t *check, uint32_t seq,
			       bool no_tcp_csum);
int tcp_update_seqack_wnd(const struct ctx *c, struct tcp_tap_conn *conn,
			  bool force_seq, struct tcp_info_linux *tinfo);
int tcp_prepare_flags(const struct ctx *c, struct tcp_tap_conn *conn,
		      int flags, struct tcphdr *th, struct tcp_syn_opts *opts,
		      size_t *optlen);

#endif /* TCP_INTERNAL_H */

debug log:

solving d5d5d064f5ab ...
found d5d5d064f5ab in https://archives.passt.top/passt-dev/20241108103733.3554357-6-lvivier@redhat.com/
found a5a47df8203d in https://passt.top/passt
preparing index
index prepared:
100644 a5a47df8203d482ba9e93baac02e49544f606e1a	tcp_internal.h

applying [1/1] https://archives.passt.top/passt-dev/20241108103733.3554357-6-lvivier@redhat.com/
diff --git a/tcp_internal.h b/tcp_internal.h
index a5a47df8203d..d5d5d064f5ab 100644

Checking patch tcp_internal.h...
Applied patch tcp_internal.h cleanly.

index at:
100644 d5d5d064f5abe48d8280c135029cb85cc0b3b882	tcp_internal.h

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).