xskxceiver.c (d2e541494935a659b67e51aa3d1945bb3b799c4e) xskxceiver.c (df82d2e89c41d1dc6f02a881f0cddac8252bb441)
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2020 Intel Corporation. */
3
4/*
5 * Some functions in this program are taken from
6 * Linux kernel samples/bpf/xdpsock* and modified
7 * for use.
8 *

--- 62 unchanged lines hidden (view full) ---

71#define _GNU_SOURCE
72#include <assert.h>
73#include <fcntl.h>
74#include <errno.h>
75#include <getopt.h>
76#include <asm/barrier.h>
77#include <linux/if_link.h>
78#include <linux/if_ether.h>
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2020 Intel Corporation. */
3
4/*
5 * Some functions in this program are taken from
6 * Linux kernel samples/bpf/xdpsock* and modified
7 * for use.
8 *

--- 62 unchanged lines hidden (view full) ---

71#define _GNU_SOURCE
72#include <assert.h>
73#include <fcntl.h>
74#include <errno.h>
75#include <getopt.h>
76#include <asm/barrier.h>
77#include <linux/if_link.h>
78#include <linux/if_ether.h>
79#include <linux/ip.h>
80#include <linux/mman.h>
79#include <linux/mman.h>
81#include <linux/udp.h>
82#include <arpa/inet.h>
83#include <net/if.h>
84#include <locale.h>
85#include <poll.h>
86#include <pthread.h>
87#include <signal.h>
80#include <arpa/inet.h>
81#include <net/if.h>
82#include <locale.h>
83#include <poll.h>
84#include <pthread.h>
85#include <signal.h>
88#include <stdbool.h>
89#include <stdio.h>
90#include <stdlib.h>
91#include <string.h>
92#include <stddef.h>
93#include <sys/mman.h>
94#include <sys/socket.h>
95#include <sys/time.h>
96#include <sys/types.h>
86#include <stdio.h>
87#include <stdlib.h>
88#include <string.h>
89#include <stddef.h>
90#include <sys/mman.h>
91#include <sys/socket.h>
92#include <sys/time.h>
93#include <sys/types.h>
97#include <sys/queue.h>
98#include <time.h>
99#include <unistd.h>
94#include <time.h>
95#include <unistd.h>
100#include <stdatomic.h>
101
102#include "xsk_xdp_progs.skel.h"
103#include "xsk.h"
104#include "xskxceiver.h"
105#include <bpf/bpf.h>
106#include <linux/filter.h>
107#include "../kselftest.h"
108#include "xsk_xdp_metadata.h"
109
110static const char *MAC1 = "\x00\x0A\x56\x9E\xEE\x62";
111static const char *MAC2 = "\x00\x0A\x56\x9E\xEE\x61";
96
97#include "xsk_xdp_progs.skel.h"
98#include "xsk.h"
99#include "xskxceiver.h"
100#include <bpf/bpf.h>
101#include <linux/filter.h>
102#include "../kselftest.h"
103#include "xsk_xdp_metadata.h"
104
105static const char *MAC1 = "\x00\x0A\x56\x9E\xEE\x62";
106static const char *MAC2 = "\x00\x0A\x56\x9E\xEE\x61";
112static const char *IP1 = "192.168.100.162";
113static const char *IP2 = "192.168.100.161";
114static const u16 UDP_PORT1 = 2020;
115static const u16 UDP_PORT2 = 2121;
116
117static void __exit_with_error(int error, const char *file, const char *func, int line)
118{
119 ksft_test_result_fail("[%s:%s:%i]: ERROR: %d/\"%s\"\n", file, func, line, error,
120 strerror(error));
121 ksft_exit_xfail();
122}
123

--- 29 unchanged lines hidden (view full) ---

153 int i;
154
155 val = htonl(val);
156
157 for (i = 0; i < (size & (~0x3)); i += 4)
158 ptr[i >> 2] = val;
159}
160
107
108static void __exit_with_error(int error, const char *file, const char *func, int line)
109{
110 ksft_test_result_fail("[%s:%s:%i]: ERROR: %d/\"%s\"\n", file, func, line, error,
111 strerror(error));
112 ksft_exit_xfail();
113}
114

--- 29 unchanged lines hidden (view full) ---

144 int i;
145
146 val = htonl(val);
147
148 for (i = 0; i < (size & (~0x3)); i += 4)
149 ptr[i >> 2] = val;
150}
151
161/*
162 * Fold a partial checksum
163 * This function code has been taken from
164 * Linux kernel include/asm-generic/checksum.h
165 */
166static __u16 csum_fold(__u32 csum)
167{
168 u32 sum = (__force u32)csum;
169
170 sum = (sum & 0xffff) + (sum >> 16);
171 sum = (sum & 0xffff) + (sum >> 16);
172 return (__force __u16)~sum;
173}
174
175/*
176 * This function code has been taken from
177 * Linux kernel lib/checksum.c
178 */
179static u32 from64to32(u64 x)
180{
181 /* add up 32-bit and 32-bit for 32+c bit */
182 x = (x & 0xffffffff) + (x >> 32);
183 /* add up carry.. */
184 x = (x & 0xffffffff) + (x >> 32);
185 return (u32)x;
186}
187
188/*
189 * This function code has been taken from
190 * Linux kernel lib/checksum.c
191 */
192static __u32 csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, __u32 sum)
193{
194 unsigned long long s = (__force u32)sum;
195
196 s += (__force u32)saddr;
197 s += (__force u32)daddr;
198#ifdef __BIG_ENDIAN__
199 s += proto + len;
200#else
201 s += (proto + len) << 8;
202#endif
203 return (__force __u32)from64to32(s);
204}
205
206/*
207 * This function has been taken from
208 * Linux kernel include/asm-generic/checksum.h
209 */
210static __u16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, __u32 sum)
211{
212 return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
213}
214
215static u16 udp_csum(u32 saddr, u32 daddr, u32 len, u8 proto, u16 *udp_pkt)
216{
217 u32 csum = 0;
218 u32 cnt = 0;
219
220 /* udp hdr and data */
221 for (; cnt < len; cnt += 2)
222 csum += udp_pkt[cnt >> 1];
223
224 return csum_tcpudp_magic(saddr, daddr, len, proto, csum);
225}
226
227static void gen_eth_hdr(struct ifobject *ifobject, struct ethhdr *eth_hdr)
228{
229 memcpy(eth_hdr->h_dest, ifobject->dst_mac, ETH_ALEN);
230 memcpy(eth_hdr->h_source, ifobject->src_mac, ETH_ALEN);
152static void gen_eth_hdr(struct ifobject *ifobject, struct ethhdr *eth_hdr)
153{
154 memcpy(eth_hdr->h_dest, ifobject->dst_mac, ETH_ALEN);
155 memcpy(eth_hdr->h_source, ifobject->src_mac, ETH_ALEN);
231 eth_hdr->h_proto = htons(ETH_P_IP);
156 eth_hdr->h_proto = htons(ETH_P_LOOPBACK);
232}
233
157}
158
234static void gen_ip_hdr(struct ifobject *ifobject, struct iphdr *ip_hdr)
235{
236 ip_hdr->version = IP_PKT_VER;
237 ip_hdr->ihl = 0x5;
238 ip_hdr->tos = IP_PKT_TOS;
239 ip_hdr->tot_len = htons(IP_PKT_SIZE);
240 ip_hdr->id = 0;
241 ip_hdr->frag_off = 0;
242 ip_hdr->ttl = IPDEFTTL;
243 ip_hdr->protocol = IPPROTO_UDP;
244 ip_hdr->saddr = ifobject->src_ip;
245 ip_hdr->daddr = ifobject->dst_ip;
246 ip_hdr->check = 0;
247}
248
249static void gen_udp_hdr(u32 payload, void *pkt, struct ifobject *ifobject,
250 struct udphdr *udp_hdr)
251{
252 udp_hdr->source = htons(ifobject->src_port);
253 udp_hdr->dest = htons(ifobject->dst_port);
254 udp_hdr->len = htons(UDP_PKT_SIZE);
255 memset32_htonl(pkt + PKT_HDR_SIZE, payload, UDP_PKT_DATA_SIZE);
256}
257
258static bool is_umem_valid(struct ifobject *ifobj)
259{
260 return !!ifobj->umem->umem;
261}
262
159static bool is_umem_valid(struct ifobject *ifobj)
160{
161 return !!ifobj->umem->umem;
162}
163
263static void gen_udp_csum(struct udphdr *udp_hdr, struct iphdr *ip_hdr)
264{
265 udp_hdr->check = 0;
266 udp_hdr->check =
267 udp_csum(ip_hdr->saddr, ip_hdr->daddr, UDP_PKT_SIZE, IPPROTO_UDP, (u16 *)udp_hdr);
268}
269
270static u32 mode_to_xdp_flags(enum test_mode mode)
271{
272 return (mode == TEST_MODE_SKB) ? XDP_FLAGS_SKB_MODE : XDP_FLAGS_DRV_MODE;
273}
274
275static int xsk_configure_umem(struct xsk_umem_info *umem, void *buffer, u64 size)
276{
277 struct xsk_umem_config cfg = {

--- 414 unchanged lines hidden (view full) ---

692 pkt_stream = test->ifobj_rx->pkt_stream;
693 for (i = 1; i < pkt_stream->nb_pkts; i += 2)
694 pkt_stream->pkts[i].valid = false;
695}
696
697static struct pkt *pkt_generate(struct ifobject *ifobject, u32 pkt_nb)
698{
699 struct pkt *pkt = pkt_stream_get_pkt(ifobject->pkt_stream, pkt_nb);
164static u32 mode_to_xdp_flags(enum test_mode mode)
165{
166 return (mode == TEST_MODE_SKB) ? XDP_FLAGS_SKB_MODE : XDP_FLAGS_DRV_MODE;
167}
168
169static int xsk_configure_umem(struct xsk_umem_info *umem, void *buffer, u64 size)
170{
171 struct xsk_umem_config cfg = {

--- 414 unchanged lines hidden (view full) ---

586 pkt_stream = test->ifobj_rx->pkt_stream;
587 for (i = 1; i < pkt_stream->nb_pkts; i += 2)
588 pkt_stream->pkts[i].valid = false;
589}
590
591static struct pkt *pkt_generate(struct ifobject *ifobject, u32 pkt_nb)
592{
593 struct pkt *pkt = pkt_stream_get_pkt(ifobject->pkt_stream, pkt_nb);
700 struct udphdr *udp_hdr;
701 struct ethhdr *eth_hdr;
594 struct ethhdr *eth_hdr;
702 struct iphdr *ip_hdr;
703 void *data;
704
705 if (!pkt)
706 return NULL;
707 if (!pkt->valid || pkt->len < MIN_PKT_SIZE)
708 return pkt;
709
710 data = xsk_umem__get_data(ifobject->umem->buffer, pkt->addr);
595 void *data;
596
597 if (!pkt)
598 return NULL;
599 if (!pkt->valid || pkt->len < MIN_PKT_SIZE)
600 return pkt;
601
602 data = xsk_umem__get_data(ifobject->umem->buffer, pkt->addr);
711 udp_hdr = (struct udphdr *)(data + sizeof(struct ethhdr) + sizeof(struct iphdr));
712 ip_hdr = (struct iphdr *)(data + sizeof(struct ethhdr));
713 eth_hdr = (struct ethhdr *)data;
603 eth_hdr = data;
714
604
715 gen_udp_hdr(pkt_nb, data, ifobject, udp_hdr);
716 gen_ip_hdr(ifobject, ip_hdr);
717 gen_udp_csum(udp_hdr, ip_hdr);
718 gen_eth_hdr(ifobject, eth_hdr);
605 gen_eth_hdr(ifobject, eth_hdr);
606 memset32_htonl(data + PKT_HDR_SIZE, pkt_nb, pkt->len - PKT_HDR_SIZE);
719
720 return pkt;
721}
722
723static void __pkt_stream_generate_custom(struct ifobject *ifobj,
724 struct pkt *pkts, u32 nb_pkts)
725{
726 struct pkt_stream *pkt_stream;

--- 14 unchanged lines hidden (view full) ---

741}
742
743static void pkt_stream_generate_custom(struct test_spec *test, struct pkt *pkts, u32 nb_pkts)
744{
745 __pkt_stream_generate_custom(test->ifobj_tx, pkts, nb_pkts);
746 __pkt_stream_generate_custom(test->ifobj_rx, pkts, nb_pkts);
747}
748
607
608 return pkt;
609}
610
611static void __pkt_stream_generate_custom(struct ifobject *ifobj,
612 struct pkt *pkts, u32 nb_pkts)
613{
614 struct pkt_stream *pkt_stream;

--- 14 unchanged lines hidden (view full) ---

629}
630
631static void pkt_stream_generate_custom(struct test_spec *test, struct pkt *pkts, u32 nb_pkts)
632{
633 __pkt_stream_generate_custom(test->ifobj_tx, pkts, nb_pkts);
634 __pkt_stream_generate_custom(test->ifobj_rx, pkts, nb_pkts);
635}
636
749static void pkt_dump(void *pkt, u32 len)
637static void pkt_dump(void *pkt)
750{
638{
751 char s[INET_ADDRSTRLEN];
752 struct ethhdr *ethhdr;
753 struct udphdr *udphdr;
754 struct iphdr *iphdr;
639 struct ethhdr *ethhdr = pkt;
755 u32 payload, i;
756
640 u32 payload, i;
641
757 ethhdr = pkt;
758 iphdr = pkt + sizeof(*ethhdr);
759 udphdr = pkt + sizeof(*ethhdr) + sizeof(*iphdr);
760
761 /*extract L2 frame */
762 fprintf(stdout, "DEBUG>> L2: dst mac: ");
763 for (i = 0; i < ETH_ALEN; i++)
764 fprintf(stdout, "%02X", ethhdr->h_dest[i]);
765
766 fprintf(stdout, "\nDEBUG>> L2: src mac: ");
767 for (i = 0; i < ETH_ALEN; i++)
768 fprintf(stdout, "%02X", ethhdr->h_source[i]);
769
642 /*extract L2 frame */
643 fprintf(stdout, "DEBUG>> L2: dst mac: ");
644 for (i = 0; i < ETH_ALEN; i++)
645 fprintf(stdout, "%02X", ethhdr->h_dest[i]);
646
647 fprintf(stdout, "\nDEBUG>> L2: src mac: ");
648 for (i = 0; i < ETH_ALEN; i++)
649 fprintf(stdout, "%02X", ethhdr->h_source[i]);
650
770 /*extract L3 frame */
771 fprintf(stdout, "\nDEBUG>> L3: ip_hdr->ihl: %02X\n", iphdr->ihl);
772 fprintf(stdout, "DEBUG>> L3: ip_hdr->saddr: %s\n",
773 inet_ntop(AF_INET, &iphdr->saddr, s, sizeof(s)));
774 fprintf(stdout, "DEBUG>> L3: ip_hdr->daddr: %s\n",
775 inet_ntop(AF_INET, &iphdr->daddr, s, sizeof(s)));
776 /*extract L4 frame */
777 fprintf(stdout, "DEBUG>> L4: udp_hdr->src: %d\n", ntohs(udphdr->source));
778 fprintf(stdout, "DEBUG>> L4: udp_hdr->dst: %d\n", ntohs(udphdr->dest));
779 /*extract L5 frame */
780 payload = ntohl(*((u32 *)(pkt + PKT_HDR_SIZE)));
781
651 /*extract L5 frame */
652 payload = ntohl(*((u32 *)(pkt + PKT_HDR_SIZE)));
653
782 fprintf(stdout, "DEBUG>> L5: payload: %d\n", payload);
654 fprintf(stdout, "\nDEBUG>> L5: payload: %d\n", payload);
783 fprintf(stdout, "---------------------------------------\n");
784}
785
786static bool is_offset_correct(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream, u64 addr,
787 u64 pkt_stream_addr)
788{
789 u32 headroom = umem->unaligned_mode ? 0 : umem->frame_headroom;
790 u32 offset = addr % umem->frame_size, expected_offset = 0;

--- 22 unchanged lines hidden (view full) ---

813 }
814
815 return true;
816}
817
818static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len)
819{
820 void *data = xsk_umem__get_data(buffer, addr);
655 fprintf(stdout, "---------------------------------------\n");
656}
657
658static bool is_offset_correct(struct xsk_umem_info *umem, struct pkt_stream *pkt_stream, u64 addr,
659 u64 pkt_stream_addr)
660{
661 u32 headroom = umem->unaligned_mode ? 0 : umem->frame_headroom;
662 u32 offset = addr % umem->frame_size, expected_offset = 0;

--- 22 unchanged lines hidden (view full) ---

685 }
686
687 return true;
688}
689
690static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len)
691{
692 void *data = xsk_umem__get_data(buffer, addr);
821 struct iphdr *iphdr = (struct iphdr *)(data + sizeof(struct ethhdr));
693 u32 seqnum;
822
823 if (!pkt) {
824 ksft_print_msg("[%s] too many packets received\n", __func__);
825 return false;
826 }
827
828 if (len < MIN_PKT_SIZE || pkt->len < MIN_PKT_SIZE) {
829 /* Do not try to verify packets that are smaller than minimum size. */
830 return true;
831 }
832
833 if (pkt->len != len) {
834 ksft_print_msg("[%s] expected length [%d], got length [%d]\n",
835 __func__, pkt->len, len);
836 return false;
837 }
838
694
695 if (!pkt) {
696 ksft_print_msg("[%s] too many packets received\n", __func__);
697 return false;
698 }
699
700 if (len < MIN_PKT_SIZE || pkt->len < MIN_PKT_SIZE) {
701 /* Do not try to verify packets that are smaller than minimum size. */
702 return true;
703 }
704
705 if (pkt->len != len) {
706 ksft_print_msg("[%s] expected length [%d], got length [%d]\n",
707 __func__, pkt->len, len);
708 return false;
709 }
710
839 if (iphdr->version == IP_PKT_VER && iphdr->tos == IP_PKT_TOS) {
840 u32 seqnum = ntohl(*((u32 *)(data + PKT_HDR_SIZE)));
711 seqnum = ntohl(*((u32 *)(data + PKT_HDR_SIZE)));
712 if (opt_pkt_dump)
713 pkt_dump(data);
841
714
842 if (opt_pkt_dump)
843 pkt_dump(data, PKT_SIZE);
844
845 if (pkt->payload != seqnum) {
846 ksft_print_msg("[%s] expected seqnum [%d], got seqnum [%d]\n",
847 __func__, pkt->payload, seqnum);
848 return false;
849 }
850 } else {
851 ksft_print_msg("Invalid frame received: ");
852 ksft_print_msg("[IP_PKT_VER: %02X], [IP_PKT_TOS: %02X]\n", iphdr->version,
853 iphdr->tos);
715 if (pkt->payload != seqnum) {
716 ksft_print_msg("[%s] expected seqnum [%d], got seqnum [%d]\n",
717 __func__, pkt->payload, seqnum);
854 return false;
855 }
856
857 return true;
858}
859
860static void kick_tx(struct xsk_socket_info *xsk)
861{

--- 739 unchanged lines hidden (view full) ---

1601 pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0);
1602 test->ifobj_tx->validation_func = validate_tx_invalid_descs;
1603 testapp_validate_traffic(test);
1604}
1605
1606static void testapp_stats_rx_full(struct test_spec *test)
1607{
1608 test_spec_set_name(test, "STAT_RX_FULL");
718 return false;
719 }
720
721 return true;
722}
723
724static void kick_tx(struct xsk_socket_info *xsk)
725{

--- 739 unchanged lines hidden (view full) ---

1465 pkt_stream_replace_half(test, XSK_UMEM__INVALID_FRAME_SIZE, 0);
1466 test->ifobj_tx->validation_func = validate_tx_invalid_descs;
1467 testapp_validate_traffic(test);
1468}
1469
1470static void testapp_stats_rx_full(struct test_spec *test)
1471{
1472 test_spec_set_name(test, "STAT_RX_FULL");
1609 pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, PKT_SIZE);
1473 pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
1610 test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
1474 test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
1611 DEFAULT_UMEM_BUFFERS, PKT_SIZE);
1475 DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
1612 if (!test->ifobj_rx->pkt_stream)
1613 exit_with_error(ENOMEM);
1614
1615 test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
1616 test->ifobj_rx->release_rx = false;
1617 test->ifobj_rx->validation_func = validate_rx_full;
1618 testapp_validate_traffic(test);
1619}
1620
1621static void testapp_stats_fill_empty(struct test_spec *test)
1622{
1623 test_spec_set_name(test, "STAT_RX_FILL_EMPTY");
1476 if (!test->ifobj_rx->pkt_stream)
1477 exit_with_error(ENOMEM);
1478
1479 test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS;
1480 test->ifobj_rx->release_rx = false;
1481 test->ifobj_rx->validation_func = validate_rx_full;
1482 testapp_validate_traffic(test);
1483}
1484
1485static void testapp_stats_fill_empty(struct test_spec *test)
1486{
1487 test_spec_set_name(test, "STAT_RX_FILL_EMPTY");
1624 pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, PKT_SIZE);
1488 pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE);
1625 test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
1489 test->ifobj_rx->pkt_stream = pkt_stream_generate(test->ifobj_rx->umem,
1626 DEFAULT_UMEM_BUFFERS, PKT_SIZE);
1490 DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE);
1627 if (!test->ifobj_rx->pkt_stream)
1628 exit_with_error(ENOMEM);
1629
1630 test->ifobj_rx->use_fill_ring = false;
1631 test->ifobj_rx->validation_func = validate_fill_empty;
1632 testapp_validate_traffic(test);
1633}
1634

