Skip to content

Commit bc21fae

Browse files
Richard Gobertkuba-moo
Richard Gobert
authored andcommitted
selftests/net: add flush id selftests
Added flush id selftests to test different cases where DF flag is set or unset and id value changes in the following packets. All cases where the packets should coalesce or should not coalesce are tested. Signed-off-by: Richard Gobert <richardbgobert@gmail.com> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://lore.kernel.org/r/20240509190819.2985-4-richardbgobert@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 4b0ebbc commit bc21fae

File tree

1 file changed

+138
-0
lines changed
  • tools/testing/selftests/net

1 file changed

+138
-0
lines changed

tools/testing/selftests/net/gro.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static bool tx_socket = true;
9393
static int tcp_offset = -1;
9494
static int total_hdr_len = -1;
9595
static int ethhdr_proto = -1;
96+
static const int num_flush_id_cases = 6;
9697

9798
static void vlog(const char *fmt, ...)
9899
{
@@ -620,6 +621,113 @@ static void add_ipv6_exthdr(void *buf, void *optpkt, __u8 exthdr_type, char *ext
620621
iph->payload_len = htons(ntohs(iph->payload_len) + MIN_EXTHDR_SIZE);
621622
}
622623

624+
static void fix_ip4_checksum(struct iphdr *iph)
625+
{
626+
iph->check = 0;
627+
iph->check = checksum_fold(iph, sizeof(struct iphdr), 0);
628+
}
629+
630+
static void send_flush_id_case(int fd, struct sockaddr_ll *daddr, int tcase)
631+
{
632+
static char buf1[MAX_HDR_LEN + PAYLOAD_LEN];
633+
static char buf2[MAX_HDR_LEN + PAYLOAD_LEN];
634+
static char buf3[MAX_HDR_LEN + PAYLOAD_LEN];
635+
bool send_three = false;
636+
struct iphdr *iph1;
637+
struct iphdr *iph2;
638+
struct iphdr *iph3;
639+
640+
iph1 = (struct iphdr *)(buf1 + ETH_HLEN);
641+
iph2 = (struct iphdr *)(buf2 + ETH_HLEN);
642+
iph3 = (struct iphdr *)(buf3 + ETH_HLEN);
643+
644+
create_packet(buf1, 0, 0, PAYLOAD_LEN, 0);
645+
create_packet(buf2, PAYLOAD_LEN, 0, PAYLOAD_LEN, 0);
646+
create_packet(buf3, PAYLOAD_LEN * 2, 0, PAYLOAD_LEN, 0);
647+
648+
switch (tcase) {
649+
case 0: /* DF=1, Incrementing - should coalesce */
650+
iph1->frag_off |= htons(IP_DF);
651+
iph1->id = htons(8);
652+
653+
iph2->frag_off |= htons(IP_DF);
654+
iph2->id = htons(9);
655+
break;
656+
657+
case 1: /* DF=1, Fixed - should coalesce */
658+
iph1->frag_off |= htons(IP_DF);
659+
iph1->id = htons(8);
660+
661+
iph2->frag_off |= htons(IP_DF);
662+
iph2->id = htons(8);
663+
break;
664+
665+
case 2: /* DF=0, Incrementing - should coalesce */
666+
iph1->frag_off &= ~htons(IP_DF);
667+
iph1->id = htons(8);
668+
669+
iph2->frag_off &= ~htons(IP_DF);
670+
iph2->id = htons(9);
671+
break;
672+
673+
case 3: /* DF=0, Fixed - should not coalesce */
674+
iph1->frag_off &= ~htons(IP_DF);
675+
iph1->id = htons(8);
676+
677+
iph2->frag_off &= ~htons(IP_DF);
678+
iph2->id = htons(8);
679+
break;
680+
681+
case 4: /* DF=1, two packets incrementing, and one fixed - should
682+
* coalesce only the first two packets
683+
*/
684+
iph1->frag_off |= htons(IP_DF);
685+
iph1->id = htons(8);
686+
687+
iph2->frag_off |= htons(IP_DF);
688+
iph2->id = htons(9);
689+
690+
iph3->frag_off |= htons(IP_DF);
691+
iph3->id = htons(9);
692+
send_three = true;
693+
break;
694+
695+
case 5: /* DF=1, two packets fixed, and one incrementing - should
696+
* coalesce only the first two packets
697+
*/
698+
iph1->frag_off |= htons(IP_DF);
699+
iph1->id = htons(8);
700+
701+
iph2->frag_off |= htons(IP_DF);
702+
iph2->id = htons(8);
703+
704+
iph3->frag_off |= htons(IP_DF);
705+
iph3->id = htons(9);
706+
send_three = true;
707+
break;
708+
}
709+
710+
fix_ip4_checksum(iph1);
711+
fix_ip4_checksum(iph2);
712+
write_packet(fd, buf1, total_hdr_len + PAYLOAD_LEN, daddr);
713+
write_packet(fd, buf2, total_hdr_len + PAYLOAD_LEN, daddr);
714+
715+
if (send_three) {
716+
fix_ip4_checksum(iph3);
717+
write_packet(fd, buf3, total_hdr_len + PAYLOAD_LEN, daddr);
718+
}
719+
}
720+
721+
static void test_flush_id(int fd, struct sockaddr_ll *daddr, char *fin_pkt)
722+
{
723+
for (int i = 0; i < num_flush_id_cases; i++) {
724+
sleep(1);
725+
send_flush_id_case(fd, daddr, i);
726+
sleep(1);
727+
write_packet(fd, fin_pkt, total_hdr_len, daddr);
728+
}
729+
}
730+
623731
static void send_ipv6_exthdr(int fd, struct sockaddr_ll *daddr, char *ext_data1, char *ext_data2)
624732
{
625733
static char buf[MAX_HDR_LEN + PAYLOAD_LEN];
@@ -938,6 +1046,8 @@ static void gro_sender(void)
9381046
send_fragment4(txfd, &daddr);
9391047
sleep(1);
9401048
write_packet(txfd, fin_pkt, total_hdr_len, &daddr);
1049+
1050+
test_flush_id(txfd, &daddr, fin_pkt);
9411051
} else if (proto == PF_INET6) {
9421052
sleep(1);
9431053
send_fragment6(txfd, &daddr);
@@ -1064,6 +1174,34 @@ static void gro_receiver(void)
10641174

10651175
printf("fragmented ip4 doesn't coalesce: ");
10661176
check_recv_pkts(rxfd, correct_payload, 2);
1177+
1178+
/* is_atomic checks */
1179+
printf("DF=1, Incrementing - should coalesce: ");
1180+
correct_payload[0] = PAYLOAD_LEN * 2;
1181+
check_recv_pkts(rxfd, correct_payload, 1);
1182+
1183+
printf("DF=1, Fixed - should coalesce: ");
1184+
correct_payload[0] = PAYLOAD_LEN * 2;
1185+
check_recv_pkts(rxfd, correct_payload, 1);
1186+
1187+
printf("DF=0, Incrementing - should coalesce: ");
1188+
correct_payload[0] = PAYLOAD_LEN * 2;
1189+
check_recv_pkts(rxfd, correct_payload, 1);
1190+
1191+
printf("DF=0, Fixed - should not coalesce: ");
1192+
correct_payload[0] = PAYLOAD_LEN;
1193+
correct_payload[1] = PAYLOAD_LEN;
1194+
check_recv_pkts(rxfd, correct_payload, 2);
1195+
1196+
printf("DF=1, 2 Incrementing and one fixed - should coalesce only first 2 packets: ");
1197+
correct_payload[0] = PAYLOAD_LEN * 2;
1198+
correct_payload[1] = PAYLOAD_LEN;
1199+
check_recv_pkts(rxfd, correct_payload, 2);
1200+
1201+
printf("DF=1, 2 Fixed and one incrementing - should coalesce only first 2 packets: ");
1202+
correct_payload[0] = PAYLOAD_LEN * 2;
1203+
correct_payload[1] = PAYLOAD_LEN;
1204+
check_recv_pkts(rxfd, correct_payload, 2);
10671205
} else if (proto == PF_INET6) {
10681206
/* GRO doesn't check for ipv6 hop limit when flushing.
10691207
* Hence no corresponding test to the ipv4 case.

0 commit comments

Comments
 (0)