Skip to content

Commit

Permalink
libxdp: Use opts to create XDP socket
Browse files Browse the repository at this point in the history
Introduce a new API xsk_socket__create_opts() to create XDP socket using opts struct.
Note that if one of fill and comp is unset, the semantic of the new API is the same
as xsk_socket__create(), otherwise the same as xsk_socket__create_shared().

Signed-off-by: Muyang Tian <[email protected]>
  • Loading branch information
tacslon committed Dec 10, 2024
1 parent 5ddccf5 commit 449ed15
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 33 deletions.
41 changes: 40 additions & 1 deletion headers/xdp/xsk.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ struct xsk_umem_config {
* If the remaining fields are unset, they will be set to
* default value (see `xsk_set_umem_config()`).
*
* Except for the fields mentioned above, none field can be set.
* Except for the fields mentioned above, no field can be set.
*/
struct xsk_umem_opts {
size_t sz;
Expand Down Expand Up @@ -249,6 +249,40 @@ struct xsk_socket_config {
__u16 bind_flags;
};

/*
* The following fields should not be NULL at the same time:
*
* @rx, @tx
* At least one traffic direction should be assigned for an xsk.
*
* The following fields are optional:
*
* @fill, @comp, @rx_size, @tx_size, @libxdp_flags, @xdp_flags,
* @bind_flags
* If a socket with exclusive ownership of a umem is going to be
* created, keep @fill and @comp unset. If the umem is to be shared
* with other sockets, set @fill and @comp to the corresponding
* fields of the umem.
* If the remaining fields are unset, they will be set to
* default value (see `xsk_set_xdp_socket_config()`).
*
* Except for the fields mentioned above, no field can be set.
*/
struct xsk_socket_opts {
size_t sz;
struct xsk_ring_cons *rx;
struct xsk_ring_prod *tx;
struct xsk_ring_prod *fill;
struct xsk_ring_cons *comp;
__u32 rx_size;
__u32 tx_size;
__u32 libxdp_flags;
__u32 xdp_flags;
__u16 bind_flags;
size_t :0;
};
#define xsk_socket_opts__last_field bind_flags

/* Set config to NULL to get the default configuration. */
int xsk_umem__create(struct xsk_umem **umem,
void *umem_area, __u64 size,
Expand Down Expand Up @@ -280,6 +314,11 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
struct xsk_ring_prod *fill,
struct xsk_ring_cons *comp,
const struct xsk_socket_config *config);
/* Newer version to create xsk by opts, recommended to use. */
struct xsk_socket *xsk_socket__create_opts(const char *ifname,
__u32 queue_id,
struct xsk_umem *umem,
struct xsk_socket_opts *opts);

/* Returns 0 for success and -EBUSY if the umem is still in use. */
int xsk_umem__delete(struct xsk_umem *umem);
Expand Down
1 change: 1 addition & 0 deletions lib/libxdp/libxdp.map
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,5 @@ LIBXDP_1.4.0 {

LIBXDP_1.5.0 {
xsk_umem__create_opts;
xsk_socket__create_opts;
} LIBXDP_1.4.0;
106 changes: 74 additions & 32 deletions lib/libxdp/xsk.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,25 +162,19 @@ static void xsk_set_umem_config(struct xsk_umem_config *cfg,
}

static int xsk_set_xdp_socket_config(struct xsk_socket_config *cfg,
const struct xsk_socket_config *usr_cfg)
const struct xsk_socket_opts *opts)
{
if (!usr_cfg) {
cfg->rx_size = XSK_RING_CONS__DEFAULT_NUM_DESCS;
cfg->tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
cfg->libbpf_flags = 0;
cfg->xdp_flags = 0;
cfg->bind_flags = 0;
return 0;
}
__u32 libxdp_flags;

if (usr_cfg->libbpf_flags & ~XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)
libxdp_flags = OPTS_GET(opts, libxdp_flags, 0);
if (libxdp_flags & ~XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD)
return -EINVAL;

cfg->rx_size = usr_cfg->rx_size;
cfg->tx_size = usr_cfg->tx_size;
cfg->libbpf_flags = usr_cfg->libbpf_flags;
cfg->xdp_flags = usr_cfg->xdp_flags;
cfg->bind_flags = usr_cfg->bind_flags;
cfg->rx_size = OPTS_GET(opts, rx_size, 0) ?: XSK_RING_CONS__DEFAULT_NUM_DESCS;
cfg->tx_size = OPTS_GET(opts, tx_size, 0) ?: XSK_RING_PROD__DEFAULT_NUM_DESCS;
cfg->libxdp_flags = libxdp_flags;
cfg->xdp_flags = OPTS_GET(opts, xdp_flags, 0);
cfg->bind_flags = OPTS_GET(opts, bind_flags, 0);

return 0;
}
Expand Down Expand Up @@ -1052,34 +1046,47 @@ int xsk_setup_xdp_prog(int ifindex, int *xsks_map_fd)
return res;
}

int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
const char *ifname,
__u32 queue_id, struct xsk_umem *umem,
struct xsk_ring_cons *rx,
struct xsk_ring_prod *tx,
struct xsk_ring_prod *fill,
struct xsk_ring_cons *comp,
const struct xsk_socket_config *usr_config)
struct xsk_socket *xsk_socket__create_opts(const char *ifname,
__u32 queue_id,
struct xsk_umem *umem,
struct xsk_socket_opts *opts)
{
bool rx_setup_done = false, tx_setup_done = false;
void *rx_map = NULL, *tx_map = NULL;
struct sockaddr_xdp sxdp = {};
struct xdp_mmap_offsets off;
struct xsk_ring_prod *fill;
struct xsk_ring_cons *comp;
struct xsk_ring_cons *rx;
struct xsk_ring_prod *tx;
struct xsk_socket *xsk;
struct xsk_ctx *ctx;
int err, ifindex;
__u64 netns_cookie;
socklen_t optlen;
bool unmap;

if (!umem || !xsk_ptr || !(rx || tx))
return -EFAULT;
if (!OPTS_VALID(opts, xsk_socket_opts)) {
err = -EINVAL;
goto err;
}
rx = OPTS_GET(opts, rx, NULL);
tx = OPTS_GET(opts, tx, NULL);
fill = OPTS_GET(opts, fill, umem->fill_save);
comp = OPTS_GET(opts, comp, umem->comp_save);

if (!umem || !(rx || tx)) {
err = -EFAULT;
goto err;
}

xsk = calloc(1, sizeof(*xsk));
if (!xsk)
return -ENOMEM;
if (!xsk) {
err = -ENOMEM;
goto err;
}

err = xsk_set_xdp_socket_config(&xsk->config, usr_config);
err = xsk_set_xdp_socket_config(&xsk->config, opts);
if (err)
goto out_xsk_alloc;

Expand Down Expand Up @@ -1218,16 +1225,15 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
goto out_mmap_tx;
}

