]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
samples/bpf: Check the prog id before exiting
authorMaciej Fijalkowski <maciejromanfijalkowski@gmail.com>
Fri, 1 Feb 2019 21:42:30 +0000 (22:42 +0100)
committerDaniel Borkmann <daniel@iogearbox.net>
Fri, 1 Feb 2019 22:37:51 +0000 (23:37 +0100)
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>
samples/bpf/xdp1_user.c
samples/bpf/xdp_adjust_tail_user.c
samples/bpf/xdp_redirect_cpu_user.c
samples/bpf/xdp_redirect_map_user.c
samples/bpf/xdp_redirect_user.c
samples/bpf/xdp_router_ipv4_user.c
samples/bpf/xdp_rxq_info_user.c
samples/bpf/xdp_sample_pkts_user.c
samples/bpf/xdp_tx_iptunnel_user.c
samples/bpf/xdpsock_user.c

index 505bce207165f9931643a9fd46cf440e43fa317f..6a64e93365e1021411224d3e41937f8e47c0ae22 100644 (file)
 
 static int ifindex;
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
+static __u32 prog_id;
 
 static void int_exit(int sig)
 {
-       bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
+               printf("bpf_get_link_xdp_id failed\n");
+               exit(1);
+       }
+       if (prog_id == curr_prog_id)
+               bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       else if (!curr_prog_id)
+               printf("couldn't find a prog id on a given interface\n");
+       else
+               printf("program on interface changed, not removing\n");
        exit(0);
 }
 
@@ -74,11 +86,14 @@ int main(int argc, char **argv)
        struct bpf_prog_load_attr prog_load_attr = {
                .prog_type      = BPF_PROG_TYPE_XDP,
        };
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        const char *optstr = "FSN";
        int prog_fd, map_fd, opt;
        struct bpf_object *obj;
        struct bpf_map *map;
        char filename[256];
+       int err;
 
        while ((opt = getopt(argc, argv, optstr)) != -1) {
                switch (opt) {
@@ -139,6 +154,13 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (err) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return err;
+       }
+       prog_id = info.id;
+
        poll_stats(map_fd, 2);
 
        return 0;
index 049bddf7778b5f682e1e07e51bdf023681fa3f48..07e1b9269e497b0ffbefad4ee3c5d310b7630ff1 100644 (file)
 
 static int ifindex = -1;
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
+static __u32 prog_id;
 
 static void int_exit(int sig)
 {
-       if (ifindex > -1)
-               bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (ifindex > -1) {
+               if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
+                       printf("bpf_get_link_xdp_id failed\n");
+                       exit(1);
+               }
+               if (prog_id == curr_prog_id)
+                       bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+               else if (!curr_prog_id)
+                       printf("couldn't find a prog id on a given iface\n");
+               else
+                       printf("program on interface changed, not removing\n");
+       }
        exit(0);
 }
 
@@ -72,11 +85,14 @@ int main(int argc, char **argv)
        };
        unsigned char opt_flags[256] = {};
        const char *optstr = "i:T:SNFh";
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        unsigned int kill_after_s = 0;
        int i, prog_fd, map_fd, opt;
        struct bpf_object *obj;
        struct bpf_map *map;
        char filename[256];
+       int err;
 
        for (i = 0; i < strlen(optstr); i++)
                if (optstr[i] != 'h' && 'a' <= optstr[i] && optstr[i] <= 'z')
@@ -146,9 +162,15 @@ int main(int argc, char **argv)
                return 1;
        }
 
-       poll_stats(map_fd, kill_after_s);
+       err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (err) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return 1;
+       }
+       prog_id = info.id;
 
-       bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       poll_stats(map_fd, kill_after_s);
+       int_exit(0);
 
        return 0;
 }
index 0224afb55845a2f2d1bbd9f0fecb6d5b104a8e0c..586b294d72d3eb4b56abe89091bf78e99d3db692 100644 (file)
@@ -32,6 +32,7 @@ static const char *__doc__ =
 static int ifindex = -1;
 static char ifname_buf[IF_NAMESIZE];
 static char *ifname;
