Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'selftests-drv-net-gro-more-test-cases'

Jakub Kicinski says:

====================
selftests: drv-net: gro: more test cases

Add a few more test cases for GRO.

First 4 patches are unchanged from v1.

Patches 5 and 6 are new. Willem pointed out that the defines are
duplicated and all these imprecise defines have been annoying me
for a while so I decided to clean them up.

With the defines cleaned up and now more precise patch 7 (was 5)
no longer has to play any games with the MTU for ip6ip6.

The last patch now sends 3 segments as requested.
====================

Link: https://patch.msgid.link/20260402210000.1512696-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+157 -57
+5 -2
tools/testing/selftests/drivers/net/gro.py
··· 11 11 Test cases: 12 12 - data_same: Same size data packets coalesce 13 13 - data_lrg_sml: Large packet followed by smaller one coalesces 14 + - data_lrg_1byte: Large packet followed by 1B one coalesces (Ethernet padding) 14 15 - data_sml_lrg: Small packet followed by larger one doesn't coalesce 15 16 - ack: Pure ACK packets do not coalesce 16 17 - flags_psh: Packets with PSH flag don't coalesce ··· 290 289 291 290 # Tests that work for all protocols 292 291 common_tests = [ 293 - "data_same", "data_lrg_sml", "data_sml_lrg", 292 + "data_same", "data_lrg_sml", "data_sml_lrg", "data_lrg_1byte", 293 + "data_burst", 294 294 "ack", 295 295 "flags_psh", "flags_syn", "flags_rst", "flags_urg", "flags_cwr", 296 296 "tcp_csum", "tcp_seq", "tcp_ts", "tcp_opt", ··· 301 299 302 300 # Tests specific to IPv4 303 301 ipv4_tests = [ 302 + "ip_csum", 304 303 "ip_ttl", "ip_opt", "ip_frag4", 305 304 "ip_id_df1_inc", "ip_id_df1_fixed", 306 305 "ip_id_df0_inc", "ip_id_df0_fixed", ··· 314 311 ] 315 312 316 313 for mode in ["sw", "hw", "lro"]: 317 - for protocol in ["ipv4", "ipv6", "ipip"]: 314 + for protocol in ["ipv4", "ipv6", "ipip", "ip6ip6"]: 318 315 for test_name in common_tests: 319 316 yield mode, protocol, test_name 320 317
+152 -55
tools/testing/selftests/net/lib/gro.c
··· 10 10 * packet coalesced: it can be smaller than the rest and coalesced 11 11 * as long as it is in the same flow. 12 12 * - data_same: same size packets coalesce 13 - * - data_lrg_sml: large then small coalesces 14 - * - data_sml_lrg: small then large doesn't 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 15 17 * 16 18 * ack: 17 19 * Pure ACK does not coalesce. ··· 36 34 * Packets with different (ECN, TTL, TOS) header, IP options or 37 35 * IP fragments shouldn't coalesce. 38 36 * - ip_ecn, ip_tos: shared between IPv4/IPv6 37 + * - ip_csum: IPv4 only, bad IP header checksum 39 38 * - ip_ttl, ip_opt, ip_frag4: IPv4 only 40 39 * - ip_id_df*: IPv4 IP ID field coalescing tests 41 40 * - ip_frag6, ip_v6ext_*: IPv6 only ··· 95 92 #define START_SEQ 100 96 93 #define START_ACK 100 97 94 #define ETH_P_NONE 0 98 - #define TOTAL_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) 99 - #define MSS (4096 - sizeof(struct tcphdr) - sizeof(struct ipv6hdr)) 100 - #define MAX_PAYLOAD (IP_MAXPACKET - sizeof(struct tcphdr) - sizeof(struct ipv6hdr)) 101 - #define NUM_LARGE_PKT (MAX_PAYLOAD / MSS) 102 - #define MAX_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)) 95 + #define ASSUMED_MTU 4096 96 + #define MAX_MSS (ASSUMED_MTU - sizeof(struct iphdr) - sizeof(struct tcphdr)) 97 + #define MAX_HDR_LEN \ 98 + (ETH_HLEN + sizeof(struct ipv6hdr) * 2 + sizeof(struct tcphdr)) 99 + #define MAX_LARGE_PKT_CNT ((IP_MAXPACKET - (MAX_HDR_LEN - ETH_HLEN)) / \ 100 + (ASSUMED_MTU - (MAX_HDR_LEN - ETH_HLEN))) 103 101 #define MIN_EXTHDR_SIZE 8 104 102 #define EXT_PAYLOAD_1 "\x00\x00\x00\x00\x00\x00" 105 103 #define EXT_PAYLOAD_2 "\x11\x11\x11\x11\x11\x11" ··· 133 129 static int total_hdr_len = -1; 134 130 static int ethhdr_proto = -1; 135 131 static bool ipip; 132 + static bool ip6ip6; 136 133 static uint64_t txtime_ns; 137 134 static int num_flows = 4; 138 135 static bool order_check; ··· 141 136 #define CAPACITY_PAYLOAD_LEN 200 142 137 143 138 #define TXTIME_DELAY_MS 5 139 + 140 + /* Max TCP payload that GRO will coalesce. The outer header overhead 141 + * varies by encapsulation, reducing the effective max payload. 142 + */ 143 + static int max_payload(void) 144 + { 145 + return IP_MAXPACKET - (total_hdr_len - ETH_HLEN); 146 + } 147 + 148 + static int calc_mss(void) 149 + { 150 + return ASSUMED_MTU - (total_hdr_len - ETH_HLEN); 151 + } 152 + 153 + static int num_large_pkt(void) 154 + { 155 + return max_payload() / calc_mss(); 156 + } 144 157 145 158 static void vlog(const char *fmt, ...) 146 159 { ··· 177 154 const int ethproto_off = offsetof(struct ethhdr, h_proto); 178 155 int optlen = 0; 179 156 int ipproto_off, opt_ipproto_off; 180 - int next_off; 181 157 182 - if (ipip) 183 - next_off = sizeof(struct iphdr) + offsetof(struct iphdr, protocol); 184 - else if (proto == PF_INET) 185 - next_off = offsetof(struct iphdr, protocol); 158 + if (proto == PF_INET) 159 + ipproto_off = tcp_offset - sizeof(struct iphdr) + 160 + offsetof(struct iphdr, protocol); 186 161 else 187 - next_off = offsetof(struct ipv6hdr, nexthdr); 188 - ipproto_off = ETH_HLEN + next_off; 162 + ipproto_off = tcp_offset - sizeof(struct ipv6hdr) + 163 + offsetof(struct ipv6hdr, nexthdr); 189 164 190 165 /* Overridden later if exthdrs are used: */ 191 166 opt_ipproto_off = ipproto_off; ··· 400 379 static void create_packet(void *buf, int seq_offset, int ack_offset, 401 380 int payload_len, int fin) 402 381 { 382 + int ip_hdr_len = (proto == PF_INET) ? 383 + sizeof(struct iphdr) : sizeof(struct ipv6hdr); 384 + int inner_ip_off = tcp_offset - ip_hdr_len; 385 + 403 386 memset(buf, 0, total_hdr_len); 404 387 memset(buf + total_hdr_len, 'a', payload_len); 405 388 406 389 fill_transportlayer(buf + tcp_offset, seq_offset, ack_offset, 407 390 payload_len, fin); 408 391 409 - if (ipip) { 410 - fill_networklayer(buf + ETH_HLEN, payload_len + sizeof(struct iphdr), 411 - IPPROTO_IPIP); 412 - fill_networklayer(buf + ETH_HLEN + sizeof(struct iphdr), 413 - payload_len, IPPROTO_TCP); 414 - } else { 415 - fill_networklayer(buf + ETH_HLEN, payload_len, IPPROTO_TCP); 392 + fill_networklayer(buf + inner_ip_off, payload_len, IPPROTO_TCP); 393 + if (inner_ip_off > ETH_HLEN) { 394 + int encap_proto = (proto == PF_INET) ? 395 + IPPROTO_IPIP : IPPROTO_IPV6; 396 + 397 + fill_networklayer(buf + ETH_HLEN, 398 + payload_len + ip_hdr_len, encap_proto); 416 399 } 417 400 418 401 fill_datalinklayer(buf); ··· 539 514 */ 540 515 static void send_large(int fd, struct sockaddr_ll *daddr, int remainder) 541 516 { 542 - static char pkts[NUM_LARGE_PKT][TOTAL_HDR_LEN + MSS]; 543 - static char last[TOTAL_HDR_LEN + MSS]; 544 - static char new_seg[TOTAL_HDR_LEN + MSS]; 517 + static char pkts[MAX_LARGE_PKT_CNT][MAX_HDR_LEN + MAX_MSS]; 518 + static char new_seg[MAX_HDR_LEN + MAX_MSS]; 519 + static char last[MAX_HDR_LEN + MAX_MSS]; 520 + const int num_pkt = num_large_pkt(); 521 + const int mss = calc_mss(); 545 522 int i; 546 523 547 - for (i = 0; i < NUM_LARGE_PKT; i++) 548 - create_packet(pkts[i], i * MSS, 0, MSS, 0); 549 - create_packet(last, NUM_LARGE_PKT * MSS, 0, remainder, 0); 550 - create_packet(new_seg, (NUM_LARGE_PKT + 1) * MSS, 0, remainder, 0); 524 + for (i = 0; i < num_pkt; i++) 525 + create_packet(pkts[i], i * mss, 0, mss, 0); 526 + create_packet(last, num_pkt * mss, 0, remainder, 0); 527 + create_packet(new_seg, (num_pkt + 1) * mss, 0, remainder, 0); 551 528 552 - for (i = 0; i < NUM_LARGE_PKT; i++) 553 - write_packet(fd, pkts[i], total_hdr_len + MSS, daddr); 529 + for (i = 0; i < num_pkt; i++) 530 + write_packet(fd, pkts[i], total_hdr_len + mss, daddr); 554 531 write_packet(fd, last, total_hdr_len + remainder, daddr); 555 532 write_packet(fd, new_seg, total_hdr_len + remainder, daddr); 556 533 } ··· 572 545 static void recompute_packet(char *buf, char *no_ext, int extlen) 573 546 { 574 547 struct tcphdr *tcphdr = (struct tcphdr *)(buf + tcp_offset); 575 - struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN); 576 - struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN); 548 + int off; 577 549 578 550 memmove(buf, no_ext, total_hdr_len); 579 551 memmove(buf + total_hdr_len + extlen, ··· 582 556 tcphdr->check = 0; 583 557 tcphdr->check = tcp_checksum(tcphdr, PAYLOAD_LEN + extlen); 584 558 if (proto == PF_INET) { 585 - iph->tot_len = htons(ntohs(iph->tot_len) + extlen); 586 - iph->check = 0; 587 - iph->check = checksum_fold(iph, sizeof(struct iphdr), 0); 559 + for (off = ETH_HLEN; off < tcp_offset; 560 + off += sizeof(struct iphdr)) { 561 + struct iphdr *iph = (struct iphdr *)(buf + off); 588 562 589 - if (ipip) { 590 - iph += 1; 591 563 iph->tot_len = htons(ntohs(iph->tot_len) + extlen); 592 564 iph->check = 0; 593 565 iph->check = checksum_fold(iph, sizeof(struct iphdr), 0); 594 566 } 595 567 } else { 596 - ip6h->payload_len = htons(ntohs(ip6h->payload_len) + extlen); 568 + for (off = ETH_HLEN; off < tcp_offset; 569 + off += sizeof(struct ipv6hdr)) { 570 + struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + off); 571 + 572 + ip6h->payload_len = 573 + htons(ntohs(ip6h->payload_len) + extlen); 574 + } 597 575 } 598 576 } 599 577 ··· 683 653 684 654 create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0); 685 655 tcph->check = tcph->check - 1; 656 + write_packet(fd, buf, pkt_size, daddr); 657 + } 658 + 659 + /* Packets with incorrect IPv4 header checksum don't coalesce. */ 660 + static void send_changed_ip_checksum(int fd, struct sockaddr_ll *daddr) 661 + { 662 + static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; 663 + struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN); 664 + int pkt_size = total_hdr_len + PAYLOAD_LEN; 665 + 666 + create_packet(buf, 0, 0, PAYLOAD_LEN, 0); 667 + write_packet(fd, buf, pkt_size, daddr); 668 + 669 + create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0); 670 + iph->check = iph->check - 1; 671 + write_packet(fd, buf, pkt_size, daddr); 672 + 673 + create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0); 686 674 write_packet(fd, buf, pkt_size, daddr); 687 675 } 688 676 ··· 1146 1098 1147 1099 if (iph->version == 4) 1148 1100 ip_ext_len = (iph->ihl - 5) * 4; 1149 - else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP) 1101 + else if (ip6h->version == 6 && !ip6ip6 && 1102 + ip6h->nexthdr != IPPROTO_TCP) 1150 1103 ip_ext_len = MIN_EXTHDR_SIZE; 1151 1104 1152 1105 tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len); ··· 1201 1152 memset(coalesced, 0, sizeof(coalesced)); 1202 1153 memset(flow_order, -1, sizeof(flow_order)); 1203 1154 1204 - while (total_data < num_flows * CAPACITY_PAYLOAD_LEN * 2) { 1155 + while (1) { 1205 1156 ip_ext_len = 0; 1206 1157 pkt_size = recv(fd, buffer, IP_MAXPACKET + ETH_HLEN + 1, 0); 1207 1158 if (pkt_size < 0) ··· 1209 1160 1210 1161 if (iph->version == 4) 1211 1162 ip_ext_len = (iph->ihl - 5) * 4; 1212 - else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP) 1163 + else if (ip6h->version == 6 && !ip6ip6 && 1164 + ip6h->nexthdr != IPPROTO_TCP) 1213 1165 ip_ext_len = MIN_EXTHDR_SIZE; 1214 1166 1215 1167 tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len); 1216 1168 1217 - /* FIN packet terminates reception */ 1218 1169 if (tcph->fin) 1219 1170 break; 1220 1171 ··· 1236 1187 data_len = pkt_size - total_hdr_len - ip_ext_len; 1237 1188 } 1238 1189 1239 - flow_order[num_pkt] = flow_id; 1190 + if (num_pkt < num_flows * 2) { 1191 + flow_order[num_pkt] = flow_id; 1192 + } else if (num_pkt == num_flows * 2) { 1193 + vlog("More packets than expected (%d)\n", 1194 + num_flows * 2); 1195 + fail_reason = fail_reason ?: "too many packets"; 1196 + } 1240 1197 coalesced[flow_id] = data_len; 1241 1198 1242 1199 if (data_len == CAPACITY_PAYLOAD_LEN * 2) { ··· 1350 1295 } else if (strcmp(testname, "data_lrg_sml") == 0) { 1351 1296 send_data_pkts(txfd, &daddr, PAYLOAD_LEN, PAYLOAD_LEN / 2); 1352 1297 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1298 + } else if (strcmp(testname, "data_lrg_1byte") == 0) { 1299 + send_data_pkts(txfd, &daddr, PAYLOAD_LEN, 1); 1300 + write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1353 1301 } else if (strcmp(testname, "data_sml_lrg") == 0) { 1354 1302 send_data_pkts(txfd, &daddr, PAYLOAD_LEN / 2, PAYLOAD_LEN); 1303 + write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1304 + } else if (strcmp(testname, "data_burst") == 0) { 1305 + static char buf[MAX_HDR_LEN + PAYLOAD_LEN]; 1306 + 1307 + create_packet(buf, 0, 0, PAYLOAD_LEN, 0); 1308 + write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr); 1309 + create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0); 1310 + write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr); 1311 + 1312 + usleep(100 * 1000); /* 100ms */ 1313 + create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0); 1314 + write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr); 1315 + create_packet(buf, PAYLOAD_LEN * 3, 0, PAYLOAD_LEN, 0); 1316 + write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr); 1317 + 1355 1318 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1356 1319 1357 1320 /* ack test */ ··· 1421 1348 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1422 1349 1423 1350 /* ip sub-tests - IPv4 only */ 1351 + } else if (strcmp(testname, "ip_csum") == 0) { 1352 + send_changed_ip_checksum(txfd, &daddr); 1353 + usleep(fin_delay_us); 1354 + write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1424 1355 } else if (strcmp(testname, "ip_ttl") == 0) { 1425 1356 send_changed_ttl(txfd, &daddr); 1426 1357 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); ··· 1477 1400 1478 1401 /* large sub-tests */ 1479 1402 } else if (strcmp(testname, "large_max") == 0) { 1480 - int offset = (proto == PF_INET && !ipip) ? 20 : 0; 1481 - int remainder = (MAX_PAYLOAD + offset) % MSS; 1403 + int remainder = max_payload() % calc_mss(); 1482 1404 1483 1405 send_large(txfd, &daddr, remainder); 1484 1406 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); 1485 1407 } else if (strcmp(testname, "large_rem") == 0) { 1486 - int offset = (proto == PF_INET && !ipip) ? 20 : 0; 1487 - int remainder = (MAX_PAYLOAD + offset) % MSS; 1408 + int remainder = max_payload() % calc_mss(); 1488 1409 1489 1410 send_large(txfd, &daddr, remainder + 1); 1490 1411 write_packet(txfd, fin_pkt, total_hdr_len, &daddr); ··· 1533 1458 printf("large data packets followed by a smaller one: "); 1534 1459 correct_payload[0] = PAYLOAD_LEN * 1.5; 1535 1460 check_recv_pkts(rxfd, correct_payload, 1); 1461 + } else if (strcmp(testname, "data_lrg_1byte") == 0) { 1462 + printf("large data packet followed by a 1 byte one: "); 1463 + correct_payload[0] = PAYLOAD_LEN + 1; 1464 + check_recv_pkts(rxfd, correct_payload, 1); 1536 1465 } else if (strcmp(testname, "data_sml_lrg") == 0) { 1537 1466 printf("small data packets followed by a larger one: "); 1538 1467 correct_payload[0] = PAYLOAD_LEN / 2; 1539 1468 correct_payload[1] = PAYLOAD_LEN; 1469 + check_recv_pkts(rxfd, correct_payload, 2); 1470 + } else if (strcmp(testname, "data_burst") == 0) { 1471 + printf("two bursts of two data packets: "); 1472 + correct_payload[0] = PAYLOAD_LEN * 2; 1473 + correct_payload[1] = PAYLOAD_LEN * 2; 1540 1474 check_recv_pkts(rxfd, correct_payload, 2); 1541 1475 1542 1476 /* ack test */ ··· 1621 1537 check_recv_pkts(rxfd, correct_payload, 2); 1622 1538 1623 1539 /* ip sub-tests - IPv4 only */ 1540 + } else if (strcmp(testname, "ip_csum") == 0) { 1541 + correct_payload[0] = PAYLOAD_LEN; 1542 + correct_payload[1] = PAYLOAD_LEN; 1543 + correct_payload[2] = PAYLOAD_LEN; 1544 + printf("bad ip checksum doesn't coalesce: "); 1545 + check_recv_pkts(rxfd, correct_payload, 3); 1624 1546 } else if (strcmp(testname, "ip_ttl") == 0) { 1625 1547 correct_payload[0] = PAYLOAD_LEN; 1626 1548 correct_payload[1] = PAYLOAD_LEN; ··· 1692 1602 1693 1603 /* large sub-tests */ 1694 1604 } else if (strcmp(testname, "large_max") == 0) { 1695 - int offset = (proto == PF_INET && !ipip) ? 20 : 0; 1696 - int remainder = (MAX_PAYLOAD + offset) % MSS; 1605 + int remainder = max_payload() % calc_mss(); 1697 1606 1698 - correct_payload[0] = (MAX_PAYLOAD + offset); 1607 + correct_payload[0] = max_payload(); 1699 1608 correct_payload[1] = remainder; 1700 1609 printf("Shouldn't coalesce if exceed IP max pkt size: "); 1701 1610 check_recv_pkts(rxfd, correct_payload, 2); 1702 1611 } else if (strcmp(testname, "large_rem") == 0) { 1703 - int offset = (proto == PF_INET && !ipip) ? 20 : 0; 1704 - int remainder = (MAX_PAYLOAD + offset) % MSS; 1612 + int remainder = max_payload() % calc_mss(); 1705 1613 1706 1614 /* last segment sent individually, doesn't start new segment */ 1707 - correct_payload[0] = (MAX_PAYLOAD + offset) - remainder; 1615 + correct_payload[0] = max_payload() - remainder; 1708 1616 correct_payload[1] = remainder + 1; 1709 1617 correct_payload[2] = remainder + 1; 1710 1618 printf("last segment sent individually: "); ··· 1733 1645 { "ipv4", no_argument, NULL, '4' }, 1734 1646 { "ipv6", no_argument, NULL, '6' }, 1735 1647 { "ipip", no_argument, NULL, 'e' }, 1648 + { "ip6ip6", no_argument, NULL, 'E' }, 1736 1649 { "num-flows", required_argument, NULL, 'n' }, 1737 1650 { "rx", no_argument, NULL, 'r' }, 1738 1651 { "saddr", required_argument, NULL, 's' }, ··· 1745 1656 }; 1746 1657 int c; 1747 1658 1748 - while ((c = getopt_long(argc, argv, "46d:D:ei:n:rs:S:t:ov", opts, NULL)) != -1) { 1659 + while ((c = getopt_long(argc, argv, "46d:D:eEi:n:rs:S:t:ov", opts, NULL)) != -1) { 1749 1660 switch (c) { 1750 1661 case '4': 1751 1662 proto = PF_INET; ··· 1759 1670 ipip = true; 1760 1671 proto = PF_INET; 1761 1672 ethhdr_proto = htons(ETH_P_IP); 1673 + break; 1674 + case 'E': 1675 + ip6ip6 = true; 1676 + proto = PF_INET6; 1677 + ethhdr_proto = htons(ETH_P_IPV6); 1762 1678 break; 1763 1679 case 'd': 1764 1680 addr4_dst = addr6_dst = optarg; ··· 1809 1715 if (ipip) { 1810 1716 tcp_offset = ETH_HLEN + sizeof(struct iphdr) * 2; 1811 1717 total_hdr_len = tcp_offset + sizeof(struct tcphdr); 1718 + } else if (ip6ip6) { 1719 + tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr) * 2; 1720 + total_hdr_len = tcp_offset + sizeof(struct tcphdr); 1812 1721 } else if (proto == PF_INET) { 1813 1722 tcp_offset = ETH_HLEN + sizeof(struct iphdr); 1814 1723 total_hdr_len = tcp_offset + sizeof(struct tcphdr); 1815 1724 } else if (proto == PF_INET6) { 1816 1725 tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr); 1817 - total_hdr_len = MAX_HDR_LEN; 1726 + total_hdr_len = tcp_offset + sizeof(struct tcphdr); 1818 1727 } else { 1819 1728 error(1, 0, "Protocol family is not ipv4 or ipv6"); 1820 1729 }