Tests use the root network namespace, so they aren't fully independent of each other. For instance, the index of the created veth interfaces is incremented every time a new test is launched. Wrap the network topology in a network namespace to ensure full isolation. Use the append_tid() helper to ensure the uniqueness of this namespace's name during parallel runs. Remove the use of the append_tid() on the veth names as they now belong to an already unique namespace. Simplify cleanup_network() by directly deleting the namespaces Signed-off-by: Bastien Curutchet (eBPF Foundation) <bastien.curutchet@xxxxxxxxxxx> --- .../selftests/bpf/prog_tests/test_xdp_veth.c | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/test_xdp_veth.c b/tools/testing/selftests/bpf/prog_tests/test_xdp_veth.c index 4fa2b452de7c8361ec575d63a3ce6fbedc220773..a1c79af23bec25529af5b549d16b2cbfaf1cebd4 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_xdp_veth.c +++ b/tools/testing/selftests/bpf/prog_tests/test_xdp_veth.c @@ -9,7 +9,11 @@ * | veth11 | | veth22 | | veth33 | * ----|----- -----|---- -----|---- * | | | - * veth1 veth2 veth3 + * ----|------------------|----------------|---- + * | veth1 veth2 veth3 | + * | | + * | NSO | + * --------------------------------------------- * * Test cases: * - [test_xdp_veth_redirect] : ping veth33 from veth11 @@ -52,10 +56,12 @@ struct veth_configuration { }; struct net_configuration { + char ns0_name[NS_NAME_MAX_LEN]; struct veth_configuration veth_cfg[VETH_PAIRS_COUNT]; }; static const struct net_configuration default_config = { + .ns0_name = "ns0-", { { .local_veth = "veth1-", @@ -144,21 +150,30 @@ static int attach_programs_to_veth_pair(struct bpf_object **objs, size_t nb_obj, static int create_network(struct net_configuration *net_config) { + struct nstoken *nstoken = NULL; int i, err; memcpy(net_config, &default_config, sizeof(struct net_configuration)); - /* First create and configure all interfaces */ + /* Create unique namespaces */ + err = append_tid(net_config->ns0_name, NS_NAME_MAX_LEN); + if (!ASSERT_OK(err, "append TID to ns0 name")) + goto fail; + SYS(fail, "ip netns add %s", net_config->ns0_name); + for (i = 0; i < VETH_PAIRS_COUNT; i++) { err = append_tid(net_config->veth_cfg[i].namespace, NS_NAME_MAX_LEN); if (!ASSERT_OK(err, "append TID to ns name")) - return -1; + goto fail; + SYS(fail, "ip netns add %s", net_config->veth_cfg[i].namespace); + } - err = append_tid(net_config->veth_cfg[i].local_veth, VETH_NAME_MAX_LEN); - if (!ASSERT_OK(err, "append TID to local veth name")) - return -1; + /* Create interfaces */ + nstoken = open_netns(net_config->ns0_name); + if (!nstoken) + goto fail; - SYS(fail, "ip netns add %s", net_config->veth_cfg[i].namespace); + for (i = 0; i < VETH_PAIRS_COUNT; i++) { SYS(fail, "ip link add %s type veth peer name %s netns %s", net_config->veth_cfg[i].local_veth, net_config->veth_cfg[i].remote_veth, net_config->veth_cfg[i].namespace); @@ -172,29 +187,21 @@ static int create_network(struct net_configuration *net_config) net_config->veth_cfg[i].remote_veth); } + close_netns(nstoken); return 0; fail: + close_netns(nstoken); return -1; } static void cleanup_network(struct net_configuration *net_config) { - struct nstoken *nstoken; int i; - for (i = 0; i < VETH_PAIRS_COUNT; i++) { - bpf_xdp_detach(if_nametoindex(net_config->veth_cfg[i].local_veth), 0, NULL); - nstoken = open_netns(net_config->veth_cfg[i].namespace); - if (nstoken) { - bpf_xdp_detach(if_nametoindex(net_config->veth_cfg[i].remote_veth), - 0, NULL); - close_netns(nstoken); - } - /* in case the detach failed */ - SYS_NOFAIL("ip link del %s", net_config->veth_cfg[i].local_veth); + SYS_NOFAIL("ip netns del %s", net_config->ns0_name); + for (i = 0; i < VETH_PAIRS_COUNT; i++) SYS_NOFAIL("ip netns del %s", net_config->veth_cfg[i].namespace); - } } #define VETH_REDIRECT_SKEL_NB 3 @@ -223,6 +230,7 @@ static void xdp_veth_redirect(u32 flags) struct bpf_object *bpf_objs[VETH_REDIRECT_SKEL_NB]; struct xdp_redirect_map *xdp_redirect_map; struct net_configuration net_config; + struct nstoken *nstoken = NULL; struct xdp_dummy *xdp_dummy; struct xdp_tx *xdp_tx; int map_fd; @@ -251,6 +259,11 @@ static void xdp_veth_redirect(u32 flags) bpf_objs[0] = xdp_dummy->obj; bpf_objs[1] = xdp_tx->obj; bpf_objs[2] = xdp_redirect_map->obj; + + nstoken = open_netns(net_config.ns0_name); + if (!ASSERT_OK_PTR(nstoken, "open NS0")) + goto destroy_xdp_redirect_map; + for (i = 0; i < VETH_PAIRS_COUNT; i++) { int next_veth = net_config.veth_cfg[i].next_veth; int interface_id; @@ -274,6 +287,7 @@ static void xdp_veth_redirect(u32 flags) net_config.veth_cfg[0].namespace, IP_DST), "ping"); destroy_xdp_redirect_map: + close_netns(nstoken); xdp_redirect_map__destroy(xdp_redirect_map); destroy_xdp_tx: xdp_tx__destroy(xdp_tx); -- 2.48.1