--- 19 unchanged lines hidden (view full) ---

1654 ksft_test_result_skip("No 2M huge pages present.\n");
1655 return false;
1656 }
1657
1658 test_spec_set_name(test, "UNALIGNED_MODE");
1659 test->ifobj_tx->umem->unaligned_mode = true;
1660 test->ifobj_rx->umem->unaligned_mode = true;
1661 /* Let half of the packets straddle a buffer boundrary */
1491 if (!test->ifobj_rx->pkt_stream)
1492 exit_with_error(ENOMEM);
1493
1494 test->ifobj_rx->use_fill_ring = false;
1495 test->ifobj_rx->validation_func = validate_fill_empty;
1496 testapp_validate_traffic(test);
1497}
1498

--- 19 unchanged lines hidden (view full) ---

1518 ksft_test_result_skip("No 2M huge pages present.\n");
1519 return false;
1520 }
1521
1522 test_spec_set_name(test, "UNALIGNED_MODE");
1523 test->ifobj_tx->umem->unaligned_mode = true;
1524 test->ifobj_rx->umem->unaligned_mode = true;
1525 /* Let half of the packets straddle a buffer boundrary */
1662 pkt_stream_replace_half(test, PKT_SIZE, -PKT_SIZE / 2);
1526 pkt_stream_replace_half(test, MIN_PKT_SIZE, -MIN_PKT_SIZE / 2);
1663 test->ifobj_rx->pkt_stream->use_addr_for_fill = true;
1664 testapp_validate_traffic(test);
1665
1666 return true;
1667}
1668
1669static void testapp_single_pkt(struct test_spec *test)
1670{
1527 test->ifobj_rx->pkt_stream->use_addr_for_fill = true;
1528 testapp_validate_traffic(test);
1529
1530 return true;
1531}
1532
1533static void testapp_single_pkt(struct test_spec *test)
1534{
1671 struct pkt pkts[] = {{0x1000, PKT_SIZE, 0, true}};
1535 struct pkt pkts[] = {{0x1000, MIN_PKT_SIZE, 0, true}};
1672
1673 pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
1674 testapp_validate_traffic(test);
1675}
1676
1677static void testapp_invalid_desc(struct test_spec *test)
1678{
1679 u64 umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
1680 struct pkt pkts[] = {
1681 /* Zero packet address allowed */
1536
1537 pkt_stream_generate_custom(test, pkts, ARRAY_SIZE(pkts));
1538 testapp_validate_traffic(test);
1539}
1540
1541static void testapp_invalid_desc(struct test_spec *test)
1542{
1543 u64 umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
1544 struct pkt pkts[] = {
1545 /* Zero packet address allowed */
1682 {0, PKT_SIZE, 0, true},
1546 {0, MIN_PKT_SIZE, 0, true},
1683 /* Allowed packet */
1547 /* Allowed packet */
1684 {0x1000, PKT_SIZE, 0, true},
1548 {0x1000, MIN_PKT_SIZE, 0, true},
1685 /* Straddling the start of umem */
1549 /* Straddling the start of umem */
1686 {-2, PKT_SIZE, 0, false},
1550 {-2, MIN_PKT_SIZE, 0, false},
1687 /* Packet too large */
1688 {0x2000, XSK_UMEM__INVALID_FRAME_SIZE, 0, false},
1689 /* Up to end of umem allowed */
1551 /* Packet too large */
1552 {0x2000, XSK_UMEM__INVALID_FRAME_SIZE, 0, false},
1553 /* Up to end of umem allowed */
1690 {umem_size - PKT_SIZE, PKT_SIZE, 0, true},
1554 {umem_size - MIN_PKT_SIZE, MIN_PKT_SIZE, 0, true},
1691 /* After umem ends */
1555 /* After umem ends */
1692 {umem_size, PKT_SIZE, 0, false},
1556 {umem_size, MIN_PKT_SIZE, 0, false},
1693 /* Straddle the end of umem */
1557 /* Straddle the end of umem */
1694 {umem_size - PKT_SIZE / 2, PKT_SIZE, 0, false},
1558 {umem_size - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
1695 /* Straddle a page boundrary */
1559 /* Straddle a page boundrary */
1696 {0x3000 - PKT_SIZE / 2, PKT_SIZE, 0, false},
1560 {0x3000 - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, false},
1697 /* Straddle a 2K boundrary */
1561 /* Straddle a 2K boundrary */
1698 {0x3800 - PKT_SIZE / 2, PKT_SIZE, 0, true},
1562 {0x3800 - MIN_PKT_SIZE / 2, MIN_PKT_SIZE, 0, true},
1699 /* Valid packet for synch so that something is received */
1563 /* Valid packet for synch so that something is received */
1700 {0x4000, PKT_SIZE, 0, true}};
1564 {0x4000, MIN_PKT_SIZE, 0, true}};
1701
1702 if (test->ifobj_tx->umem->unaligned_mode) {
1703 /* Crossing a page boundrary allowed */
1704 pkts[7].valid = true;
1705 }
1706 if (test->ifobj_tx->umem->frame_size == XSK_UMEM__DEFAULT_FRAME_SIZE / 2) {
1707 /* Crossing a 2K frame size boundrary not allowed */
1708 pkts[8].valid = false;

--- 74 unchanged lines hidden (view full) ---

1783}
1784
1785static void xsk_unload_xdp_programs(struct ifobject *ifobj)
1786{
1787 xsk_xdp_progs__destroy(ifobj->xdp_progs);
1788}
1789
1790static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
1565
1566 if (test->ifobj_tx->umem->unaligned_mode) {
1567 /* Crossing a page boundrary allowed */
1568 pkts[7].valid = true;
1569 }
1570 if (test->ifobj_tx->umem->frame_size == XSK_UMEM__DEFAULT_FRAME_SIZE / 2) {
1571 /* Crossing a 2K frame size boundrary not allowed */
1572 pkts[8].valid = false;

--- 74 unchanged lines hidden (view full) ---

1647}
1648
1649static void xsk_unload_xdp_programs(struct ifobject *ifobj)
1650{
1651 xsk_xdp_progs__destroy(ifobj->xdp_progs);
1652}
1653
1654static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
1791 const char *dst_ip, const char *src_ip, const u16 dst_port,
1792 const u16 src_port, thread_func_t func_ptr)
1655 thread_func_t func_ptr)
1793{
1656{
1794 struct in_addr ip;
1795 int err;
1796
1797 memcpy(ifobj->dst_mac, dst_mac, ETH_ALEN);
1798 memcpy(ifobj->src_mac, src_mac, ETH_ALEN);
1799
1657 int err;
1658
1659 memcpy(ifobj->dst_mac, dst_mac, ETH_ALEN);
1660 memcpy(ifobj->src_mac, src_mac, ETH_ALEN);
1661
1800 inet_aton(dst_ip, &ip);
1801 ifobj->dst_ip = ip.s_addr;
1802
1803 inet_aton(src_ip, &ip);
1804 ifobj->src_ip = ip.s_addr;
1805
1806 ifobj->dst_port = dst_port;
1807 ifobj->src_port = src_port;
1808
1809 ifobj->func_ptr = func_ptr;
1810
1811 err = xsk_load_xdp_programs(ifobj);
1812 if (err) {
1813 printf("Error loading XDP program\n");
1814 exit_with_error(err);
1815 }
1816}

--- 33 unchanged lines hidden (view full) ---

1850 case TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT:
1851 test_spec_set_name(test, "RUN_TO_COMPLETION_SINGLE_PKT");
1852 testapp_single_pkt(test);
1853 break;
1854 case TEST_TYPE_RUN_TO_COMPLETION_2K_FRAME:
1855 test_spec_set_name(test, "RUN_TO_COMPLETION_2K_FRAME_SIZE");
1856 test->ifobj_tx->umem->frame_size = 2048;
1857 test->ifobj_rx->umem->frame_size = 2048;
1662 ifobj->func_ptr = func_ptr;
1663
1664 err = xsk_load_xdp_programs(ifobj);
1665 if (err) {
1666 printf("Error loading XDP program\n");
1667 exit_with_error(err);
1668 }
1669}

