xref: /linux/tools/testing/selftests/net/lib/gro.c (revision 5d7f3375cd574fc83f0cd30839b21455c0e79ae2)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * This testsuite provides conformance testing for GRO coalescing.
4  *
5  * Test cases:
6  *
7  * data_*:
8  *  Data packets of the same size and same header setup with correct
9  *  sequence numbers coalesce. The one exception being the last data
10  *  packet coalesced: it can be smaller than the rest and coalesced
11  *  as long as it is in the same flow.
12  *   - data_same:    same size packets coalesce
13  *   - data_lrg_sml:   large then small coalesces
14  *   - data_lrg_1byte: large then 1 byte coalesces (Ethernet padding)
15  *   - data_sml_lrg:   small then large doesn't coalesce
16  *   - data_burst:   two bursts of two, separated by 100ms
17  *
18  * ack:
19  *  Pure ACK does not coalesce.
20  *
21  * flags_*:
22  *  No packets with PSH, SYN, URG, RST, CWR set will be coalesced.
23  *   - flags_psh, flags_syn, flags_rst, flags_urg, flags_cwr
24  *
25  * tcp_*:
26  *  Packets with incorrect checksum, non-consecutive seqno and
27  *  different TCP header options shouldn't coalesce. Nit: given that
28  *  some extension headers have paddings, such as timestamp, headers
29  *  that are padded differently would not be coalesced.
30  *   - tcp_csum: incorrect checksum
31  *   - tcp_seq:  non-consecutive sequence numbers
32  *   - tcp_ts:   different timestamps
33  *   - tcp_opt:  different TCP options
34  *
35  * ip_*:
36  *  Packets with different (ECN, TTL, TOS) header, IP options or
37  *  IP fragments shouldn't coalesce.
38  *   - ip_ecn, ip_tos:            shared between IPv4/IPv6
39  *   - ip_csum:                   IPv4 only, bad IP header checksum
40  *   - ip_ttl, ip_opt, ip_frag4:  IPv4 only
41  *   - ip_id_df*:                 IPv4 IP ID field coalescing tests
42  *   - ip_frag6, ip_v6ext_*:      IPv6 only
43  *
44  * large_*:
45  *  Packets larger than GRO_MAX_SIZE packets shouldn't coalesce.
46  *   - large_max: exceeding max size
47  *   - large_rem: remainder handling
48  *
49  * big_tcp_*:
50  *   - big_tcp_data_same:    equal segments coalescing past IP_MAXPACKET
51  *   - big_tcp_data_lrg_sml: a smaller final segment carrying it over
52  *   - big_tcp_tcp_seq:      16-bit truncated sequence number must not coalesce
53  *   - big_tcp_large_max:    coalescing stops at the configured limit
54  *
55  * single, capacity:
56  *  Boring cases used to test coalescing machinery itself and stats
57  *  more than protocol behavior.
58  *
59  * MSS is defined as 4096 - header because if it is too small
60  * (i.e. 1500 MTU - header), it will result in many packets,
61  * increasing the "large" test case's flakiness. This is because
62  * due to time sensitivity in the coalescing window, the receiver
63  * may not coalesce all of the packets.
64  *
65  * Note the timing issue applies to all of the test cases, so some
66  * flakiness is to be expected.
67  *
68  */
69 
70 #define _GNU_SOURCE
71 
72 #include <arpa/inet.h>
73 #include <errno.h>
74 #include <error.h>
75 #include <getopt.h>
76 #include <net/ethernet.h>
77 #include <net/if.h>
78 #include <linux/filter.h>
79 #include <linux/if_packet.h>
80 #include <linux/if_pppox.h>
81 #include <linux/ipv6.h>
82 #include <linux/net_tstamp.h>
83 #include <linux/ppp_defs.h>
84 #include <netinet/in.h>
85 #include <netinet/ip.h>
86 #include <netinet/ip6.h>
87 #include <netinet/tcp.h>
88 #include <stdbool.h>
89 #include <stddef.h>
90 #include <stdio.h>
91 #include <stdarg.h>
92 #include <string.h>
93 #include <time.h>
94 #include <unistd.h>
95 
96 #include "kselftest.h"
97 #include "ksft.h"
98 
99 #define DPORT 8000
100 #define SPORT 1500
101 #define PAYLOAD_LEN 100
102 #define NUM_PACKETS 4
103 #define START_SEQ 100
104 #define START_ACK 100
105 #define ETH_P_NONE 0
106 #define ASSUMED_MTU 4096
107 #define MAX_MSS (ASSUMED_MTU - sizeof(struct iphdr) - sizeof(struct tcphdr))
108 #define MAX_HDR_LEN \
109 	(ETH_HLEN + sizeof(struct ipv6hdr) * 2 + sizeof(struct tcphdr))
110 #define MAX_LARGE_PKT_CNT ((IP_MAXPACKET - (MAX_HDR_LEN - ETH_HLEN)) /	\
111 			   (ASSUMED_MTU - (MAX_HDR_LEN - ETH_HLEN)))
112 #define MIN_EXTHDR_SIZE 8
113 #define L2_HLEN_MAX	(ETH_HLEN + PPPOE_SES_HLEN)
114 #define EXT_PAYLOAD_1 "\x00\x00\x00\x00\x00\x00"
115 #define EXT_PAYLOAD_2 "\x11\x11\x11\x11\x11\x11"
116 
117 #define EXIT_OVER_COALESCE	42
118 
119 /* Must match BIG_TCP_GRO_MAX_SIZE in gro_lib.py. */
120 #define BIG_TCP_GRO_MAX_SIZE	128000
121 
122 #define BIG_TCP_RECV_BUF_LEN \
123 	(BIG_TCP_GRO_MAX_SIZE + MAX_MSS + L2_HLEN_MAX)
124 #define BIG_TCP_MIN_MSS		(ASSUMED_MTU - (MAX_HDR_LEN - ETH_HLEN))
125 #define BIG_TCP_MAX_FILL_CNT \
126 	((int)((BIG_TCP_GRO_MAX_SIZE - 1 - (MAX_HDR_LEN - ETH_HLEN)) / \
127 	       BIG_TCP_MIN_MSS))
128 
129 #define ipv6_optlen(p)  (((p)->hdrlen+1) << 3) /* calculate IPv6 extension header len */
130 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
131 
132 enum flush_id_case {
133 	FLUSH_ID_DF1_INC,
134 	FLUSH_ID_DF1_FIXED,
135 	FLUSH_ID_DF0_INC,
136 	FLUSH_ID_DF0_FIXED,
137 	FLUSH_ID_DF1_INC_FIXED,
138 	FLUSH_ID_DF1_FIXED_INC,
139 };
140 
141 static const char *addr6_src = "fdaa::2";
142 static const char *addr6_dst = "fdaa::1";
143 static const char *addr4_src = "192.168.1.200";
144 static const char *addr4_dst = "192.168.1.100";
145 static int proto = -1;
146 static uint8_t src_mac[ETH_ALEN], dst_mac[ETH_ALEN];
147 static char *testname = "data";
148 static char *ifname = "eth0";
149 static char *smac = "aa:00:00:00:00:02";
150 static char *dmac = "aa:00:00:00:00:01";
151 static bool verbose;
152 static bool tx_socket = true;
153 static int tcp_offset = -1;
154 static int total_hdr_len = -1;
155 static int ethhdr_proto = -1;
156 static bool ipip;
157 static bool ip6ip6;
158 static bool pppoe;
159 static uint64_t txtime_ns;
160 static int num_flows = 4;
161 static bool order_check;
162 
163 #define CAPACITY_PAYLOAD_LEN 200
164 
165 #define TXTIME_DELAY_MS 5
166 
167 /* Max TCP payload that GRO will coalesce. The outer header overhead
168  * varies by encapsulation, reducing the effective max payload.
169  */
170 static int max_payload(void)
171 {
172 	return IP_MAXPACKET - (total_hdr_len - ETH_HLEN);
173 }
174 
175 static int calc_mss(void)
176 {
177 	return ASSUMED_MTU - (total_hdr_len - ETH_HLEN);
178 }
179 
180 static int num_large_pkt(void)
181 {
182 	return max_payload() / calc_mss();
183 }
184 
185 /* How many maximum sized segments fit under the configured limit. */
186 static int big_tcp_large_cnt(void)
187 {
188 	return (BIG_TCP_GRO_MAX_SIZE - 1 - (total_hdr_len - ETH_HLEN)) /
189 	       calc_mss();
190 }
191 
192 /* How many calc_mss() sized segments are needed to satisfy the
193  * following condition:
194  * pkt_count * calc_mss() < IP_MAXPACKET < (pkt_count + 1) * calc_mss()
195  */
196 static int big_tcp_fill_cnt(void)
197 {
198 	return IP_MAXPACKET / calc_mss();
199 }
200 
201 static int big_tcp_fill_len(void)
202 {
203 	return big_tcp_fill_cnt() * calc_mss();
204 }
205 
206 static void vlog(const char *fmt, ...)
207 {
208 	va_list args;
209 
210 	if (verbose) {
211 		va_start(args, fmt);
212 		vfprintf(stderr, fmt, args);
213 		va_end(args);
214 	}
215 }
216 
217 static void fill_pppoelayer(void *buf, int payload_len, uint16_t sid)
218 {
219 	struct pppoe_ppp_hdr {
220 		struct pppoe_hdr eh;
221 		__be16 proto;
222 	} *ph = buf;
223 
224 	payload_len += sizeof(struct tcphdr);
225 	ph->eh.type = 1;
226 	ph->eh.ver = 1;
227 	ph->eh.code = 0;
228 	ph->eh.sid = htons(sid);
229 	ph->eh.length = htons(payload_len + sizeof(ph->proto));
230 	ph->proto = htons(proto == PF_INET ? PPP_IP : PPP_IPV6);
231 }
232 
233 static void setup_sock_filter(int fd)
234 {
235 	const int dport_off = tcp_offset + offsetof(struct tcphdr, dest);
236 	const int ethproto_off = offsetof(struct ethhdr, h_proto);
237 	int optlen = 0;
238 	int ipproto_off, opt_ipproto_off;
239 
240 	if (proto == PF_INET)
241 		ipproto_off = tcp_offset - sizeof(struct iphdr) +
242 			      offsetof(struct iphdr, protocol);
243 	else
244 		ipproto_off = tcp_offset - sizeof(struct ipv6hdr) +
245 			      offsetof(struct ipv6hdr, nexthdr);
246 
247 	/* Overridden later if exthdrs are used: */
248 	opt_ipproto_off = ipproto_off;
249 
250 	if (strcmp(testname, "ip_opt") == 0) {
251 		optlen = sizeof(struct ip_timestamp);
252 	} else if (strcmp(testname, "ip_frag6") == 0 ||
253 		   strcmp(testname, "ip_v6ext_same") == 0 ||
254 		   strcmp(testname, "ip_v6ext_diff") == 0) {
255 		BUILD_BUG_ON(sizeof(struct ip6_hbh) > MIN_EXTHDR_SIZE);
256 		BUILD_BUG_ON(sizeof(struct ip6_dest) > MIN_EXTHDR_SIZE);
257 		BUILD_BUG_ON(sizeof(struct ip6_frag) > MIN_EXTHDR_SIZE);
258 
259 		/* same size for HBH and Fragment extension header types */
260 		optlen = MIN_EXTHDR_SIZE;
261 		opt_ipproto_off = ETH_HLEN + sizeof(struct ipv6hdr)
262 			+ offsetof(struct ip6_ext, ip6e_nxt);
263 	}
264 
265 	/* this filter validates the following:
266 	 *	- packet is IPv4/IPv6 according to the running test.
267 	 *	- packet is TCP. Also handles the case of one extension header and then TCP.
268 	 *	- checks the packet tcp dport equals to DPORT. Also handles the case of one
269 	 *	  extension header and then TCP.
270 	 */
271 	struct sock_filter filter[] = {
272 			BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, ethproto_off),
273 			BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ntohs(ethhdr_proto), 0, 9),
274 			BPF_STMT(BPF_LD  + BPF_B   + BPF_ABS, ipproto_off),
275 			BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_TCP, 2, 0),
276 			BPF_STMT(BPF_LD  + BPF_B   + BPF_ABS, opt_ipproto_off),
277 			BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_TCP, 0, 5),
278 			BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, dport_off),
279 			BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DPORT, 2, 0),
280 			BPF_STMT(BPF_LD  + BPF_H   + BPF_ABS, dport_off + optlen),
281 			BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DPORT, 0, 1),
282 			BPF_STMT(BPF_RET + BPF_K, 0xFFFFFFFF),
283 			BPF_STMT(BPF_RET + BPF_K, 0),
284 	};
285 
286 	struct sock_fprog bpf = {
287 		.len = ARRAY_SIZE(filter),
288 		.filter = filter,
289 	};
290 
291 	if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)) < 0)
292 		error(1, errno, "error setting filter");
293 }
294 
295 static uint32_t checksum_nofold(void *data, size_t len, uint32_t sum)
296 {
297 	uint16_t *words = data;
298 	int i;
299 
300 	for (i = 0; i < len / 2; i++)
301 		sum += words[i];
302 	if (len & 1)
303 		sum += ((char *)data)[len - 1];
304 	return sum;
305 }
306 
307 static uint16_t checksum_fold(void *data, size_t len, uint32_t sum)
308 {
309 	sum = checksum_nofold(data, len, sum);
310 	while (sum > 0xFFFF)
311 		sum = (sum & 0xFFFF) + (sum >> 16);
312 	return ~sum;
313 }
314 
315 static uint16_t tcp_checksum(void *buf, int payload_len)
316 {
317 	struct pseudo_header6 {
318 		struct in6_addr saddr;
319 		struct in6_addr daddr;
320 		uint16_t protocol;
321 		uint16_t payload_len;
322 	} ph6;
323 	struct pseudo_header4 {
324 		struct in_addr saddr;
325 		struct in_addr daddr;
326 		uint16_t protocol;
327 		uint16_t payload_len;
328 	} ph4;
329 	uint32_t sum = 0;
330 
331 	if (proto == PF_INET6) {
332 		if (inet_pton(AF_INET6, addr6_src, &ph6.saddr) != 1)
333 			error(1, errno, "inet_pton6 source ip pseudo");
334 		if (inet_pton(AF_INET6, addr6_dst, &ph6.daddr) != 1)
335 			error(1, errno, "inet_pton6 dest ip pseudo");
336 		ph6.protocol = htons(IPPROTO_TCP);
337 		ph6.payload_len = htons(sizeof(struct tcphdr) + payload_len);
338 
339 		sum = checksum_nofold(&ph6, sizeof(ph6), 0);
340 	} else if (proto == PF_INET) {
341 		if (inet_pton(AF_INET, addr4_src, &ph4.saddr) != 1)
342 			error(1, errno, "inet_pton source ip pseudo");
343 		if (inet_pton(AF_INET, addr4_dst, &ph4.daddr) != 1)
344 			error(1, errno, "inet_pton dest ip pseudo");
345 		ph4.protocol = htons(IPPROTO_TCP);
346 		ph4.payload_len = htons(sizeof(struct tcphdr) + payload_len);
347 
348 		sum = checksum_nofold(&ph4, sizeof(ph4), 0);
349 	}
350 
351 	return checksum_fold(buf, sizeof(struct tcphdr) + payload_len, sum);
352 }
353 
354 static void read_MAC(uint8_t *mac_addr, char *mac)
355 {
356 	if (sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
357 		   &mac_addr[0], &mac_addr[1], &mac_addr[2],
358 		   &mac_addr[3], &mac_addr[4], &mac_addr[5]) != 6)
359 		error(1, 0, "sscanf");
360 }
361 
362 static void fill_datalinklayer(void *buf)
363 {
364 	struct ethhdr *eth = buf;
365 
366 	memcpy(eth->h_dest, dst_mac, ETH_ALEN);
367 	memcpy(eth->h_source, src_mac, ETH_ALEN);
368 	eth->h_proto = ethhdr_proto;
369 }
370 
371 static void fill_networklayer(void *buf, int payload_len, int protocol)
372 {
373 	struct ipv6hdr *ip6h = buf;
374 	struct iphdr *iph = buf;
375 
376 	if (proto == PF_INET6) {
377 		memset(ip6h, 0, sizeof(*ip6h));
378 
379 		ip6h->version = 6;
380 		ip6h->payload_len = htons(sizeof(struct tcphdr) + payload_len);
381 		ip6h->nexthdr = protocol;
382 		ip6h->hop_limit = 8;
383 		if (inet_pton(AF_INET6, addr6_src, &ip6h->saddr) != 1)
384 			error(1, errno, "inet_pton source ip6");
385 		if (inet_pton(AF_INET6, addr6_dst, &ip6h->daddr) != 1)
386 			error(1, errno, "inet_pton dest ip6");
387 	} else if (proto == PF_INET) {
388 		memset(iph, 0, sizeof(*iph));
389 
390 		iph->version = 4;
391 		iph->ihl = 5;
392 		iph->ttl = 8;
393 		iph->protocol	= protocol;
394 		iph->tot_len = htons(sizeof(struct tcphdr) +
395 				payload_len + sizeof(struct iphdr));
396 		iph->frag_off = htons(0x4000); /* DF = 1, MF = 0 */
397 		if (inet_pton(AF_INET, addr4_src, &iph->saddr) != 1)
398 			error(1, errno, "inet_pton source ip");
399 		if (inet_pton(AF_INET, addr4_dst, &iph->daddr) != 1)
400 			error(1, errno, "inet_pton dest ip");
401 		iph->check = checksum_fold(buf, sizeof(struct iphdr), 0);
402 	}
403 }
404 
405 static void fill_transportlayer(void *buf, int seq_offset, int ack_offset,
406 				int payload_len, int fin)
407 {
408 	struct tcphdr *tcph = buf;
409 
410 	memset(tcph, 0, sizeof(*tcph));
411 
412 	tcph->source = htons(SPORT);
413 	tcph->dest = htons(DPORT);
414 	tcph->seq = ntohl(START_SEQ + seq_offset);
415 	tcph->ack_seq = ntohl(START_ACK + ack_offset);
416 	tcph->ack = 1;
417 	tcph->fin = fin;
418 	tcph->doff = 5;
419 	tcph->window = htons(TCP_MAXWIN);
420 	tcph->urg_ptr = 0;
421 	tcph->check = tcp_checksum(tcph, payload_len);
422 }
423 
424 static void write_packet(int fd, char *buf, int len, struct sockaddr_ll *daddr)
425 {
426 	char control[CMSG_SPACE(sizeof(uint64_t))];
427 	struct msghdr msg = {};
428 	struct iovec iov = {};
429 	struct cmsghdr *cm;
430 	int ret = -1;
431 
432 	iov.iov_base = buf;
433 	iov.iov_len = len;
434 
435 	msg.msg_iov = &iov;
436 	msg.msg_iovlen = 1;
437 	msg.msg_name = daddr;
438 	msg.msg_namelen = sizeof(*daddr);
439 
440 	if (txtime_ns) {
441 		memset(control, 0, sizeof(control));
442 		msg.msg_control = control;
443 		msg.msg_controllen = sizeof(control);
444 
445 		cm = CMSG_FIRSTHDR(&msg);
446 		cm->cmsg_level = SOL_SOCKET;
447 		cm->cmsg_type = SCM_TXTIME;
448 		cm->cmsg_len = CMSG_LEN(sizeof(uint64_t));
449 		memcpy(CMSG_DATA(cm), &txtime_ns, sizeof(txtime_ns));
450 	}
451 
452 	ret = sendmsg(fd, &msg, 0);
453 	if (ret == -1)
454 		error(1, errno, "sendmsg failure");
455 	if (ret != len)
456 		error(1, 0, "sendmsg wrong length: %d vs %d", ret, len);
457 }
458 
459 static void create_packet(void *buf, int seq_offset, int ack_offset,
460 			  int payload_len, int fin)
461 {
462 	int ip_hdr_len = (proto == PF_INET) ?
463 			 sizeof(struct iphdr) : sizeof(struct ipv6hdr);
464 	int inner_ip_off = tcp_offset - ip_hdr_len;
465 
466 	memset(buf, 0, total_hdr_len);
467 	memset(buf + total_hdr_len, 'a', payload_len);
468 
469 	fill_transportlayer(buf + tcp_offset, seq_offset, ack_offset,
470 			    payload_len, fin);
471 
472 	fill_networklayer(buf + inner_ip_off, payload_len, IPPROTO_TCP);
473 	if (inner_ip_off > ETH_HLEN) {
474 		if (pppoe) {
475 			fill_pppoelayer(buf + ETH_HLEN, payload_len + ip_hdr_len, 0x1234);
476 		} else {
477 			int encap_proto = (proto == PF_INET) ?
478 					  IPPROTO_IPIP : IPPROTO_IPV6;
479 
480 			fill_networklayer(buf + ETH_HLEN,
481 					  payload_len + ip_hdr_len, encap_proto);
482 		}
483 	}
484 
485 	fill_datalinklayer(buf);
486 }
487 
488 static void create_capacity_packet(void *buf, int flow_id, int pkt_idx, int psh)
489 {
490 	int seq_offset = pkt_idx * CAPACITY_PAYLOAD_LEN;
491 	struct tcphdr *tcph;
492 
493 	create_packet(buf, seq_offset, 0, CAPACITY_PAYLOAD_LEN, 0);
494 
495 	/* Customize for this flow id */
496 	memset(buf + total_hdr_len, 'a' + flow_id, CAPACITY_PAYLOAD_LEN);
497 
498 	tcph = buf + tcp_offset;
499 	tcph->source = htons(SPORT + flow_id);
500 	tcph->psh = psh;
501 	tcph->check = 0;
502 	tcph->check = tcp_checksum(tcph, CAPACITY_PAYLOAD_LEN);
503 }
504 
505 /* Send a capacity test, 2 packets per flow, all first packets then all second:
506  *  A1 B1 C1 D1 ... A2 B2 C2 D2 ...
507  */
508 static void send_capacity(int fd, struct sockaddr_ll *daddr)
509 {
510 	static char buf[MAX_HDR_LEN + CAPACITY_PAYLOAD_LEN];
511 	int pkt_size = total_hdr_len + CAPACITY_PAYLOAD_LEN;
512 	int i;
513 
514 	/* Send first packet of each flow (no PSH) */
515 	for (i = 0; i < num_flows; i++) {
516 		create_capacity_packet(buf, i, 0, 0);
517 		write_packet(fd, buf, pkt_size, daddr);
518 	}
519 
520 	/* Send second packet of each flow (with PSH to flush) */
521 	for (i = 0; i < num_flows; i++) {
522 		create_capacity_packet(buf, i, 1, 1);
523 		write_packet(fd, buf, pkt_size, daddr);
524 	}
525 }
526 
527 #ifndef TH_CWR
528 #define TH_CWR 0x80
529 #endif
530 static void set_flags(struct tcphdr *tcph, int payload_len, int psh, int syn,
531 		      int rst, int urg, int cwr)
532 {
533 	tcph->psh = psh;
534 	tcph->syn = syn;
535 	tcph->rst = rst;
536 	tcph->urg = urg;
537 	if (cwr)
538 		tcph->th_flags |= TH_CWR;
539 	else
540 		tcph->th_flags &= ~TH_CWR;
541 	tcph->check = 0;
542 	tcph->check = tcp_checksum(tcph, payload_len);
543 }
544 
545 /* send extra flags of the (NUM_PACKETS / 2) and (NUM_PACKETS / 2 - 1)
546  * pkts, not first and not last pkt
547  */
548 static void send_flags(int fd, struct sockaddr_ll *daddr, int psh, int syn,
549 		       int rst, int urg, int cwr)
550 {
551 	static char flag_buf[2][MAX_HDR_LEN + PAYLOAD_LEN];
552 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
553 	int payload_len, pkt_size, i;
554 	struct tcphdr *tcph;
555 	int flag[2];
556 
557 	payload_len = PAYLOAD_LEN * (psh || cwr);
558 	pkt_size = total_hdr_len + payload_len;
559 	flag[0] = NUM_PACKETS / 2;
560 	flag[1] = NUM_PACKETS / 2 - 1;
561 
562 	/* Create and configure packets with flags
563 	 */
564 	for (i = 0; i < 2; i++) {
565 		if (flag[i] > 0) {
566 			create_packet(flag_buf[i], flag[i] * payload_len, 0,
567 				      payload_len, 0);
568 			tcph = (struct tcphdr *)(flag_buf[i] + tcp_offset);
569 			set_flags(tcph, payload_len, psh, syn, rst, urg, cwr);
570 		}
571 	}
572 
573 	for (i = 0; i < NUM_PACKETS + 1; i++) {
574 		if (i == flag[0]) {
575 			write_packet(fd, flag_buf[0], pkt_size, daddr);
576 			continue;
577 		} else if (i == flag[1] && cwr) {
578 			write_packet(fd, flag_buf[1], pkt_size, daddr);
579 			continue;
580 		}
581 		create_packet(buf, i * PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
582 		write_packet(fd, buf, total_hdr_len + PAYLOAD_LEN, daddr);
583 	}
584 }
585 
586 /* Test for data of same length, smaller than previous
587  * and of different lengths
588  */
589 static void send_data_pkts(int fd, struct sockaddr_ll *daddr,
590 			   int payload_len1, int payload_len2)
591 {
592 	static char buf[L2_HLEN_MAX + IP_MAXPACKET];
593 
594 	create_packet(buf, 0, 0, payload_len1, 0);
595 	write_packet(fd, buf, total_hdr_len + payload_len1, daddr);
596 	create_packet(buf, payload_len1, 0, payload_len2, 0);
597 	write_packet(fd, buf, total_hdr_len + payload_len2, daddr);
598 }
599 
600 /* Send num_pkt segments of pkt_len bytes, then one of remainder len. */
601 static void send_big_tcp(int fd, struct sockaddr_ll *daddr, int pkt_len,
602 			 int num_pkt, int remainder)
603 {
604 	static char pkts[BIG_TCP_MAX_FILL_CNT][MAX_HDR_LEN + MAX_MSS];
605 	static char last[MAX_HDR_LEN + MAX_MSS];
606 	const int filled = num_pkt * pkt_len;
607 	int i;
608 
609 	if (num_pkt > BIG_TCP_MAX_FILL_CNT)
610 		error(1, 0, "need %d packets, array holds %d",
611 		      num_pkt, BIG_TCP_MAX_FILL_CNT);
612 
613 	for (i = 0; i < num_pkt; i++)
614 		create_packet(pkts[i], i * pkt_len, 0, pkt_len, 0);
615 	create_packet(last, filled, 0, remainder, 0);
616 
617 	for (i = 0; i < num_pkt; i++)
618 		write_packet(fd, pkts[i], total_hdr_len + pkt_len, daddr);
619 	write_packet(fd, last, total_hdr_len + remainder, daddr);
620 }
621 
622 /* In BIG TCP configuration, the total aggregate length can
623  * be greater than the legacy IP_MAXPACKET. Since the aggregate
624  * length is used in calculating the sequence numbers,
625  * send a packet with a sequence number that differs by IP_MAXPACKET + 1,
626  * to test against truncation bugs.
627  */
628 static void send_big_tcp_bad_seq(int fd, struct sockaddr_ll *daddr)
629 {
630 	static char pkts[BIG_TCP_MAX_FILL_CNT][MAX_HDR_LEN + MAX_MSS];
631 	const int num_pkt = big_tcp_fill_cnt() + 1;
632 	static char last[MAX_HDR_LEN + MAX_MSS];
633 	const int pkt_len = calc_mss();
634 	int bad_seq;
635 	int filled;
636 	int i;
637 
638 	filled = num_pkt * pkt_len;
639 	/* Low 16 bits match with the correct incoming sequence number. */
640 	bad_seq = filled - (IP_MAXPACKET + 1);
641 
642 	if (num_pkt > BIG_TCP_MAX_FILL_CNT)
643 		error(1, 0, "need %d packets, array holds %d",
644 		      num_pkt, BIG_TCP_MAX_FILL_CNT);
645 
646 	for (i = 0; i < num_pkt; i++)
647 		create_packet(pkts[i], i * pkt_len, 0, pkt_len, 0);
648 	create_packet(last, bad_seq, 0, pkt_len, 0);
649 
650 	for (i = 0; i < num_pkt; i++)
651 		write_packet(fd, pkts[i], total_hdr_len + pkt_len, daddr);
652 	write_packet(fd, last, total_hdr_len + pkt_len, daddr);
653 }
654 
655 /* If incoming segments make tracked segment length exceed
656  * legal IP datagram length, do not coalesce
657  */
658 static void send_large(int fd, struct sockaddr_ll *daddr, int remainder)
659 {
660 	static char pkts[MAX_LARGE_PKT_CNT][MAX_HDR_LEN + MAX_MSS];
661 	static char new_seg[MAX_HDR_LEN + MAX_MSS];
662 	static char last[MAX_HDR_LEN + MAX_MSS];
663 	const int num_pkt = num_large_pkt();
664 	const int mss = calc_mss();
665 	int i;
666 
667 	for (i = 0; i < num_pkt; i++)
668 		create_packet(pkts[i], i * mss, 0, mss, 0);
669 	create_packet(last, num_pkt * mss, 0, remainder, 0);
670 	create_packet(new_seg, (num_pkt + 1) * mss, 0, remainder, 0);
671 
672 	for (i = 0; i < num_pkt; i++)
673 		write_packet(fd, pkts[i], total_hdr_len + mss, daddr);
674 	write_packet(fd, last, total_hdr_len + remainder, daddr);
675 	write_packet(fd, new_seg, total_hdr_len + remainder, daddr);
676 }
677 
678 /* Pure acks and dup acks don't coalesce */
679 static void send_ack(int fd, struct sockaddr_ll *daddr)
680 {
681 	static char buf[MAX_HDR_LEN];
682 
683 	create_packet(buf, 0, 0, 0, 0);
684 	write_packet(fd, buf, total_hdr_len, daddr);
685 	write_packet(fd, buf, total_hdr_len, daddr);
686 	create_packet(buf, 0, 1, 0, 0);
687 	write_packet(fd, buf, total_hdr_len, daddr);
688 }
689 
690 static void recompute_packet(char *buf, char *no_ext, int extlen)
691 {
692 	struct tcphdr *tcphdr = (struct tcphdr *)(buf + tcp_offset);
693 	int off;
694 
695 	memmove(buf, no_ext, total_hdr_len);
696 	memmove(buf + total_hdr_len + extlen,
697 		no_ext + total_hdr_len, PAYLOAD_LEN);
698 
699 	tcphdr->doff = tcphdr->doff + (extlen / 4);
700 	tcphdr->check = 0;
701 	tcphdr->check = tcp_checksum(tcphdr, PAYLOAD_LEN + extlen);
702 	if (proto == PF_INET) {
703 		for (off = ETH_HLEN; off < tcp_offset;
704 		     off += sizeof(struct iphdr)) {
705 			struct iphdr *iph = (struct iphdr *)(buf + off);
706 
707 			iph->tot_len = htons(ntohs(iph->tot_len) + extlen);
708 			iph->check = 0;
709 			iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
710 		}
711 	} else {
712 		for (off = ETH_HLEN; off < tcp_offset;
713 		     off += sizeof(struct ipv6hdr)) {
714 			struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + off);
715 
716 			ip6h->payload_len =
717 				htons(ntohs(ip6h->payload_len) + extlen);
718 		}
719 	}
720 }
721 
722 static void tcp_write_options(char *buf, int kind, int ts)
723 {
724 	struct tcp_option_ts {
725 		uint8_t kind;
726 		uint8_t len;
727 		uint32_t tsval;
728 		uint32_t tsecr;
729 	} *opt_ts = (void *)buf;
730 	struct tcp_option_window {
731 		uint8_t kind;
732 		uint8_t len;
733 		uint8_t shift;
734 	} *opt_window = (void *)buf;
735 
736 	switch (kind) {
737 	case TCPOPT_NOP:
738 		buf[0] = TCPOPT_NOP;
739 		break;
740 	case TCPOPT_WINDOW:
741 		memset(opt_window, 0, sizeof(struct tcp_option_window));
742 		opt_window->kind = TCPOPT_WINDOW;
743 		opt_window->len = TCPOLEN_WINDOW;
744 		opt_window->shift = 0;
745 		break;
746 	case TCPOPT_TIMESTAMP:
747 		memset(opt_ts, 0, sizeof(struct tcp_option_ts));
748 		opt_ts->kind = TCPOPT_TIMESTAMP;
749 		opt_ts->len = TCPOLEN_TIMESTAMP;
750 		opt_ts->tsval = ts;
751 		opt_ts->tsecr = 0;
752 		break;
753 	default:
754 		error(1, 0, "unimplemented TCP option");
755 		break;
756 	}
757 }
758 
759 /* TCP with options is always a permutation of {TS, NOP, NOP}.
760  * Implement different orders to verify coalescing stops.
761  */
762 static void add_standard_tcp_options(char *buf, char *no_ext, int ts, int order)
763 {
764 	switch (order) {
765 	case 0:
766 		tcp_write_options(buf + total_hdr_len, TCPOPT_NOP, 0);
767 		tcp_write_options(buf + total_hdr_len + 1, TCPOPT_NOP, 0);
768 		tcp_write_options(buf + total_hdr_len + 2 /* two NOP opts */,
769 				  TCPOPT_TIMESTAMP, ts);
770 		break;
771 	case 1:
772 		tcp_write_options(buf + total_hdr_len, TCPOPT_NOP, 0);
773 		tcp_write_options(buf + total_hdr_len + 1,
774 				  TCPOPT_TIMESTAMP, ts);
775 		tcp_write_options(buf + total_hdr_len + 1 + TCPOLEN_TIMESTAMP,
776 				  TCPOPT_NOP, 0);
777 		break;
778 	case 2:
779 		tcp_write_options(buf + total_hdr_len, TCPOPT_TIMESTAMP, ts);
780 		tcp_write_options(buf + total_hdr_len + TCPOLEN_TIMESTAMP + 1,
781 				  TCPOPT_NOP, 0);
782 		tcp_write_options(buf + total_hdr_len + TCPOLEN_TIMESTAMP + 2,
783 				  TCPOPT_NOP, 0);
784 		break;
785 	default:
786 		error(1, 0, "unknown order");
787 		break;
788 	}
789 	recompute_packet(buf, no_ext, TCPOLEN_TSTAMP_APPA);
790 }
791 
792 /* Packets with invalid checksum don't coalesce. */
793 static void send_changed_checksum(int fd, struct sockaddr_ll *daddr)
794 {
795 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
796 	struct tcphdr *tcph = (struct tcphdr *)(buf + tcp_offset);
797 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
798 
799 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
800 	write_packet(fd, buf, pkt_size, daddr);
801 
802 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
803 	tcph->check = tcph->check - 1;
804 	write_packet(fd, buf, pkt_size, daddr);
805 }
806 
807 /* Packets with incorrect IPv4 header checksum don't coalesce. */
808 static void send_changed_ip_checksum(int fd, struct sockaddr_ll *daddr)
809 {
810 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
811 	struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
812 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
813 
814 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
815 	write_packet(fd, buf, pkt_size, daddr);
816 
817 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
818 	iph->check = iph->check - 1;
819 	write_packet(fd, buf, pkt_size, daddr);
820 
821 	create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
822 	write_packet(fd, buf, pkt_size, daddr);
823 }
824 
825  /* Packets with non-consecutive sequence number don't coalesce.*/
826 static void send_changed_seq(int fd, struct sockaddr_ll *daddr)
827 {
828 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
829 	struct tcphdr *tcph = (struct tcphdr *)(buf + tcp_offset);
830 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
831 
832 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
833 	write_packet(fd, buf, pkt_size, daddr);
834 
835 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
836 	tcph->seq = ntohl(htonl(tcph->seq) + 1);
837 	tcph->check = 0;
838 	tcph->check = tcp_checksum(tcph, PAYLOAD_LEN);
839 	write_packet(fd, buf, pkt_size, daddr);
840 }
841 
842  /* Packet with different timestamp option or different timestamps
843   * don't coalesce.
844   */
845 static void send_changed_ts(int fd, struct sockaddr_ll *daddr)
846 {
847 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
848 	static char extpkt[sizeof(buf) + TCPOLEN_TSTAMP_APPA];
849 	int pkt_size = total_hdr_len + PAYLOAD_LEN + TCPOLEN_TSTAMP_APPA;
850 
851 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
852 	add_standard_tcp_options(extpkt, buf, 0, 0);
853 	write_packet(fd, extpkt, pkt_size, daddr);
854 
855 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
856 	add_standard_tcp_options(extpkt, buf, 0, 0);
857 	write_packet(fd, extpkt, pkt_size, daddr);
858 
859 	create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
860 	add_standard_tcp_options(extpkt, buf, 100, 0);
861 	write_packet(fd, extpkt, pkt_size, daddr);
862 
863 	create_packet(buf, PAYLOAD_LEN * 3, 0, PAYLOAD_LEN, 0);
864 	add_standard_tcp_options(extpkt, buf, 100, 1);
865 	write_packet(fd, extpkt, pkt_size, daddr);
866 
867 	create_packet(buf, PAYLOAD_LEN * 4, 0, PAYLOAD_LEN, 0);
868 	add_standard_tcp_options(extpkt, buf, 100, 2);
869 	write_packet(fd, extpkt, pkt_size, daddr);
870 }
871 
872 /* Packet with different tcp options don't coalesce. */
873 static void send_diff_opt(int fd, struct sockaddr_ll *daddr)
874 {
875 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
876 	static char extpkt1[sizeof(buf) + TCPOLEN_TSTAMP_APPA];
877 	static char extpkt2[sizeof(buf) + TCPOLEN_MAXSEG];
878 	int extpkt1_size = total_hdr_len + PAYLOAD_LEN + TCPOLEN_TSTAMP_APPA;
879 	int extpkt2_size = total_hdr_len + PAYLOAD_LEN + TCPOLEN_MAXSEG;
880 
881 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
882 	add_standard_tcp_options(extpkt1, buf, 0, 0);
883 	write_packet(fd, extpkt1, extpkt1_size, daddr);
884 
885 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
886 	add_standard_tcp_options(extpkt1, buf, 0, 0);
887 	write_packet(fd, extpkt1, extpkt1_size, daddr);
888 
889 	create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
890 	tcp_write_options(extpkt2 + MAX_HDR_LEN, TCPOPT_NOP, 0);
891 	tcp_write_options(extpkt2 + MAX_HDR_LEN + 1, TCPOPT_WINDOW, 0);
892 	recompute_packet(extpkt2, buf, TCPOLEN_WINDOW + 1);
893 	write_packet(fd, extpkt2, extpkt2_size, daddr);
894 }
895 
896 static void add_ipv4_ts_option(void *buf, void *optpkt)
897 {
898 	struct ip_timestamp *ts = (struct ip_timestamp *)(optpkt + tcp_offset);
899 	int optlen = sizeof(struct ip_timestamp);
900 	struct iphdr *iph;
901 
902 	if (optlen % 4)
903 		error(1, 0, "ipv4 timestamp length is not a multiple of 4B");
904 
905 	ts->ipt_code = IPOPT_TS;
906 	ts->ipt_len = optlen;
907 	ts->ipt_ptr = 5;
908 	ts->ipt_flg = IPOPT_TS_TSONLY;
909 
910 	memcpy(optpkt, buf, tcp_offset);
911 	memcpy(optpkt + tcp_offset + optlen, buf + tcp_offset,
912 	       sizeof(struct tcphdr) + PAYLOAD_LEN);
913 
914 	iph = (struct iphdr *)(optpkt + ETH_HLEN);
915 	iph->ihl = 5 + (optlen / 4);
916 	iph->tot_len = htons(ntohs(iph->tot_len) + optlen);
917 	iph->check = 0;
918 	iph->check = checksum_fold(iph, sizeof(struct iphdr) + optlen, 0);
919 }
920 
921 static void add_ipv6_exthdr(void *buf, void *optpkt, __u8 exthdr_type, char *ext_payload)
922 {
923 	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr *)(optpkt + tcp_offset);
924 	struct ipv6hdr *iph = (struct ipv6hdr *)(optpkt + ETH_HLEN);
925 	char *exthdr_payload_start = (char *)(exthdr + 1);
926 
927 	exthdr->hdrlen = 0;
928 	exthdr->nexthdr = IPPROTO_TCP;
929 
930 	memcpy(exthdr_payload_start, ext_payload, MIN_EXTHDR_SIZE - sizeof(*exthdr));
931 
932 	memcpy(optpkt, buf, tcp_offset);
933 	memcpy(optpkt + tcp_offset + MIN_EXTHDR_SIZE, buf + tcp_offset,
934 		sizeof(struct tcphdr) + PAYLOAD_LEN);
935 
936 	iph->nexthdr = exthdr_type;
937 	iph->payload_len = htons(ntohs(iph->payload_len) + MIN_EXTHDR_SIZE);
938 }
939 
940 static void fix_ip4_checksum(struct iphdr *iph)
941 {
942 	iph->check = 0;
943 	iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
944 }
945 
946 static void send_flush_id_case(int fd, struct sockaddr_ll *daddr,
947 			       enum flush_id_case tcase)
948 {
949 	static char buf1[MAX_HDR_LEN + PAYLOAD_LEN];
950 	static char buf2[MAX_HDR_LEN + PAYLOAD_LEN];
951 	static char buf3[MAX_HDR_LEN + PAYLOAD_LEN];
952 	bool send_three = false;
953 	struct iphdr *iph1;
954 	struct iphdr *iph2;
955 	struct iphdr *iph3;
956 
957 	iph1 = (struct iphdr *)(buf1 + ETH_HLEN);
958 	iph2 = (struct iphdr *)(buf2 + ETH_HLEN);
959 	iph3 = (struct iphdr *)(buf3 + ETH_HLEN);
960 
961 	create_packet(buf1, 0, 0, PAYLOAD_LEN, 0);
962 	create_packet(buf2, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
963 	create_packet(buf3, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
964 
965 	switch (tcase) {
966 	case FLUSH_ID_DF1_INC: /* DF=1, Incrementing - should coalesce */
967 		iph1->frag_off |= htons(IP_DF);
968 		iph1->id = htons(8);
969 
970 		iph2->frag_off |= htons(IP_DF);
971 		iph2->id = htons(9);
972 		break;
973 
974 	case FLUSH_ID_DF1_FIXED: /* DF=1, Fixed - should coalesce */
975 		iph1->frag_off |= htons(IP_DF);
976 		iph1->id = htons(8);
977 
978 		iph2->frag_off |= htons(IP_DF);
979 		iph2->id = htons(8);
980 		break;
981 
982 	case FLUSH_ID_DF0_INC: /* DF=0, Incrementing - should coalesce */
983 		iph1->frag_off &= ~htons(IP_DF);
984 		iph1->id = htons(8);
985 
986 		iph2->frag_off &= ~htons(IP_DF);
987 		iph2->id = htons(9);
988 		break;
989 
990 	case FLUSH_ID_DF0_FIXED: /* DF=0, Fixed - should coalesce */
991 		iph1->frag_off &= ~htons(IP_DF);
992 		iph1->id = htons(8);
993 
994 		iph2->frag_off &= ~htons(IP_DF);
995 		iph2->id = htons(8);
996 		break;
997 
998 	case FLUSH_ID_DF1_INC_FIXED: /* DF=1, two packets incrementing, and
999 				      * one fixed - should coalesce only the
1000 				      * first two packets
1001 				      */
1002 		iph1->frag_off |= htons(IP_DF);
1003 		iph1->id = htons(8);
1004 
1005 		iph2->frag_off |= htons(IP_DF);
1006 		iph2->id = htons(9);
1007 
1008 		iph3->frag_off |= htons(IP_DF);
1009 		iph3->id = htons(9);
1010 		send_three = true;
1011 		break;
1012 
1013 	case FLUSH_ID_DF1_FIXED_INC: /* DF=1, two packets fixed, and one
1014 				      * incrementing - should coalesce only
1015 				      * the first two packets
1016 				      */
1017 		iph1->frag_off |= htons(IP_DF);
1018 		iph1->id = htons(8);
1019 
1020 		iph2->frag_off |= htons(IP_DF);
1021 		iph2->id = htons(8);
1022 
1023 		iph3->frag_off |= htons(IP_DF);
1024 		iph3->id = htons(9);
1025 		send_three = true;
1026 		break;
1027 	}
1028 
1029 	fix_ip4_checksum(iph1);
1030 	fix_ip4_checksum(iph2);
1031 	write_packet(fd, buf1, total_hdr_len + PAYLOAD_LEN, daddr);
1032 	write_packet(fd, buf2, total_hdr_len + PAYLOAD_LEN, daddr);
1033 
1034 	if (send_three) {
1035 		fix_ip4_checksum(iph3);
1036 		write_packet(fd, buf3, total_hdr_len + PAYLOAD_LEN, daddr);
1037 	}
1038 }
1039 
1040 static void send_ipv6_exthdr(int fd, struct sockaddr_ll *daddr, char *ext_data1, char *ext_data2)
1041 {
1042 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1043 	static char exthdr_pck[sizeof(buf) + MIN_EXTHDR_SIZE];
1044 
1045 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1046 	add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_DSTOPTS, ext_data1);
1047 	write_packet(fd, exthdr_pck, total_hdr_len + PAYLOAD_LEN + MIN_EXTHDR_SIZE, daddr);
1048 
1049 	create_packet(buf, PAYLOAD_LEN * 1, 0, PAYLOAD_LEN, 0);
1050 	add_ipv6_exthdr(buf, exthdr_pck, IPPROTO_DSTOPTS, ext_data2);
1051 	write_packet(fd, exthdr_pck, total_hdr_len + PAYLOAD_LEN + MIN_EXTHDR_SIZE, daddr);
1052 }
1053 
1054 /* IPv4 options shouldn't coalesce */
1055 static void send_ip_options(int fd, struct sockaddr_ll *daddr)
1056 {
1057 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1058 	static char optpkt[sizeof(buf) + sizeof(struct ip_timestamp)];
1059 	int optlen = sizeof(struct ip_timestamp);
1060 	int pkt_size = total_hdr_len + PAYLOAD_LEN + optlen;
1061 
1062 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1063 	write_packet(fd, buf, total_hdr_len + PAYLOAD_LEN, daddr);
1064 
1065 	create_packet(buf, PAYLOAD_LEN * 1, 0, PAYLOAD_LEN, 0);
1066 	add_ipv4_ts_option(buf, optpkt);
1067 	write_packet(fd, optpkt, pkt_size, daddr);
1068 
1069 	create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
1070 	write_packet(fd, buf, total_hdr_len + PAYLOAD_LEN, daddr);
1071 }
1072 
1073 /*  IPv4 fragments shouldn't coalesce */
1074 static void send_fragment4(int fd, struct sockaddr_ll *daddr)
1075 {
1076 	static char buf[IP_MAXPACKET];
1077 	struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
1078 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
1079 
1080 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1081 	write_packet(fd, buf, pkt_size, daddr);
1082 
1083 	/* Once fragmented, packet would retain the total_len.
1084 	 * Tcp header is prepared as if rest of data is in follow-up frags,
1085 	 * but follow up frags aren't actually sent.
1086 	 */
1087 	memset(buf + total_hdr_len, 'a', PAYLOAD_LEN * 2);
1088 	fill_transportlayer(buf + tcp_offset, PAYLOAD_LEN, 0, PAYLOAD_LEN * 2, 0);
1089 	fill_networklayer(buf + ETH_HLEN, PAYLOAD_LEN, IPPROTO_TCP);
1090 	fill_datalinklayer(buf);
1091 
1092 	iph->frag_off = htons(0x6000); // DF = 1, MF = 1
1093 	iph->check = 0;
1094 	iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
1095 	write_packet(fd, buf, pkt_size, daddr);
1096 }
1097 
1098 /* IPv4 packets with different ttl don't coalesce.*/
1099 static void send_changed_ttl(int fd, struct sockaddr_ll *daddr)
1100 {
1101 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
1102 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1103 	struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
1104 
1105 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1106 	write_packet(fd, buf, pkt_size, daddr);
1107 
1108 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
1109 	iph->ttl = 7;
1110 	iph->check = 0;
1111 	iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
1112 	write_packet(fd, buf, pkt_size, daddr);
1113 }
1114 
1115 /* Packets with different tos don't coalesce.*/
1116 static void send_changed_tos(int fd, struct sockaddr_ll *daddr)
1117 {
1118 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
1119 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1120 	struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
1121 	struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN);
1122 
1123 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1124 	write_packet(fd, buf, pkt_size, daddr);
1125 
1126 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
1127 	if (proto == PF_INET) {
1128 		iph->tos = 1;
1129 		iph->check = 0;
1130 		iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
1131 	} else if (proto == PF_INET6) {
1132 		ip6h->priority = 0xf;
1133 	}
1134 	write_packet(fd, buf, pkt_size, daddr);
1135 }
1136 
1137 /* Packets with different ECN don't coalesce.*/
1138 static void send_changed_ECN(int fd, struct sockaddr_ll *daddr)
1139 {
1140 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
1141 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1142 	struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
1143 
1144 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1145 	write_packet(fd, buf, pkt_size, daddr);
1146 
1147 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
1148 	if (proto == PF_INET) {
1149 		buf[ETH_HLEN + 1] ^= 0x2; // ECN set to 10
1150 		iph->check = 0;
1151 		iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
1152 	} else {
1153 		buf[ETH_HLEN + 1] ^= 0x20; // ECN set to 10
1154 	}
1155 	write_packet(fd, buf, pkt_size, daddr);
1156 }
1157 
1158 /* IPv6 fragments and packets with extensions don't coalesce.*/
1159 static void send_fragment6(int fd, struct sockaddr_ll *daddr)
1160 {
1161 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1162 	static char extpkt[MAX_HDR_LEN + PAYLOAD_LEN +
1163 			   sizeof(struct ip6_frag)];
1164 	struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN);
1165 	struct ip6_frag *frag = (void *)(extpkt + tcp_offset);
1166 	int extlen = sizeof(struct ip6_frag);
1167 	int bufpkt_len = total_hdr_len + PAYLOAD_LEN;
1168 	int extpkt_len = bufpkt_len + extlen;
1169 	int i;
1170 
1171 	for (i = 0; i < 2; i++) {
1172 		create_packet(buf, PAYLOAD_LEN * i, 0, PAYLOAD_LEN, 0);
1173 		write_packet(fd, buf, bufpkt_len, daddr);
1174 	}
1175 	sleep(1);
1176 	create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
1177 	memset(extpkt, 0, extpkt_len);
1178 
1179 	ip6h->nexthdr = IPPROTO_FRAGMENT;
1180 	ip6h->payload_len = htons(ntohs(ip6h->payload_len) + extlen);
1181 	frag->ip6f_nxt = IPPROTO_TCP;
1182 
1183 	memcpy(extpkt, buf, tcp_offset);
1184 	memcpy(extpkt + tcp_offset + extlen, buf + tcp_offset,
1185 	       sizeof(struct tcphdr) + PAYLOAD_LEN);
1186 	write_packet(fd, extpkt, extpkt_len, daddr);
1187 
1188 	create_packet(buf, PAYLOAD_LEN * 3, 0, PAYLOAD_LEN, 0);
1189 	write_packet(fd, buf, bufpkt_len, daddr);
1190 }
1191 
1192 static void send_changed_pppoe_sid(int fd, struct sockaddr_ll *daddr)
1193 {
1194 	static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1195 	int pkt_size = total_hdr_len + PAYLOAD_LEN;
1196 	struct pppoe_hdr *hdr = (struct pppoe_hdr *)(buf + ETH_HLEN);
1197 
1198 	create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1199 	write_packet(fd, buf, pkt_size, daddr);
1200 
1201 	create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
1202 	hdr->sid = htons(0x4321);
1203 	write_packet(fd, buf, pkt_size, daddr);
1204 }
1205 
1206 static void bind_packetsocket(int fd)
1207 {
1208 	struct sockaddr_ll daddr = {};
1209 
1210 	daddr.sll_family = AF_PACKET;
1211 	daddr.sll_protocol = ethhdr_proto;
1212 	daddr.sll_ifindex = if_nametoindex(ifname);
1213 	if (daddr.sll_ifindex == 0)
1214 		error(1, errno, "if_nametoindex");
1215 
1216 	if (bind(fd, (void *)&daddr, sizeof(daddr)) < 0)
1217 		error(1, errno, "could not bind socket");
1218 }
1219 
1220 static void set_timeout(int fd)
1221 {
1222 	struct timeval timeout;
1223 
1224 	timeout.tv_sec = 3;
1225 	timeout.tv_usec = 0;
1226 	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
1227 		       sizeof(timeout)) < 0)
1228 		error(1, errno, "cannot set timeout, setsockopt failed");
1229 }
1230 
1231 static void set_rcvbuf(int fd)
1232 {
1233 	int bufsize = 1 * 1024 * 1024; /* 1 MB */
1234 
1235 	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize)))
1236 		error(1, errno, "cannot set rcvbuf size, setsockopt failed");
1237 }
1238 
1239 static void recv_error(int fd, int rcv_errno)
1240 {
1241 	struct tpacket_stats stats;
1242 	socklen_t len;
1243 
1244 	len = sizeof(stats);
1245 	if (getsockopt(fd, SOL_PACKET, PACKET_STATISTICS, &stats, &len))
1246 		error(1, errno, "can't get stats");
1247 
1248 	fprintf(stderr, "Socket stats: packets=%u, drops=%u\n",
1249 		stats.tp_packets, stats.tp_drops);
1250 	error(1, rcv_errno, "could not receive");
1251 }
1252 
1253 static void check_recv_pkts(int fd, int *correct_payload,
1254 			    int correct_num_pkts)
1255 {
1256 	static char buffer[BIG_TCP_RECV_BUF_LEN];
1257 	int nhoff = ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0);
1258 	struct iphdr *iph = (struct iphdr *)(buffer + nhoff);
1259 	struct ipv6hdr *ip6h = (struct ipv6hdr *)(buffer + nhoff);
1260 	struct tcphdr *tcph;
1261 	bool bad_packet = false;
1262 	int bytes_expected = 0;
1263 	int bytes_received = 0;
1264 	int tcp_ext_len = 0;
1265 	int ip_ext_len = 0;
1266 	int pkt_size = -1;
1267 	int data_len = 0;
1268 	int num_pkt = 0;
1269 	int i;
1270 
1271 	vlog("Expected {");
1272 	for (i = 0; i < correct_num_pkts; i++) {
1273 		vlog("%d ", correct_payload[i]);
1274 		bytes_expected += correct_payload[i];
1275 	}
1276 	vlog("}, Total %d packets\nReceived {", correct_num_pkts);
1277 
1278 	while (1) {
1279 		ip_ext_len = 0;
1280 		pkt_size = recv(fd, buffer, sizeof(buffer), 0);
1281 		if (pkt_size < 0)
1282 			recv_error(fd, errno);
1283 
1284 		if (iph->version == 4)
1285 			ip_ext_len = (iph->ihl - 5) * 4;
1286 		else if (ip6h->version == 6 && !ip6ip6 &&
1287 			 ip6h->nexthdr != IPPROTO_TCP)
1288 			ip_ext_len = MIN_EXTHDR_SIZE;
1289 
1290 		tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
1291 
1292 		if (tcph->fin)
1293 			break;
1294 
1295 		tcp_ext_len = (tcph->doff - 5) * 4;
1296 		data_len = pkt_size - total_hdr_len - tcp_ext_len - ip_ext_len;
1297 		/* Min ethernet frame payload is 46(ETH_ZLEN - ETH_HLEN) by RFC 802.3.
1298 		 * Ipv4/tcp packets without at least 6 bytes of data will be padded.
1299 		 * Packet sockets are protocol agnostic, and will not trim the padding.
1300 		 */
1301 		if (pkt_size == ETH_ZLEN && iph->version == 4) {
1302 			data_len = ntohs(iph->tot_len)
1303 				- sizeof(struct tcphdr) - sizeof(struct iphdr);
1304 		}
1305 		vlog("%d ", data_len);
1306 		if (num_pkt < correct_num_pkts &&
1307 		    data_len != correct_payload[num_pkt]) {
1308 			vlog("[!=%d]", correct_payload[num_pkt]);
1309 			bad_packet = true;
1310 		}
1311 		bytes_received += data_len;
1312 		num_pkt++;
1313 	}
1314 	vlog("}, Total %d packets.\n", num_pkt);
1315 	/* Signal over-coalescing explicitly, it's a hard failure, unlike
1316 	 * under-coalescing which could be timing- or loss-related.
1317 	 */
1318 	if (num_pkt < correct_num_pkts && bytes_received == bytes_expected)
1319 		error(EXIT_OVER_COALESCE, 0,
1320 		      "over-coalesced: got %d pkts vs expected %d (%d B)",
1321 		      num_pkt, correct_num_pkts, bytes_received);
1322 	if (num_pkt != correct_num_pkts)
1323 		error(1, 0, "incorrect number of packets");
1324 	if (bad_packet)
1325 		error(1, 0, "incorrect packet geometry");
1326 
1327 	printf("Test succeeded\n\n");
1328 }
1329 
1330 static void check_capacity_pkts(int fd)
1331 {
1332 	static char buffer[IP_MAXPACKET + L2_HLEN_MAX + 1];
1333 	int nhoff = ETH_HLEN + (pppoe ? PPPOE_SES_HLEN : 0);
1334 	struct iphdr *iph = (struct iphdr *)(buffer + nhoff);
1335 	struct ipv6hdr *ip6h = (struct ipv6hdr *)(buffer + nhoff);
1336 	int num_pkt = 0, num_coal = 0, pkt_idx;
1337 	const char *fail_reason = NULL;
1338 	int flow_order[num_flows * 2];
1339 	int coalesced[num_flows];
1340 	struct tcphdr *tcph;
1341 	int ip_ext_len = 0;
1342 	int pkt_size = -1;
1343 	int data_len = 0;
1344 	int flow_id;
1345 	int sport;
1346 
1347 	memset(coalesced, 0, sizeof(coalesced));
1348 	memset(flow_order, -1, sizeof(flow_order));
1349 
1350 	while (1) {
1351 		ip_ext_len = 0;
1352 		pkt_size = recv(fd, buffer, sizeof(buffer), 0);
1353 		if (pkt_size < 0)
1354 			recv_error(fd, errno);
1355 
1356 		if (iph->version == 4)
1357 			ip_ext_len = (iph->ihl - 5) * 4;
1358 		else if (ip6h->version == 6 && !ip6ip6 &&
1359 			 ip6h->nexthdr != IPPROTO_TCP)
1360 			ip_ext_len = MIN_EXTHDR_SIZE;
1361 
1362 		tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
1363 
1364 		if (tcph->fin)
1365 			break;
1366 
1367 		sport = ntohs(tcph->source);
1368 		flow_id = sport - SPORT;
1369 
1370 		if (flow_id < 0 || flow_id >= num_flows) {
1371 			vlog("Invalid flow_id %d from sport %d\n",
1372 			     flow_id, sport);
1373 			fail_reason = fail_reason ?: "invalid packet";
1374 			continue;
1375 		}
1376 
1377 		/* Calculate payload length */
1378 		if (pkt_size == ETH_ZLEN && iph->version == 4) {
1379 			data_len = ntohs(iph->tot_len)
1380 				- sizeof(struct tcphdr) - sizeof(struct iphdr);
1381 		} else {
1382 			data_len = pkt_size - total_hdr_len - ip_ext_len;
1383 		}
1384 
1385 		if (num_pkt < num_flows * 2) {
1386 			flow_order[num_pkt] = flow_id;
1387 		} else if (num_pkt == num_flows * 2) {
1388 			vlog("More packets than expected (%d)\n",
1389 			     num_flows * 2);
1390 			fail_reason = fail_reason ?: "too many packets";
1391 		}
1392 		coalesced[flow_id] = data_len;
1393 
1394 		if (data_len == CAPACITY_PAYLOAD_LEN * 2) {
1395 			num_coal++;
1396 		} else {
1397 			vlog("Pkt %d: flow %d, sport %d, len %d (expected %d)\n",
1398 			     num_pkt, flow_id, sport, data_len,
1399 			     CAPACITY_PAYLOAD_LEN * 2);
1400 			fail_reason = fail_reason ?: "not coalesced";
1401 		}
1402 
1403 		num_pkt++;
1404 	}
1405 
1406 	/* Check flow ordering. We expect to see all non-coalesced first segs
1407 	 * then interleaved coalesced and non-coalesced second frames.
1408 	 */
1409 	pkt_idx = 0;
1410 	for (flow_id = 0; order_check && flow_id < num_flows; flow_id++) {
1411 		bool coaled = coalesced[flow_id] > CAPACITY_PAYLOAD_LEN;
1412 
1413 		if (coaled)
1414 			continue;
1415 
1416 		if (flow_order[pkt_idx] != flow_id) {
1417 			vlog("Flow order mismatch (non-coalesced) at position %d: expected flow %d, got flow %d\n",
1418 			     pkt_idx, flow_id, flow_order[pkt_idx]);
1419 			fail_reason = fail_reason ?: "bad packet order (1)";
1420 		}
1421 		pkt_idx++;
1422 	}
1423 	for (flow_id = 0; order_check && flow_id < num_flows; flow_id++) {
1424 		bool coaled = coalesced[flow_id] > CAPACITY_PAYLOAD_LEN;
1425 
1426 		if (flow_order[pkt_idx] != flow_id) {
1427 			vlog("Flow order mismatch at position %d: expected flow %d, got flow %d, coalesced: %d\n",
1428 			     pkt_idx, flow_id, flow_order[pkt_idx], coaled);
1429 			fail_reason = fail_reason ?: "bad packet order (2)";
1430 		}
1431 		pkt_idx++;
1432 	}
1433 
1434 	if (!fail_reason) {
1435 		vlog("All %d flows coalesced correctly\n", num_flows);
1436 		printf("Test succeeded\n\n");
1437 	} else {
1438 		printf("FAILED\n");
1439 	}
1440 
1441 	/* Always print stats for external validation */
1442 	printf("STATS: received=%d wire=%d coalesced=%d\n",
1443 	       num_pkt, num_pkt + num_coal, num_coal);
1444 
1445 	if (fail_reason)
1446 		error(1, 0, "capacity test failed %s", fail_reason);
1447 }
1448 
1449 static void gro_sender(void)
1450 {
1451 	int bufsize = 4 * 1024 * 1024; /* 4 MB */
1452 	const int fin_delay_us = 100 * 1000;
1453 	static char fin_pkt[MAX_HDR_LEN];
1454 	struct sockaddr_ll daddr = {};
1455 	int txfd = -1;
1456 
1457 	txfd = socket(PF_PACKET, SOCK_RAW, IPPROTO_RAW);
1458 	if (txfd < 0)
1459 		error(1, errno, "socket creation");
1460 
1461 	if (setsockopt(txfd, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)))
1462 		error(1, errno, "cannot set sndbuf size, setsockopt failed");
1463 
1464 	/* Enable SO_TXTIME unless test case generates more than one flow
1465 	 * SO_TXTIME could result in qdisc layer sorting the packets at sender.
1466 	 */
1467 	if (strcmp(testname, "single") && strcmp(testname, "capacity")) {
1468 		struct sock_txtime so_txtime = { .clockid = CLOCK_MONOTONIC, };
1469 		struct timespec ts;
1470 
1471 		if (setsockopt(txfd, SOL_SOCKET, SO_TXTIME,
1472 			       &so_txtime, sizeof(so_txtime)))
1473 			error(1, errno, "setsockopt SO_TXTIME");
1474 
1475 		if (clock_gettime(CLOCK_MONOTONIC, &ts))
1476 			error(1, errno, "clock_gettime");
1477 
1478 		txtime_ns = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
1479 		txtime_ns += TXTIME_DELAY_MS * 1000000ULL;
1480 	}
1481 
1482 	memset(&daddr, 0, sizeof(daddr));
1483 	daddr.sll_ifindex = if_nametoindex(ifname);
1484 	if (daddr.sll_ifindex == 0)
1485 		error(1, errno, "if_nametoindex");
1486 	daddr.sll_family = AF_PACKET;
1487 	memcpy(daddr.sll_addr, dst_mac, ETH_ALEN);
1488 	daddr.sll_halen = ETH_ALEN;
1489 	create_packet(fin_pkt, PAYLOAD_LEN * 2, 0, 0, 1);
1490 
1491 	/* data sub-tests */
1492 	if (strcmp(testname, "data_same") == 0) {
1493 		send_data_pkts(txfd, &daddr, PAYLOAD_LEN, PAYLOAD_LEN);
1494 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1495 	} else if (strcmp(testname, "data_lrg_sml") == 0) {
1496 		send_data_pkts(txfd, &daddr, PAYLOAD_LEN, PAYLOAD_LEN / 2);
1497 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1498 	} else if (strcmp(testname, "data_lrg_1byte") == 0) {
1499 		send_data_pkts(txfd, &daddr, PAYLOAD_LEN, 1);
1500 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1501 	} else if (strcmp(testname, "data_sml_lrg") == 0) {
1502 		send_data_pkts(txfd, &daddr, PAYLOAD_LEN / 2, PAYLOAD_LEN);
1503 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1504 	} else if (strcmp(testname, "data_burst") == 0) {
1505 		static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1506 
1507 		create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1508 		write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
1509 		create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
1510 		write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
1511 
1512 		usleep(100 * 1000); /* 100ms */
1513 		create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
1514 		write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
1515 		create_packet(buf, PAYLOAD_LEN * 3, 0, PAYLOAD_LEN, 0);
1516 		write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
1517 
1518 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1519 
1520 	/* ack test */
1521 	} else if (strcmp(testname, "ack") == 0) {
1522 		send_ack(txfd, &daddr);
1523 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1524 
1525 	/* flags sub-tests */
1526 	} else if (strcmp(testname, "flags_psh") == 0) {
1527 		send_flags(txfd, &daddr, 1, 0, 0, 0, 0);
1528 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1529 	} else if (strcmp(testname, "flags_syn") == 0) {
1530 		send_flags(txfd, &daddr, 0, 1, 0, 0, 0);
1531 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1532 	} else if (strcmp(testname, "flags_rst") == 0) {
1533 		send_flags(txfd, &daddr, 0, 0, 1, 0, 0);
1534 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1535 	} else if (strcmp(testname, "flags_urg") == 0) {
1536 		send_flags(txfd, &daddr, 0, 0, 0, 1, 0);
1537 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1538 	} else if (strcmp(testname, "flags_cwr") == 0) {
1539 		send_flags(txfd, &daddr, 0, 0, 0, 0, 1);
1540 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1541 
1542 	/* tcp sub-tests */
1543 	} else if (strcmp(testname, "tcp_csum") == 0) {
1544 		send_changed_checksum(txfd, &daddr);
1545 		usleep(fin_delay_us);
1546 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1547 	} else if (strcmp(testname, "tcp_seq") == 0) {
1548 		send_changed_seq(txfd, &daddr);
1549 		usleep(fin_delay_us);
1550 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1551 	} else if (strcmp(testname, "tcp_ts") == 0) {
1552 		send_changed_ts(txfd, &daddr);
1553 		usleep(fin_delay_us);
1554 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1555 	} else if (strcmp(testname, "tcp_opt") == 0) {
1556 		send_diff_opt(txfd, &daddr);
1557 		usleep(fin_delay_us);
1558 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1559 
1560 	/* ip sub-tests - shared between IPv4 and IPv6 */
1561 	} else if (strcmp(testname, "ip_ecn") == 0) {
1562 		send_changed_ECN(txfd, &daddr);
1563 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1564 	} else if (strcmp(testname, "ip_tos") == 0) {
1565 		send_changed_tos(txfd, &daddr);
1566 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1567 
1568 	/* ip sub-tests - IPv4 only */
1569 	} else if (strcmp(testname, "ip_csum") == 0) {
1570 		send_changed_ip_checksum(txfd, &daddr);
1571 		usleep(fin_delay_us);
1572 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1573 	} else if (strcmp(testname, "ip_ttl") == 0) {
1574 		send_changed_ttl(txfd, &daddr);
1575 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1576 	} else if (strcmp(testname, "ip_opt") == 0) {
1577 		send_ip_options(txfd, &daddr);
1578 		usleep(fin_delay_us);
1579 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1580 	} else if (strcmp(testname, "ip_frag4") == 0) {
1581 		send_fragment4(txfd, &daddr);
1582 		usleep(fin_delay_us);
1583 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1584 	} else if (strcmp(testname, "ip_id_df1_inc") == 0) {
1585 		send_flush_id_case(txfd, &daddr, FLUSH_ID_DF1_INC);
1586 		usleep(fin_delay_us);
1587 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1588 	} else if (strcmp(testname, "ip_id_df1_fixed") == 0) {
1589 		send_flush_id_case(txfd, &daddr, FLUSH_ID_DF1_FIXED);
1590 		usleep(fin_delay_us);
1591 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1592 	} else if (strcmp(testname, "ip_id_df0_inc") == 0) {
1593 		send_flush_id_case(txfd, &daddr, FLUSH_ID_DF0_INC);
1594 		usleep(fin_delay_us);
1595 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1596 	} else if (strcmp(testname, "ip_id_df0_fixed") == 0) {
1597 		send_flush_id_case(txfd, &daddr, FLUSH_ID_DF0_FIXED);
1598 		usleep(fin_delay_us);
1599 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1600 	} else if (strcmp(testname, "ip_id_df1_inc_fixed") == 0) {
1601 		send_flush_id_case(txfd, &daddr, FLUSH_ID_DF1_INC_FIXED);
1602 		usleep(fin_delay_us);
1603 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1604 	} else if (strcmp(testname, "ip_id_df1_fixed_inc") == 0) {
1605 		send_flush_id_case(txfd, &daddr, FLUSH_ID_DF1_FIXED_INC);
1606 		usleep(fin_delay_us);
1607 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1608 
1609 	/* ip sub-tests - IPv6 only */
1610 	} else if (strcmp(testname, "ip_frag6") == 0) {
1611 		send_fragment6(txfd, &daddr);
1612 		usleep(fin_delay_us);
1613 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1614 	} else if (strcmp(testname, "ip_v6ext_same") == 0) {
1615 		send_ipv6_exthdr(txfd, &daddr, EXT_PAYLOAD_1, EXT_PAYLOAD_1);
1616 		usleep(fin_delay_us);
1617 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1618 	} else if (strcmp(testname, "ip_v6ext_diff") == 0) {
1619 		send_ipv6_exthdr(txfd, &daddr, EXT_PAYLOAD_1, EXT_PAYLOAD_2);
1620 		usleep(fin_delay_us);
1621 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1622 
1623 	/* large sub-tests */
1624 	} else if (strcmp(testname, "large_max") == 0) {
1625 		int remainder = max_payload() % calc_mss();
1626 
1627 		send_large(txfd, &daddr, remainder);
1628 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1629 	} else if (strcmp(testname, "large_rem") == 0) {
1630 		int remainder = max_payload() % calc_mss();
1631 
1632 		send_large(txfd, &daddr, remainder + 1);
1633 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1634 
1635 	/* big tcp sub-tests */
1636 	} else if (strcmp(testname, "big_tcp_data_same") == 0) {
1637 		send_big_tcp(txfd, &daddr, calc_mss(), big_tcp_fill_cnt(),
1638 			     calc_mss());
1639 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1640 	} else if (strcmp(testname, "big_tcp_data_lrg_sml") == 0) {
1641 		int remainder = calc_mss() / 2;
1642 
1643 		send_big_tcp(txfd, &daddr, calc_mss(), big_tcp_fill_cnt(),
1644 			     remainder);
1645 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1646 	} else if (strcmp(testname, "big_tcp_tcp_seq") == 0) {
1647 		send_big_tcp_bad_seq(txfd, &daddr);
1648 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1649 	} else if (strcmp(testname, "big_tcp_large_max") == 0) {
1650 		send_big_tcp(txfd, &daddr, calc_mss(), big_tcp_large_cnt(),
1651 			     calc_mss());
1652 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1653 
1654 	/* machinery sub-tests */
1655 	} else if (strcmp(testname, "single") == 0) {
1656 		static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
1657 
1658 		create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
1659 		write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
1660 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1661 	} else if (strcmp(testname, "capacity") == 0) {
1662 		send_capacity(txfd, &daddr);
1663 		usleep(fin_delay_us);
1664 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1665 
1666 	/* PPPoE sub-tests */
1667 	} else if (strcmp(testname, "pppoe_sid") == 0) {
1668 		send_changed_pppoe_sid(txfd, &daddr);
1669 		usleep(fin_delay_us);
1670 		write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1671 
1672 	} else {
1673 		error(1, 0, "Unknown testcase: %s", testname);
1674 	}
1675 
1676 	if (close(txfd))
1677 		error(1, errno, "socket close");
1678 }
1679 
1680 static void gro_receiver(void)
1681 {
1682 	static int correct_payload[NUM_PACKETS];
1683 	int rxfd = -1;
1684 
1685 	rxfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_NONE));
1686 	if (rxfd < 0)
1687 		error(1, 0, "socket creation");
1688 	setup_sock_filter(rxfd);
1689 	set_timeout(rxfd);
1690 	set_rcvbuf(rxfd);
1691 	bind_packetsocket(rxfd);
1692 
1693 	ksft_ready();
1694 
1695 	memset(correct_payload, 0, sizeof(correct_payload));
1696 
1697 	/* data sub-tests */
1698 	if (strcmp(testname, "data_same") == 0) {
1699 		printf("pure data packet of same size: ");
1700 		correct_payload[0] = PAYLOAD_LEN * 2;
1701 		check_recv_pkts(rxfd, correct_payload, 1);
1702 	} else if (strcmp(testname, "data_lrg_sml") == 0) {
1703 		printf("large data packets followed by a smaller one: ");
1704 		correct_payload[0] = PAYLOAD_LEN * 1.5;
1705 		check_recv_pkts(rxfd, correct_payload, 1);
1706 	} else if (strcmp(testname, "data_lrg_1byte") == 0) {
1707 		printf("large data packet followed by a 1 byte one: ");
1708 		correct_payload[0] = PAYLOAD_LEN + 1;
1709 		check_recv_pkts(rxfd, correct_payload, 1);
1710 	} else if (strcmp(testname, "data_sml_lrg") == 0) {
1711 		printf("small data packets followed by a larger one: ");
1712 		correct_payload[0] = PAYLOAD_LEN / 2;
1713 		correct_payload[1] = PAYLOAD_LEN;
1714 		check_recv_pkts(rxfd, correct_payload, 2);
1715 	} else if (strcmp(testname, "data_burst") == 0) {
1716 		printf("two bursts of two data packets: ");
1717 		correct_payload[0] = PAYLOAD_LEN * 2;
1718 		correct_payload[1] = PAYLOAD_LEN * 2;
1719 		check_recv_pkts(rxfd, correct_payload, 2);
1720 
1721 	/* ack test */
1722 	} else if (strcmp(testname, "ack") == 0) {
1723 		printf("duplicate ack and pure ack: ");
1724 		check_recv_pkts(rxfd, correct_payload, 3);
1725 
1726 	/* flags sub-tests */
1727 	} else if (strcmp(testname, "flags_psh") == 0) {
1728 		correct_payload[0] = PAYLOAD_LEN * 3;
1729 		correct_payload[1] = PAYLOAD_LEN * 2;
1730 		printf("psh flag ends coalescing: ");
1731 		check_recv_pkts(rxfd, correct_payload, 2);
1732 	} else if (strcmp(testname, "flags_syn") == 0) {
1733 		correct_payload[0] = PAYLOAD_LEN * 2;
1734 		correct_payload[1] = 0;
1735 		correct_payload[2] = PAYLOAD_LEN * 2;
1736 		printf("syn flag ends coalescing: ");
1737 		check_recv_pkts(rxfd, correct_payload, 3);
1738 	} else if (strcmp(testname, "flags_rst") == 0) {
1739 		correct_payload[0] = PAYLOAD_LEN * 2;
1740 		correct_payload[1] = 0;
1741 		correct_payload[2] = PAYLOAD_LEN * 2;
1742 		printf("rst flag ends coalescing: ");
1743 		check_recv_pkts(rxfd, correct_payload, 3);
1744 	} else if (strcmp(testname, "flags_urg") == 0) {
1745 		correct_payload[0] = PAYLOAD_LEN * 2;
1746 		correct_payload[1] = 0;
1747 		correct_payload[2] = PAYLOAD_LEN * 2;
1748 		printf("urg flag ends coalescing: ");
1749 		check_recv_pkts(rxfd, correct_payload, 3);
1750 	} else if (strcmp(testname, "flags_cwr") == 0) {
1751 		correct_payload[0] = PAYLOAD_LEN;
1752 		correct_payload[1] = PAYLOAD_LEN * 2;
1753 		correct_payload[2] = PAYLOAD_LEN * 2;
1754 		printf("cwr flag ends coalescing: ");
1755 		check_recv_pkts(rxfd, correct_payload, 3);
1756 
1757 	/* tcp sub-tests */
1758 	} else if (strcmp(testname, "tcp_csum") == 0) {
1759 		correct_payload[0] = PAYLOAD_LEN;
1760 		correct_payload[1] = PAYLOAD_LEN;
1761 		printf("changed checksum does not coalesce: ");
1762 		check_recv_pkts(rxfd, correct_payload, 2);
1763 	} else if (strcmp(testname, "tcp_seq") == 0) {
1764 		correct_payload[0] = PAYLOAD_LEN;
1765 		correct_payload[1] = PAYLOAD_LEN;
1766 		printf("Wrong Seq number doesn't coalesce: ");
1767 		check_recv_pkts(rxfd, correct_payload, 2);
1768 	} else if (strcmp(testname, "tcp_ts") == 0) {
1769 		correct_payload[0] = PAYLOAD_LEN * 2;
1770 		correct_payload[1] = PAYLOAD_LEN;
1771 		correct_payload[2] = PAYLOAD_LEN;
1772 		correct_payload[3] = PAYLOAD_LEN;
1773 		printf("Different timestamp doesn't coalesce: ");
1774 		check_recv_pkts(rxfd, correct_payload, 4);
1775 	} else if (strcmp(testname, "tcp_opt") == 0) {
1776 		correct_payload[0] = PAYLOAD_LEN * 2;
1777 		correct_payload[1] = PAYLOAD_LEN;
1778 		printf("Different options doesn't coalesce: ");
1779 		check_recv_pkts(rxfd, correct_payload, 2);
1780 
1781 	/* ip sub-tests - shared between IPv4 and IPv6 */
1782 	} else if (strcmp(testname, "ip_ecn") == 0) {
1783 		correct_payload[0] = PAYLOAD_LEN;
1784 		correct_payload[1] = PAYLOAD_LEN;
1785 		printf("different ECN doesn't coalesce: ");
1786 		check_recv_pkts(rxfd, correct_payload, 2);
1787 	} else if (strcmp(testname, "ip_tos") == 0) {
1788 		correct_payload[0] = PAYLOAD_LEN;
1789 		correct_payload[1] = PAYLOAD_LEN;
1790 		printf("different tos doesn't coalesce: ");
1791 		check_recv_pkts(rxfd, correct_payload, 2);
1792 
1793 	/* ip sub-tests - IPv4 only */
1794 	} else if (strcmp(testname, "ip_csum") == 0) {
1795 		correct_payload[0] = PAYLOAD_LEN;
1796 		correct_payload[1] = PAYLOAD_LEN;
1797 		correct_payload[2] = PAYLOAD_LEN;
1798 		printf("bad ip checksum doesn't coalesce: ");
1799 		check_recv_pkts(rxfd, correct_payload, 3);
1800 	} else if (strcmp(testname, "ip_ttl") == 0) {
1801 		correct_payload[0] = PAYLOAD_LEN;
1802 		correct_payload[1] = PAYLOAD_LEN;
1803 		printf("different ttl doesn't coalesce: ");
1804 		check_recv_pkts(rxfd, correct_payload, 2);
1805 	} else if (strcmp(testname, "ip_opt") == 0) {
1806 		correct_payload[0] = PAYLOAD_LEN;
1807 		correct_payload[1] = PAYLOAD_LEN;
1808 		correct_payload[2] = PAYLOAD_LEN;
1809 		printf("ip options doesn't coalesce: ");
1810 		check_recv_pkts(rxfd, correct_payload, 3);
1811 	} else if (strcmp(testname, "ip_frag4") == 0) {
1812 		correct_payload[0] = PAYLOAD_LEN;
1813 		correct_payload[1] = PAYLOAD_LEN;
1814 		printf("fragmented ip4 doesn't coalesce: ");
1815 		check_recv_pkts(rxfd, correct_payload, 2);
1816 	} else if (strcmp(testname, "ip_id_df1_inc") == 0) {
1817 		printf("DF=1, Incrementing - should coalesce: ");
1818 		correct_payload[0] = PAYLOAD_LEN * 2;
1819 		check_recv_pkts(rxfd, correct_payload, 1);
1820 	} else if (strcmp(testname, "ip_id_df1_fixed") == 0) {
1821 		printf("DF=1, Fixed - should coalesce: ");
1822 		correct_payload[0] = PAYLOAD_LEN * 2;
1823 		check_recv_pkts(rxfd, correct_payload, 1);
1824 	} else if (strcmp(testname, "ip_id_df0_inc") == 0) {
1825 		printf("DF=0, Incrementing - should coalesce: ");
1826 		correct_payload[0] = PAYLOAD_LEN * 2;
1827 		check_recv_pkts(rxfd, correct_payload, 1);
1828 	} else if (strcmp(testname, "ip_id_df0_fixed") == 0) {
1829 		printf("DF=0, Fixed - should coalesce: ");
1830 		correct_payload[0] = PAYLOAD_LEN * 2;
1831 		check_recv_pkts(rxfd, correct_payload, 1);
1832 	} else if (strcmp(testname, "ip_id_df1_inc_fixed") == 0) {
1833 		printf("DF=1, 2 Incrementing and one fixed - should coalesce only first 2 packets: ");
1834 		correct_payload[0] = PAYLOAD_LEN * 2;
1835 		correct_payload[1] = PAYLOAD_LEN;
1836 		check_recv_pkts(rxfd, correct_payload, 2);
1837 	} else if (strcmp(testname, "ip_id_df1_fixed_inc") == 0) {
1838 		printf("DF=1, 2 Fixed and one incrementing - should coalesce only first 2 packets: ");
1839 		correct_payload[0] = PAYLOAD_LEN * 2;
1840 		correct_payload[1] = PAYLOAD_LEN;
1841 		check_recv_pkts(rxfd, correct_payload, 2);
1842 
1843 	/* ip sub-tests - IPv6 only */
1844 	} else if (strcmp(testname, "ip_frag6") == 0) {
1845 		/* GRO doesn't check for ipv6 hop limit when flushing.
1846 		 * Hence no corresponding test to the ipv4 case.
1847 		 */
1848 		printf("fragmented ip6 doesn't coalesce: ");
1849 		correct_payload[0] = PAYLOAD_LEN * 2;
1850 		correct_payload[1] = PAYLOAD_LEN;
1851 		correct_payload[2] = PAYLOAD_LEN;
1852 		check_recv_pkts(rxfd, correct_payload, 3);
1853 	} else if (strcmp(testname, "ip_v6ext_same") == 0) {
1854 		printf("ipv6 with ext header does coalesce: ");
1855 		correct_payload[0] = PAYLOAD_LEN * 2;
1856 		check_recv_pkts(rxfd, correct_payload, 1);
1857 	} else if (strcmp(testname, "ip_v6ext_diff") == 0) {
1858 		printf("ipv6 with ext header with different payloads doesn't coalesce: ");
1859 		correct_payload[0] = PAYLOAD_LEN;
1860 		correct_payload[1] = PAYLOAD_LEN;
1861 		check_recv_pkts(rxfd, correct_payload, 2);
1862 
1863 	/* large sub-tests */
1864 	} else if (strcmp(testname, "large_max") == 0) {
1865 		int remainder = max_payload() % calc_mss();
1866 
1867 		correct_payload[0] = max_payload();
1868 		correct_payload[1] = remainder;
1869 		printf("Shouldn't coalesce if exceed IP max pkt size: ");
1870 		check_recv_pkts(rxfd, correct_payload, 2);
1871 	} else if (strcmp(testname, "large_rem") == 0) {
1872 		int remainder = max_payload() % calc_mss();
1873 
1874 		/* last segment sent individually, doesn't start new segment */
1875 		correct_payload[0] = max_payload() - remainder;
1876 		correct_payload[1] = remainder + 1;
1877 		correct_payload[2] = remainder + 1;
1878 		printf("last segment sent individually: ");
1879 		check_recv_pkts(rxfd, correct_payload, 3);
1880 
1881 	/* big tcp sub-tests */
1882 	} else if (strcmp(testname, "big_tcp_data_same") == 0) {
1883 		correct_payload[0] = big_tcp_fill_len() + calc_mss();
1884 		printf("data packets of same size past IP_MAXPACKET: ");
1885 		check_recv_pkts(rxfd, correct_payload, 1);
1886 	} else if (strcmp(testname, "big_tcp_data_lrg_sml") == 0) {
1887 		correct_payload[0] = big_tcp_fill_len() + calc_mss() / 2;
1888 		printf("smaller last packet past IP_MAXPACKET: ");
1889 		check_recv_pkts(rxfd, correct_payload, 1);
1890 	} else if (strcmp(testname, "big_tcp_tcp_seq") == 0) {
1891 		correct_payload[0] = (big_tcp_fill_cnt() + 1) * calc_mss();
1892 		correct_payload[1] = calc_mss();
1893 		printf("aliased seq past IP_MAXPACKET doesn't coalesce: ");
1894 		check_recv_pkts(rxfd, correct_payload, 2);
1895 	} else if (strcmp(testname, "big_tcp_large_max") == 0) {
1896 		correct_payload[0] = big_tcp_large_cnt() * calc_mss();
1897 		correct_payload[1] = calc_mss();
1898 		printf("shouldn't coalesce past gro_max_size: ");
1899 		check_recv_pkts(rxfd, correct_payload, 2);
1900 
1901 	/* machinery sub-tests */
1902 	} else if (strcmp(testname, "single") == 0) {
1903 		printf("single data packet: ");
1904 		correct_payload[0] = PAYLOAD_LEN;
1905 		check_recv_pkts(rxfd, correct_payload, 1);
1906 	} else if (strcmp(testname, "capacity") == 0) {
1907 		check_capacity_pkts(rxfd);
1908 
1909 	} else if (strcmp(testname, "pppoe_sid") == 0) {
1910 		correct_payload[0] = PAYLOAD_LEN;
1911 		correct_payload[1] = PAYLOAD_LEN;
1912 		printf("different PPPoE session ID doesn't coalesce: ");
1913 		check_recv_pkts(rxfd, correct_payload, 2);
1914 
1915 	} else {
1916 		error(1, 0, "Test case error: unknown testname %s", testname);
1917 	}
1918 
1919 	if (close(rxfd))
1920 		error(1, 0, "socket close");
1921 }
1922 
1923 static void parse_args(int argc, char **argv)
1924 {
1925 	static const struct option opts[] = {
1926 		{ "daddr", required_argument, NULL, 'd' },
1927 		{ "dmac", required_argument, NULL, 'D' },
1928 		{ "iface", required_argument, NULL, 'i' },
1929 		{ "ipv4", no_argument, NULL, '4' },
1930 		{ "ipv6", no_argument, NULL, '6' },
1931 		{ "ipip", no_argument, NULL, 'e' },
1932 		{ "ip6ip6", no_argument, NULL, 'E' },
1933 		{ "pppoev4", no_argument, NULL, 'p' },
1934 		{ "pppoev6", no_argument, NULL, 'P' },
1935 		{ "num-flows", required_argument, NULL, 'n' },
1936 		{ "rx", no_argument, NULL, 'r' },
1937 		{ "saddr", required_argument, NULL, 's' },
1938 		{ "smac", required_argument, NULL, 'S' },
1939 		{ "test", required_argument, NULL, 't' },
1940 		{ "order-check", no_argument, NULL, 'o' },
1941 		{ "verbose", no_argument, NULL, 'v' },
1942 		{ 0, 0, 0, 0 }
1943 	};
1944 	int c;
1945 
1946 	while ((c = getopt_long(argc, argv, "46d:D:eEi:n:pPrs:S:t:ov", opts, NULL)) != -1) {
1947 		switch (c) {
1948 		case '4':
1949 			proto = PF_INET;
1950 			ethhdr_proto = htons(ETH_P_IP);
1951 			break;
1952 		case '6':
1953 			proto = PF_INET6;
1954 			ethhdr_proto = htons(ETH_P_IPV6);
1955 			break;
1956 		case 'e':
1957 			ipip = true;
1958 			proto = PF_INET;
1959 			ethhdr_proto = htons(ETH_P_IP);
1960 			break;
1961 		case 'E':
1962 			ip6ip6 = true;
1963 			proto = PF_INET6;
1964 			ethhdr_proto = htons(ETH_P_IPV6);
1965 			break;
1966 		case 'p':
1967 			pppoe = true;
1968 			proto = PF_INET;
1969 			ethhdr_proto = htons(ETH_P_PPP_SES);
1970 			break;
1971 		case 'P':
1972 			pppoe = true;
1973 			proto = PF_INET6;
1974 			ethhdr_proto = htons(ETH_P_PPP_SES);
1975 			break;
1976 		case 'd':
1977 			addr4_dst = addr6_dst = optarg;
1978 			break;
1979 		case 'D':
1980 			dmac = optarg;
1981 			break;
1982 		case 'i':
1983 			ifname = optarg;
1984 			break;
1985 		case 'n':
1986 			num_flows = atoi(optarg);
1987 			break;
1988 		case 'r':
1989 			tx_socket = false;
1990 			break;
1991 		case 's':
1992 			addr4_src = addr6_src = optarg;
1993 			break;
1994 		case 'S':
1995 			smac = optarg;
1996 			break;
1997 		case 't':
1998 			testname = optarg;
1999 			break;
2000 		case 'o':
2001 			order_check = true;
2002 			break;
2003 		case 'v':
2004 			verbose = true;
2005 			break;
2006 		default:
2007 			error(1, 0, "%s invalid option %c\n", __func__, c);
2008 			break;
2009 		}
2010 	}
2011 }
2012 
2013 int main(int argc, char **argv)
2014 {
2015 	parse_args(argc, argv);
2016 
2017 	if (ipip) {
2018 		tcp_offset = ETH_HLEN + sizeof(struct iphdr) * 2;
2019 		total_hdr_len = tcp_offset + sizeof(struct tcphdr);
2020 	} else if (ip6ip6) {
2021 		tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr) * 2;
2022 		total_hdr_len = tcp_offset + sizeof(struct tcphdr);
2023 	} else if (pppoe) {
2024 		tcp_offset = ETH_HLEN + PPPOE_SES_HLEN +
2025 			(proto == PF_INET ? sizeof(struct iphdr) : sizeof(struct ipv6hdr));
2026 		total_hdr_len = tcp_offset + sizeof(struct tcphdr);
2027 	} else if (proto == PF_INET) {
2028 		tcp_offset = ETH_HLEN + sizeof(struct iphdr);
2029 		total_hdr_len = tcp_offset + sizeof(struct tcphdr);
2030 	} else if (proto == PF_INET6) {
2031 		tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr);
2032 		total_hdr_len = tcp_offset + sizeof(struct tcphdr);
2033 	} else {
2034 		error(1, 0, "Protocol family is not ipv4 or ipv6");
2035 	}
2036 
2037 	read_MAC(src_mac, smac);
2038 	read_MAC(dst_mac, dmac);
2039 
2040 	if (tx_socket) {
2041 		gro_sender();
2042 	} else {
2043 		/* Only the receiver exit status determines test success. */
2044 		gro_receiver();
2045 		fprintf(stderr, "Gro::%s test passed.\n", testname);
2046 	}
2047 
2048 	return 0;
2049 }
2050