Skip to content

Commit

Permalink
tools/ebpf: load XDP for multiple interfaces
Browse files Browse the repository at this point in the history
Signed-off-by: Ric Li <[email protected]>
  • Loading branch information
ricmli committed Nov 3, 2023
1 parent 783d90b commit 4f4df9f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 21 deletions.
8 changes: 5 additions & 3 deletions lib/src/dev/mt_af_xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions lib/src/mt_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
5 changes: 5 additions & 0 deletions lib/src/mt_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down
56 changes: 39 additions & 17 deletions tools/ebpf/et.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <a,b,...>\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);
Expand Down Expand Up @@ -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:
Expand All @@ -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 <type> : attach to prog <type>\n");
printf(" --ifname <name> : interface name\n");
printf(" --help : print this help\n");
printf(" --print : print libbpf output\n");
printf(" --prog <type> : attach to prog <type>\n");
printf(
" --ifname <name1,name2> : interface names which XDP program will be attached "
"to\n");
printf("\n");
}

Expand All @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion tools/ebpf/et.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

0 comments on commit 4f4df9f

Please sign in to comment.