* act_mirred: Fix bogus header when redirecting from VLAN
@ 2015-04-17 1:02 Herbert Xu
2015-04-17 1:34 ` Alexei Starovoitov
0 siblings, 1 reply; 7+ messages in thread
From: Herbert Xu @ 2015-04-17 1:02 UTC (permalink / raw)
To: netdev, jamal
When you redirect a VLAN device to an ifb device, you end up with
crap within the ifb device because they have unequal hard header
lengths and the redirected packet contains four extra bytes at the
start which then gets interpreted as part of the MAC address.
This patch fixes this by only pushing on the hard header length
of ifb. This assumes that the original packet actually has enough
header for that so checks have been added to that effect.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 34f846b..1256d26 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -105,7 +105,7 @@ static void ri_tasklet(unsigned long dev)
if (from & AT_EGRESS) {
dev_queue_xmit(skb);
} else if (from & AT_INGRESS) {
- skb_pull(skb, skb->dev->hard_header_len);
+ skb_pull(skb, _dev->hard_header_len);
netif_receive_skb(skb);
} else
BUG();
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 5953517..44e4d50 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -151,13 +151,25 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
}
at = G_TC_AT(skb->tc_verd);
+
+ if (!(at & AT_EGRESS) && m->tcfm_ok_push &&
+ (skb_headroom(skb) < dev->hard_header_len ||
+ skb->dev->hard_header_len < dev->hard_header_len)) {
+ net_notice_ratelimited(
+ "tc mirred: Insufficient headroom from %s to %s: "
+ "%d %d\n",
+ skb->dev->name, dev->name,
+ skb_headroom(skb), skb->dev->hard_header_len);
+ goto out;
+ }
+
skb2 = skb_act_clone(skb, GFP_ATOMIC, m->tcf_action);
if (skb2 == NULL)
goto out;
if (!(at & AT_EGRESS)) {
if (m->tcfm_ok_push)
- skb_push(skb2, skb2->dev->hard_header_len);
+ skb_push(skb2, dev->hard_header_len);
}
/* mirror is always swallowed */
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: act_mirred: Fix bogus header when redirecting from VLAN
2015-04-17 1:02 act_mirred: Fix bogus header when redirecting from VLAN Herbert Xu
@ 2015-04-17 1:34 ` Alexei Starovoitov
2015-04-17 2:15 ` Herbert Xu
0 siblings, 1 reply; 7+ messages in thread
From: Alexei Starovoitov @ 2015-04-17 1:34 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, jamal
On Fri, Apr 17, 2015 at 09:02:16AM +0800, Herbert Xu wrote:
> @@ -105,7 +105,7 @@ static void ri_tasklet(unsigned long dev)
> if (from & AT_EGRESS) {
> dev_queue_xmit(skb);
> } else if (from & AT_INGRESS) {
> - skb_pull(skb, skb->dev->hard_header_len);
> + skb_pull(skb, _dev->hard_header_len);
...
> if (!(at & AT_EGRESS)) {
> if (m->tcfm_ok_push)
> - skb_push(skb2, skb2->dev->hard_header_len);
> + skb_push(skb2, dev->hard_header_len);
seems the cleaner fix will be to push skb->mac_len instead?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: act_mirred: Fix bogus header when redirecting from VLAN
2015-04-17 1:34 ` Alexei Starovoitov
@ 2015-04-17 2:15 ` Herbert Xu
2015-04-17 2:40 ` Alexei Starovoitov
0 siblings, 1 reply; 7+ messages in thread
From: Herbert Xu @ 2015-04-17 2:15 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: netdev, jamal
On Thu, Apr 16, 2015 at 06:34:02PM -0700, Alexei Starovoitov wrote:
> On Fri, Apr 17, 2015 at 09:02:16AM +0800, Herbert Xu wrote:
> > @@ -105,7 +105,7 @@ static void ri_tasklet(unsigned long dev)
> > if (from & AT_EGRESS) {
> > dev_queue_xmit(skb);
> > } else if (from & AT_INGRESS) {
> > - skb_pull(skb, skb->dev->hard_header_len);
> > + skb_pull(skb, _dev->hard_header_len);
> ...
> > if (!(at & AT_EGRESS)) {
> > if (m->tcfm_ok_push)
> > - skb_push(skb2, skb2->dev->hard_header_len);
> > + skb_push(skb2, dev->hard_header_len);
>
> seems the cleaner fix will be to push skb->mac_len instead?
No skb->mac_len is the same as skb2->dev->hard_header_len.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: act_mirred: Fix bogus header when redirecting from VLAN
2015-04-17 2:15 ` Herbert Xu
@ 2015-04-17 2:40 ` Alexei Starovoitov
2015-04-17 5:32 ` [v2] " Herbert Xu
0 siblings, 1 reply; 7+ messages in thread
From: Alexei Starovoitov @ 2015-04-17 2:40 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, jamal
On Fri, Apr 17, 2015 at 10:15:01AM +0800, Herbert Xu wrote:
> > seems the cleaner fix will be to push skb->mac_len instead?
>
> No skb->mac_len is the same as skb2->dev->hard_header_len.
hmm. please help me understand the problem then.
In the commit log you mentioned that your vlan dev and ifb
have unequal hard header length. I think that can only happen if
your master dev used to create vlan, didn't have vlan offload,
so vlandev->hhl = 18 and ifb->hhl = 14. Then when tagged packet
arrives on master device we call skb_vlan_untag() and
skb->mac_len becomes 14, then vlan_do_receive() will do
another_round, ingress qdisc will trigger and act_mirred
eventually will be called. So existing act_mirred will be pushing
18 bytes, whereas only 14 bytes are valid and the lowest 4 have junk.
By 'fixing it' using ifb's 14 byte the patch is only masking the
problem, no?
^ permalink raw reply [flat|nested] 7+ messages in thread
* [v2] act_mirred: Fix bogus header when redirecting from VLAN
2015-04-17 2:40 ` Alexei Starovoitov
@ 2015-04-17 5:32 ` Herbert Xu
2015-04-17 15:26 ` Alexei Starovoitov
2015-04-17 17:29 ` David Miller
0 siblings, 2 replies; 7+ messages in thread
From: Herbert Xu @ 2015-04-17 5:32 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: netdev, jamal
On Thu, Apr 16, 2015 at 07:40:30PM -0700, Alexei Starovoitov wrote:
> On Fri, Apr 17, 2015 at 10:15:01AM +0800, Herbert Xu wrote:
> > > seems the cleaner fix will be to push skb->mac_len instead?
> >
> > No skb->mac_len is the same as skb2->dev->hard_header_len.
>
> hmm. please help me understand the problem then.
> In the commit log you mentioned that your vlan dev and ifb
> have unequal hard header length. I think that can only happen if
> your master dev used to create vlan, didn't have vlan offload,
> so vlandev->hhl = 18 and ifb->hhl = 14. Then when tagged packet
> arrives on master device we call skb_vlan_untag() and
> skb->mac_len becomes 14, then vlan_do_receive() will do
You are right. I should've just used mac_len.
---8<---
When you redirect a VLAN device to any device, you end up with
crap in af_packet on the xmit path because hard_header_len is
not equal to skb->mac_len. So the redirected packet contains
four extra bytes at the start which then gets interpreted as
part of the MAC address.
This patch fixes this by only pushing skb->mac_len. We also
need to fix ifb because it tries to undo the pushing done by
act_mirred.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 34f846b..94570aa 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -105,7 +105,7 @@ static void ri_tasklet(unsigned long dev)
if (from & AT_EGRESS) {
dev_queue_xmit(skb);
} else if (from & AT_INGRESS) {
- skb_pull(skb, skb->dev->hard_header_len);
+ skb_pull(skb, skb->mac_len);
netif_receive_skb(skb);
} else
BUG();
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index 5953517..3f63cea 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -157,7 +157,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
if (!(at & AT_EGRESS)) {
if (m->tcfm_ok_push)
- skb_push(skb2, skb2->dev->hard_header_len);
+ skb_push(skb2, skb->mac_len);
}
/* mirror is always swallowed */
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [v2] act_mirred: Fix bogus header when redirecting from VLAN
2015-04-17 5:32 ` [v2] " Herbert Xu
@ 2015-04-17 15:26 ` Alexei Starovoitov
2015-04-17 17:29 ` David Miller
1 sibling, 0 replies; 7+ messages in thread
From: Alexei Starovoitov @ 2015-04-17 15:26 UTC (permalink / raw)
To: Herbert Xu; +Cc: netdev, jamal
On Fri, Apr 17, 2015 at 01:32:09PM +0800, Herbert Xu wrote:
> When you redirect a VLAN device to any device, you end up with
> crap in af_packet on the xmit path because hard_header_len is
> not equal to skb->mac_len. So the redirected packet contains
> four extra bytes at the start which then gets interpreted as
> part of the MAC address.
>
> This patch fixes this by only pushing skb->mac_len. We also
> need to fix ifb because it tries to undo the pushing done by
> act_mirred.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [v2] act_mirred: Fix bogus header when redirecting from VLAN
2015-04-17 5:32 ` [v2] " Herbert Xu
2015-04-17 15:26 ` Alexei Starovoitov
@ 2015-04-17 17:29 ` David Miller
1 sibling, 0 replies; 7+ messages in thread
From: David Miller @ 2015-04-17 17:29 UTC (permalink / raw)
To: herbert; +Cc: alexei.starovoitov, netdev, hadi
From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Fri, 17 Apr 2015 13:32:09 +0800
> On Thu, Apr 16, 2015 at 07:40:30PM -0700, Alexei Starovoitov wrote:
>> On Fri, Apr 17, 2015 at 10:15:01AM +0800, Herbert Xu wrote:
>> > > seems the cleaner fix will be to push skb->mac_len instead?
>> >
>> > No skb->mac_len is the same as skb2->dev->hard_header_len.
>>
>> hmm. please help me understand the problem then.
>> In the commit log you mentioned that your vlan dev and ifb
>> have unequal hard header length. I think that can only happen if
>> your master dev used to create vlan, didn't have vlan offload,
>> so vlandev->hhl = 18 and ifb->hhl = 14. Then when tagged packet
>> arrives on master device we call skb_vlan_untag() and
>> skb->mac_len becomes 14, then vlan_do_receive() will do
>
> You are right. I should've just used mac_len.
>
> ---8<---
> When you redirect a VLAN device to any device, you end up with
> crap in af_packet on the xmit path because hard_header_len is
> not equal to skb->mac_len. So the redirected packet contains
> four extra bytes at the start which then gets interpreted as
> part of the MAC address.
>
> This patch fixes this by only pushing skb->mac_len. We also
> need to fix ifb because it tries to undo the pushing done by
> act_mirred.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Applied.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-04-17 17:29 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-17 1:02 act_mirred: Fix bogus header when redirecting from VLAN Herbert Xu
2015-04-17 1:34 ` Alexei Starovoitov
2015-04-17 2:15 ` Herbert Xu
2015-04-17 2:40 ` Alexei Starovoitov
2015-04-17 5:32 ` [v2] " Herbert Xu
2015-04-17 15:26 ` Alexei Starovoitov
2015-04-17 17:29 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).