Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2020 Facebook */
  3#include <uapi/linux/if_link.h>
  4#include <test_progs.h>
  5#include "test_xdp_link.skel.h"
  6
  7#define IFINDEX_LO 1
  8
  9void serial_test_xdp_link(void)
 10{
 
 
 11	struct test_xdp_link *skel1 = NULL, *skel2 = NULL;
 12	__u32 id1, id2, id0 = 0, prog_fd1, prog_fd2;
 13	LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
 14	struct bpf_link_info link_info;
 15	struct bpf_prog_info prog_info;
 16	struct bpf_link *link;
 17	int err;
 18	__u32 link_info_len = sizeof(link_info);
 19	__u32 prog_info_len = sizeof(prog_info);
 20
 21	skel1 = test_xdp_link__open_and_load();
 22	if (!ASSERT_OK_PTR(skel1, "skel_load"))
 23		goto cleanup;
 24	prog_fd1 = bpf_program__fd(skel1->progs.xdp_handler);
 25
 26	skel2 = test_xdp_link__open_and_load();
 27	if (!ASSERT_OK_PTR(skel2, "skel_load"))
 28		goto cleanup;
 29	prog_fd2 = bpf_program__fd(skel2->progs.xdp_handler);
 30
 31	memset(&prog_info, 0, sizeof(prog_info));
 32	err = bpf_prog_get_info_by_fd(prog_fd1, &prog_info, &prog_info_len);
 33	if (!ASSERT_OK(err, "fd_info1"))
 34		goto cleanup;
 35	id1 = prog_info.id;
 36
 37	memset(&prog_info, 0, sizeof(prog_info));
 38	err = bpf_prog_get_info_by_fd(prog_fd2, &prog_info, &prog_info_len);
 39	if (!ASSERT_OK(err, "fd_info2"))
 40		goto cleanup;
 41	id2 = prog_info.id;
 42
 43	/* set initial prog attachment */
 44	err = bpf_xdp_attach(IFINDEX_LO, prog_fd1, XDP_FLAGS_REPLACE, &opts);
 45	if (!ASSERT_OK(err, "fd_attach"))
 46		goto cleanup;
 47
 48	/* validate prog ID */
 49	err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
 50	if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
 51		goto cleanup;
 52
 53	/* BPF link is not allowed to replace prog attachment */
 54	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
 55	if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {
 56		bpf_link__destroy(link);
 57		/* best-effort detach prog */
 58		opts.old_prog_fd = prog_fd1;
 59		bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);
 60		goto cleanup;
 61	}
 62
 63	/* detach BPF program */
 64	opts.old_prog_fd = prog_fd1;
 65	err = bpf_xdp_detach(IFINDEX_LO, XDP_FLAGS_REPLACE, &opts);
 66	if (!ASSERT_OK(err, "prog_detach"))
 67		goto cleanup;
 68
 69	/* now BPF link should attach successfully */
 70	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
 71	if (!ASSERT_OK_PTR(link, "link_attach"))
 72		goto cleanup;
 73	skel1->links.xdp_handler = link;
 74
 75	/* validate prog ID */
 76	err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
 77	if (!ASSERT_OK(err, "id1_check_err") || !ASSERT_EQ(id0, id1, "id1_check_val"))
 
 78		goto cleanup;
 79
 80	/* BPF prog attach is not allowed to replace BPF link */
 81	opts.old_prog_fd = prog_fd1;
 82	err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, XDP_FLAGS_REPLACE, &opts);
 83	if (!ASSERT_ERR(err, "prog_attach_fail"))
 84		goto cleanup;
 85
 86	/* Can't force-update when BPF link is active */
 87	err = bpf_xdp_attach(IFINDEX_LO, prog_fd2, 0, NULL);
 88	if (!ASSERT_ERR(err, "prog_update_fail"))
 89		goto cleanup;
 90
 91	/* Can't force-detach when BPF link is active */
 92	err = bpf_xdp_detach(IFINDEX_LO, 0, NULL);
 93	if (!ASSERT_ERR(err, "prog_detach_fail"))
 94		goto cleanup;
 95
 96	/* BPF link is not allowed to replace another BPF link */
 97	link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
 98	if (!ASSERT_ERR_PTR(link, "link_attach_should_fail")) {
 99		bpf_link__destroy(link);
100		goto cleanup;
101	}
102
103	bpf_link__destroy(skel1->links.xdp_handler);
104	skel1->links.xdp_handler = NULL;
105
106	/* new link attach should succeed */
107	link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
108	if (!ASSERT_OK_PTR(link, "link_attach"))
109		goto cleanup;
110	skel2->links.xdp_handler = link;
111
112	err = bpf_xdp_query_id(IFINDEX_LO, 0, &id0);
113	if (!ASSERT_OK(err, "id2_check_err") || !ASSERT_EQ(id0, id2, "id2_check_val"))
 