+static __u32 prog_id;
 
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 static int cpu_map_fd;
@@ -68,11 +69,24 @@ static const struct option long_options[] = {
 
 static void int_exit(int sig)
 {
-       fprintf(stderr,
-               "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
-               ifindex, ifname);
-       if (ifindex > -1)
-               bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (ifindex > -1) {
+               if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
+                       printf("bpf_get_link_xdp_id failed\n");
+                       exit(EXIT_FAIL);
+               }
+               if (prog_id == curr_prog_id) {
+                       fprintf(stderr,
+                               "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
+                               ifindex, ifname);
+                       bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+               } else if (!curr_prog_id) {
+                       printf("couldn't find a prog id on a given iface\n");
+               } else {
+                       printf("program on interface changed, not removing\n");
+               }
+       }
        exit(EXIT_OK);
 }
 
@@ -608,6 +622,8 @@ int main(int argc, char **argv)
        struct bpf_prog_load_attr prog_load_attr = {
                .prog_type      = BPF_PROG_TYPE_UNSPEC,
        };
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        bool use_separators = true;
        bool stress_mode = false;
        struct bpf_program *prog;
@@ -617,9 +633,9 @@ int main(int argc, char **argv)
        int longindex = 0;
        int interval = 2;
        int add_cpu = -1;
+       int opt, err;
        int prog_fd;
        __u32 qsize;
-       int opt;
 
        /* Notice: choosing he queue size is very important with the
         * ixgbe driver, because it's driver page recycling trick is
@@ -746,6 +762,13 @@ int main(int argc, char **argv)
                return EXIT_FAIL_XDP;
        }
 
+       err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (err) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return err;
+       }
+       prog_id = info.id;
+
        stats_poll(interval, use_separators, prog_name, stress_mode);
        return EXIT_OK;
 }
index 470e1a7e8810948bdde416b057a3e3f4b9a56842..327226be5a06990aa3092a417b4c0fa2dfb57048 100644 (file)
 static int ifindex_in;
 static int ifindex_out;
 static bool ifindex_out_xdp_dummy_attached = true;
+static __u32 prog_id;
+static __u32 dummy_prog_id;
 
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 static int rxcnt_map_fd;
 
 static void int_exit(int sig)
 {
-       bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
-       if (ifindex_out_xdp_dummy_attached)
-               bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (bpf_get_link_xdp_id(ifindex_in, &curr_prog_id, xdp_flags)) {
+               printf("bpf_get_link_xdp_id failed\n");
+               exit(1);
+       }
+       if (prog_id == curr_prog_id)
+               bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
+       else if (!curr_prog_id)
+               printf("couldn't find a prog id on iface IN\n");
+       else
+               printf("program on iface IN changed, not removing\n");
+
+       if (ifindex_out_xdp_dummy_attached) {
+               curr_prog_id = 0;
+               if (bpf_get_link_xdp_id(ifindex_out, &curr_prog_id,
+                                       xdp_flags)) {
+                       printf("bpf_get_link_xdp_id failed\n");
+                       exit(1);
+               }
+               if (prog_id == curr_prog_id)
+                       bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+               else if (!curr_prog_id)
+                       printf("couldn't find a prog id on iface OUT\n");
+               else
+                       printf("program on iface OUT changed, not removing\n");
+       }
        exit(0);
 }
 
@@ -82,6 +108,8 @@ int main(int argc, char **argv)
                .prog_type      = BPF_PROG_TYPE_XDP,
        };
        struct bpf_program *prog, *dummy_prog;
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        int prog_fd, dummy_prog_fd;
        const char *optstr = "FSN";
        struct bpf_object *obj;
@@ -153,6 +181,13 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (ret) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return ret;
+       }
+       prog_id = info.id;
+
        /* Loading dummy XDP prog on out-device */
        if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
                            (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
@@ -160,6 +195,14 @@ int main(int argc, char **argv)
                ifindex_out_xdp_dummy_attached = false;
        }
 
+       memset(&info, 0, sizeof(info));
+       ret = bpf_obj_get_info_by_fd(dummy_prog_fd, &info, &info_len);
+       if (ret) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return ret;
+       }
+       dummy_prog_id = info.id;
+
        signal(SIGINT, int_exit);
        signal(SIGTERM, int_exit);
 
index be6058cda97cb632f27cc05aed68174055697cdb..a5d8ad3129edebfa8385491890d8a0c8b592d921 100644 (file)
 static int ifindex_in;
 static int ifindex_out;
 static bool ifindex_out_xdp_dummy_attached = true;
