mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
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>
This commit is contained in:
commit
071fe8b5d5
|
|
@ -11,6 +11,7 @@ coalescing behavior.
|
|||
Test cases:
|
||||
- data_same: Same size data packets coalesce
|
||||
- data_lrg_sml: Large packet followed by smaller one coalesces
|
||||
- data_lrg_1byte: Large packet followed by 1B one coalesces (Ethernet padding)
|
||||
- data_sml_lrg: Small packet followed by larger one doesn't coalesce
|
||||
- ack: Pure ACK packets do not coalesce
|
||||
- flags_psh: Packets with PSH flag don't coalesce
|
||||
|
|
@ -289,7 +290,8 @@ def _gro_variants():
|
|||
|
||||
# Tests that work for all protocols
|
||||
common_tests = [
|
||||
"data_same", "data_lrg_sml", "data_sml_lrg",
|
||||
"data_same", "data_lrg_sml", "data_sml_lrg", "data_lrg_1byte",
|
||||
"data_burst",
|
||||
"ack",
|
||||
"flags_psh", "flags_syn", "flags_rst", "flags_urg", "flags_cwr",
|
||||
"tcp_csum", "tcp_seq", "tcp_ts", "tcp_opt",
|
||||
|
|
@ -299,6 +301,7 @@ def _gro_variants():
|
|||
|
||||
# Tests specific to IPv4
|
||||
ipv4_tests = [
|
||||
"ip_csum",
|
||||
"ip_ttl", "ip_opt", "ip_frag4",
|
||||
"ip_id_df1_inc", "ip_id_df1_fixed",
|
||||
"ip_id_df0_inc", "ip_id_df0_fixed",
|
||||
|
|
@ -311,7 +314,7 @@ def _gro_variants():
|
|||
]
|
||||
|
||||
for mode in ["sw", "hw", "lro"]:
|
||||
for protocol in ["ipv4", "ipv6", "ipip"]:
|
||||
for protocol in ["ipv4", "ipv6", "ipip", "ip6ip6"]:
|
||||
for test_name in common_tests:
|
||||
yield mode, protocol, test_name
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@
|
|||
* packet coalesced: it can be smaller than the rest and coalesced
|
||||
* as long as it is in the same flow.
|
||||
* - data_same: same size packets coalesce
|
||||
* - data_lrg_sml: large then small coalesces
|
||||
* - data_sml_lrg: small then large doesn't coalesce
|
||||
* - data_lrg_sml: large then small coalesces
|
||||
* - data_lrg_1byte: large then 1 byte coalesces (Ethernet padding)
|
||||
* - data_sml_lrg: small then large doesn't coalesce
|
||||
* - data_burst: two bursts of two, separated by 100ms
|
||||
*
|
||||
* ack:
|
||||
* Pure ACK does not coalesce.
|
||||
|
|
@ -34,6 +36,7 @@
|
|||
* Packets with different (ECN, TTL, TOS) header, IP options or
|
||||
* IP fragments shouldn't coalesce.
|
||||
* - ip_ecn, ip_tos: shared between IPv4/IPv6
|
||||
* - ip_csum: IPv4 only, bad IP header checksum
|
||||
* - ip_ttl, ip_opt, ip_frag4: IPv4 only
|
||||
* - ip_id_df*: IPv4 IP ID field coalescing tests
|
||||
* - ip_frag6, ip_v6ext_*: IPv6 only
|
||||
|
|
@ -92,11 +95,12 @@
|
|||
#define START_SEQ 100
|
||||
#define START_ACK 100
|
||||
#define ETH_P_NONE 0
|
||||
#define TOTAL_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr))
|
||||
#define MSS (4096 - sizeof(struct tcphdr) - sizeof(struct ipv6hdr))
|
||||
#define MAX_PAYLOAD (IP_MAXPACKET - sizeof(struct tcphdr) - sizeof(struct ipv6hdr))
|
||||
#define NUM_LARGE_PKT (MAX_PAYLOAD / MSS)
|
||||
#define MAX_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr))
|
||||
#define ASSUMED_MTU 4096
|
||||
#define MAX_MSS (ASSUMED_MTU - sizeof(struct iphdr) - sizeof(struct tcphdr))
|
||||
#define MAX_HDR_LEN \
|
||||
(ETH_HLEN + sizeof(struct ipv6hdr) * 2 + sizeof(struct tcphdr))
|
||||
#define MAX_LARGE_PKT_CNT ((IP_MAXPACKET - (MAX_HDR_LEN - ETH_HLEN)) / \
|
||||
(ASSUMED_MTU - (MAX_HDR_LEN - ETH_HLEN)))
|
||||
#define MIN_EXTHDR_SIZE 8
|
||||
#define EXT_PAYLOAD_1 "\x00\x00\x00\x00\x00\x00"
|
||||
#define EXT_PAYLOAD_2 "\x11\x11\x11\x11\x11\x11"
|
||||
|
|
@ -129,6 +133,7 @@ static int tcp_offset = -1;
|
|||
static int total_hdr_len = -1;
|
||||
static int ethhdr_proto = -1;
|
||||
static bool ipip;
|
||||
static bool ip6ip6;
|
||||
static uint64_t txtime_ns;
|
||||
static int num_flows = 4;
|
||||
static bool order_check;
|
||||
|
|
@ -137,6 +142,24 @@ static bool order_check;
|
|||
|
||||
#define TXTIME_DELAY_MS 5
|
||||
|
||||
/* Max TCP payload that GRO will coalesce. The outer header overhead
|
||||
* varies by encapsulation, reducing the effective max payload.
|
||||
*/
|
||||
static int max_payload(void)
|
||||
{
|
||||
return IP_MAXPACKET - (total_hdr_len - ETH_HLEN);
|
||||
}
|
||||
|
||||
static int calc_mss(void)
|
||||
{
|
||||
return ASSUMED_MTU - (total_hdr_len - ETH_HLEN);
|
||||
}
|
||||
|
||||
static int num_large_pkt(void)
|
||||
{
|
||||
return max_payload() / calc_mss();
|
||||
}
|
||||
|
||||
static void vlog(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
|
@ -154,15 +177,13 @@ static void setup_sock_filter(int fd)
|
|||
const int ethproto_off = offsetof(struct ethhdr, h_proto);
|
||||
int optlen = 0;
|
||||
int ipproto_off, opt_ipproto_off;
|
||||
int next_off;
|
||||
|
||||
if (ipip)
|
||||
next_off = sizeof(struct iphdr) + offsetof(struct iphdr, protocol);
|
||||
else if (proto == PF_INET)
|
||||
next_off = offsetof(struct iphdr, protocol);
|
||||
if (proto == PF_INET)
|
||||
ipproto_off = tcp_offset - sizeof(struct iphdr) +
|
||||
offsetof(struct iphdr, protocol);
|
||||
else
|
||||
next_off = offsetof(struct ipv6hdr, nexthdr);
|
||||
ipproto_off = ETH_HLEN + next_off;
|
||||
ipproto_off = tcp_offset - sizeof(struct ipv6hdr) +
|
||||
offsetof(struct ipv6hdr, nexthdr);
|
||||
|
||||
/* Overridden later if exthdrs are used: */
|
||||
opt_ipproto_off = ipproto_off;
|
||||
|
|
@ -379,19 +400,23 @@ static void write_packet(int fd, char *buf, int len, struct sockaddr_ll *daddr)
|
|||
static void create_packet(void *buf, int seq_offset, int ack_offset,
|
||||
int payload_len, int fin)
|
||||
{
|
||||
int ip_hdr_len = (proto == PF_INET) ?
|
||||
sizeof(struct iphdr) : sizeof(struct ipv6hdr);
|
||||
int inner_ip_off = tcp_offset - ip_hdr_len;
|
||||
|
||||
memset(buf, 0, total_hdr_len);
|
||||
memset(buf + total_hdr_len, 'a', payload_len);
|
||||
|
||||
fill_transportlayer(buf + tcp_offset, seq_offset, ack_offset,
|
||||
payload_len, fin);
|
||||
|
||||
if (ipip) {
|
||||
fill_networklayer(buf + ETH_HLEN, payload_len + sizeof(struct iphdr),
|
||||
IPPROTO_IPIP);
|
||||
fill_networklayer(buf + ETH_HLEN + sizeof(struct iphdr),
|
||||
payload_len, IPPROTO_TCP);
|
||||
} else {
|
||||
fill_networklayer(buf + ETH_HLEN, payload_len, IPPROTO_TCP);
|
||||
fill_networklayer(buf + inner_ip_off, payload_len, IPPROTO_TCP);
|
||||
if (inner_ip_off > ETH_HLEN) {
|
||||
int encap_proto = (proto == PF_INET) ?
|
||||
IPPROTO_IPIP : IPPROTO_IPV6;
|
||||
|
||||
fill_networklayer(buf + ETH_HLEN,
|
||||
payload_len + ip_hdr_len, encap_proto);
|
||||
}
|
||||
|
||||
fill_datalinklayer(buf);
|
||||
|
|
@ -514,18 +539,20 @@ static void send_data_pkts(int fd, struct sockaddr_ll *daddr,
|
|||
*/
|
||||
static void send_large(int fd, struct sockaddr_ll *daddr, int remainder)
|
||||
{
|
||||
static char pkts[NUM_LARGE_PKT][TOTAL_HDR_LEN + MSS];
|
||||
static char last[TOTAL_HDR_LEN + MSS];
|
||||
static char new_seg[TOTAL_HDR_LEN + MSS];
|
||||
static char pkts[MAX_LARGE_PKT_CNT][MAX_HDR_LEN + MAX_MSS];
|
||||
static char new_seg[MAX_HDR_LEN + MAX_MSS];
|
||||
static char last[MAX_HDR_LEN + MAX_MSS];
|
||||
const int num_pkt = num_large_pkt();
|
||||
const int mss = calc_mss();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_LARGE_PKT; i++)
|
||||
create_packet(pkts[i], i * MSS, 0, MSS, 0);
|
||||
create_packet(last, NUM_LARGE_PKT * MSS, 0, remainder, 0);
|
||||
create_packet(new_seg, (NUM_LARGE_PKT + 1) * MSS, 0, remainder, 0);
|
||||
for (i = 0; i < num_pkt; i++)
|
||||
create_packet(pkts[i], i * mss, 0, mss, 0);
|
||||
create_packet(last, num_pkt * mss, 0, remainder, 0);
|
||||
create_packet(new_seg, (num_pkt + 1) * mss, 0, remainder, 0);
|
||||
|
||||
for (i = 0; i < NUM_LARGE_PKT; i++)
|
||||
write_packet(fd, pkts[i], total_hdr_len + MSS, daddr);
|
||||
for (i = 0; i < num_pkt; i++)
|
||||
write_packet(fd, pkts[i], total_hdr_len + mss, daddr);
|
||||
write_packet(fd, last, total_hdr_len + remainder, daddr);
|
||||
write_packet(fd, new_seg, total_hdr_len + remainder, daddr);
|
||||
}
|
||||
|
|
@ -545,8 +572,7 @@ static void send_ack(int fd, struct sockaddr_ll *daddr)
|
|||
static void recompute_packet(char *buf, char *no_ext, int extlen)
|
||||
{
|
||||
struct tcphdr *tcphdr = (struct tcphdr *)(buf + tcp_offset);
|
||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + ETH_HLEN);
|
||||
struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
|
||||
int off;
|
||||
|
||||
memmove(buf, no_ext, total_hdr_len);
|
||||
memmove(buf + total_hdr_len + extlen,
|
||||
|
|
@ -556,18 +582,22 @@ static void recompute_packet(char *buf, char *no_ext, int extlen)
|
|||
tcphdr->check = 0;
|
||||
tcphdr->check = tcp_checksum(tcphdr, PAYLOAD_LEN + extlen);
|
||||
if (proto == PF_INET) {
|
||||
iph->tot_len = htons(ntohs(iph->tot_len) + extlen);
|
||||
iph->check = 0;
|
||||
iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
|
||||
for (off = ETH_HLEN; off < tcp_offset;
|
||||
off += sizeof(struct iphdr)) {
|
||||
struct iphdr *iph = (struct iphdr *)(buf + off);
|
||||
|
||||
if (ipip) {
|
||||
iph += 1;
|
||||
iph->tot_len = htons(ntohs(iph->tot_len) + extlen);
|
||||
iph->check = 0;
|
||||
iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
|
||||
}
|
||||
} else {
|
||||
ip6h->payload_len = htons(ntohs(ip6h->payload_len) + extlen);
|
||||
for (off = ETH_HLEN; off < tcp_offset;
|
||||
off += sizeof(struct ipv6hdr)) {
|
||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)(buf + off);
|
||||
|
||||
ip6h->payload_len =
|
||||
htons(ntohs(ip6h->payload_len) + extlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -656,6 +686,24 @@ static void send_changed_checksum(int fd, struct sockaddr_ll *daddr)
|
|||
write_packet(fd, buf, pkt_size, daddr);
|
||||
}
|
||||
|
||||
/* Packets with incorrect IPv4 header checksum don't coalesce. */
|
||||
static void send_changed_ip_checksum(int fd, struct sockaddr_ll *daddr)
|
||||
{
|
||||
static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
|
||||
struct iphdr *iph = (struct iphdr *)(buf + ETH_HLEN);
|
||||
int pkt_size = total_hdr_len + PAYLOAD_LEN;
|
||||
|
||||
create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
|
||||
write_packet(fd, buf, pkt_size, daddr);
|
||||
|
||||
create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
|
||||
iph->check = iph->check - 1;
|
||||
write_packet(fd, buf, pkt_size, daddr);
|
||||
|
||||
create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
|
||||
write_packet(fd, buf, pkt_size, daddr);
|
||||
}
|
||||
|
||||
/* Packets with non-consecutive sequence number don't coalesce.*/
|
||||
static void send_changed_seq(int fd, struct sockaddr_ll *daddr)
|
||||
{
|
||||
|
|
@ -1098,7 +1146,8 @@ static void check_recv_pkts(int fd, int *correct_payload,
|
|||
|
||||
if (iph->version == 4)
|
||||
ip_ext_len = (iph->ihl - 5) * 4;
|
||||
else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP)
|
||||
else if (ip6h->version == 6 && !ip6ip6 &&
|
||||
ip6h->nexthdr != IPPROTO_TCP)
|
||||
ip_ext_len = MIN_EXTHDR_SIZE;
|
||||
|
||||
tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
|
||||
|
|
@ -1152,7 +1201,7 @@ static void check_capacity_pkts(int fd)
|
|||
memset(coalesced, 0, sizeof(coalesced));
|
||||
memset(flow_order, -1, sizeof(flow_order));
|
||||
|
||||
while (total_data < num_flows * CAPACITY_PAYLOAD_LEN * 2) {
|
||||
while (1) {
|
||||
ip_ext_len = 0;
|
||||
pkt_size = recv(fd, buffer, IP_MAXPACKET + ETH_HLEN + 1, 0);
|
||||
if (pkt_size < 0)
|
||||
|
|
@ -1160,12 +1209,12 @@ static void check_capacity_pkts(int fd)
|
|||
|
||||
if (iph->version == 4)
|
||||
ip_ext_len = (iph->ihl - 5) * 4;
|
||||
else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP)
|
||||
else if (ip6h->version == 6 && !ip6ip6 &&
|
||||
ip6h->nexthdr != IPPROTO_TCP)
|
||||
ip_ext_len = MIN_EXTHDR_SIZE;
|
||||
|
||||
tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
|
||||
|
||||
/* FIN packet terminates reception */
|
||||
if (tcph->fin)
|
||||
break;
|
||||
|
||||
|
|
@ -1187,7 +1236,13 @@ static void check_capacity_pkts(int fd)
|
|||
data_len = pkt_size - total_hdr_len - ip_ext_len;
|
||||
}
|
||||
|
||||
flow_order[num_pkt] = flow_id;
|
||||
if (num_pkt < num_flows * 2) {
|
||||
flow_order[num_pkt] = flow_id;
|
||||
} else if (num_pkt == num_flows * 2) {
|
||||
vlog("More packets than expected (%d)\n",
|
||||
num_flows * 2);
|
||||
fail_reason = fail_reason ?: "too many packets";
|
||||
}
|
||||
coalesced[flow_id] = data_len;
|
||||
|
||||
if (data_len == CAPACITY_PAYLOAD_LEN * 2) {
|
||||
|
|
@ -1295,9 +1350,27 @@ static void gro_sender(void)
|
|||
} else if (strcmp(testname, "data_lrg_sml") == 0) {
|
||||
send_data_pkts(txfd, &daddr, PAYLOAD_LEN, PAYLOAD_LEN / 2);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
} else if (strcmp(testname, "data_lrg_1byte") == 0) {
|
||||
send_data_pkts(txfd, &daddr, PAYLOAD_LEN, 1);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
} else if (strcmp(testname, "data_sml_lrg") == 0) {
|
||||
send_data_pkts(txfd, &daddr, PAYLOAD_LEN / 2, PAYLOAD_LEN);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
} else if (strcmp(testname, "data_burst") == 0) {
|
||||
static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
|
||||
|
||||
create_packet(buf, 0, 0, PAYLOAD_LEN, 0);
|
||||
write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
|
||||
create_packet(buf, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
|
||||
write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
|
||||
|
||||
usleep(100 * 1000); /* 100ms */
|
||||
create_packet(buf, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
|
||||
write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
|
||||
create_packet(buf, PAYLOAD_LEN * 3, 0, PAYLOAD_LEN, 0);
|
||||
write_packet(txfd, buf, total_hdr_len + PAYLOAD_LEN, &daddr);
|
||||
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
|
||||
/* ack test */
|
||||
} else if (strcmp(testname, "ack") == 0) {
|
||||
|
|
@ -1348,6 +1421,10 @@ static void gro_sender(void)
|
|||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
|
||||
/* ip sub-tests - IPv4 only */
|
||||
} else if (strcmp(testname, "ip_csum") == 0) {
|
||||
send_changed_ip_checksum(txfd, &daddr);
|
||||
usleep(fin_delay_us);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
} else if (strcmp(testname, "ip_ttl") == 0) {
|
||||
send_changed_ttl(txfd, &daddr);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
|
|
@ -1400,14 +1477,12 @@ static void gro_sender(void)
|
|||
|
||||
/* large sub-tests */
|
||||
} else if (strcmp(testname, "large_max") == 0) {
|
||||
int offset = (proto == PF_INET && !ipip) ? 20 : 0;
|
||||
int remainder = (MAX_PAYLOAD + offset) % MSS;
|
||||
int remainder = max_payload() % calc_mss();
|
||||
|
||||
send_large(txfd, &daddr, remainder);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
} else if (strcmp(testname, "large_rem") == 0) {
|
||||
int offset = (proto == PF_INET && !ipip) ? 20 : 0;
|
||||
int remainder = (MAX_PAYLOAD + offset) % MSS;
|
||||
int remainder = max_payload() % calc_mss();
|
||||
|
||||
send_large(txfd, &daddr, remainder + 1);
|
||||
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
|
||||
|
|
@ -1458,11 +1533,20 @@ static void gro_receiver(void)
|
|||
printf("large data packets followed by a smaller one: ");
|
||||
correct_payload[0] = PAYLOAD_LEN * 1.5;
|
||||
check_recv_pkts(rxfd, correct_payload, 1);
|
||||
} else if (strcmp(testname, "data_lrg_1byte") == 0) {
|
||||
printf("large data packet followed by a 1 byte one: ");
|
||||
correct_payload[0] = PAYLOAD_LEN + 1;
|
||||
check_recv_pkts(rxfd, correct_payload, 1);
|
||||
} else if (strcmp(testname, "data_sml_lrg") == 0) {
|
||||
printf("small data packets followed by a larger one: ");
|
||||
correct_payload[0] = PAYLOAD_LEN / 2;
|
||||
correct_payload[1] = PAYLOAD_LEN;
|
||||
check_recv_pkts(rxfd, correct_payload, 2);
|
||||
} else if (strcmp(testname, "data_burst") == 0) {
|
||||
printf("two bursts of two data packets: ");
|
||||
correct_payload[0] = PAYLOAD_LEN * 2;
|
||||
correct_payload[1] = PAYLOAD_LEN * 2;
|
||||
check_recv_pkts(rxfd, correct_payload, 2);
|
||||
|
||||
/* ack test */
|
||||
} else if (strcmp(testname, "ack") == 0) {
|
||||
|
|
@ -1537,6 +1621,12 @@ static void gro_receiver(void)
|
|||
check_recv_pkts(rxfd, correct_payload, 2);
|
||||
|
||||
/* ip sub-tests - IPv4 only */
|
||||
} else if (strcmp(testname, "ip_csum") == 0) {
|
||||
correct_payload[0] = PAYLOAD_LEN;
|
||||
correct_payload[1] = PAYLOAD_LEN;
|
||||
correct_payload[2] = PAYLOAD_LEN;
|
||||
printf("bad ip checksum doesn't coalesce: ");
|
||||
check_recv_pkts(rxfd, correct_payload, 3);
|
||||
} else if (strcmp(testname, "ip_ttl") == 0) {
|
||||
correct_payload[0] = PAYLOAD_LEN;
|
||||
correct_payload[1] = PAYLOAD_LEN;
|
||||
|
|
@ -1602,19 +1692,17 @@ static void gro_receiver(void)
|
|||
|
||||
/* large sub-tests */
|
||||
} else if (strcmp(testname, "large_max") == 0) {
|
||||
int offset = (proto == PF_INET && !ipip) ? 20 : 0;
|
||||
int remainder = (MAX_PAYLOAD + offset) % MSS;
|
||||
int remainder = max_payload() % calc_mss();
|
||||
|
||||
correct_payload[0] = (MAX_PAYLOAD + offset);
|
||||
correct_payload[0] = max_payload();
|
||||
correct_payload[1] = remainder;
|
||||
printf("Shouldn't coalesce if exceed IP max pkt size: ");
|
||||
check_recv_pkts(rxfd, correct_payload, 2);
|
||||
} else if (strcmp(testname, "large_rem") == 0) {
|
||||
int offset = (proto == PF_INET && !ipip) ? 20 : 0;
|
||||
int remainder = (MAX_PAYLOAD + offset) % MSS;
|
||||
int remainder = max_payload() % calc_mss();
|
||||
|
||||
/* last segment sent individually, doesn't start new segment */
|
||||
correct_payload[0] = (MAX_PAYLOAD + offset) - remainder;
|
||||
correct_payload[0] = max_payload() - remainder;
|
||||
correct_payload[1] = remainder + 1;
|
||||
correct_payload[2] = remainder + 1;
|
||||
printf("last segment sent individually: ");
|
||||
|
|
@ -1645,6 +1733,7 @@ static void parse_args(int argc, char **argv)
|
|||
{ "ipv4", no_argument, NULL, '4' },
|
||||
{ "ipv6", no_argument, NULL, '6' },
|
||||
{ "ipip", no_argument, NULL, 'e' },
|
||||
{ "ip6ip6", no_argument, NULL, 'E' },
|
||||
{ "num-flows", required_argument, NULL, 'n' },
|
||||
{ "rx", no_argument, NULL, 'r' },
|
||||
{ "saddr", required_argument, NULL, 's' },
|
||||
|
|
@ -1656,7 +1745,7 @@ static void parse_args(int argc, char **argv)
|
|||
};
|
||||
int c;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "46d:D:ei:n:rs:S:t:ov", opts, NULL)) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "46d:D:eEi:n:rs:S:t:ov", opts, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case '4':
|
||||
proto = PF_INET;
|
||||
|
|
@ -1671,6 +1760,11 @@ static void parse_args(int argc, char **argv)
|
|||
proto = PF_INET;
|
||||
ethhdr_proto = htons(ETH_P_IP);
|
||||
break;
|
||||
case 'E':
|
||||
ip6ip6 = true;
|
||||
proto = PF_INET6;
|
||||
ethhdr_proto = htons(ETH_P_IPV6);
|
||||
break;
|
||||
case 'd':
|
||||
addr4_dst = addr6_dst = optarg;
|
||||
break;
|
||||
|
|
@ -1715,12 +1809,15 @@ int main(int argc, char **argv)
|
|||
if (ipip) {
|
||||
tcp_offset = ETH_HLEN + sizeof(struct iphdr) * 2;
|
||||
total_hdr_len = tcp_offset + sizeof(struct tcphdr);
|
||||
} else if (ip6ip6) {
|
||||
tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr) * 2;
|
||||
total_hdr_len = tcp_offset + sizeof(struct tcphdr);
|
||||
} else if (proto == PF_INET) {
|
||||
tcp_offset = ETH_HLEN + sizeof(struct iphdr);
|
||||
total_hdr_len = tcp_offset + sizeof(struct tcphdr);
|
||||
} else if (proto == PF_INET6) {
|
||||
tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr);
|
||||
total_hdr_len = MAX_HDR_LEN;
|
||||
total_hdr_len = tcp_offset + sizeof(struct tcphdr);
|
||||
} else {
|
||||
error(1, 0, "Protocol family is not ipv4 or ipv6");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user