--- 33 unchanged lines hidden (view full) ---

1703 case TEST_TYPE_RUN_TO_COMPLETION_SINGLE_PKT:
1704 test_spec_set_name(test, "RUN_TO_COMPLETION_SINGLE_PKT");
1705 testapp_single_pkt(test);
1706 break;
1707 case TEST_TYPE_RUN_TO_COMPLETION_2K_FRAME:
1708 test_spec_set_name(test, "RUN_TO_COMPLETION_2K_FRAME_SIZE");
1709 test->ifobj_tx->umem->frame_size = 2048;
1710 test->ifobj_rx->umem->frame_size = 2048;
1858 pkt_stream_replace(test, DEFAULT_PKT_CNT, PKT_SIZE);
1711 pkt_stream_replace(test, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
1859 testapp_validate_traffic(test);
1860 break;
1861 case TEST_TYPE_RX_POLL:
1862 test->ifobj_rx->use_poll = true;
1863 test_spec_set_name(test, "POLL_RX");
1864 testapp_validate_traffic(test);
1865 break;
1866 case TEST_TYPE_TX_POLL:

--- 40 unchanged lines hidden (view full) ---

1907 test->ifobj_rx->umem->frame_size = 4001;
1908 test->ifobj_tx->umem->unaligned_mode = true;
1909 test->ifobj_rx->umem->unaligned_mode = true;
1910 /* This test exists to test descriptors that staddle the end of
1911 * the UMEM but not a page.
1912 */
1913 page_size = sysconf(_SC_PAGESIZE);
1914 umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
1712 testapp_validate_traffic(test);
1713 break;
1714 case TEST_TYPE_RX_POLL:
1715 test->ifobj_rx->use_poll = true;
1716 test_spec_set_name(test, "POLL_RX");
1717 testapp_validate_traffic(test);
1718 break;
1719 case TEST_TYPE_TX_POLL:

--- 40 unchanged lines hidden (view full) ---

1760 test->ifobj_rx->umem->frame_size = 4001;
1761 test->ifobj_tx->umem->unaligned_mode = true;
1762 test->ifobj_rx->umem->unaligned_mode = true;
1763 /* This test exists to test descriptors that staddle the end of
1764 * the UMEM but not a page.
1765 */
1766 page_size = sysconf(_SC_PAGESIZE);
1767 umem_size = test->ifobj_tx->umem->num_frames * test->ifobj_tx->umem->frame_size;
1915 assert(umem_size % page_size > PKT_SIZE);
1916 assert(umem_size % page_size < page_size - PKT_SIZE);
1768 assert(umem_size % page_size > MIN_PKT_SIZE);
1769 assert(umem_size % page_size < page_size - MIN_PKT_SIZE);
1917 testapp_invalid_desc(test);
1918 break;
1919 }
1920 case TEST_TYPE_UNALIGNED:
1921 if (!testapp_unaligned(test))
1922 return;
1923 break;
1924 case TEST_TYPE_HEADROOM:

