2020
2121#define UDP_PAYLOAD_BYTES 4
2222
23- #define AF_XDP_SOURCE_PORT 1234
23+ #define UDP_SOURCE_PORT 1234
2424#define AF_XDP_CONSUMER_PORT 8080
2525
2626#define UMEM_NUM 16
3333#define RX_ADDR "10.0.0.2"
3434#define PREFIX_LEN "8"
3535#define FAMILY AF_INET
36+ #define TX_NETNS_NAME "xdp_metadata_tx"
37+ #define RX_NETNS_NAME "xdp_metadata_rx"
38+ #define TX_MAC "00:00:00:00:00:01"
39+ #define RX_MAC "00:00:00:00:00:02"
40+
41+ #define XDP_RSS_TYPE_L4 BIT(3)
3642
3743struct xsk {
3844 void * umem_area ;
@@ -181,7 +187,7 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
181187 ASSERT_EQ (inet_pton (FAMILY , RX_ADDR , & iph -> daddr ), 1 , "inet_pton(RX_ADDR)" );
182188 ip_csum (iph );
183189
184- udph -> source = htons (AF_XDP_SOURCE_PORT );
190+ udph -> source = htons (UDP_SOURCE_PORT );
185191 udph -> dest = htons (dst_port );
186192 udph -> len = htons (sizeof (* udph ) + UDP_PAYLOAD_BYTES );
187193 udph -> check = ~csum_tcpudp_magic (iph -> saddr , iph -> daddr ,
@@ -204,6 +210,30 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
204210 return 0 ;
205211}
206212
213+ static int generate_packet_inet (void )
214+ {
215+ char udp_payload [UDP_PAYLOAD_BYTES ];
216+ struct sockaddr_in rx_addr ;
217+ int sock_fd , err = 0 ;
218+
219+ /* Build a packet */
220+ memset (udp_payload , 0xAA , UDP_PAYLOAD_BYTES );
221+ rx_addr .sin_addr .s_addr = inet_addr (RX_ADDR );
222+ rx_addr .sin_family = AF_INET ;
223+ rx_addr .sin_port = htons (AF_XDP_CONSUMER_PORT );
224+
225+ sock_fd = socket (AF_INET , SOCK_DGRAM , IPPROTO_UDP );
226+ if (!ASSERT_GE (sock_fd , 0 , "socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)" ))
227+ return sock_fd ;
228+
229+ err = sendto (sock_fd , udp_payload , UDP_PAYLOAD_BYTES , MSG_DONTWAIT ,
230+ (void * )& rx_addr , sizeof (rx_addr ));
231+ ASSERT_GE (err , 0 , "sendto" );
232+
233+ close (sock_fd );
234+ return err ;
235+ }
236+
207237static void complete_tx (struct xsk * xsk )
208238{
209239 struct xsk_tx_metadata * meta ;
@@ -236,7 +266,7 @@ static void refill_rx(struct xsk *xsk, __u64 addr)
236266 }
237267}
238268
239- static int verify_xsk_metadata (struct xsk * xsk )
269+ static int verify_xsk_metadata (struct xsk * xsk , bool sent_from_af_xdp )
240270{
241271 const struct xdp_desc * rx_desc ;
242272 struct pollfd fds = {};
@@ -290,17 +320,36 @@ static int verify_xsk_metadata(struct xsk *xsk)
290320 if (!ASSERT_NEQ (meta -> rx_hash , 0 , "rx_hash" ))
291321 return -1 ;
292322
323+ if (!sent_from_af_xdp ) {
324+ if (!ASSERT_NEQ (meta -> rx_hash_type & XDP_RSS_TYPE_L4 , 0 , "rx_hash_type" ))
325+ return -1 ;
326+ goto done ;
327+ }
328+
293329 ASSERT_EQ (meta -> rx_hash_type , 0 , "rx_hash_type" );
294330
295331 /* checksum offload */
296332 ASSERT_EQ (udph -> check , htons (0x721c ), "csum" );
297333
334+ done :
298335 xsk_ring_cons__release (& xsk -> rx , 1 );
299336 refill_rx (xsk , comp_addr );
300337
301338 return 0 ;
302339}
303340
341+ static void switch_ns_to_rx (struct nstoken * * tok )
342+ {
343+ close_netns (* tok );
344+ * tok = open_netns (RX_NETNS_NAME );
345+ }
346+
347+ static void switch_ns_to_tx (struct nstoken * * tok )
348+ {
349+ close_netns (* tok );
350+ * tok = open_netns (TX_NETNS_NAME );
351+ }
352+
304353void test_xdp_metadata (void )
305354{
306355 struct xdp_metadata2 * bpf_obj2 = NULL ;
@@ -318,27 +367,31 @@ void test_xdp_metadata(void)
318367 int sock_fd ;
319368 int ret ;
320369
321- /* Setup new networking namespace, with a veth pair. */
370+ /* Setup new networking namespaces, with a veth pair. */
371+ SYS (out , "ip netns add " TX_NETNS_NAME );
372+ SYS (out , "ip netns add " RX_NETNS_NAME );
322373
323- SYS (out , "ip netns add xdp_metadata" );
324- tok = open_netns ("xdp_metadata" );
374+ tok = open_netns (TX_NETNS_NAME );
325375 SYS (out , "ip link add numtxqueues 1 numrxqueues 1 " TX_NAME
326376 " type veth peer " RX_NAME " numtxqueues 1 numrxqueues 1" );
327- SYS (out , "ip link set dev " TX_NAME " address 00:00:00:00:00:01" );
328- SYS (out , "ip link set dev " RX_NAME " address 00:00:00:00:00:02" );
377+ SYS (out , "ip link set " RX_NAME " netns " RX_NETNS_NAME );
378+
379+ SYS (out , "ip link set dev " TX_NAME " address " TX_MAC );
329380 SYS (out , "ip link set dev " TX_NAME " up" );
330- SYS (out , "ip link set dev " RX_NAME " up" );
331381 SYS (out , "ip addr add " TX_ADDR "/" PREFIX_LEN " dev " TX_NAME );
382+
383+ /* Avoid ARP calls */
384+ SYS (out , "ip -4 neigh add " RX_ADDR " lladdr " RX_MAC " dev " TX_NAME );
385+
386+ switch_ns_to_rx (& tok );
387+
388+ SYS (out , "ip link set dev " RX_NAME " address " RX_MAC );
389+ SYS (out , "ip link set dev " RX_NAME " up" );
332390 SYS (out , "ip addr add " RX_ADDR "/" PREFIX_LEN " dev " RX_NAME );
333391
334392 rx_ifindex = if_nametoindex (RX_NAME );
335- tx_ifindex = if_nametoindex (TX_NAME );
336393
337- /* Setup separate AF_XDP for TX and RX interfaces. */
338-
339- ret = open_xsk (tx_ifindex , & tx_xsk );
340- if (!ASSERT_OK (ret , "open_xsk(TX_NAME)" ))
341- goto out ;
394+ /* Setup separate AF_XDP for RX interface. */
342395
343396 ret = open_xsk (rx_ifindex , & rx_xsk );
344397 if (!ASSERT_OK (ret , "open_xsk(RX_NAME)" ))
@@ -379,18 +432,38 @@ void test_xdp_metadata(void)
379432 if (!ASSERT_GE (ret , 0 , "bpf_map_update_elem" ))
380433 goto out ;
381434
382- /* Send packet destined to RX AF_XDP socket. */
435+ switch_ns_to_tx (& tok );
436+
437+ /* Setup separate AF_XDP for TX interface nad send packet to the RX socket. */
438+ tx_ifindex = if_nametoindex (TX_NAME );
439+ ret = open_xsk (tx_ifindex , & tx_xsk );
440+ if (!ASSERT_OK (ret , "open_xsk(TX_NAME)" ))
441+ goto out ;
442+
383443 if (!ASSERT_GE (generate_packet (& tx_xsk , AF_XDP_CONSUMER_PORT ), 0 ,
384444 "generate AF_XDP_CONSUMER_PORT" ))
385445 goto out ;
386446
387- /* Verify AF_XDP RX packet has proper metadata. */
388- if (!ASSERT_GE (verify_xsk_metadata (& rx_xsk ), 0 ,
447+ switch_ns_to_rx (& tok );
448+
449+ /* Verify packet sent from AF_XDP has proper metadata. */
450+ if (!ASSERT_GE (verify_xsk_metadata (& rx_xsk , true), 0 ,
389451 "verify_xsk_metadata" ))
390452 goto out ;
391453
454+ switch_ns_to_tx (& tok );
392455 complete_tx (& tx_xsk );
393456
457+ /* Now check metadata of packet, generated with network stack */
458+ if (!ASSERT_GE (generate_packet_inet (), 0 , "generate UDP packet" ))
459+ goto out ;
460+
461+ switch_ns_to_rx (& tok );
462+
463+ if (!ASSERT_GE (verify_xsk_metadata (& rx_xsk , false), 0 ,
464+ "verify_xsk_metadata" ))
465+ goto out ;
466+
394467 /* Make sure freplace correctly picks up original bound device
395468 * and doesn't crash.
396469 */
@@ -408,11 +481,15 @@ void test_xdp_metadata(void)
408481 if (!ASSERT_OK (xdp_metadata2__attach (bpf_obj2 ), "attach freplace" ))
409482 goto out ;
410483
484+ switch_ns_to_tx (& tok );
485+
411486 /* Send packet to trigger . */
412487 if (!ASSERT_GE (generate_packet (& tx_xsk , AF_XDP_CONSUMER_PORT ), 0 ,
413488 "generate freplace packet" ))
414489 goto out ;
415490
491+ switch_ns_to_rx (& tok );
492+
416493 while (!retries -- ) {
417494 if (bpf_obj2 -> bss -> called )
418495 break ;
@@ -427,5 +504,6 @@ void test_xdp_metadata(void)
427504 xdp_metadata__destroy (bpf_obj );
428505 if (tok )
429506 close_netns (tok );
430- SYS_NOFAIL ("ip netns del xdp_metadata" );
507+ SYS_NOFAIL ("ip netns del " RX_NETNS_NAME );
508+ SYS_NOFAIL ("ip netns del " TX_NETNS_NAME );
431509}
0 commit comments