+static __u32 prog_id;
+static __u32 dummy_prog_id;
 
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 static int rxcnt_map_fd;
 
 static void int_exit(int sig)
 {
-       bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
-       if (ifindex_out_xdp_dummy_attached)
-               bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (bpf_get_link_xdp_id(ifindex_in, &curr_prog_id, xdp_flags)) {
+               printf("bpf_get_link_xdp_id failed\n");
+               exit(1);
+       }
+       if (prog_id == curr_prog_id)
+               bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
+       else if (!curr_prog_id)
+               printf("couldn't find a prog id on iface IN\n");
+       else
+               printf("program on iface IN changed, not removing\n");
+
+       if (ifindex_out_xdp_dummy_attached) {
+               curr_prog_id = 0;
+               if (bpf_get_link_xdp_id(ifindex_out, &curr_prog_id,
+                                       xdp_flags)) {
+                       printf("bpf_get_link_xdp_id failed\n");
+                       exit(1);
+               }
+               if (prog_id == curr_prog_id)
+                       bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+               else if (!curr_prog_id)
+                       printf("couldn't find a prog id on iface OUT\n");
+               else
+                       printf("program on iface OUT changed, not removing\n");
+       }
        exit(0);
 }
 
@@ -84,6 +110,8 @@ int main(int argc, char **argv)
        };
        struct bpf_program *prog, *dummy_prog;
        int prog_fd, tx_port_map_fd, opt;
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        const char *optstr = "FSN";
        struct bpf_object *obj;
        char filename[256];
@@ -154,6 +182,13 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (ret) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return ret;
+       }
+       prog_id = info.id;
+
        /* Loading dummy XDP prog on out-device */
        if (bpf_set_link_xdp_fd(ifindex_out, dummy_prog_fd,
                            (xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
@@ -161,6 +196,14 @@ int main(int argc, char **argv)
                ifindex_out_xdp_dummy_attached = false;
        }
 
+       memset(&info, 0, sizeof(info));
+       ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (ret) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return ret;
+       }
+       dummy_prog_id = info.id;
+
        signal(SIGINT, int_exit);
        signal(SIGTERM, int_exit);
 
index 208d6a9964781d8895a56284261e66e0be9c8c57..79fe7bc26ab45eedddd1c3a4a418afdbe6bdd19b 100644 (file)
@@ -30,7 +30,8 @@
 
 int sock, sock_arp, flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 static int total_ifindex;
-int *ifindex_list;
+static int *ifindex_list;
+static __u32 *prog_id_list;
 char buf[8192];
 static int lpm_map_fd;
 static int rxcnt_map_fd;
@@ -41,23 +42,34 @@ static int tx_port_map_fd;
 static int get_route_table(int rtm_family);
 static void int_exit(int sig)
 {
+       __u32 prog_id = 0;
        int i = 0;
 
-       for (i = 0; i < total_ifindex; i++)
-               bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
+       for (i = 0; i < total_ifindex; i++) {
+               if (bpf_get_link_xdp_id(ifindex_list[i], &prog_id, flags)) {
+                       printf("bpf_get_link_xdp_id on iface %d failed\n",
+                              ifindex_list[i]);
+                       exit(1);
+               }
+               if (prog_id_list[i] == prog_id)
+                       bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
+               else if (!prog_id)
+                       printf("couldn't find a prog id on iface %d\n",
+                              ifindex_list[i]);
+               else
+                       printf("program on iface %d changed, not removing\n",
+                              ifindex_list[i]);
+               prog_id = 0;
+       }
        exit(0);
 }
 
 static void close_and_exit(int sig)
 {
-       int i = 0;
-
        close(sock);
        close(sock_arp);
 
-       for (i = 0; i < total_ifindex; i++)
-               bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
-       exit(0);
+       int_exit(0);
 }
 
 /* Get the mac address of the interface given interface name */
@@ -186,13 +198,8 @@ static void read_route(struct nlmsghdr *nh, int nll)
                route.iface_name = alloca(sizeof(char *) * IFNAMSIZ);
                route.iface_name = if_indextoname(route.iface, route.iface_name);
                route.mac = getmac(route.iface_name);
-               if (route.mac == -1) {
-                       int i = 0;
-
-                       for (i = 0; i < total_ifindex; i++)
-                               bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
-                       exit(0);
-               }
+               if (route.mac == -1)
+                       int_exit(0);
                assert(bpf_map_update_elem(tx_port_map_fd,
                                           &route.iface, &route.iface, 0) == 0);
                if (rtm_family == AF_INET) {
@@ -625,12 +632,14 @@ int main(int ac, char **argv)
        struct bpf_prog_load_attr prog_load_attr = {
                .prog_type      = BPF_PROG_TYPE_XDP,
        };
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        const char *optstr = "SF";
        struct bpf_object *obj;
        char filename[256];
        char **ifname_list;
        int prog_fd, opt;
-       int i = 1;
+       int err, i = 1;
 
        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
        prog_load_attr.file = filename;
@@ -687,7 +696,7 @@ int main(int ac, char **argv)
                return 1;
        }
 
-       ifindex_list = (int *)malloc(total_ifindex * sizeof(int *));
+       ifindex_list = (int *)calloc(total_ifindex, sizeof(int *));
        for (i = 0; i < total_ifindex; i++) {
                ifindex_list[i] = if_nametoindex(ifname_list[i]);
                if (!ifindex_list[i]) {
@@ -696,6 +705,7 @@ int main(int ac, char **argv)
                        return 1;
                }
        }
+       prog_id_list = (__u32 *)calloc(total_ifindex, sizeof(__u32 *));
        for (i = 0; i < total_ifindex; i++) {
                if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd, flags) < 0) {
                        printf("link set xdp fd failed\n");
@@ -706,6 +716,13 @@ int main(int ac, char **argv)
 
                        return 1;
                }