--- 109 unchanged lines hidden (view full) ---

2034 }
2035
2036 if (is_xdp_supported(ifobj_tx->ifindex)) {
2037 modes++;
2038 if (ifobj_zc_avail(ifobj_tx))
2039 modes++;
2040 }
2041
1770 testapp_invalid_desc(test);
1771 break;
1772 }
1773 case TEST_TYPE_UNALIGNED:
1774 if (!testapp_unaligned(test))
1775 return;
1776 break;
1777 case TEST_TYPE_HEADROOM:

--- 109 unchanged lines hidden (view full) ---

1887 }
1888
1889 if (is_xdp_supported(ifobj_tx->ifindex)) {
1890 modes++;
1891 if (ifobj_zc_avail(ifobj_tx))
1892 modes++;
1893 }
1894
2042 init_iface(ifobj_rx, MAC1, MAC2, IP1, IP2, UDP_PORT1, UDP_PORT2,
2043 worker_testapp_validate_rx);
2044 init_iface(ifobj_tx, MAC2, MAC1, IP2, IP1, UDP_PORT2, UDP_PORT1,
2045 worker_testapp_validate_tx);
1895 init_iface(ifobj_rx, MAC1, MAC2, worker_testapp_validate_rx);
1896 init_iface(ifobj_tx, MAC2, MAC1, worker_testapp_validate_tx);
2046
2047 test_spec_init(&test, ifobj_tx, ifobj_rx, 0);
1897
1898 test_spec_init(&test, ifobj_tx, ifobj_rx, 0);
2048 tx_pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, PKT_SIZE);
2049 rx_pkt_stream_default = pkt_stream_generate(ifobj_rx->umem, DEFAULT_PKT_CNT, PKT_SIZE);
1899 tx_pkt_stream_default = pkt_stream_generate(ifobj_tx->umem, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
1900 rx_pkt_stream_default = pkt_stream_generate(ifobj_rx->umem, DEFAULT_PKT_CNT, MIN_PKT_SIZE);
2050 if (!tx_pkt_stream_default || !rx_pkt_stream_default)
2051 exit_with_error(ENOMEM);
2052 test.tx_pkt_stream_default = tx_pkt_stream_default;
2053 test.rx_pkt_stream_default = rx_pkt_stream_default;
2054
2055 ksft_set_plan(modes * TEST_TYPE_MAX);
2056
2057 for (i = 0; i < modes; i++) {

--- 22 unchanged lines hidden ---
1901 if (!tx_pkt_stream_default || !rx_pkt_stream_default)
1902 exit_with_error(ENOMEM);
1903 test.tx_pkt_stream_default = tx_pkt_stream_default;
1904 test.rx_pkt_stream_default = rx_pkt_stream_default;
1905
1906 ksft_set_plan(modes * TEST_TYPE_MAX);
1907
1908 for (i = 0; i < modes; i++) {

--- 22 unchanged lines hidden ---