Commit 18baed26 authored by Björn Töpel's avatar Björn Töpel Committed by Daniel Borkmann

xsk: include XDP meta data in AF_XDP frames

Previously, the AF_XDP (XDP_DRV/XDP_SKB copy-mode) ingress logic did
not include XDP meta data in the data buffers copied out to the user
application.

In this commit, we check if meta data is available, and if so, it is
prepended to the frame.
Signed-off-by: default avatarBjörn Töpel <bjorn.topel@intel.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 56b48c6a
...@@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr); ...@@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr);
static int __xsk_rcv(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len) static int __xsk_rcv(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len)
{ {
void *buffer; void *to_buf, *from_buf;
u32 metalen;
u64 addr; u64 addr;
int err; int err;
if (!xskq_peek_addr(xs->umem->fq, &addr) || if (!xskq_peek_addr(xs->umem->fq, &addr) ||
len > xs->umem->chunk_size_nohr) { len > xs->umem->chunk_size_nohr - XDP_PACKET_HEADROOM) {
xs->rx_dropped++; xs->rx_dropped++;
return -ENOSPC; return -ENOSPC;
} }
addr += xs->umem->headroom; addr += xs->umem->headroom;
buffer = xdp_umem_get_data(xs->umem, addr); if (unlikely(xdp_data_meta_unsupported(xdp))) {
memcpy(buffer, xdp->data, len); from_buf = xdp->data;
metalen = 0;
} else {
from_buf = xdp->data_meta;
metalen = xdp->data - xdp->data_meta;
}
to_buf = xdp_umem_get_data(xs->umem, addr);
memcpy(to_buf, from_buf, len + metalen);
addr += metalen;
err = xskq_produce_batch_desc(xs->rx, addr, len); err = xskq_produce_batch_desc(xs->rx, addr, len);
if (!err) { if (!err) {
xskq_discard_addr(xs->umem->fq); xskq_discard_addr(xs->umem->fq);
...@@ -111,6 +121,7 @@ void xsk_flush(struct xdp_sock *xs) ...@@ -111,6 +121,7 @@ void xsk_flush(struct xdp_sock *xs)
int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
{ {
u32 metalen = xdp->data - xdp->data_meta;
u32 len = xdp->data_end - xdp->data; u32 len = xdp->data_end - xdp->data;
void *buffer; void *buffer;
u64 addr; u64 addr;
...@@ -120,7 +131,7 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) ...@@ -120,7 +131,7 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
return -EINVAL; return -EINVAL;
if (!xskq_peek_addr(xs->umem->fq, &addr) || if (!xskq_peek_addr(xs->umem->fq, &addr) ||
len > xs->umem->chunk_size_nohr) { len > xs->umem->chunk_size_nohr - XDP_PACKET_HEADROOM) {
xs->rx_dropped++; xs->rx_dropped++;
return -ENOSPC; return -ENOSPC;
} }
...@@ -128,7 +139,8 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp) ...@@ -128,7 +139,8 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
addr += xs->umem->headroom; addr += xs->umem->headroom;
buffer = xdp_umem_get_data(xs->umem, addr); buffer = xdp_umem_get_data(xs->umem, addr);
memcpy(buffer, xdp->data, len); memcpy(buffer, xdp->data_meta, len + metalen);
addr += metalen;
err = xskq_produce_batch_desc(xs->rx, addr, len); err = xskq_produce_batch_desc(xs->rx, addr, len);
if (!err) { if (!err) {
xskq_discard_addr(xs->umem->fq); xskq_discard_addr(xs->umem->fq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment