20
20
21
21
#define UDP_PAYLOAD_BYTES 4
22
22
23
- #define AF_XDP_SOURCE_PORT 1234
23
+ #define UDP_SOURCE_PORT 1234
24
24
#define AF_XDP_CONSUMER_PORT 8080
25
25
26
26
#define UMEM_NUM 16
33
33
#define RX_ADDR "10.0.0.2"
34
34
#define PREFIX_LEN "8"
35
35
#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)
36
42
37
43
struct xsk {
38
44
void * umem_area ;
@@ -181,7 +187,7 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
181
187
ASSERT_EQ (inet_pton (FAMILY , RX_ADDR , & iph -> daddr ), 1 , "inet_pton(RX_ADDR)" );
182
188
ip_csum (iph );
183
189
184
- udph -> source = htons (AF_XDP_SOURCE_PORT );
190
+ udph -> source = htons (UDP_SOURCE_PORT );
185
191
udph -> dest = htons (dst_port );
186
192
udph -> len = htons (sizeof (* udph ) + UDP_PAYLOAD_BYTES );
187
193
udph -> check = ~csum_tcpudp_magic (iph -> saddr , iph -> daddr ,
@@ -204,6 +210,30 @@ static int generate_packet(struct xsk *xsk, __u16 dst_port)
204
210
return 0 ;
205
211
}
206
212
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
+
207
237
static void complete_tx (struct xsk * xsk )
208
238
{
209
239
struct xsk_tx_metadata * meta ;
@@ -236,7 +266,7 @@ static void refill_rx(struct xsk *xsk, __u64 addr)
236
266
}
237
267
}
238
268
239
- static int verify_xsk_metadata (struct xsk * xsk )
269
+ static int verify_xsk_metadata (struct xsk * xsk , bool sent_from_af_xdp )
240
270
{
241
271
const struct xdp_desc * rx_desc ;
242
272
struct pollfd fds = {};
@@ -290,17 +320,36 @@ static int verify_xsk_metadata(struct xsk *xsk)
290
320
if (!ASSERT_NEQ (meta -> rx_hash , 0 , "rx_hash" ))
291
321
return -1 ;
292
322
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
+
293
329
ASSERT_EQ (meta -> rx_hash_type , 0 , "rx_hash_type" );
294
330
295
331
/* checksum offload */
296
332
ASSERT_EQ (udph -> check , htons (0x721c ), "csum" );
297
333
334
+ done :
298
335
xsk_ring_cons__release (& xsk -> rx , 1 );
299
336
refill_rx (xsk , comp_addr );
300
337
301
338
return 0 ;
302
339
}
303
340
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
+
304
353
void test_xdp_metadata (void )
305
354
{
306
355
struct xdp_metadata2 * bpf_obj2 = NULL ;
@@ -318,27 +367,31 @@ void test_xdp_metadata(void)
318
367
int sock_fd ;
319
368
int ret ;
320
369
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 );
322
373
323
- SYS (out , "ip netns add xdp_metadata" );
324
- tok = open_netns ("xdp_metadata" );
374
+ tok = open_netns (TX_NETNS_NAME );
325
375
SYS (out , "ip link add numtxqueues 1 numrxqueues 1 " TX_NAME
326
376
" 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 );
329
380
SYS (out , "ip link set dev " TX_NAME " up" );
330
- SYS (out , "ip link set dev " RX_NAME " up" );
331
381
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" );
332
390
SYS (out , "ip addr add " RX_ADDR "/" PREFIX_LEN " dev " RX_NAME );
333
391
334
392
rx_ifindex = if_nametoindex (RX_NAME );
335
- tx_ifindex = if_nametoindex (TX_NAME );
336
393
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. */
342
395
343
396
ret = open_xsk (rx_ifindex , & rx_xsk );
344
397
if (!ASSERT_OK (ret , "open_xsk(RX_NAME)" ))
@@ -379,18 +432,38 @@ void test_xdp_metadata(void)
379
432
if (!ASSERT_GE (ret , 0 , "bpf_map_update_elem" ))
380
433
goto out ;
381
434
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
+
383
443
if (!ASSERT_GE (generate_packet (& tx_xsk , AF_XDP_CONSUMER_PORT ), 0 ,
384
444
"generate AF_XDP_CONSUMER_PORT" ))
385
445
goto out ;
386
446
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 ,
389
451
"verify_xsk_metadata" ))
390
452
goto out ;
391
453
454
+ switch_ns_to_tx (& tok );
392
455
complete_tx (& tx_xsk );
393
456
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
+
394
467
/* Make sure freplace correctly picks up original bound device
395
468
* and doesn't crash.
396
469
*/
@@ -408,11 +481,15 @@ void test_xdp_metadata(void)
408
481
if (!ASSERT_OK (xdp_metadata2__attach (bpf_obj2 ), "attach freplace" ))
409
482
goto out ;
410
483
484
+ switch_ns_to_tx (& tok );
485
+
411
486
/* Send packet to trigger . */
412
487
if (!ASSERT_GE (generate_packet (& tx_xsk , AF_XDP_CONSUMER_PORT ), 0 ,
413
488
"generate freplace packet" ))
414
489
goto out ;
415
490
491
+ switch_ns_to_rx (& tok );
492
+
416
493
while (!retries -- ) {
417
494
if (bpf_obj2 -> bss -> called )
418
495
break ;
@@ -427,5 +504,6 @@ void test_xdp_metadata(void)
427
504
xdp_metadata__destroy (bpf_obj );
428
505
if (tok )
429
506
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 );
431
509
}
0 commit comments