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 --- |