From 4f4df9f634373ef2b69d0c745efed4dfbe68fc07 Mon Sep 17 00:00:00 2001 From: Ric Li Date: Fri, 3 Nov 2023 16:17:39 +0800 Subject: [PATCH] tools/ebpf: load XDP for multiple interfaces Signed-off-by: Ric Li --- lib/src/dev/mt_af_xdp.c | 8 +++--- lib/src/mt_main.c | 5 ++++ lib/src/mt_main.h | 5 ++++ tools/ebpf/et.c | 56 ++++++++++++++++++++++++++++------------- tools/ebpf/et.h | 3 ++- 5 files changed, 56 insertions(+), 21 deletions(-) diff --git a/lib/src/dev/mt_af_xdp.c b/lib/src/dev/mt_af_xdp.c index 266ead09b..5461bd3cc 100644 --- a/lib/src/dev/mt_af_xdp.c +++ b/lib/src/dev/mt_af_xdp.c @@ -330,7 +330,7 @@ static int xdp_rx_prod_init(struct mt_xdp_queue* xq) { return 0; } -static int xdp_socket_update_xskmap(struct mt_xdp_queue* xq) { +static int xdp_socket_update_xskmap(struct mt_xdp_queue* xq, const char* ifname) { enum mtl_port port = xq->port; uint16_t q = xq->q; struct sockaddr_un server; @@ -352,6 +352,8 @@ static int xdp_socket_update_xskmap(struct mt_xdp_queue* xq) { return errno; } + send(sock, ifname, IFNAMSIZ, 0); + char cms[CMSG_SPACE(sizeof(int))]; struct cmsghdr* cmsg; struct msghdr msg; @@ -402,7 +404,7 @@ static int xdp_socket_init(struct mt_xdp_priv* xdp, struct mt_xdp_queue* xq) { cfg.rx_size = mt_if_nb_rx_desc(impl, port); cfg.tx_size = mt_if_nb_tx_desc(impl, port); cfg.xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; - if (true /* no root */) /* this will skip load xdp prog */ + if (!mt_is_privileged(impl)) /* this will skip load xdp prog */ cfg.libxdp_flags = XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD; // cfg.bind_flags = XDP_USE_NEED_WAKEUP; @@ -418,7 +420,7 @@ static int xdp_socket_init(struct mt_xdp_priv* xdp, struct mt_xdp_queue* xq) { } xq->socket_fd = xsk_socket__fd(xq->socket); - if (true /* no root */) return xdp_socket_update_xskmap(xq); + if (!mt_is_privileged(impl)) return xdp_socket_update_xskmap(xq, if_name); return 0; } diff --git a/lib/src/mt_main.c b/lib/src/mt_main.c index ac4ae65e8..1d62999c2 100644 --- a/lib/src/mt_main.c +++ b/lib/src/mt_main.c @@ -452,6 +452,11 @@ mtl_handle mtl_init(struct mtl_init_params* p) { impl = mt_rte_zmalloc_socket(sizeof(*impl), socket[MTL_PORT_P]); if (!impl) goto err_exit; + if (geteuid() == 0) + impl->privileged = true; + else + impl->privileged = false; + rte_memcpy(&impl->user_para, p, sizeof(*p)); impl->var_para.sch_default_sleep_us = 1 * US_PER_MS; /* default 1ms */ /* use sleep zero if sleep us is smaller than this thresh */ diff --git a/lib/src/mt_main.h b/lib/src/mt_main.h index c9d2d719d..5dd3bc78f 100644 --- a/lib/src/mt_main.h +++ b/lib/src/mt_main.h @@ -1120,12 +1120,17 @@ struct mtl_main_impl { int mempool_idx; int arp_timeout_ms; + bool privileged; /* if app running with root privilege */ }; static inline struct mtl_init_params* mt_get_user_params(struct mtl_main_impl* impl) { return &impl->user_para; } +static inline bool mt_is_privileged(struct mtl_main_impl* impl) { + return impl->privileged; +} + static inline struct mt_interface* mt_if(struct mtl_main_impl* impl, enum mtl_port port) { return &impl->inf[port]; } diff --git a/tools/ebpf/et.c b/tools/ebpf/et.c index bfda42312..cfd6c7706 100644 --- a/tools/ebpf/et.c +++ b/tools/ebpf/et.c @@ -124,14 +124,21 @@ static int send_fd(int sock, int fd) { static int et_xdp_loop(struct et_ctx* ctx) { struct sockaddr_un addr; int ret = 0; - int xsks_map_fd = -1; + int xsks_map_fd[ctx->xdp_if_cnt]; int sock = -1, conn; - /* here we load the default xdp program built by libxdp */ - if (xsk_setup_xdp_prog(ctx->xdp_ifindex, &xsks_map_fd) || xsks_map_fd < 0) { - perror("xsk_setup_xdp_prog failed"); - ret = -1; - goto cleanup; + if (ctx->xdp_if_cnt <= 0) { + printf("please specify interfaces with --ifname \n"); + return -EIO; + } + + /* load xdp program for each interface */ + for (int i = 0; i < ctx->xdp_if_cnt; i++) { + ret = xsk_setup_xdp_prog(ctx->xdp_ifindex[i], &xsks_map_fd[i]); + if (ret || xsks_map_fd[i] < 0) { + printf("xsk_socket__bind failed\n"); + goto cleanup; + } } sock = socket(AF_UNIX, SOCK_STREAM, 0); @@ -161,9 +168,20 @@ static int et_xdp_loop(struct et_ctx* ctx) { sleep(1); continue; } - send_fd(conn, xsks_map_fd); + char ifname[IFNAMSIZ]; + int map_fd; + recv(conn, ifname, sizeof(ifname), 0); + printf("request xsk_map_fd for ifname %s\n", ifname); + int ifindex = if_nametoindex(ifname); + for (int i = 0; i < ctx->xdp_if_cnt; i++) { + if (ctx->xdp_ifindex[i] == ifindex) { + map_fd = xsks_map_fd[i]; + break; + } + } + send_fd(conn, map_fd); close(conn); - printf("map_fd %d sent, close conn\n", xsks_map_fd); + printf("map_fd %d sent, close conn\n", map_fd); } cleanup: @@ -181,10 +199,12 @@ static void et_print_help() { printf("\n"); printf("##### Usage: #####\n\n"); printf(" Params:\n"); - printf(" --help : print this help\n"); - printf(" --print : print libbpf output\n"); - printf(" --prog : attach to prog \n"); - printf(" --ifname : interface name\n"); + printf(" --help : print this help\n"); + printf(" --print : print libbpf output\n"); + printf(" --prog : attach to prog \n"); + printf( + " --ifname : interface names which XDP program will be attached " + "to\n"); printf("\n"); } @@ -207,12 +227,14 @@ static int et_parse_args(struct et_ctx* ctx, int argc, char** argv) { libbpf_set_print(libbpf_print_fn); break; case ET_ARG_IFNAME: - int ifindex = if_nametoindex(optarg); - if (!ifindex) { - fprintf(stderr, "invalid interface name: %s\n", optarg); - return -1; + char* ifname; + ctx->xdp_if_cnt = 0; + ifname = strtok(optarg, ","); + while (ifname) { + ctx->xdp_ifindex[ctx->xdp_if_cnt++] = if_nametoindex(ifname); + ifname = strtok(NULL, ","); } - ctx->xdp_ifindex = ifindex; + break; case ET_ARG_HELP: default: et_print_help(); diff --git a/tools/ebpf/et.h b/tools/ebpf/et.h index 781287678..289c8ef8c 100644 --- a/tools/ebpf/et.h +++ b/tools/ebpf/et.h @@ -41,7 +41,8 @@ static const char* prog_type_str[] = { struct et_ctx { enum et_prog_type prog_type; - int xdp_ifindex; + int xdp_ifindex[8]; + int xdp_if_cnt; }; #endif /* __ET_H */ \ No newline at end of file