114		goto cleanup;
115
116	/* updating program under active BPF link works as expected */
117	err = bpf_link__update_program(link, skel1->progs.xdp_handler);
118	if (!ASSERT_OK(err, "link_upd"))
119		goto cleanup;
120
121	memset(&link_info, 0, sizeof(link_info));
122	err = bpf_link_get_info_by_fd(bpf_link__fd(link),
123				      &link_info, &link_info_len);
124	if (!ASSERT_OK(err, "link_info"))
125		goto cleanup;
126
127	ASSERT_EQ(link_info.type, BPF_LINK_TYPE_XDP, "link_type");
128	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
129	ASSERT_EQ(link_info.xdp.ifindex, IFINDEX_LO, "link_ifindex");
130
131	/* updating program under active BPF link with different type fails */
132	err = bpf_link__update_program(link, skel1->progs.tc_handler);
133	if (!ASSERT_ERR(err, "link_upd_invalid"))
134		goto cleanup;
135
136	err = bpf_link__detach(link);
137	if (!ASSERT_OK(err, "link_detach"))
138		goto cleanup;
139
140	memset(&link_info, 0, sizeof(link_info));
141	err = bpf_link_get_info_by_fd(bpf_link__fd(link),
142				      &link_info, &link_info_len);
143
144	ASSERT_OK(err, "link_info");
145	ASSERT_EQ(link_info.prog_id, id1, "link_prog_id");
146	/* ifindex should be zeroed out */
147	ASSERT_EQ(link_info.xdp.ifindex, 0, "link_ifindex");
 
