From: Jesper Dangaard Brouer <brouer@redhat.com>
To: Toshiaki Makita <toshiaki.makita1@gmail.com>
Cc: brouer@redhat.com, Mao Wenan <maowenan@huawei.com>,
davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net,
kuba@kernel.org, hawk@kernel.org, john.fastabend@gmail.com,
kafai@fb.com, songliubraving@fb.com, yhs@fb.com, andriin@fb.com,
jwi@linux.ibm.com, jianglidong3@jd.com, edumazet@google.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
bpf@vger.kernel.org, kernel-janitors@vger.kernel.org
Subject: Re: [PATCH net v2] veth: xdp: use head instead of hard_start
Date: Wed, 1 Apr 2020 18:15:17 +0200 [thread overview]
Message-ID: <20200401181419.7acd2aa6@carbon> (raw)
In-Reply-To: <7a1d55ad-1427-67fe-f204-4d4a0ab2c4b1@gmail.com>
On Tue, 31 Mar 2020 15:16:22 +0900
Toshiaki Makita <toshiaki.makita1@gmail.com> wrote:
> On 2020/03/31 15:06, Mao Wenan wrote:
> > xdp.data_hard_start is equal to first address of
> > struct xdp_frame, which is mentioned in
> > convert_to_xdp_frame(). But the pointer hard_start
> > in veth_xdp_rcv_one() is 32 bytes offset of frame,
> > so it should use head instead of hard_start to
> > set xdp.data_hard_start. Otherwise, if BPF program
> > calls helper_function such as bpf_xdp_adjust_head, it
> > will be confused for xdp_frame_end.
>
> I think you should discuss this more with Jesper before
> submitting v2.
> He does not like this to be included now due to merge conflict risk.
> Basically I agree with him that we don't need to hurry with this fix.
>
> Toshiaki Makita
>
> >
> > Fixes: 9fc8d518d9d5 ("veth: Handle xdp_frames in xdp napi ring")
> > Signed-off-by: Mao Wenan <maowenan@huawei.com>
> > ---
> > v2: add fixes tag, as well as commit log.
> > drivers/net/veth.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > index d4cbb9e8c63f..5ea550884bf8 100644
> > --- a/drivers/net/veth.c
> > +++ b/drivers/net/veth.c
> > @@ -506,7 +506,7 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
> > struct xdp_buff xdp;
> > u32 act;
> >
> > - xdp.data_hard_start = hard_start;
> > + xdp.data_hard_start = head;
> > xdp.data = frame->data;
> > xdp.data_end = frame->data + frame->len;
> > xdp.data_meta = frame->data - frame->metasize;
> >
Below is the patch that I have in my queue. I've added a Reported-by
tag to give you some credit, even-though I already had plans to fix
this, as part of my XDP frame_sz work.
[PATCH RFC net-next] veth: adjust hard_start offset on redirect XDP frames
When native XDP redirect into a veth device, the frame arrives in the
xdp_frame structure. It is then processed in veth_xdp_rcv_one(),
which can run a new XDP bpf_prog on the packet. Doing so requires
converting xdp_frame to xdp_buff, but the tricky part is that
xdp_frame memory area is located in the top (data_hard_start) memory
area that xdp_buff will point into.
The current code tried to protect the xdp_frame area, by assigning
xdp_buff.data_hard_start past this memory. This results in 32 bytes
less headroom to expand into via BPF-helper bpf_xdp_adjust_head().
This protect step is actually not needed, because BPF-helper
bpf_xdp_adjust_head() already reserve this area, and don't allow
BPF-prog to expand into it. Thus, it is safe to point data_hard_start
directly at xdp_frame memory area.
Cc: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Fixes: 9fc8d518d9d5 ("veth: Handle xdp_frames in xdp napi ring")
Reported-by: Mao Wenan <maowenan@huawei.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
drivers/net/veth.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8cdc4415fa70..2edc04a8ab8e 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -493,13 +493,15 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
struct veth_xdp_tx_bq *bq)
{
void *hard_start = frame->data - frame->headroom;
- void *head = hard_start - sizeof(struct xdp_frame);
int len = frame->len, delta = 0;
struct xdp_frame orig_frame;
struct bpf_prog *xdp_prog;
unsigned int headroom;
struct sk_buff *skb;
+ /* bpf_xdp_adjust_head() assures BPF cannot access xdp_frame area */
+ hard_start -= sizeof(struct xdp_frame);
+
rcu_read_lock();
xdp_prog = rcu_dereference(rq->xdp_prog);
if (likely(xdp_prog)) {
@@ -521,7 +523,6 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
break;
case XDP_TX:
orig_frame = *frame;
- xdp.data_hard_start = head;
xdp.rxq->mem = frame->mem;
if (unlikely(veth_xdp_tx(rq->dev, &xdp, bq) < 0)) {
trace_xdp_exception(rq->dev, xdp_prog, act);
@@ -533,7 +534,6 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
goto xdp_xmit;
case XDP_REDIRECT:
orig_frame = *frame;
- xdp.data_hard_start = head;
xdp.rxq->mem = frame->mem;
if (xdp_do_redirect(rq->dev, &xdp, xdp_prog)) {
frame = &orig_frame;
@@ -555,7 +555,7 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
rcu_read_unlock();
headroom = sizeof(struct xdp_frame) + frame->headroom - delta;
- skb = veth_build_skb(head, headroom, len, 0);
+ skb = veth_build_skb(hard_start, headroom, len, 0);
if (!skb) {
xdp_return_frame(frame);
goto err;
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
WARNING: multiple messages have this Message-ID (diff)
From: Jesper Dangaard Brouer <brouer@redhat.com>
To: Toshiaki Makita <toshiaki.makita1@gmail.com>
Cc: brouer@redhat.com, Mao Wenan <maowenan@huawei.com>,
davem@davemloft.net, ast@kernel.org, daniel@iogearbox.net,
kuba@kernel.org, hawk@kernel.org, john.fastabend@gmail.com,
kafai@fb.com, songliubraving@fb.com, yhs@fb.com, andriin@fb.com,
jwi@linux.ibm.com, jianglidong3@jd.com, edumazet@google.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
bpf@vger.kernel.org, kernel-janitors@vger.kernel.org
Subject: Re: [PATCH net v2] veth: xdp: use head instead of hard_start
Date: Wed, 01 Apr 2020 16:15:17 +0000 [thread overview]
Message-ID: <20200401181419.7acd2aa6@carbon> (raw)
In-Reply-To: <7a1d55ad-1427-67fe-f204-4d4a0ab2c4b1@gmail.com>
On Tue, 31 Mar 2020 15:16:22 +0900
Toshiaki Makita <toshiaki.makita1@gmail.com> wrote:
> On 2020/03/31 15:06, Mao Wenan wrote:
> > xdp.data_hard_start is equal to first address of
> > struct xdp_frame, which is mentioned in
> > convert_to_xdp_frame(). But the pointer hard_start
> > in veth_xdp_rcv_one() is 32 bytes offset of frame,
> > so it should use head instead of hard_start to
> > set xdp.data_hard_start. Otherwise, if BPF program
> > calls helper_function such as bpf_xdp_adjust_head, it
> > will be confused for xdp_frame_end.
>
> I think you should discuss this more with Jesper before
> submitting v2.
> He does not like this to be included now due to merge conflict risk.
> Basically I agree with him that we don't need to hurry with this fix.
>
> Toshiaki Makita
>
> >
> > Fixes: 9fc8d518d9d5 ("veth: Handle xdp_frames in xdp napi ring")
> > Signed-off-by: Mao Wenan <maowenan@huawei.com>
> > ---
> > v2: add fixes tag, as well as commit log.
> > drivers/net/veth.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/net/veth.c b/drivers/net/veth.c
> > index d4cbb9e8c63f..5ea550884bf8 100644
> > --- a/drivers/net/veth.c
> > +++ b/drivers/net/veth.c
> > @@ -506,7 +506,7 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
> > struct xdp_buff xdp;
> > u32 act;
> >
> > - xdp.data_hard_start = hard_start;
> > + xdp.data_hard_start = head;
> > xdp.data = frame->data;
> > xdp.data_end = frame->data + frame->len;
> > xdp.data_meta = frame->data - frame->metasize;
> >
Below is the patch that I have in my queue. I've added a Reported-by
tag to give you some credit, even-though I already had plans to fix
this, as part of my XDP frame_sz work.
[PATCH RFC net-next] veth: adjust hard_start offset on redirect XDP frames
When native XDP redirect into a veth device, the frame arrives in the
xdp_frame structure. It is then processed in veth_xdp_rcv_one(),
which can run a new XDP bpf_prog on the packet. Doing so requires
converting xdp_frame to xdp_buff, but the tricky part is that
xdp_frame memory area is located in the top (data_hard_start) memory
area that xdp_buff will point into.
The current code tried to protect the xdp_frame area, by assigning
xdp_buff.data_hard_start past this memory. This results in 32 bytes
less headroom to expand into via BPF-helper bpf_xdp_adjust_head().
This protect step is actually not needed, because BPF-helper
bpf_xdp_adjust_head() already reserve this area, and don't allow
BPF-prog to expand into it. Thus, it is safe to point data_hard_start
directly at xdp_frame memory area.
Cc: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Fixes: 9fc8d518d9d5 ("veth: Handle xdp_frames in xdp napi ring")
Reported-by: Mao Wenan <maowenan@huawei.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
drivers/net/veth.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8cdc4415fa70..2edc04a8ab8e 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -493,13 +493,15 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
struct veth_xdp_tx_bq *bq)
{
void *hard_start = frame->data - frame->headroom;
- void *head = hard_start - sizeof(struct xdp_frame);
int len = frame->len, delta = 0;
struct xdp_frame orig_frame;
struct bpf_prog *xdp_prog;
unsigned int headroom;
struct sk_buff *skb;
+ /* bpf_xdp_adjust_head() assures BPF cannot access xdp_frame area */
+ hard_start -= sizeof(struct xdp_frame);
+
rcu_read_lock();
xdp_prog = rcu_dereference(rq->xdp_prog);
if (likely(xdp_prog)) {
@@ -521,7 +523,6 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
break;
case XDP_TX:
orig_frame = *frame;
- xdp.data_hard_start = head;
xdp.rxq->mem = frame->mem;
if (unlikely(veth_xdp_tx(rq->dev, &xdp, bq) < 0)) {
trace_xdp_exception(rq->dev, xdp_prog, act);
@@ -533,7 +534,6 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
goto xdp_xmit;
case XDP_REDIRECT:
orig_frame = *frame;
- xdp.data_hard_start = head;
xdp.rxq->mem = frame->mem;
if (xdp_do_redirect(rq->dev, &xdp, xdp_prog)) {
frame = &orig_frame;
@@ -555,7 +555,7 @@ static struct sk_buff *veth_xdp_rcv_one(struct veth_rq *rq,
rcu_read_unlock();
headroom = sizeof(struct xdp_frame) + frame->headroom - delta;
- skb = veth_build_skb(head, headroom, len, 0);
+ skb = veth_build_skb(hard_start, headroom, len, 0);
if (!skb) {
xdp_return_frame(frame);
goto err;
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
next prev parent reply other threads:[~2020-04-01 16:15 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-30 10:26 [PATCH net] veth: xdp: use head instead of hard_start Mao Wenan
2020-03-30 10:26 ` Mao Wenan
2020-03-30 11:34 ` Jesper Dangaard Brouer
2020-03-30 11:34 ` Jesper Dangaard Brouer
2020-03-30 23:35 ` Toshiaki Makita
2020-03-30 23:35 ` Toshiaki Makita
2020-03-31 3:56 ` maowenan
2020-03-31 3:56 ` maowenan
2020-03-31 5:45 ` Toshiaki Makita
2020-03-31 5:45 ` Toshiaki Makita
2020-03-31 6:06 ` [PATCH net v2] " Mao Wenan
2020-03-31 6:06 ` Mao Wenan
2020-03-31 6:16 ` Toshiaki Makita
2020-03-31 6:16 ` Toshiaki Makita
2020-04-01 16:15 ` Jesper Dangaard Brouer [this message]
2020-04-01 16:15 ` Jesper Dangaard Brouer
2020-04-02 0:47 ` Toshiaki Makita
2020-04-02 0:47 ` Toshiaki Makita
2020-04-02 9:06 ` Jesper Dangaard Brouer
2020-04-02 9:06 ` Jesper Dangaard Brouer
2020-04-02 15:40 ` Alexei Starovoitov
2020-04-02 15:40 ` Alexei Starovoitov
2020-04-03 7:58 ` Jesper Dangaard Brouer
2020-04-03 7:58 ` Jesper Dangaard Brouer
2020-04-03 21:12 ` Alexei Starovoitov
2020-04-03 21:12 ` Alexei Starovoitov
2020-04-02 1:23 ` maowenan
2020-04-02 1:23 ` maowenan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200401181419.7acd2aa6@carbon \
--to=brouer@redhat.com \
--cc=andriin@fb.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hawk@kernel.org \
--cc=jianglidong3@jd.com \
--cc=john.fastabend@gmail.com \
--cc=jwi@linux.ibm.com \
--cc=kafai@fb.com \
--cc=kernel-janitors@vger.kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maowenan@huawei.com \
--cc=netdev@vger.kernel.org \
--cc=songliubraving@fb.com \
--cc=toshiaki.makita1@gmail.com \
--cc=yhs@fb.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.