if (!(xsk->config.libbpf_flags & XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD)) {
if (!(xsk->config.libxdp_flags & XSK_LIBXDP_FLAGS__INHIBIT_PROG_LOAD)) {
err = __xsk_setup_xdp_prog(xsk, NULL);
if (err)
goto out_mmap_tx;
}

*xsk_ptr = xsk;
umem->fill_save = NULL;
umem->comp_save = NULL;
return 0;
return xsk;

out_mmap_tx:
if (tx)
Expand All @@ -1245,7 +1251,43 @@ int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
close(xsk->fd);
out_xsk_alloc:
free(xsk);
return err;
err:
return libxdp_err_ptr(err, true);
}

int xsk_socket__create_shared(struct xsk_socket **xsk_ptr,
const char *ifname,
__u32 queue_id, struct xsk_umem *umem,
struct xsk_ring_cons *rx,
struct xsk_ring_prod *tx,
struct xsk_ring_prod *fill,
struct xsk_ring_cons *comp,
const struct xsk_socket_config *usr_config)
{
struct xsk_socket *xsk;

if (!xsk_ptr)
return -EFAULT;

DECLARE_LIBXDP_OPTS(xsk_socket_opts, opts,
.rx = rx,
.tx = tx,
.fill = fill,
.comp = comp,
);
if (usr_config) {
opts.rx_size = usr_config->rx_size;
opts.tx_size= usr_config->tx_size;
opts.libxdp_flags = usr_config->libxdp_flags;
opts.xdp_flags = usr_config->xdp_flags;
opts.bind_flags = usr_config->bind_flags;
}
xsk = xsk_socket__create_opts(ifname, queue_id, umem, &opts);
if (!xsk)
return errno;

*xsk_ptr = xsk;
return 0;
}

int xsk_socket__create(struct xsk_socket **xsk_ptr, const char *ifname,
Expand Down

0 comments on commit 449ed15

Please sign in to comment.