148
149cleanup:
150	test_xdp_link__destroy(skel1);
151	test_xdp_link__destroy(skel2);
152}
v5.9
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2020 Facebook */
  3#include <uapi/linux/if_link.h>
  4#include <test_progs.h>
  5#include "test_xdp_link.skel.h"
  6
  7#define IFINDEX_LO 1
  8
  9void test_xdp_link(void)
 10{
 11	__u32 duration = 0, id1, id2, id0 = 0, prog_fd1, prog_fd2, err;
 12	DECLARE_LIBBPF_OPTS(bpf_xdp_set_link_opts, opts, .old_fd = -1);
 13	struct test_xdp_link *skel1 = NULL, *skel2 = NULL;
 
 
 14	struct bpf_link_info link_info;
 15	struct bpf_prog_info prog_info;
 16	struct bpf_link *link;
 
 17	__u32 link_info_len = sizeof(link_info);
 18	__u32 prog_info_len = sizeof(prog_info);
 19
 20	skel1 = test_xdp_link__open_and_load();
 21	if (CHECK(!skel1, "skel_load", "skeleton open and load failed\n"))
 22		goto cleanup;
 23	prog_fd1 = bpf_program__fd(skel1->progs.xdp_handler);
 24
 25	skel2 = test_xdp_link__open_and_load();
 26	if (CHECK(!skel2, "skel_load", "skeleton open and load failed\n"))
 27		goto cleanup;
 28	prog_fd2 = bpf_program__fd(skel2->progs.xdp_handler);
 29
 30	memset(&prog_info, 0, sizeof(prog_info));
 31	err = bpf_obj_get_info_by_fd(prog_fd1, &prog_info, &prog_info_len);
 32	if (CHECK(err, "fd_info1", "failed %d\n", -errno))
 33		goto cleanup;
 34	id1 = prog_info.id;
 35
 36	memset(&prog_info, 0, sizeof(prog_info));
 37	err = bpf_obj_get_info_by_fd(prog_fd2, &prog_info, &prog_info_len);
 38	if (CHECK(err, "fd_info2", "failed %d\n", -errno))
 39		goto cleanup;
 40	id2 = prog_info.id;
 41
 42	/* set initial prog attachment */
 43	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, prog_fd1, XDP_FLAGS_REPLACE, &opts);
 44	if (CHECK(err, "fd_attach", "initial prog attach failed: %d\n", err))
 45		goto cleanup;
 46
 47	/* validate prog ID */
 48	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
 49	CHECK(err || id0 != id1, "id1_check",
 50	      "loaded prog id %u != id1 %u, err %d", id0, id1, err);
 51
 52	/* BPF link is not allowed to replace prog attachment */
 53	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
 54	if (CHECK(!IS_ERR(link), "link_attach_fail", "unexpected success\n")) {
 55		bpf_link__destroy(link);
 56		/* best-effort detach prog */
 57		opts.old_fd = prog_fd1;
 58		bpf_set_link_xdp_fd_opts(IFINDEX_LO, -1, XDP_FLAGS_REPLACE, &opts);
 59		goto cleanup;
 60	}
 61
 62	/* detach BPF program */
 63	opts.old_fd = prog_fd1;
 64	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, -1, XDP_FLAGS_REPLACE, &opts);
 65	if (CHECK(err, "prog_detach", "failed %d\n", err))
 66		goto cleanup;
 67
 68	/* now BPF link should attach successfully */
 69	link = bpf_program__attach_xdp(skel1->progs.xdp_handler, IFINDEX_LO);
 70	if (CHECK(IS_ERR(link), "link_attach", "failed: %ld\n", PTR_ERR(link)))
 71		goto cleanup;
 72	skel1->links.xdp_handler = link;
 73
 74	/* validate prog ID */
 75	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
 76	if (CHECK(err || id0 != id1, "id1_check",
 77		  "loaded prog id %u != id1 %u, err %d", id0, id1, err))
 78		goto cleanup;
 79
 80	/* BPF prog attach is not allowed to replace BPF link */
 81	opts.old_fd = prog_fd1;
 82	err = bpf_set_link_xdp_fd_opts(IFINDEX_LO, prog_fd2, XDP_FLAGS_REPLACE, &opts);
 83	if (CHECK(!err, "prog_attach_fail", "unexpected success\n"))
 84		goto cleanup;
 85
 86	/* Can't force-update when BPF link is active */
 87	err = bpf_set_link_xdp_fd(IFINDEX_LO, prog_fd2, 0);
 88	if (CHECK(!err, "prog_update_fail", "unexpected success\n"))
 89		goto cleanup;
 90
 91	/* Can't force-detach when BPF link is active */
 92	err = bpf_set_link_xdp_fd(IFINDEX_LO, -1, 0);
 93	if (CHECK(!err, "prog_detach_fail", "unexpected success\n"))
 94		goto cleanup;
 95
 96	/* BPF link is not allowed to replace another BPF link */
 97	link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
 98	if (CHECK(!IS_ERR(link), "link_attach_fail", "unexpected success\n")) {
 99		bpf_link__destroy(link);
100		goto cleanup;
101	}
102
103	bpf_link__destroy(skel1->links.xdp_handler);
104	skel1->links.xdp_handler = NULL;
105
106	/* new link attach should succeed */
107	link = bpf_program__attach_xdp(skel2->progs.xdp_handler, IFINDEX_LO);
108	if (CHECK(IS_ERR(link), "link_attach", "failed: %ld\n", PTR_ERR(link)))
109		goto cleanup;
110	skel2->links.xdp_handler = link;
111
112	err = bpf_get_link_xdp_id(IFINDEX_LO, &id0, 0);
113	if (CHECK(err || id0 != id2, "id2_check",
114		  "loaded prog id %u != id2 %u, err %d", id0, id1, err))
115		goto cleanup;
116
117	/* updating program under active BPF link works as expected */
118	err = bpf_link__update_program(link, skel1->progs.xdp_handler);
119	if (CHECK(err, "link_upd", "failed: %d\n", err))
120		goto cleanup;
121
122	memset(&link_info, 0, sizeof(link_info));
123	err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
124	if (CHECK(err, "link_info", "failed: %d\n", err))
 
125		goto cleanup;
126
127	CHECK(link_info.type != BPF_LINK_TYPE_XDP, "link_type",
128	      "got %u != exp %u\n", link_info.type, BPF_LINK_TYPE_XDP);
129	CHECK(link_info.prog_id != id1, "link_prog_id",
130	      "got %u != exp %u\n", link_info.prog_id, id1);
131	CHECK(link_info.xdp.ifindex != IFINDEX_LO, "link_ifindex",
132	      "got %u != exp %u\n", link_info.xdp.ifindex, IFINDEX_LO);
 
 
133
134	err = bpf_link__detach(link);
135	if (CHECK(err, "link_detach", "failed %d\n", err))
136		goto cleanup;
137
138	memset(&link_info, 0, sizeof(link_info));
139	err = bpf_obj_get_info_by_fd(bpf_link__fd(link), &link_info, &link_info_len);
140	if (CHECK(err, "link_info", "failed: %d\n", err))
141		goto cleanup;
142	CHECK(link_info.prog_id != id1, "link_prog_id",
143	      "got %u != exp %u\n", link_info.prog_id, id1);
144	/* ifindex should be zeroed out */
145	CHECK(link_info.xdp.ifindex != 0, "link_ifindex",
146	      "got %u != exp %u\n", link_info.xdp.ifindex, 0);
147
148cleanup:
149	test_xdp_link__destroy(skel1);
150	test_xdp_link__destroy(skel2);
151}