* [PATCH bpf-next] xsk: include XDP meta data in AF_XDP frames
@ 2018-08-30 8:09 Björn Töpel
2018-08-30 12:37 ` Daniel Borkmann
2018-08-30 13:12 ` [PATCH bpf-next v2] " Björn Töpel
0 siblings, 2 replies; 5+ messages in thread
From: Björn Töpel @ 2018-08-30 8:09 UTC (permalink / raw)
To: bjorn.topel, magnus.karlsson, magnus.karlsson, ast, daniel,
netdev
Cc: Björn Töpel, brouer
From: Björn Töpel <bjorn.topel@intel.com>
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: Björn Töpel <bjorn.topel@intel.com>
---
net/xdp/xsk.c | 37 ++++++++++++++++++++++++++++---------
1 file changed, 28 insertions(+), 9 deletions(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 4e937cd7c17d..817e4cee1540 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr);
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;
int err;
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++;
return -ENOSPC;
}
addr += xs->umem->headroom;
- buffer = xdp_umem_get_data(xs->umem, addr);
- memcpy(buffer, xdp->data, len);
+ if (xdp_data_meta_unsupported(xdp)) {
+ 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);
if (!err) {
xskq_discard_addr(xs->umem->fq);
@@ -111,8 +121,8 @@ void xsk_flush(struct xdp_sock *xs)
int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
{
- u32 len = xdp->data_end - xdp->data;
- void *buffer;
+ u32 metalen, len = xdp->data_end - xdp->data;
+ void *to_buf, *from_buf;
u64 addr;
int err;
@@ -120,15 +130,24 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
return -EINVAL;
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++;
return -ENOSPC;
}
addr += xs->umem->headroom;
- buffer = xdp_umem_get_data(xs->umem, addr);
- memcpy(buffer, xdp->data, len);
+ if (xdp_data_meta_unsupported(xdp)) {
+ 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);
if (!err) {
xskq_discard_addr(xs->umem->fq);
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next] xsk: include XDP meta data in AF_XDP frames
2018-08-30 8:09 [PATCH bpf-next] xsk: include XDP meta data in AF_XDP frames Björn Töpel
@ 2018-08-30 12:37 ` Daniel Borkmann
2018-08-30 12:51 ` Björn Töpel
2018-08-30 13:12 ` [PATCH bpf-next v2] " Björn Töpel
1 sibling, 1 reply; 5+ messages in thread
From: Daniel Borkmann @ 2018-08-30 12:37 UTC (permalink / raw)
To: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
netdev
Cc: Björn Töpel, brouer
On 08/30/2018 10:09 AM, Björn Töpel wrote:
> From: Björn Töpel <bjorn.topel@intel.com>
>
> 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: Björn Töpel <bjorn.topel@intel.com>
> ---
> net/xdp/xsk.c | 37 ++++++++++++++++++++++++++++---------
> 1 file changed, 28 insertions(+), 9 deletions(-)
>
> diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> index 4e937cd7c17d..817e4cee1540 100644
> --- a/net/xdp/xsk.c
> +++ b/net/xdp/xsk.c
> @@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr);
>
> 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;
> int err;
>
> 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++;
> return -ENOSPC;
> }
>
> addr += xs->umem->headroom;
>
> - buffer = xdp_umem_get_data(xs->umem, addr);
> - memcpy(buffer, xdp->data, len);
> + if (xdp_data_meta_unsupported(xdp)) {
Nit: Probably makes sense to wrap with unlikely() since we expect all
drivers to implement this.
> + 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);
> if (!err) {
> xskq_discard_addr(xs->umem->fq);
> @@ -111,8 +121,8 @@ void xsk_flush(struct xdp_sock *xs)
>
> int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
> {
> - u32 len = xdp->data_end - xdp->data;
> - void *buffer;
> + u32 metalen, len = xdp->data_end - xdp->data;
> + void *to_buf, *from_buf;
> u64 addr;
> int err;
>
> @@ -120,15 +130,24 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
> return -EINVAL;
>
> 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++;
> return -ENOSPC;
> }
>
> addr += xs->umem->headroom;
>
> - buffer = xdp_umem_get_data(xs->umem, addr);
> - memcpy(buffer, xdp->data, len);
> + if (xdp_data_meta_unsupported(xdp)) {
> + from_buf = xdp->data;
> + metalen = 0;
Note that this condition should be dead code. netif_receive_generic_xdp()
sets xdp->data_meta to xdp->data, so all good here and above is never hit.
> + } 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);
> if (!err) {
> xskq_discard_addr(xs->umem->fq);
>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next] xsk: include XDP meta data in AF_XDP frames
2018-08-30 12:37 ` Daniel Borkmann
@ 2018-08-30 12:51 ` Björn Töpel
0 siblings, 0 replies; 5+ messages in thread
From: Björn Töpel @ 2018-08-30 12:51 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Karlsson, Magnus, Magnus Karlsson, ast, Netdev,
Björn Töpel, Jesper Dangaard Brouer
Den tors 30 aug. 2018 kl 14:37 skrev Daniel Borkmann <daniel@iogearbox.net>:
>
> On 08/30/2018 10:09 AM, Björn Töpel wrote:
> > From: Björn Töpel <bjorn.topel@intel.com>
> >
> > 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: Björn Töpel <bjorn.topel@intel.com>
> > ---
> > net/xdp/xsk.c | 37 ++++++++++++++++++++++++++++---------
> > 1 file changed, 28 insertions(+), 9 deletions(-)
> >
> > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > index 4e937cd7c17d..817e4cee1540 100644
> > --- a/net/xdp/xsk.c
> > +++ b/net/xdp/xsk.c
> > @@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr);
> >
> > 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;
> > int err;
> >
> > 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++;
> > return -ENOSPC;
> > }
> >
> > addr += xs->umem->headroom;
> >
> > - buffer = xdp_umem_get_data(xs->umem, addr);
> > - memcpy(buffer, xdp->data, len);
> > + if (xdp_data_meta_unsupported(xdp)) {
>
> Nit: Probably makes sense to wrap with unlikely() since we expect all
> drivers to implement this.
>
I'll send a v2 fixing this...
> > + 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);
> > if (!err) {
> > xskq_discard_addr(xs->umem->fq);
> > @@ -111,8 +121,8 @@ void xsk_flush(struct xdp_sock *xs)
> >
> > int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
> > {
> > - u32 len = xdp->data_end - xdp->data;
> > - void *buffer;
> > + u32 metalen, len = xdp->data_end - xdp->data;
> > + void *to_buf, *from_buf;
> > u64 addr;
> > int err;
> >
> > @@ -120,15 +130,24 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
> > return -EINVAL;
> >
> > 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++;
> > return -ENOSPC;
> > }
> >
> > addr += xs->umem->headroom;
> >
> > - buffer = xdp_umem_get_data(xs->umem, addr);
> > - memcpy(buffer, xdp->data, len);
> > + if (xdp_data_meta_unsupported(xdp)) {
> > + from_buf = xdp->data;
> > + metalen = 0;
>
> Note that this condition should be dead code. netif_receive_generic_xdp()
> sets xdp->data_meta to xdp->data, so all good here and above is never hit.
>
...and this! Thanks for pointing this out!
Björn
> > + } 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);
> > if (!err) {
> > xskq_discard_addr(xs->umem->fq);
> >
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH bpf-next v2] xsk: include XDP meta data in AF_XDP frames
2018-08-30 8:09 [PATCH bpf-next] xsk: include XDP meta data in AF_XDP frames Björn Töpel
2018-08-30 12:37 ` Daniel Borkmann
@ 2018-08-30 13:12 ` Björn Töpel
2018-08-30 13:27 ` Daniel Borkmann
1 sibling, 1 reply; 5+ messages in thread
From: Björn Töpel @ 2018-08-30 13:12 UTC (permalink / raw)
To: bjorn.topel, magnus.karlsson, magnus.karlsson, ast, daniel,
netdev
Cc: Björn Töpel, brouer
From: Björn Töpel <bjorn.topel@intel.com>
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: Björn Töpel <bjorn.topel@intel.com>
---
net/xdp/xsk.c | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
index 4e937cd7c17d..569048e299df 100644
--- a/net/xdp/xsk.c
+++ b/net/xdp/xsk.c
@@ -55,20 +55,30 @@ EXPORT_SYMBOL(xsk_umem_discard_addr);
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;
int err;
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++;
return -ENOSPC;
}
addr += xs->umem->headroom;
- buffer = xdp_umem_get_data(xs->umem, addr);
- memcpy(buffer, xdp->data, len);
+ if (unlikely(xdp_data_meta_unsupported(xdp))) {
+ 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);
if (!err) {
xskq_discard_addr(xs->umem->fq);
@@ -111,6 +121,7 @@ void xsk_flush(struct xdp_sock *xs)
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;
void *buffer;
u64 addr;
@@ -120,7 +131,7 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
return -EINVAL;
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++;
return -ENOSPC;
}
@@ -128,7 +139,8 @@ int xsk_generic_rcv(struct xdp_sock *xs, struct xdp_buff *xdp)
addr += xs->umem->headroom;
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);
if (!err) {
xskq_discard_addr(xs->umem->fq);
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH bpf-next v2] xsk: include XDP meta data in AF_XDP frames
2018-08-30 13:12 ` [PATCH bpf-next v2] " Björn Töpel
@ 2018-08-30 13:27 ` Daniel Borkmann
0 siblings, 0 replies; 5+ messages in thread
From: Daniel Borkmann @ 2018-08-30 13:27 UTC (permalink / raw)
To: Björn Töpel, magnus.karlsson, magnus.karlsson, ast,
netdev
Cc: Björn Töpel, brouer
On 08/30/2018 03:12 PM, Björn Töpel wrote:
> From: Björn Töpel <bjorn.topel@intel.com>
>
> 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: Björn Töpel <bjorn.topel@intel.com>
Applied to bpf-next, thanks Björn!
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-08-30 17:29 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-30 8:09 [PATCH bpf-next] xsk: include XDP meta data in AF_XDP frames Björn Töpel
2018-08-30 12:37 ` Daniel Borkmann
2018-08-30 12:51 ` Björn Töpel
2018-08-30 13:12 ` [PATCH bpf-next v2] " Björn Töpel
2018-08-30 13:27 ` Daniel Borkmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox