From f30f99246823f1c4ac4225e5aa0f2b838af2083d Mon Sep 17 00:00:00 2001 From: gamemann Date: Fri, 18 Dec 2020 01:51:35 +0000 Subject: [PATCH] Add support for offload/hardware mode. --- README.md | 1 + src/xdpfw_loader.c | 82 ++++++++++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 71fbf38..ca4a44c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Additionally, if the host's NIC doesn't support XDP-native, the program will att The following command line arguments are supported: * `--config -c` => Location to config file. Default => **/etc/xdpfw/xdpfw.conf**. +* `--offload -o` => Tries to load the XDP program in hardware/offload mode. * `--list -l` => List all filtering rules scanned from config file. * `--help -h` => Print help menu for command line options. diff --git a/src/xdpfw_loader.c b/src/xdpfw_loader.c index 6d001a3..7284116 100644 --- a/src/xdpfw_loader.c +++ b/src/xdpfw_loader.c @@ -23,10 +23,12 @@ static char *configFile; static int help = 0; static int list = 0; +static int offload = 0; const struct option opts[] = { {"config", required_argument, NULL, 'c'}, + {"offload", no_argument, &offload, 'o'}, {"list", no_argument, &list, 'l'}, {"help", no_argument, &help, 'h'}, {NULL, 0, NULL, 0} @@ -55,6 +57,11 @@ void parse_command_line(int argc, char *argv[]) break; + case 'o': + offload = 1; + + break; + case 'l': list = 1; @@ -193,43 +200,54 @@ static int xdp_attach(int ifindex, uint32_t *xdp_flags, int prog_fd) { int err; - err = bpf_set_link_xdp_fd(ifindex, prog_fd, *xdp_flags); - - if (err == -EEXIST && !(*xdp_flags & XDP_FLAGS_UPDATE_IF_NOEXIST)) + if (offload) { + fprintf(stdout, "Trying to load in offload/hardware mode...\n"); - uint32_t oldflags = *xdp_flags; - - *xdp_flags &= ~XDP_FLAGS_MODES; - *xdp_flags |= (oldflags & XDP_FLAGS_SKB_MODE) ? XDP_FLAGS_DRV_MODE : XDP_FLAGS_SKB_MODE; - - err = bpf_set_link_xdp_fd(ifindex, -1, *xdp_flags); - - if (!err) - { - err = bpf_set_link_xdp_fd(ifindex, prog_fd, oldflags); - } - } - - // Check for no XDP-Native support. - if (err) - { - fprintf(stdout, "XDP-Native may not be supported with this NIC. Using SKB instead.\n"); - - // Remove DRV Mode flag. - if (*xdp_flags & XDP_FLAGS_DRV_MODE) - { - *xdp_flags &= ~XDP_FLAGS_DRV_MODE; - } - - // Add SKB Mode flag. - if (!(*xdp_flags & XDP_FLAGS_SKB_MODE)) - { - *xdp_flags |= XDP_FLAGS_SKB_MODE; - } + *xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_HW_MODE; err = bpf_set_link_xdp_fd(ifindex, prog_fd, *xdp_flags); } + else + { + err = bpf_set_link_xdp_fd(ifindex, prog_fd, *xdp_flags); + + if (err == -EEXIST && !(*xdp_flags & XDP_FLAGS_UPDATE_IF_NOEXIST)) + { + + uint32_t oldflags = *xdp_flags; + + *xdp_flags &= ~XDP_FLAGS_MODES; + *xdp_flags |= (oldflags & XDP_FLAGS_SKB_MODE) ? XDP_FLAGS_DRV_MODE : XDP_FLAGS_SKB_MODE; + + err = bpf_set_link_xdp_fd(ifindex, -1, *xdp_flags); + + if (!err) + { + err = bpf_set_link_xdp_fd(ifindex, prog_fd, oldflags); + } + } + + // Check for no XDP-Native support. + if (err) + { + fprintf(stdout, "XDP-Native may not be supported with this NIC. Using SKB instead.\n"); + + // Remove DRV Mode flag. + if (*xdp_flags & XDP_FLAGS_DRV_MODE) + { + *xdp_flags &= ~XDP_FLAGS_DRV_MODE; + } + + // Add SKB Mode flag. + if (!(*xdp_flags & XDP_FLAGS_SKB_MODE)) + { + *xdp_flags |= XDP_FLAGS_SKB_MODE; + } + + err = bpf_set_link_xdp_fd(ifindex, prog_fd, *xdp_flags); + } + } if (err < 0) {