+               err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+               if (err) {
+                       printf("can't get prog info - %s\n", strerror(errno));
+                       return err;
+               }
+               prog_id_list[i] = info.id;
+               memset(&info, 0, sizeof(info));
                printf("Attached to %d\n", ifindex_list[i]);
        }
        signal(SIGINT, int_exit);
index e7a98c2a440f8b0f9fc5b52e17a672adb1654e9f..1210f3b170f0b8aa197c61b309615a10e7bb8f29 100644 (file)
@@ -29,6 +29,7 @@ static const char *__doc__ = " XDP RX-queue info extract example\n\n"
 static int ifindex = -1;
 static char ifname_buf[IF_NAMESIZE];
 static char *ifname;
+static __u32 prog_id;
 
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 
@@ -58,11 +59,24 @@ static const struct option long_options[] = {
 
 static void int_exit(int sig)
 {
-       fprintf(stderr,
-               "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
-               ifindex, ifname);
-       if (ifindex > -1)
-               bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (ifindex > -1) {
+               if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
+                       printf("bpf_get_link_xdp_id failed\n");
+                       exit(EXIT_FAIL);
+               }
+               if (prog_id == curr_prog_id) {
+                       fprintf(stderr,
+                               "Interrupted: Removing XDP program on ifindex:%d device:%s\n",
+                               ifindex, ifname);
+                       bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+               } else if (!curr_prog_id) {
+                       printf("couldn't find a prog id on a given iface\n");
+               } else {
+                       printf("program on interface changed, not removing\n");
+               }
+       }
        exit(EXIT_OK);
 }
 
@@ -447,6 +461,8 @@ int main(int argc, char **argv)
        struct bpf_prog_load_attr prog_load_attr = {
                .prog_type      = BPF_PROG_TYPE_XDP,
        };
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        int prog_fd, map_fd, opt, err;
        bool use_separators = true;
        struct config cfg = { 0 };
@@ -580,6 +596,13 @@ int main(int argc, char **argv)
                return EXIT_FAIL_XDP;
        }
 
+       err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (err) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return err;
+       }
+       prog_id = info.id;
+
        stats_poll(interval, action, cfg_options);
        return EXIT_OK;
 }
index 62f34827c7756a072f067faed097dbe791dc3068..dc66345a929a8a142001b2f26e863f1c676bab31 100644 (file)
@@ -24,25 +24,49 @@ static int pmu_fds[MAX_CPUS], if_idx;
 static struct perf_event_mmap_page *headers[MAX_CPUS];
 static char *if_name;
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
+static __u32 prog_id;
 
 static int do_attach(int idx, int fd, const char *name)
 {
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        int err;
 
        err = bpf_set_link_xdp_fd(idx, fd, xdp_flags);
-       if (err < 0)
+       if (err < 0) {
                printf("ERROR: failed to attach program to %s\n", name);
+               return err;
+       }
+
+       err = bpf_obj_get_info_by_fd(fd, &info, &info_len);
+       if (err) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return err;
+       }
+       prog_id = info.id;
 
        return err;
 }
 
 static int do_detach(int idx, const char *name)
 {
-       int err;
+       __u32 curr_prog_id = 0;
+       int err = 0;
 
-       err = bpf_set_link_xdp_fd(idx, -1, 0);
-       if (err < 0)
-               printf("ERROR: failed to detach program from %s\n", name);
+       err = bpf_get_link_xdp_id(idx, &curr_prog_id, 0);
+       if (err) {
+               printf("bpf_get_link_xdp_id failed\n");
+               return err;
+       }
+       if (prog_id == curr_prog_id) {
+               err = bpf_set_link_xdp_fd(idx, -1, 0);
+               if (err < 0)
+                       printf("ERROR: failed to detach prog from %s\n", name);
+       } else if (!curr_prog_id) {
+               printf("couldn't find a prog id on a %s\n", name);
+       } else {
+               printf("program on interface changed, not removing\n");
+       }
 
        return err;
 }
