aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorMaciej Fijalkowski <maciejromanfijalkowski@gmail.com>2019-02-01 16:42:30 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2019-02-01 17:37:51 -0500
commit3b7a8ec2dec3e408288dbc80b8aef25df20ba119 (patch)
tree234d9207292e271029c3615016f5625e05d3b5d0 /samples
parent50db9f0731889b9f3839cab5f44163733eb44f04 (diff)
samples/bpf: Check the prog id before exiting
Check the program id within the signal handler on polling xdp samples that were previously converted to libbpf usage. Avoid the situation of unloading the program that was not attached by sample that is exiting. Handle also the case where bpf_get_link_xdp_id didn't exit with an error but the xdp program was not found on an interface. Reported-by: Michal Papaj <michal.papaj@intel.com> Reported-by: Jakub Spizewski <jakub.spizewski@intel.com> Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/xdp1_user.c24
-rw-r--r--samples/bpf/xdp_adjust_tail_user.c30
-rw-r--r--samples/bpf/xdp_redirect_cpu_user.c35
-rw-r--r--samples/bpf/xdp_redirect_map_user.c49
-rw-r--r--samples/bpf/xdp_redirect_user.c49
-rw-r--r--samples/bpf/xdp_router_ipv4_user.c51
-rw-r--r--samples/bpf/xdp_rxq_info_user.c33
-rw-r--r--samples/bpf/xdp_sample_pkts_user.c34
-rw-r--r--samples/bpf/xdp_tx_iptunnel_user.c28
-rw-r--r--samples/bpf/xdpsock_user.c23
10 files changed, 308 insertions, 48 deletions
diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c
index 505bce207165..6a64e93365e1 100644
--- a/samples/bpf/xdp1_user.c
+++ b/samples/bpf/xdp1_user.c
@@ -23,10 +23,22 @@
23 23
24static int ifindex; 24static int ifindex;
25static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 25static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
26static __u32 prog_id;
26 27
27static void int_exit(int sig) 28static void int_exit(int sig)
28{ 29{
29 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 30 __u32 curr_prog_id = 0;
31
32 if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
33 printf("bpf_get_link_xdp_id failed\n");
34 exit(1);
35 }
36 if (prog_id == curr_prog_id)
37 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
38 else if (!curr_prog_id)
39 printf("couldn't find a prog id on a given interface\n");
40 else
41 printf("program on interface changed, not removing\n");
30 exit(0); 42 exit(0);
31} 43}
32 44
@@ -74,11 +86,14 @@ int main(int argc, char **argv)
74 struct bpf_prog_load_attr prog_load_attr = { 86 struct bpf_prog_load_attr prog_load_attr = {
75 .prog_type = BPF_PROG_TYPE_XDP, 87 .prog_type = BPF_PROG_TYPE_XDP,
76 }; 88 };
89 struct bpf_prog_info info = {};
90 __u32 info_len = sizeof(info);
77 const char *optstr = "FSN"; 91 const char *optstr = "FSN";
78 int prog_fd, map_fd, opt; 92 int prog_fd, map_fd, opt;
79 struct bpf_object *obj; 93 struct bpf_object *obj;
80 struct bpf_map *map; 94 struct bpf_map *map;
81 char filename[256]; 95 char filename[256];
96 int err;
82 97
83 while ((opt = getopt(argc, argv, optstr)) != -1) { 98 while ((opt = getopt(argc, argv, optstr)) != -1) {
84 switch (opt) { 99 switch (opt) {
@@ -139,6 +154,13 @@ int main(int argc, char **argv)
139 return 1; 154 return 1;
140 } 155 }
141 156
157 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
158 if (err) {
159 printf("can't get prog info - %s\n", strerror(errno));
160 return err;
161 }
162 prog_id = info.id;
163
142 poll_stats(map_fd, 2); 164 poll_stats(map_fd, 2);
143 165
144 return 0; 166 return 0;
diff --git a/samples/bpf/xdp_adjust_tail_user.c b/samples/bpf/xdp_adjust_tail_user.c
index 049bddf7778b..07e1b9269e49 100644
--- a/samples/bpf/xdp_adjust_tail_user.c
+++ b/samples/bpf/xdp_adjust_tail_user.c
@@ -25,11 +25,24 @@
25 25
26static int ifindex = -1; 26static int ifindex = -1;
27static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 27static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
28static __u32 prog_id;
28 29
29static void int_exit(int sig) 30static void int_exit(int sig)
30{ 31{
31 if (ifindex > -1) 32 __u32 curr_prog_id = 0;
32 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 33
34 if (ifindex > -1) {
35 if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
36 printf("bpf_get_link_xdp_id failed\n");
37 exit(1);
38 }
39 if (prog_id == curr_prog_id)
40 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
41 else if (!curr_prog_id)
42 printf("couldn't find a prog id on a given iface\n");
43 else
44 printf("program on interface changed, not removing\n");
45 }
33 exit(0); 46 exit(0);
34} 47}
35 48
@@ -72,11 +85,14 @@ int main(int argc, char **argv)
72 }; 85 };
73 unsigned char opt_flags[256] = {}; 86 unsigned char opt_flags[256] = {};
74 const char *optstr = "i:T:SNFh"; 87 const char *optstr = "i:T:SNFh";
88 struct bpf_prog_info info = {};
89 __u32 info_len = sizeof(info);
75 unsigned int kill_after_s = 0; 90 unsigned int kill_after_s = 0;
76 int i, prog_fd, map_fd, opt; 91 int i, prog_fd, map_fd, opt;
77 struct bpf_object *obj; 92 struct bpf_object *obj;
78 struct bpf_map *map; 93 struct bpf_map *map;
79 char filename[256]; 94 char filename[256];
95 int err;
80 96
81 for (i = 0; i < strlen(optstr); i++) 97 for (i = 0; i < strlen(optstr); i++)
82 if (optstr[i] != 'h' && 'a' <= optstr[i] && optstr[i] <= 'z') 98 if (optstr[i] != 'h' && 'a' <= optstr[i] && optstr[i] <= 'z')
@@ -146,9 +162,15 @@ int main(int argc, char **argv)
146 return 1; 162 return 1;
147 } 163 }
148 164
149 poll_stats(map_fd, kill_after_s); 165 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
166 if (err) {
167 printf("can't get prog info - %s\n", strerror(errno));
168 return 1;
169 }
170 prog_id = info.id;
150 171
151 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 172 poll_stats(map_fd, kill_after_s);
173 int_exit(0);
152 174
153 return 0; 175 return 0;
154} 176}
diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c
index 0224afb55845..586b294d72d3 100644
--- a/samples/bpf/xdp_redirect_cpu_user.c
+++ b/samples/bpf/xdp_redirect_cpu_user.c
@@ -32,6 +32,7 @@ static const char *__doc__ =
32static int ifindex = -1; 32static int ifindex = -1;
33static char ifname_buf[IF_NAMESIZE]; 33static char ifname_buf[IF_NAMESIZE];
34static char *ifname; 34static char *ifname;
35static __u32 prog_id;
35 36
36static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 37static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
37static int cpu_map_fd; 38static int cpu_map_fd;
@@ -68,11 +69,24 @@ static const struct option long_options[] = {
68 69
69static void int_exit(int sig) 70static void int_exit(int sig)
70{ 71{
71 fprintf(stderr, 72 __u32 curr_prog_id = 0;
72 "Interrupted: Removing XDP program on ifindex:%d device:%s\n", 73
73 ifindex, ifname); 74 if (ifindex > -1) {
74 if (ifindex > -1) 75 if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
75 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 76 printf("bpf_get_link_xdp_id failed\n");
77 exit(EXIT_FAIL);
78 }
79 if (prog_id == curr_prog_id) {
80 fprintf(stderr,
81 "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
82 ifindex, ifname);
83 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
84 } else if (!curr_prog_id) {
85 printf("couldn't find a prog id on a given iface\n");
86 } else {
87 printf("program on interface changed, not removing\n");
88 }
89 }
76 exit(EXIT_OK); 90 exit(EXIT_OK);
77} 91}
78 92
@@ -608,6 +622,8 @@ int main(int argc, char **argv)
608 struct bpf_prog_load_attr prog_load_attr = { 622 struct bpf_prog_load_attr prog_load_attr = {
609 .prog_type = BPF_PROG_TYPE_UNSPEC, 623 .prog_type = BPF_PROG_TYPE_UNSPEC,
610 }; 624 };
625 struct bpf_prog_info info = {};
626 __u32 info_len = sizeof(info);
611 bool use_separators = true; 627 bool use_separators = true;
612 bool stress_mode = false; 628 bool stress_mode = false;
613 struct bpf_program *prog; 629 struct bpf_program *prog;
@@ -617,9 +633,9 @@ int main(int argc, char **argv)
617 int longindex = 0; 633 int longindex = 0;
618 int interval = 2; 634 int interval = 2;
619 int add_cpu = -1; 635 int add_cpu = -1;
636 int opt, err;
620 int prog_fd; 637 int prog_fd;
621 __u32 qsize; 638 __u32 qsize;
622 int opt;
623 639
624 /* Notice: choosing he queue size is very important with the 640 /* Notice: choosing he queue size is very important with the
625 * ixgbe driver, because it's driver page recycling trick is 641 * ixgbe driver, because it's driver page recycling trick is
@@ -746,6 +762,13 @@ int main(int argc, char **argv)
746 return EXIT_FAIL_XDP; 762 return EXIT_FAIL_XDP;
747 } 763 }
748 764
765 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
766 if (err) {
767 printf("can't get prog info - %s\n", strerror(errno));
768 return err;
769 }
770 prog_id = info.id;
771
749 stats_poll(interval, use_separators, prog_name, stress_mode); 772 stats_poll(interval, use_separators, prog_name, stress_mode);
750 return EXIT_OK; 773 return EXIT_OK;
751} 774}
diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c
index 470e1a7e8810..327226be5a06 100644
--- a/samples/bpf/xdp_redirect_map_user.c
+++ b/samples/bpf/xdp_redirect_map_user.c
@@ -29,15 +29,41 @@
29static int ifindex_in; 29static int ifindex_in;
30static int ifindex_out; 30static int ifindex_out;
31static bool ifindex_out_xdp_dummy_attached = true; 31static bool ifindex_out_xdp_dummy_attached = true;
32static __u32 prog_id;
33static __u32 dummy_prog_id;
32 34
33static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 35static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
34static int rxcnt_map_fd; 36static int rxcnt_map_fd;
35 37
36static void int_exit(int sig) 38static void int_exit(int sig)
37{ 39{
38 bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags); 40 __u32 curr_prog_id = 0;
39 if (ifindex_out_xdp_dummy_attached) 41
40 bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags); 42 if (bpf_get_link_xdp_id(ifindex_in, &curr_prog_id, xdp_flags)) {
43 printf("bpf_get_link_xdp_id failed\n");
44 exit(1);
45 }
46 if (prog_id == curr_prog_id)
47 bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
48 else if (!curr_prog_id)
49 printf("couldn't find a prog id on iface IN\n");
50 else
51 printf("program on iface IN changed, not removing\n");
52
53 if (ifindex_out_xdp_dummy_attached) {
54 curr_prog_id = 0;
55 if (bpf_get_link_xdp_id(ifindex_out, &curr_prog_id,
56 xdp_flags)) {
57 printf("bpf_get_link_xdp_id failed\n");
58 exit(1);
59 }
60 if (prog_id == curr_prog_id)
61 bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
62 else if (!curr_prog_id)
63 printf("couldn't find a prog id on iface OUT\n");
64 else
65 printf("program on iface OUT changed, not removing\n");
66 }
41 exit(0); 67 exit(0);
42} 68}
43 69
@@ -82,6 +108,8 @@ int main(int argc, char **argv)
82 .prog_type = BPF_PROG_TYPE_XDP, 108 .prog_type = BPF_PROG_TYPE_XDP,
83 }; 109 };
84 struct bpf_program *prog, *dummy_prog; 110 struct bpf_program *prog, *dummy_prog;
111 struct bpf_prog_info info = {};
112 __u32 info_len = sizeof(info);
85 int prog_fd, dummy_prog_fd; 113 int prog_fd, dummy_prog_fd;
86 const char *optstr = "FSN"; 114 const char *optstr = "FSN";
87 struct bpf_object *obj; 115 struct bpf_object *obj;
@@ -153,6 +181,13 @@ int main(int argc, char **argv)
153 return 1; 181 return 1;
154 } 182 }
155 183
184 ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
185 if (ret) {
186 printf("can't get prog info - %s\n", strerror(errno));
187 return ret;
188 }
189 prog_id = info.id;
190
156 /* Loading dummy XDP prog on out-device */ 191 /* Loading dummy XDP prog on out-device */
157 if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd, 192 if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
158 (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { 193 (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
@@ -160,6 +195,14 @@ int main(int argc, char **argv)
160 ifindex_out_xdp_dummy_attached = false; 195 ifindex_out_xdp_dummy_attached = false;
161 } 196 }
162 197
198 memset(&info, 0, sizeof(info));
199 ret = bpf_obj_get_info_by_fd(dummy_prog_fd, &info, &info_len);
200 if (ret) {
201 printf("can't get prog info - %s\n", strerror(errno));
202 return ret;
203 }
204 dummy_prog_id = info.id;
205
163 signal(SIGINT, int_exit); 206 signal(SIGINT, int_exit);
164 signal(SIGTERM, int_exit); 207 signal(SIGTERM, int_exit);
165 208
diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
index be6058cda97c..a5d8ad3129ed 100644
--- a/samples/bpf/xdp_redirect_user.c
+++ b/samples/bpf/xdp_redirect_user.c
@@ -29,15 +29,41 @@
29static int ifindex_in; 29static int ifindex_in;
30static int ifindex_out; 30static int ifindex_out;
31static bool ifindex_out_xdp_dummy_attached = true; 31static bool ifindex_out_xdp_dummy_attached = true;
32static __u32 prog_id;
33static __u32 dummy_prog_id;
32 34
33static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 35static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
34static int rxcnt_map_fd; 36static int rxcnt_map_fd;
35 37
36static void int_exit(int sig) 38static void int_exit(int sig)
37{ 39{
38 bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags); 40 __u32 curr_prog_id = 0;
39 if (ifindex_out_xdp_dummy_attached) 41
40 bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags); 42 if (bpf_get_link_xdp_id(ifindex_in, &curr_prog_id, xdp_flags)) {
43 printf("bpf_get_link_xdp_id failed\n");
44 exit(1);
45 }
46 if (prog_id == curr_prog_id)
47 bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
48 else if (!curr_prog_id)
49 printf("couldn't find a prog id on iface IN\n");
50 else
51 printf("program on iface IN changed, not removing\n");
52
53 if (ifindex_out_xdp_dummy_attached) {
54 curr_prog_id = 0;
55 if (bpf_get_link_xdp_id(ifindex_out, &curr_prog_id,
56 xdp_flags)) {
57 printf("bpf_get_link_xdp_id failed\n");
58 exit(1);
59 }
60 if (prog_id == curr_prog_id)
61 bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
62 else if (!curr_prog_id)
63 printf("couldn't find a prog id on iface OUT\n");
64 else
65 printf("program on iface OUT changed, not removing\n");
66 }
41 exit(0); 67 exit(0);
42} 68}
43 69
@@ -84,6 +110,8 @@ int main(int argc, char **argv)
84 }; 110 };
85 struct bpf_program *prog, *dummy_prog; 111 struct bpf_program *prog, *dummy_prog;
86 int prog_fd, tx_port_map_fd, opt; 112 int prog_fd, tx_port_map_fd, opt;
113 struct bpf_prog_info info = {};
114 __u32 info_len = sizeof(info);
87 const char *optstr = "FSN"; 115 const char *optstr = "FSN";
88 struct bpf_object *obj; 116 struct bpf_object *obj;
89 char filename[256]; 117 char filename[256];
@@ -154,6 +182,13 @@ int main(int argc, char **argv)
154 return 1; 182 return 1;
155 } 183 }
156 184
185 ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
186 if (ret) {
187 printf("can't get prog info - %s\n", strerror(errno));
188 return ret;
189 }
190 prog_id = info.id;
191
157 /* Loading dummy XDP prog on out-device */ 192 /* Loading dummy XDP prog on out-device */
158 if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd, 193 if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
159 (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) { 194 (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
@@ -161,6 +196,14 @@ int main(int argc, char **argv)
161 ifindex_out_xdp_dummy_attached = false; 196 ifindex_out_xdp_dummy_attached = false;
162 } 197 }
163 198
199 memset(&info, 0, sizeof(info));
200 ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
201 if (ret) {
202 printf("can't get prog info - %s\n", strerror(errno));
203 return ret;
204 }
205 dummy_prog_id = info.id;
206
164 signal(SIGINT, int_exit); 207 signal(SIGINT, int_exit);
165 signal(SIGTERM, int_exit); 208 signal(SIGTERM, int_exit);
166 209
diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c
index 208d6a996478..79fe7bc26ab4 100644
--- a/samples/bpf/xdp_router_ipv4_user.c
+++ b/samples/bpf/xdp_router_ipv4_user.c
@@ -30,7 +30,8 @@
30 30
31int sock, sock_arp, flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 31int sock, sock_arp, flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
32static int total_ifindex; 32static int total_ifindex;
33int *ifindex_list; 33static int *ifindex_list;
34static __u32 *prog_id_list;
34char buf[8192]; 35char buf[8192];
35static int lpm_map_fd; 36static int lpm_map_fd;
36static int rxcnt_map_fd; 37static int rxcnt_map_fd;
@@ -41,23 +42,34 @@ static int tx_port_map_fd;
41static int get_route_table(int rtm_family); 42static int get_route_table(int rtm_family);
42static void int_exit(int sig) 43static void int_exit(int sig)
43{ 44{
45 __u32 prog_id = 0;
44 int i = 0; 46 int i = 0;
45 47
46 for (i = 0; i < total_ifindex; i++) 48 for (i = 0; i < total_ifindex; i++) {
47 bpf_set_link_xdp_fd(ifindex_list[i], -1, flags); 49 if (bpf_get_link_xdp_id(ifindex_list[i], &prog_id, flags)) {
50 printf("bpf_get_link_xdp_id on iface %d failed\n",
51 ifindex_list[i]);
52 exit(1);
53 }
54 if (prog_id_list[i] == prog_id)
55 bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
56 else if (!prog_id)
57 printf("couldn't find a prog id on iface %d\n",
58 ifindex_list[i]);
59 else
60 printf("program on iface %d changed, not removing\n",
61 ifindex_list[i]);
62 prog_id = 0;
63 }
48 exit(0); 64 exit(0);
49} 65}
50 66
51static void close_and_exit(int sig) 67static void close_and_exit(int sig)
52{ 68{
53 int i = 0;
54
55 close(sock); 69 close(sock);
56 close(sock_arp); 70 close(sock_arp);
57 71
58 for (i = 0; i < total_ifindex; i++) 72 int_exit(0);
59 bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
60 exit(0);
61} 73}
62 74
63/* Get the mac address of the interface given interface name */ 75/* Get the mac address of the interface given interface name */
@@ -186,13 +198,8 @@ static void read_route(struct nlmsghdr *nh, int nll)
186 route.iface_name = alloca(sizeof(char *) * IFNAMSIZ); 198 route.iface_name = alloca(sizeof(char *) * IFNAMSIZ);
187 route.iface_name = if_indextoname(route.iface, route.iface_name); 199 route.iface_name = if_indextoname(route.iface, route.iface_name);
188 route.mac = getmac(route.iface_name); 200 route.mac = getmac(route.iface_name);
189 if (route.mac == -1) { 201 if (route.mac == -1)
190 int i = 0; 202 int_exit(0);
191
192 for (i = 0; i < total_ifindex; i++)
193 bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
194 exit(0);
195 }
196 assert(bpf_map_update_elem(tx_port_map_fd, 203 assert(bpf_map_update_elem(tx_port_map_fd,
197 &route.iface, &route.iface, 0) == 0); 204 &route.iface, &route.iface, 0) == 0);
198 if (rtm_family == AF_INET) { 205 if (rtm_family == AF_INET) {
@@ -625,12 +632,14 @@ int main(int ac, char **argv)
625 struct bpf_prog_load_attr prog_load_attr = { 632 struct bpf_prog_load_attr prog_load_attr = {
626 .prog_type = BPF_PROG_TYPE_XDP, 633 .prog_type = BPF_PROG_TYPE_XDP,
627 }; 634 };
635 struct bpf_prog_info info = {};
636 __u32 info_len = sizeof(info);
628 const char *optstr = "SF"; 637 const char *optstr = "SF";
629 struct bpf_object *obj; 638 struct bpf_object *obj;
630 char filename[256]; 639 char filename[256];
631 char **ifname_list; 640 char **ifname_list;
632 int prog_fd, opt; 641 int prog_fd, opt;
633 int i = 1; 642 int err, i = 1;
634 643
635 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); 644 snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
636 prog_load_attr.file = filename; 645 prog_load_attr.file = filename;
@@ -687,7 +696,7 @@ int main(int ac, char **argv)
687 return 1; 696 return 1;
688 } 697 }
689 698
690 ifindex_list = (int *)malloc(total_ifindex * sizeof(int *)); 699 ifindex_list = (int *)calloc(total_ifindex, sizeof(int *));
691 for (i = 0; i < total_ifindex; i++) { 700 for (i = 0; i < total_ifindex; i++) {
692 ifindex_list[i] = if_nametoindex(ifname_list[i]); 701 ifindex_list[i] = if_nametoindex(ifname_list[i]);
693 if (!ifindex_list[i]) { 702 if (!ifindex_list[i]) {
@@ -696,6 +705,7 @@ int main(int ac, char **argv)
696 return 1; 705 return 1;
697 } 706 }
698 } 707 }
708 prog_id_list = (__u32 *)calloc(total_ifindex, sizeof(__u32 *));
699 for (i = 0; i < total_ifindex; i++) { 709 for (i = 0; i < total_ifindex; i++) {
700 if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd, flags) < 0) { 710 if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd, flags) < 0) {
701 printf("link set xdp fd failed\n"); 711 printf("link set xdp fd failed\n");
@@ -706,6 +716,13 @@ int main(int ac, char **argv)
706 716
707 return 1; 717 return 1;
708 } 718 }
719 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
720 if (err) {
721 printf("can't get prog info - %s\n", strerror(errno));
722 return err;
723 }
724 prog_id_list[i] = info.id;
725 memset(&info, 0, sizeof(info));
709 printf("Attached to %d\n", ifindex_list[i]); 726 printf("Attached to %d\n", ifindex_list[i]);
710 } 727 }
711 signal(SIGINT, int_exit); 728 signal(SIGINT, int_exit);
diff --git a/samples/bpf/xdp_rxq_info_user.c b/samples/bpf/xdp_rxq_info_user.c
index e7a98c2a440f..1210f3b170f0 100644
--- a/samples/bpf/xdp_rxq_info_user.c
+++ b/samples/bpf/xdp_rxq_info_user.c
@@ -29,6 +29,7 @@ static const char *__doc__ = " XDP RX-queue info extract example\n\n"
29static int ifindex = -1; 29static int ifindex = -1;
30static char ifname_buf[IF_NAMESIZE]; 30static char ifname_buf[IF_NAMESIZE];
31static char *ifname; 31static char *ifname;
32static __u32 prog_id;
32 33
33static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 34static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
34 35
@@ -58,11 +59,24 @@ static const struct option long_options[] = {
58 59
59static void int_exit(int sig) 60static void int_exit(int sig)
60{ 61{
61 fprintf(stderr, 62 __u32 curr_prog_id = 0;
62 "Interrupted: Removing XDP program on ifindex:%d device:%s\n", 63
63 ifindex, ifname); 64 if (ifindex > -1) {
64 if (ifindex > -1) 65 if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
65 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 66 printf("bpf_get_link_xdp_id failed\n");
67 exit(EXIT_FAIL);
68 }
69 if (prog_id == curr_prog_id) {
70 fprintf(stderr,
71 "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
72 ifindex, ifname);
73 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
74 } else if (!curr_prog_id) {
75 printf("couldn't find a prog id on a given iface\n");
76 } else {
77 printf("program on interface changed, not removing\n");
78 }
79 }
66 exit(EXIT_OK); 80 exit(EXIT_OK);
67} 81}
68 82
@@ -447,6 +461,8 @@ int main(int argc, char **argv)
447 struct bpf_prog_load_attr prog_load_attr = { 461 struct bpf_prog_load_attr prog_load_attr = {
448 .prog_type = BPF_PROG_TYPE_XDP, 462 .prog_type = BPF_PROG_TYPE_XDP,
449 }; 463 };
464 struct bpf_prog_info info = {};
465 __u32 info_len = sizeof(info);
450 int prog_fd, map_fd, opt, err; 466 int prog_fd, map_fd, opt, err;
451 bool use_separators = true; 467 bool use_separators = true;
452 struct config cfg = { 0 }; 468 struct config cfg = { 0 };
@@ -580,6 +596,13 @@ int main(int argc, char **argv)
580 return EXIT_FAIL_XDP; 596 return EXIT_FAIL_XDP;
581 } 597 }
582 598
599 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
600 if (err) {
601 printf("can't get prog info - %s\n", strerror(errno));
602 return err;
603 }
604 prog_id = info.id;
605
583 stats_poll(interval, action, cfg_options); 606 stats_poll(interval, action, cfg_options);
584 return EXIT_OK; 607 return EXIT_OK;
585} 608}
diff --git a/samples/bpf/xdp_sample_pkts_user.c b/samples/bpf/xdp_sample_pkts_user.c
index 62f34827c775..dc66345a929a 100644
--- a/samples/bpf/xdp_sample_pkts_user.c
+++ b/samples/bpf/xdp_sample_pkts_user.c
@@ -24,25 +24,49 @@ static int pmu_fds[MAX_CPUS], if_idx;
24static struct perf_event_mmap_page *headers[MAX_CPUS]; 24static struct perf_event_mmap_page *headers[MAX_CPUS];
25static char *if_name; 25static char *if_name;
26static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 26static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
27static __u32 prog_id;
27 28
28static int do_attach(int idx, int fd, const char *name) 29static int do_attach(int idx, int fd, const char *name)
29{ 30{
31 struct bpf_prog_info info = {};
32 __u32 info_len = sizeof(info);
30 int err; 33 int err;
31 34
32 err = bpf_set_link_xdp_fd(idx, fd, xdp_flags); 35 err = bpf_set_link_xdp_fd(idx, fd, xdp_flags);
33 if (err < 0) 36 if (err < 0) {
34 printf("ERROR: failed to attach program to %s\n", name); 37 printf("ERROR: failed to attach program to %s\n", name);
38 return err;
39 }
40
41 err = bpf_obj_get_info_by_fd(fd, &info, &info_len);
42 if (err) {
43 printf("can't get prog info - %s\n", strerror(errno));
44 return err;
45 }
46 prog_id = info.id;
35 47
36 return err; 48 return err;
37} 49}
38 50
39static int do_detach(int idx, const char *name) 51static int do_detach(int idx, const char *name)
40{ 52{
41 int err; 53 __u32 curr_prog_id = 0;
54 int err = 0;
42 55
43 err = bpf_set_link_xdp_fd(idx, -1, 0); 56 err = bpf_get_link_xdp_id(idx, &curr_prog_id, 0);
44 if (err < 0) 57 if (err) {
45 printf("ERROR: failed to detach program from %s\n", name); 58 printf("bpf_get_link_xdp_id failed\n");
59 return err;
60 }
61 if (prog_id == curr_prog_id) {
62 err = bpf_set_link_xdp_fd(idx, -1, 0);
63 if (err < 0)
64 printf("ERROR: failed to detach prog from %s\n", name);
65 } else if (!curr_prog_id) {
66 printf("couldn't find a prog id on a %s\n", name);
67 } else {
68 printf("program on interface changed, not removing\n");
69 }
46 70
47 return err; 71 return err;
48} 72}
diff --git a/samples/bpf/xdp_tx_iptunnel_user.c b/samples/bpf/xdp_tx_iptunnel_user.c
index e3de60930d27..4a1511eb7812 100644
--- a/samples/bpf/xdp_tx_iptunnel_user.c
+++ b/samples/bpf/xdp_tx_iptunnel_user.c
@@ -27,11 +27,24 @@
27static int ifindex = -1; 27static int ifindex = -1;
28static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; 28static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
29static int rxcnt_map_fd; 29static int rxcnt_map_fd;
30static __u32 prog_id;
30 31
31static void int_exit(int sig) 32static void int_exit(int sig)
32{ 33{
33 if (ifindex > -1) 34 __u32 curr_prog_id = 0;
34 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 35
36 if (ifindex > -1) {
37 if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
38 printf("bpf_get_link_xdp_id failed\n");
39 exit(1);
40 }
41 if (prog_id == curr_prog_id)
42 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
43 else if (!curr_prog_id)
44 printf("couldn't find a prog id on a given iface\n");
45 else
46 printf("program on interface changed, not removing\n");
47 }
35 exit(0); 48 exit(0);
36} 49}
37 50
@@ -148,13 +161,15 @@ int main(int argc, char **argv)
148 int min_port = 0, max_port = 0, vip2tnl_map_fd; 161 int min_port = 0, max_port = 0, vip2tnl_map_fd;
149 const char *optstr = "i:a:p:s:d:m:T:P:FSNh"; 162 const char *optstr = "i:a:p:s:d:m:T:P:FSNh";
150 unsigned char opt_flags[256] = {}; 163 unsigned char opt_flags[256] = {};
164 struct bpf_prog_info info = {};
165 __u32 info_len = sizeof(info);
151 unsigned int kill_after_s = 0; 166 unsigned int kill_after_s = 0;
152 struct iptnl_info tnl = {}; 167 struct iptnl_info tnl = {};
153 struct bpf_object *obj; 168 struct bpf_object *obj;
154 struct vip vip = {}; 169 struct vip vip = {};
155 char filename[256]; 170 char filename[256];
156 int opt, prog_fd; 171 int opt, prog_fd;
157 int i; 172 int i, err;
158 173
159 tnl.family = AF_UNSPEC; 174 tnl.family = AF_UNSPEC;
160 vip.protocol = IPPROTO_TCP; 175 vip.protocol = IPPROTO_TCP;
@@ -276,6 +291,13 @@ int main(int argc, char **argv)
276 return 1; 291 return 1;
277 } 292 }
278 293
294 err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
295 if (err) {
296 printf("can't get prog info - %s\n", strerror(errno));
297 return err;
298 }
299 prog_id = info.id;
300
279 poll_stats(kill_after_s); 301 poll_stats(kill_after_s);
280 302
281 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags); 303 bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c
index 188723784768..f73055e0191f 100644
--- a/samples/bpf/xdpsock_user.c
+++ b/samples/bpf/xdpsock_user.c
@@ -76,6 +76,7 @@ static int opt_poll;
76static int opt_shared_packet_buffer; 76static int opt_shared_packet_buffer;
77static int opt_interval = 1; 77static int opt_interval = 1;
78static u32 opt_xdp_bind_flags; 78static u32 opt_xdp_bind_flags;
79static __u32 prog_id;
79 80
80struct xdp_umem_uqueue { 81struct xdp_umem_uqueue {
81 u32 cached_prod; 82 u32 cached_prod;
@@ -631,9 +632,20 @@ static void *poller(void *arg)
631 632
632static void int_exit(int sig) 633static void int_exit(int sig)
633{ 634{
635 __u32 curr_prog_id = 0;
636
634 (void)sig; 637 (void)sig;
635 dump_stats(); 638 dump_stats();
636 bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags); 639 if (bpf_get_link_xdp_id(opt_ifindex, &curr_prog_id, opt_xdp_flags)) {
640 printf("bpf_get_link_xdp_id failed\n");
641 exit(EXIT_FAILURE);
642 }
643 if (prog_id == curr_prog_id)
644 bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags);
645 else if (!curr_prog_id)
646 printf("couldn't find a prog id on a given interface\n");
647 else
648 printf("program on interface changed, not removing\n");
637 exit(EXIT_SUCCESS); 649 exit(EXIT_SUCCESS);
638} 650}
639 651
@@ -907,6 +919,8 @@ int main(int argc, char **argv)
907 .prog_type = BPF_PROG_TYPE_XDP, 919 .prog_type = BPF_PROG_TYPE_XDP,
908 }; 920 };
909 int prog_fd, qidconf_map, xsks_map; 921 int prog_fd, qidconf_map, xsks_map;
922 struct bpf_prog_info info = {};
923 __u32 info_len = sizeof(info);
910 struct bpf_object *obj; 924 struct bpf_object *obj;
911 char xdp_filename[256]; 925 char xdp_filename[256];
912 struct bpf_map *map; 926 struct bpf_map *map;
@@ -953,6 +967,13 @@ int main(int argc, char **argv)
953 exit(EXIT_FAILURE); 967 exit(EXIT_FAILURE);
954 } 968 }
955 969
970 ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
971 if (ret) {
972 printf("can't get prog info - %s\n", strerror(errno));
973 return 1;
974 }
975 prog_id = info.id;
976
956 ret = bpf_map_update_elem(qidconf_map, &key, &opt_queue, 0); 977 ret = bpf_map_update_elem(qidconf_map, &key, &opt_queue, 0);
957 if (ret) { 978 if (ret) {
958 fprintf(stderr, "ERROR: bpf_map_update_elem qidconf\n"); 979 fprintf(stderr, "ERROR: bpf_map_update_elem qidconf\n");