From 87c94fbb103d5d3aa7c72c3f6425aa5b7b6cbed6 Mon Sep 17 00:00:00 2001 From: Ric Li Date: Mon, 30 Oct 2023 18:35:25 +0800 Subject: [PATCH] af_xdp: add run as inhibit mode Signed-off-by: Ric Li --- lib/src/dev/mt_af_xdp.c | 71 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/lib/src/dev/mt_af_xdp.c b/lib/src/dev/mt_af_xdp.c index 4c6ea659d..1d7ae068b 100644 --- a/lib/src/dev/mt_af_xdp.c +++ b/lib/src/dev/mt_af_xdp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "../mt_flow.h" @@ -316,6 +317,67 @@ static int xdp_rx_prod_init(struct mt_xdp_queue* xq) { return 0; } +static int xdp_socket_update_xskmap(struct mt_xdp_queue* xq) { + enum mtl_port port = xq->port; + uint16_t q = xq->q; + struct sockaddr_un server; + int ret; + int xsks_map_fd = -1; + + int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + err("%s(%d,%u), unix socket create fail, %s\n", __func__, port, q, strerror(errno)); + return errno; + } + + server.sun_family = AF_UNIX; + snprintf(server.sun_path, sizeof(server.sun_path), "/var/run/et_xdp.sock"); + + if (connect(sock, (struct sockaddr*)&server, sizeof(struct sockaddr_un)) < 0) { + close(sock); + err("%s(%d,%u), connect socket fail, %s\n", __func__, port, q, strerror(errno)); + return errno; + } + + char cms[CMSG_SPACE(sizeof(int))]; + struct cmsghdr* cmsg; + struct msghdr msg; + struct iovec iov; + int value; + int len; + + iov.iov_base = &value; + iov.iov_len = sizeof(int); + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = (caddr_t)cms; + msg.msg_controllen = sizeof(cms); + + len = recvmsg(sock, &msg, 0); + + if (len <= 0) { + err("%s(%d,%u), recvmsg wrong length %d\n", __func__, port, q, len); + return -EINVAL; + } + + cmsg = CMSG_FIRSTHDR(&msg); + xsks_map_fd = *(int*)CMSG_DATA(cmsg); + if (xsks_map_fd < 0) { + err("%s(%d,%u), get xsks_map_fd fail, %s\n", __func__, port, q, strerror(errno)); + return errno; + } + + ret = xsk_socket__update_xskmap(xq->socket, xsks_map_fd); + if (ret) { + err("%s(%d,%u), get xsks_map_fd fail, %d\n", __func__, port, q, ret); + return ret; + } + + return 0; +} + static int xdp_socket_init(struct mt_xdp_priv* xdp, struct mt_xdp_queue* xq) { enum mtl_port port = xq->port; uint16_t q = xq->q; @@ -327,17 +389,24 @@ 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 */ + cfg.libxdp_flags = XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD; // cfg.bind_flags = XDP_USE_NEED_WAKEUP; const char* if_name = mt_kernel_if_name(impl, port); ret = xsk_socket__create(&xq->socket, if_name, q, xq->umem, &xq->rx_cons, &xq->tx_prod, &cfg); if (ret < 0) { + if (ret == -EPERM) { + err("%s(%d,%u), please run as inhibit mode or root user\n", __func__, port, q); + } err("%s(%d,%u), xsk create fail %d\n", __func__, port, q, ret); return ret; } - xq->socket_fd = xsk_socket__fd(xq->socket); + + if (true /* no root */) return xdp_socket_update_xskmap(xq); + return 0; }