index e3de60930d2771a94c8a29383125d73e27ac09de..4a1511eb78128c3d9777f7704fbe9c094fbe5c80 100644 (file)
 static int ifindex = -1;
 static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
 static int rxcnt_map_fd;
+static __u32 prog_id;
 
 static void int_exit(int sig)
 {
-       if (ifindex > -1)
-               bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+       __u32 curr_prog_id = 0;
+
+       if (ifindex > -1) {
+               if (bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags)) {
+                       printf("bpf_get_link_xdp_id failed\n");
+                       exit(1);
+               }
+               if (prog_id == curr_prog_id)
+                       bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
+               else if (!curr_prog_id)
+                       printf("couldn't find a prog id on a given iface\n");
+               else
+                       printf("program on interface changed, not removing\n");
+       }
        exit(0);
 }
 
@@ -148,13 +161,15 @@ int main(int argc, char **argv)
        int min_port = 0, max_port = 0, vip2tnl_map_fd;
        const char *optstr = "i:a:p:s:d:m:T:P:FSNh";
        unsigned char opt_flags[256] = {};
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        unsigned int kill_after_s = 0;
        struct iptnl_info tnl = {};
        struct bpf_object *obj;
        struct vip vip = {};
        char filename[256];
        int opt, prog_fd;
-       int i;
+       int i, err;
 
        tnl.family = AF_UNSPEC;
        vip.protocol = IPPROTO_TCP;
@@ -276,6 +291,13 @@ int main(int argc, char **argv)
                return 1;
        }
 
+       err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (err) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return err;
+       }
+       prog_id = info.id;
+
        poll_stats(kill_after_s);
 
        bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
index 1887237847680ae85093d4c860891a49d55269ad..f73055e0191fbc728c9b81c9d748edf53309f5d3 100644 (file)
@@ -76,6 +76,7 @@ static int opt_poll;
 static int opt_shared_packet_buffer;
 static int opt_interval = 1;
 static u32 opt_xdp_bind_flags;
+static __u32 prog_id;
 
 struct xdp_umem_uqueue {
        u32 cached_prod;
@@ -631,9 +632,20 @@ static void *poller(void *arg)
 
 static void int_exit(int sig)
 {
+       __u32 curr_prog_id = 0;
+
        (void)sig;
        dump_stats();
-       bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags);
+       if (bpf_get_link_xdp_id(opt_ifindex, &curr_prog_id, opt_xdp_flags)) {
+               printf("bpf_get_link_xdp_id failed\n");
+               exit(EXIT_FAILURE);
+       }
+       if (prog_id == curr_prog_id)
+               bpf_set_link_xdp_fd(opt_ifindex, -1, opt_xdp_flags);
+       else if (!curr_prog_id)
+               printf("couldn't find a prog id on a given interface\n");
+       else
+               printf("program on interface changed, not removing\n");
        exit(EXIT_SUCCESS);
 }
 
@@ -907,6 +919,8 @@ int main(int argc, char **argv)
                .prog_type      = BPF_PROG_TYPE_XDP,
        };
        int prog_fd, qidconf_map, xsks_map;
+       struct bpf_prog_info info = {};
+       __u32 info_len = sizeof(info);
        struct bpf_object *obj;
        char xdp_filename[256];
        struct bpf_map *map;
@@ -953,6 +967,13 @@ int main(int argc, char **argv)
                exit(EXIT_FAILURE);
        }
 
+       ret = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
+       if (ret) {
+               printf("can't get prog info - %s\n", strerror(errno));
+               return 1;
+       }
+       prog_id = info.id;
+
        ret = bpf_map_update_elem(qidconf_map, &key, &opt_queue, 0);
        if (ret) {
                fprintf(stderr, "ERROR: bpf_map_update_elem qidconf\n");