28
28
* | | | | | |
29
29
* | ------------------ ------------------ |
30
30
* -----------------------------------------
31
+ *
32
+ * - [test_xdp_veth_broadcast_redirect]: broadcast from veth11
33
+ * - IPv4 ping : BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS
34
+ * -> echo request received by all except veth11
35
+ * - IPv4 ping : BPF_F_BROADCAST
36
+ * -> echo request received by all veth
37
+ *
38
+ * veth11 veth22 veth33
39
+ * (XDP_PASS) (XDP_PASS) (XDP_PASS)
40
+ * | | |
41
+ * | | |
42
+ * veth1 veth2 veth3
43
+ * (XDP_REDIRECT) (XDP_REDIRECT) (XDP_REDIRECT)
44
+ * | ^ ^
45
+ * | | |
46
+ * ----------------------------------------
47
+ *
31
48
*/
32
49
33
50
#define _GNU_SOURCE
36
53
#include "network_helpers.h"
37
54
#include "xdp_dummy.skel.h"
38
55
#include "xdp_redirect_map.skel.h"
56
+ #include "xdp_redirect_multi_kern.skel.h"
39
57
#include "xdp_tx.skel.h"
40
58
#include <uapi/linux/if_link.h>
41
59
44
62
#define IP_MAX_LEN 16
45
63
#define IP_SRC "10.1.1.11"
46
64
#define IP_DST "10.1.1.33"
65
+ #define IP_NEIGH "10.1.1.253"
47
66
#define PROG_NAME_MAX_LEN 128
48
67
#define NS_NAME_MAX_LEN 32
49
68
@@ -297,6 +316,121 @@ static void xdp_veth_redirect(u32 flags)
297
316
cleanup_network (& net_config );
298
317
}
299
318
319
+ #define BROADCAST_REDIRECT_SKEL_NB 2
320
+ static void xdp_veth_broadcast_redirect (u32 attach_flags , u64 redirect_flags )
321
+ {
322
+ struct prog_configuration prog_cfg [VETH_PAIRS_COUNT ] = {
323
+ {
324
+ .local_name = "xdp_redirect_map_multi_prog" ,
325
+ .remote_name = "xdp_count_0" ,
326
+ .local_flags = attach_flags ,
327
+ .remote_flags = attach_flags ,
328
+ },
329
+ {
330
+ .local_name = "xdp_redirect_map_multi_prog" ,
331
+ .remote_name = "xdp_count_1" ,
332
+ .local_flags = attach_flags ,
333
+ .remote_flags = attach_flags ,
334
+ },
335
+ {
336
+ .local_name = "xdp_redirect_map_multi_prog" ,
337
+ .remote_name = "xdp_count_2" ,
338
+ .local_flags = attach_flags ,
339
+ .remote_flags = attach_flags ,
340
+ }
341
+ };
342
+ struct bpf_object * bpf_objs [BROADCAST_REDIRECT_SKEL_NB ];
343
+ struct xdp_redirect_multi_kern * xdp_redirect_multi_kern ;
344
+ struct xdp_redirect_map * xdp_redirect_map ;
345
+ struct bpf_devmap_val devmap_val = {};
346
+ struct net_configuration net_config ;
347
+ struct nstoken * nstoken = NULL ;
348
+ u16 protocol = ETH_P_IP ;
349
+ int group_map ;
350
+ int flags_map ;
351
+ int cnt_map ;
352
+ u64 cnt = 0 ;
353
+ int i , err ;
354
+
355
+ xdp_redirect_multi_kern = xdp_redirect_multi_kern__open_and_load ();
356
+ if (!ASSERT_OK_PTR (xdp_redirect_multi_kern , "xdp_redirect_multi_kern__open_and_load" ))
357
+ return ;
358
+
359
+ xdp_redirect_map = xdp_redirect_map__open_and_load ();
360
+ if (!ASSERT_OK_PTR (xdp_redirect_map , "xdp_redirect_map__open_and_load" ))
361
+ goto destroy_xdp_redirect_multi_kern ;
362
+
363
+ if (!ASSERT_OK (create_network (& net_config ), "create network" ))
364
+ goto destroy_xdp_redirect_map ;
365
+
366
+ group_map = bpf_map__fd (xdp_redirect_multi_kern -> maps .map_all );
367
+ if (!ASSERT_OK_FD (group_map , "open map_all" ))
368
+ goto destroy_xdp_redirect_map ;
369
+
370
+ flags_map = bpf_map__fd (xdp_redirect_multi_kern -> maps .redirect_flags );
371
+ if (!ASSERT_OK_FD (group_map , "open map_all" ))
372
+ goto destroy_xdp_redirect_map ;
373
+
374
+ err = bpf_map_update_elem (flags_map , & protocol , & redirect_flags , BPF_NOEXIST );
375
+ if (!ASSERT_OK (err , "init IP count" ))
376
+ goto destroy_xdp_redirect_map ;
377
+
378
+ cnt_map = bpf_map__fd (xdp_redirect_map -> maps .rxcnt );
379
+ if (!ASSERT_OK_FD (cnt_map , "open rxcnt map" ))
380
+ goto destroy_xdp_redirect_map ;
381
+
382
+ bpf_objs [0 ] = xdp_redirect_multi_kern -> obj ;
383
+ bpf_objs [1 ] = xdp_redirect_map -> obj ;
384
+
385
+ nstoken = open_netns (net_config .ns0_name );
386
+ if (!ASSERT_OK_PTR (nstoken , "open NS0" ))
387
+ goto destroy_xdp_redirect_map ;
388
+
389
+ for (i = 0 ; i < VETH_PAIRS_COUNT ; i ++ ) {
390
+ int ifindex = if_nametoindex (net_config .veth_cfg [i ].local_veth );
391
+
392
+ if (attach_programs_to_veth_pair (bpf_objs , BROADCAST_REDIRECT_SKEL_NB ,
393
+ & net_config , prog_cfg , i ))
394
+ goto destroy_xdp_redirect_map ;
395
+
396
+ SYS (destroy_xdp_redirect_map ,
397
+ "ip -n %s neigh add %s lladdr 00:00:00:00:00:01 dev %s" ,
398
+ net_config .veth_cfg [i ].namespace , IP_NEIGH , net_config .veth_cfg [i ].remote_veth );
399
+
400
+ devmap_val .ifindex = ifindex ;
401
+ err = bpf_map_update_elem (group_map , & ifindex , & devmap_val , 0 );
402
+ if (!ASSERT_OK (err , "bpf_map_update_elem" ))
403
+ goto destroy_xdp_redirect_map ;
404
+
405
+ }
406
+
407
+ SYS_NOFAIL ("ip netns exec %s ping %s -i 0.1 -c 4 -W1 > /dev/null " ,
408
+ net_config .veth_cfg [0 ].namespace , IP_NEIGH );
409
+
410
+ for (i = 0 ; i < VETH_PAIRS_COUNT ; i ++ ) {
411
+ err = bpf_map_lookup_elem (cnt_map , & i , & cnt );
412
+ if (!ASSERT_OK (err , "get IP cnt" ))
413
+ goto destroy_xdp_redirect_map ;
414
+
415
+ if (redirect_flags & BPF_F_EXCLUDE_INGRESS )
416
+ /* veth11 shouldn't receive the ICMP requests;
417
+ * others should
418
+ */
419
+ ASSERT_EQ (cnt , i ? 4 : 0 , "compare IP cnt" );
420
+ else
421
+ /* All remote veth should receive the ICMP requests */
422
+ ASSERT_EQ (cnt , 4 , "compare IP cnt" );
423
+ }
424
+
425
+ destroy_xdp_redirect_map :
426
+ close_netns (nstoken );
427
+ xdp_redirect_map__destroy (xdp_redirect_map );
428
+ destroy_xdp_redirect_multi_kern :
429
+ xdp_redirect_multi_kern__destroy (xdp_redirect_multi_kern );
430
+
431
+ cleanup_network (& net_config );
432
+ }
433
+
300
434
void test_xdp_veth_redirect (void )
301
435
{
302
436
if (test__start_subtest ("0" ))
@@ -308,3 +442,26 @@ void test_xdp_veth_redirect(void)
308
442
if (test__start_subtest ("SKB_MODE" ))
309
443
xdp_veth_redirect (XDP_FLAGS_SKB_MODE );
310
444
}
445
+
446
+ void test_xdp_veth_broadcast_redirect (void )
447
+ {
448
+ if (test__start_subtest ("0/BROADCAST" ))
449
+ xdp_veth_broadcast_redirect (0 , BPF_F_BROADCAST );
450
+
451
+ if (test__start_subtest ("0/(BROADCAST | EXCLUDE_INGRESS)" ))
452
+ xdp_veth_broadcast_redirect (0 , BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS );
453
+
454
+ if (test__start_subtest ("DRV_MODE/BROADCAST" ))
455
+ xdp_veth_broadcast_redirect (XDP_FLAGS_DRV_MODE , BPF_F_BROADCAST );
456
+
457
+ if (test__start_subtest ("DRV_MODE/(BROADCAST | EXCLUDE_INGRESS)" ))
458
+ xdp_veth_broadcast_redirect (XDP_FLAGS_DRV_MODE ,
459
+ BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS );
460
+
461
+ if (test__start_subtest ("SKB_MODE/BROADCAST" ))
462
+ xdp_veth_broadcast_redirect (XDP_FLAGS_SKB_MODE , BPF_F_BROADCAST );
463
+
464
+ if (test__start_subtest ("SKB_MODE/(BROADCAST | EXCLUDE_INGRESS)" ))
465
+ xdp_veth_broadcast_redirect (XDP_FLAGS_SKB_MODE ,
466
+ BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS );
467
+ }
0 commit comments