summaryrefslogtreecommitdiffstats
path: root/src/plugins/af_xdp/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/af_xdp/device.c')
-rw-r--r--src/plugins/af_xdp/device.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/src/plugins/af_xdp/device.c b/src/plugins/af_xdp/device.c
index a269e3c9723..06b86893646 100644
--- a/src/plugins/af_xdp/device.c
+++ b/src/plugins/af_xdp/device.c
@@ -145,6 +145,39 @@ af_xdp_exit_netns (char *netns, int *fds)
return ret;
}
+static int
+af_xdp_remove_program (af_xdp_device_t *ad)
+{
+ u32 curr_prog_id = 0;
+ int ret;
+ int ns_fds[2];
+
+ af_xdp_enter_netns (ad->netns, ns_fds);
+ ret = bpf_xdp_query_id (ad->linux_ifindex, XDP_FLAGS_UPDATE_IF_NOEXIST,
+ &curr_prog_id);
+ if (ret != 0)
+ {
+ af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "bpf_xdp_query_id failed\n");
+ goto err0;
+ }
+
+ ret = bpf_xdp_detach (ad->linux_ifindex, XDP_FLAGS_UPDATE_IF_NOEXIST, NULL);
+ if (ret != 0)
+ {
+ af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "bpf_xdp_detach failed\n");
+ goto err0;
+ }
+ af_xdp_exit_netns (ad->netns, ns_fds);
+ if (ad->bpf_obj)
+ bpf_object__close (ad->bpf_obj);
+
+ return 0;
+
+err0:
+ af_xdp_exit_netns (ad->netns, ns_fds);
+ return ret;
+}
+
void
af_xdp_delete_if (vlib_main_t * vm, af_xdp_device_t * ad)
{
@@ -172,15 +205,8 @@ af_xdp_delete_if (vlib_main_t * vm, af_xdp_device_t * ad)
for (i = 0; i < ad->rxq_num; i++)
clib_file_del_by_index (&file_main, vec_elt (ad->rxqs, i).file_index);
- if (ad->bpf_obj)
- {
- int ns_fds[2];
- af_xdp_enter_netns (ad->netns, ns_fds);
- bpf_xdp_detach (ad->linux_ifindex, XDP_FLAGS_UPDATE_IF_NOEXIST, NULL);
- af_xdp_exit_netns (ad->netns, ns_fds);
-
- bpf_object__close (ad->bpf_obj);
- }
+ if (af_xdp_remove_program (ad) != 0)
+ af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, "Error while removing XDP program.\n");
vec_free (ad->xsk);
vec_free (ad->umem);
@@ -206,16 +232,6 @@ af_xdp_load_program (af_xdp_create_if_args_t * args, af_xdp_device_t * ad)
"setrlimit(%s) failed: %s (errno %d)", ad->linux_ifname,
strerror (errno), errno);
- ad->linux_ifindex = if_nametoindex (ad->linux_ifname);
- if (!ad->linux_ifindex)
- {
- args->rv = VNET_API_ERROR_INVALID_VALUE;
- args->error =
- clib_error_return_unix (0, "if_nametoindex(%s) failed",
- ad->linux_ifname);
- goto err0;
- }
-
ad->bpf_obj = bpf_object__open_file (args->prog, NULL);
if (libbpf_get_error (ad->bpf_obj))
{
@@ -251,7 +267,6 @@ err1:
bpf_object__close (ad->bpf_obj);
ad->bpf_obj = 0;
err0:
- ad->linux_ifindex = ~0;
return -1;
}
@@ -624,6 +639,16 @@ af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args)
ad->netns = (char *) format (0, "%s", args->netns);
+ ad->linux_ifindex = if_nametoindex (ad->linux_ifname);
+ if (!ad->linux_ifindex)
+ {
+ args->rv = VNET_API_ERROR_INVALID_VALUE;
+ args->error = clib_error_return_unix (0, "if_nametoindex(%s) failed",
+ ad->linux_ifname);
+ ad->linux_ifindex = ~0;
+ goto err1;
+ }
+
if (args->prog && af_xdp_load_program (args, ad))
goto err2;