diff options
author | Christian Poessinger <christian@poessinger.com> | 2021-03-14 20:12:34 +0100 |
---|---|---|
committer | Christian Poessinger <christian@poessinger.com> | 2021-03-14 20:12:34 +0100 |
commit | 85ff856a32ccb5bc20604bacfb4fa5cb66375487 (patch) | |
tree | 9fa6fa4ef84c39dae14accc018187fce57fd91e2 /src/xdp/common/common_user_bpf_xdp.c | |
parent | 59ad580cdea2e66e24470ee3d84f29a8619b7bf9 (diff) | |
download | vyos-1x-85ff856a32ccb5bc20604bacfb4fa5cb66375487.tar.gz vyos-1x-85ff856a32ccb5bc20604bacfb4fa5cb66375487.zip |
xdp: T2666: remove entire XDP code for 1.3 LTS image
This is an extension to commit 801c5235 ("xdp: T2666: disable this highly
experimental feature in 1.3 LTS") by dropping all XDP references in the
equuleus codebase.
Diffstat (limited to 'src/xdp/common/common_user_bpf_xdp.c')
-rw-r--r-- | src/xdp/common/common_user_bpf_xdp.c | 380 |
1 files changed, 0 insertions, 380 deletions
diff --git a/src/xdp/common/common_user_bpf_xdp.c b/src/xdp/common/common_user_bpf_xdp.c deleted file mode 100644 index e7ef77174..000000000 --- a/src/xdp/common/common_user_bpf_xdp.c +++ /dev/null @@ -1,380 +0,0 @@ -#include <bpf/libbpf.h> /* bpf_get_link_xdp_id + bpf_set_link_xdp_id */ -#include <string.h> /* strerror */ -#include <net/if.h> /* IF_NAMESIZE */ -#include <stdlib.h> /* exit(3) */ -#include <errno.h> - -#include <bpf/bpf.h> -#include <bpf/libbpf.h> - -#include <linux/if_link.h> /* Need XDP flags */ -#include <linux/err.h> - -#include "common_defines.h" - -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - -int xdp_link_attach(int ifindex, __u32 xdp_flags, int prog_fd) -{ - int err; - - /* libbpf provide the XDP net_device link-level hook attach helper */ - err = bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags); - if (err == -EEXIST && !(xdp_flags & XDP_FLAGS_UPDATE_IF_NOEXIST)) { - /* Force mode didn't work, probably because a program of the - * opposite type is loaded. Let's unload that and try loading - * again. - */ - - __u32 old_flags = xdp_flags; - - xdp_flags &= ~XDP_FLAGS_MODES; - xdp_flags |= (old_flags & 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, old_flags); - } - if (err < 0) { - fprintf(stderr, "ERR: " - "ifindex(%d) link set xdp fd failed (%d): %s\n", - ifindex, -err, strerror(-err)); - - switch (-err) { - case EBUSY: - case EEXIST: - fprintf(stderr, "Hint: XDP already loaded on device" - " use --force to swap/replace\n"); - break; - case EOPNOTSUPP: - fprintf(stderr, "Hint: Native-XDP not supported" - " use --skb-mode or --auto-mode\n"); - break; - default: - break; - } - return EXIT_FAIL_XDP; - } - - return EXIT_OK; -} - -int xdp_link_detach(int ifindex, __u32 xdp_flags, __u32 expected_prog_id) -{ - __u32 curr_prog_id; - int err; - - err = bpf_get_link_xdp_id(ifindex, &curr_prog_id, xdp_flags); - if (err) { - fprintf(stderr, "ERR: get link xdp id failed (err=%d): %s\n", - -err, strerror(-err)); - return EXIT_FAIL_XDP; - } - - if (!curr_prog_id) { - if (verbose) - printf("INFO: %s() no curr XDP prog on ifindex:%d\n", - __func__, ifindex); - return EXIT_OK; - } - - if (expected_prog_id && curr_prog_id != expected_prog_id) { - fprintf(stderr, "ERR: %s() " - "expected prog ID(%d) no match(%d), not removing\n", - __func__, expected_prog_id, curr_prog_id); - return EXIT_FAIL; - } - - if ((err = bpf_set_link_xdp_fd(ifindex, -1, xdp_flags)) < 0) { - fprintf(stderr, "ERR: %s() link set xdp failed (err=%d): %s\n", - __func__, err, strerror(-err)); - return EXIT_FAIL_XDP; - } - - if (verbose) - printf("INFO: %s() removed XDP prog ID:%d on ifindex:%d\n", - __func__, curr_prog_id, ifindex); - - return EXIT_OK; -} - -struct bpf_object *load_bpf_object_file(const char *filename, int ifindex) -{ - int first_prog_fd = -1; - struct bpf_object *obj; - int err; - - /* This struct allow us to set ifindex, this features is used for - * hardware offloading XDP programs (note this sets libbpf - * bpf_program->prog_ifindex and foreach bpf_map->map_ifindex). - */ - struct bpf_prog_load_attr prog_load_attr = { - .prog_type = BPF_PROG_TYPE_XDP, - .ifindex = ifindex, - }; - prog_load_attr.file = filename; - - /* Use libbpf for extracting BPF byte-code from BPF-ELF object, and - * loading this into the kernel via bpf-syscall - */ - err = bpf_prog_load_xattr(&prog_load_attr, &obj, &first_prog_fd); - if (err) { - fprintf(stderr, "ERR: loading BPF-OBJ file(%s) (%d): %s\n", - filename, err, strerror(-err)); - return NULL; - } - - /* Notice how a pointer to a libbpf bpf_object is returned */ - return obj; -} - -static struct bpf_object *open_bpf_object(const char *file, int ifindex) -{ - int err; - struct bpf_object *obj; - struct bpf_map *map; - struct bpf_program *prog, *first_prog = NULL; - - struct bpf_object_open_attr open_attr = { - .file = file, - .prog_type = BPF_PROG_TYPE_XDP, - }; - - obj = bpf_object__open_xattr(&open_attr); - if (IS_ERR_OR_NULL(obj)) { - err = -PTR_ERR(obj); - fprintf(stderr, "ERR: opening BPF-OBJ file(%s) (%d): %s\n", - file, err, strerror(-err)); - return NULL; - } - - bpf_object__for_each_program(prog, obj) { - bpf_program__set_type(prog, BPF_PROG_TYPE_XDP); - bpf_program__set_ifindex(prog, ifindex); - if (!first_prog) - first_prog = prog; - } - - bpf_object__for_each_map(map, obj) { - if (!bpf_map__is_offload_neutral(map)) - bpf_map__set_ifindex(map, ifindex); - } - - if (!first_prog) { - fprintf(stderr, "ERR: file %s contains no programs\n", file); - return NULL; - } - - return obj; -} - -static int reuse_maps(struct bpf_object *obj, const char *path) -{ - struct bpf_map *map; - - if (!obj) - return -ENOENT; - - if (!path) - return -EINVAL; - - bpf_object__for_each_map(map, obj) { - int len, err; - int pinned_map_fd; - char buf[PATH_MAX]; - - len = snprintf(buf, PATH_MAX, "%s/%s", path, bpf_map__name(map)); - if (len < 0) { - return -EINVAL; - } else if (len >= PATH_MAX) { - return -ENAMETOOLONG; - } - - pinned_map_fd = bpf_obj_get(buf); - if (pinned_map_fd < 0) - return pinned_map_fd; - - err = bpf_map__reuse_fd(map, pinned_map_fd); - if (err) - return err; - } - - return 0; -} - -struct bpf_object *load_bpf_object_file_reuse_maps(const char *file, - int ifindex, - const char *pin_dir) -{ - int err; - struct bpf_object *obj; - - obj = open_bpf_object(file, ifindex); - if (!obj) { - fprintf(stderr, "ERR: failed to open object %s\n", file); - return NULL; - } - - err = reuse_maps(obj, pin_dir); - if (err) { - fprintf(stderr, "ERR: failed to reuse maps for object %s, pin_dir=%s\n", - file, pin_dir); - return NULL; - } - - err = bpf_object__load(obj); - if (err) { - fprintf(stderr, "ERR: loading BPF-OBJ file(%s) (%d): %s\n", - file, err, strerror(-err)); - return NULL; - } - - return obj; -} - -struct bpf_object *load_bpf_and_xdp_attach(struct config *cfg) -{ - struct bpf_program *bpf_prog; - struct bpf_object *bpf_obj; - int offload_ifindex = 0; - int prog_fd = -1; - int err; - - /* If flags indicate hardware offload, supply ifindex */ - if (cfg->xdp_flags & XDP_FLAGS_HW_MODE) - offload_ifindex = cfg->ifindex; - - /* Load the BPF-ELF object file and get back libbpf bpf_object */ - if (cfg->reuse_maps) - bpf_obj = load_bpf_object_file_reuse_maps(cfg->filename, - offload_ifindex, - cfg->pin_dir); - else - bpf_obj = load_bpf_object_file(cfg->filename, offload_ifindex); - if (!bpf_obj) { - fprintf(stderr, "ERR: loading file: %s\n", cfg->filename); - exit(EXIT_FAIL_BPF); - } - /* At this point: All XDP/BPF programs from the cfg->filename have been - * loaded into the kernel, and evaluated by the verifier. Only one of - * these gets attached to XDP hook, the others will get freed once this - * process exit. - */ - - if (cfg->progsec[0]) - /* Find a matching BPF prog section name */ - bpf_prog = bpf_object__find_program_by_title(bpf_obj, cfg->progsec); - else - /* Find the first program */ - bpf_prog = bpf_program__next(NULL, bpf_obj); - - if (!bpf_prog) { - fprintf(stderr, "ERR: couldn't find a program in ELF section '%s'\n", cfg->progsec); - exit(EXIT_FAIL_BPF); - } - - strncpy(cfg->progsec, bpf_program__title(bpf_prog, false), sizeof(cfg->progsec)); - - prog_fd = bpf_program__fd(bpf_prog); - if (prog_fd <= 0) { - fprintf(stderr, "ERR: bpf_program__fd failed\n"); - exit(EXIT_FAIL_BPF); - } - - /* At this point: BPF-progs are (only) loaded by the kernel, and prog_fd - * is our select file-descriptor handle. Next step is attaching this FD - * to a kernel hook point, in this case XDP net_device link-level hook. - */ - err = xdp_link_attach(cfg->ifindex, cfg->xdp_flags, prog_fd); - if (err) - exit(err); - - return bpf_obj; -} - -#define XDP_UNKNOWN XDP_REDIRECT + 1 -#ifndef XDP_ACTION_MAX -#define XDP_ACTION_MAX (XDP_UNKNOWN + 1) -#endif - -static const char *xdp_action_names[XDP_ACTION_MAX] = { - [XDP_ABORTED] = "XDP_ABORTED", - [XDP_DROP] = "XDP_DROP", - [XDP_PASS] = "XDP_PASS", - [XDP_TX] = "XDP_TX", - [XDP_REDIRECT] = "XDP_REDIRECT", - [XDP_UNKNOWN] = "XDP_UNKNOWN", -}; - -const char *action2str(__u32 action) -{ - if (action < XDP_ACTION_MAX) - return xdp_action_names[action]; - return NULL; -} - -int check_map_fd_info(const struct bpf_map_info *info, - const struct bpf_map_info *exp) -{ - if (exp->key_size && exp->key_size != info->key_size) { - fprintf(stderr, "ERR: %s() " - "Map key size(%d) mismatch expected size(%d)\n", - __func__, info->key_size, exp->key_size); - return EXIT_FAIL; - } - if (exp->value_size && exp->value_size != info->value_size) { - fprintf(stderr, "ERR: %s() " - "Map value size(%d) mismatch expected size(%d)\n", - __func__, info->value_size, exp->value_size); - return EXIT_FAIL; - } - if (exp->max_entries && exp->max_entries != info->max_entries) { - fprintf(stderr, "ERR: %s() " - "Map max_entries(%d) mismatch expected size(%d)\n", - __func__, info->max_entries, exp->max_entries); - return EXIT_FAIL; - } - if (exp->type && exp->type != info->type) { - fprintf(stderr, "ERR: %s() " - "Map type(%d) mismatch expected type(%d)\n", - __func__, info->type, exp->type); - return EXIT_FAIL; - } - - return 0; -} - -int open_bpf_map_file(const char *pin_dir, - const char *mapname, - struct bpf_map_info *info) -{ - char filename[PATH_MAX]; - int err, len, fd; - __u32 info_len = sizeof(*info); - - len = snprintf(filename, PATH_MAX, "%s/%s", pin_dir, mapname); - if (len < 0) { - fprintf(stderr, "ERR: constructing full mapname path\n"); - return -1; - } - - fd = bpf_obj_get(filename); - if (fd < 0) { - fprintf(stderr, - "WARN: Failed to open bpf map file:%s err(%d):%s\n", - filename, errno, strerror(errno)); - return fd; - } - - if (info) { - err = bpf_obj_get_info_by_fd(fd, info, &info_len); - if (err) { - fprintf(stderr, "ERR: %s() can't get info - %s\n", - __func__, strerror(errno)); - return EXIT_FAIL_BPF; - } - } - - return fd; -} |