* [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic
@ 2004-02-29 18:14 Bart De Schuymer
2004-03-01 5:54 ` David S. Miller
0 siblings, 1 reply; 5+ messages in thread
From: Bart De Schuymer @ 2004-02-29 18:14 UTC (permalink / raw)
To: David S.Miller; +Cc: ebtables-devel, netdev
Hi Dave,
When vlan-tagged fragmented IP traffic passes the bridging firewall and
ip_conntrack is loaded and iptables sees this IP traffic, an oops can
occur when trying to fragment the defragmented packets. This only
happens in the slow_path of ip_fragment().
The problem was reported, diagnosed and fixed by Adam Osuchowski and
Tomasz Dubinski.
When ip_fragment() is fragmenting an IP packet that's encapsulated, it has
to make sure there is enough head room for the encapsulating header.
The patch below fixes it. I saw no other way than to add some code to
ip_fragment(), but this extra code is located in the slow_path so it's
hardly ever executed.
cheers,
Bart
--- linux-2.6.3/include/linux/netfilter_bridge.h.save Sun Feb 29 17:13:44 2004
+++ linux-2.6.3/include/linux/netfilter_bridge.h Sun Feb 29 17:43:55 2004
@@ -88,6 +88,20 @@ void nf_bridge_save_header(struct sk_buf
memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
}
+/* This is called by the IP fragmenting code and it ensures there is
+ * enough room for the encapsulating header (if there is one). */
+static inline
+int nf_bridge_pad(struct sk_buff *skb)
+{
+ if (skb->protocol == __constant_htons(ETH_P_IP))
+ return 0;
+ if (skb->nf_bridge) {
+ if (skb->protocol == __constant_htons(ETH_P_8021Q))
+ return 4;
+ }
+ return 0;
+}
+
struct bridge_skb_cb {
union {
__u32 ipv4;
--- linux-2.6.3/net/ipv4/ip_output.c.save Sun Feb 29 16:30:05 2004
+++ linux-2.6.3/net/ipv4/ip_output.c Sun Feb 29 19:11:35 2004
@@ -80,6 +80,7 @@
#include <net/inetpeer.h>
#include <linux/igmp.h>
#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_bridge.h>
#include <linux/mroute.h>
#include <linux/netlink.h>
@@ -442,7 +443,7 @@ int ip_fragment(struct sk_buff *skb, int
int ptr;
struct net_device *dev;
struct sk_buff *skb2;
- unsigned int mtu, hlen, left, len;
+ unsigned int mtu, hlen, left, len, ll_rs;
int offset;
int not_last_frag;
struct rtable *rt = (struct rtable*)skb->dst;
@@ -563,6 +564,14 @@ slow_path:
left = skb->len - hlen; /* Space per frame */
ptr = raw + hlen; /* Where to start from */
+#ifdef CONFIG_BRIDGE_NETFILTER
+ /* for bridged IP traffic encapsulated inside f.e. a vlan header,
+ * we need to make room for the encapsulating header */
+ ll_rs = LL_RESERVED_SPACE(rt->u.dst.dev + nf_bridge_pad(skb));
+ mtu -= nf_bridge_pad(skb);
+#else
+ ll_rs = LL_RESERVED_SPACE(rt->u.dst.dev);
+#endif
/*
* Fragment the datagram.
*/
@@ -588,7 +597,7 @@ slow_path:
* Allocate buffer.
*/
- if ((skb2 = alloc_skb(len+hlen+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
+ if ((skb2 = alloc_skb(len+hlen+ll_rs, GFP_ATOMIC)) == NULL) {
NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
err = -ENOMEM;
goto fail;
@@ -599,7 +608,7 @@ slow_path:
*/
ip_copy_metadata(skb2, skb);
- skb_reserve(skb2, LL_RESERVED_SPACE(rt->u.dst.dev));
+ skb_reserve(skb2, ll_rs);
skb_put(skb2, len + hlen);
skb2->nh.raw = skb2->data;
skb2->h.raw = skb2->data + hlen;
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic
2004-02-29 18:14 [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic Bart De Schuymer
@ 2004-03-01 5:54 ` David S. Miller
[not found] ` <20040229215421.0ca987e8.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: David S. Miller @ 2004-03-01 5:54 UTC (permalink / raw)
To: Bart De Schuymer; +Cc: ebtables-devel, netdev
On Sun, 29 Feb 2004 19:14:53 +0100
Bart De Schuymer <bdschuym@pandora.be> wrote:
> When vlan-tagged fragmented IP traffic passes the bridging firewall and
> ip_conntrack is loaded and iptables sees this IP traffic, an oops can
> occur when trying to fragment the defragmented packets. This only
> happens in the slow_path of ip_fragment().
...
> The patch below fixes it. I saw no other way than to add some code to
> ip_fragment(), but this extra code is located in the slow_path so it's
> hardly ever executed.
Can you explain the 'mtu' fiddling a little bit? I think it's correct...
but you know :)
The one case I'm concerned about is when the device does hw acceleration
of vlan tagging (ie. therefore things are transparent supposedly), is
the 'mtu' adjustment thing correct in that case?
I'm applying this for now, as I can't come up with a better fix either.
If we find a problem with this change, we'll fix that up.
I'm really concerned, btw, that this is going to propagate to other places
as well, what if something that gets handled this way gets sent over an
IPIP tunnel via some route, and then IPIP has to make all of these crazy
adjustments too? That's going too far and we'll have to find a better
way if that is the case.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic
[not found] ` <20040229215421.0ca987e8.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2004-03-01 7:06 ` Bart De Schuymer
2004-03-01 8:35 ` David S. Miller
0 siblings, 1 reply; 5+ messages in thread
From: Bart De Schuymer @ 2004-03-01 7:06 UTC (permalink / raw)
To: David S. Miller
Cc: ebtables-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
netdev-VZNHf3L845pBDgjK7y7TUQ
On Monday 01 March 2004 06:54, David S. Miller wrote:
> Can you explain the 'mtu' fiddling a little bit? I think it's correct...
> but you know :)
Between the Ethernet header and the IP header, there will be put a
vlan-header. This is done in br_dev_queue_push_xmit(), with
nf_bridge_maybe_copy_header(). By changing the mtu we make sure the IP
packets arre small enough to allow the vlan header to be added.
> The one case I'm concerned about is when the device does hw acceleration
> of vlan tagging (ie. therefore things are transparent supposedly), is
> the 'mtu' adjustment thing correct in that case?
I don't think that's a problem. We only have this problem when the vlan-tagged
IP packet enters the bridge as a whole, so the incoming bridge port doesn't
strip the vlan header. Therefore, the outgoing bridge port shouldn't be
adding the vlan-header, as it's already supposed to be there.
The difference between the slow_path and the normal path in ip_fragment() is
that in the normal path we can use the skbuffs of the fragments and these
already have enough space for the vlan header and the IP fragment size is
small enough. In the slow_path the skbuffs are constructed and then we need
these special measures.
> I'm applying this for now, as I can't come up with a better fix either.
> If we find a problem with this change, we'll fix that up.
>
> I'm really concerned, btw, that this is going to propagate to other places
> as well, what if something that gets handled this way gets sent over an
> IPIP tunnel via some route, and then IPIP has to make all of these crazy
> adjustments too? That's going too far and we'll have to find a better
> way if that is the case.
I'm not sure how IPIP tunnels are implemented, but I'm assuming they strip the
first IP header like the vlan code strips the vlan header when a vlan-packet
arrives on a vlan-enabled device. Then there should be no problem with this.
Even if it's done differently, I don't _think_ it will give a problem.
The problem is caused purely by the fact that the bridge-nf code
(br_netfilter.c) skb_pulls the packet by 4 bytes if it's an IP packet inside
a vlan-header, allowing the IP packet to be filtered by iptables, and as far
as the IP code and iptables is concerned, there is no vlan-header. So we need
to give the IP code a little help.
Extra code, analogous to the code for vlan, would need to be added in
nf_bridge_pad() if we were to allow filtering IP packets inside a bridged
IPIP packet, of course.
cheers,
Bart
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic
2004-03-01 7:06 ` Bart De Schuymer
@ 2004-03-01 8:35 ` David S. Miller
[not found] ` <20040301003525.522d6db2.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
0 siblings, 1 reply; 5+ messages in thread
From: David S. Miller @ 2004-03-01 8:35 UTC (permalink / raw)
To: Bart De Schuymer; +Cc: ebtables-devel, netdev
On Mon, 1 Mar 2004 08:06:29 +0100
Bart De Schuymer <bdschuym@pandora.be> wrote:
> > I'm really concerned, btw, that this is going to propagate to other places
> > as well, what if something that gets handled this way gets sent over an
> > IPIP tunnel via some route, and then IPIP has to make all of these crazy
> > adjustments too? That's going too far and we'll have to find a better
> > way if that is the case.
>
> I'm not sure how IPIP tunnels are implemented, but I'm assuming they strip the
> first IP header like the vlan code strips the vlan header when a vlan-packet
> arrives on a vlan-enabled device. Then there should be no problem with this.
Let us say that on input, br strips the 4 bytes as you say, iptables looks
at the thing and rewrites the IP source/destination address or whatever,
and this causes the packet to actually get forwarded out via a different IP
route, and let us say that this new IP route causes the packet to go out
via an IPIP tunnel device, which must do all the same kind of crap the code
you're patching here does, that is determine the LL header size etc. in order
to make sure there is enough headroom to slap on the new IP encapsulating
header.
If you can show that this kind of scenerio would never be generated in the
cases where br-netfilter is involved, then fine.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic
[not found] ` <20040301003525.522d6db2.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2004-03-01 18:47 ` Bart De Schuymer
0 siblings, 0 replies; 5+ messages in thread
From: Bart De Schuymer @ 2004-03-01 18:47 UTC (permalink / raw)
To: David S. Miller
Cc: ebtables-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
netdev-VZNHf3L845pBDgjK7y7TUQ
On Monday 01 March 2004 09:35, David S. Miller wrote:
> Let us say that on input, br strips the 4 bytes as you say, iptables looks
> at the thing and rewrites the IP source/destination address or whatever,
> and this causes the packet to actually get forwarded out via a different IP
> route, and let us say that this new IP route causes the packet to go out
> via an IPIP tunnel device, which must do all the same kind of crap the code
> you're patching here does, that is determine the LL header size etc. in
> order to make sure there is enough headroom to slap on the new IP
> encapsulating header.
>
> If you can show that this kind of scenerio would never be generated in the
> cases where br-netfilter is involved, then fine.
The IPIP code does
dev->hard_header_len=LL_MAX_HEADER+sizeof(struct iphdr);
so there's no problem there because the macro LL_RESERVED_SPACE uses that
value. There should never be a problem like that with routing.
When routing IP packets, skb->protocol will always be set to ETH_P_IP, so
nf_bridge_pad doesn't do anything.
Obviously, adding a normal Ethernet device and, say, a vlan-enabled device as
bridge ports of the same bridge is bound to give problems because full
Ethernet frames will arrive on the normal device and there's no room to
insert a vlan header before sending them onto the vlan-enabled port. For IP
packets we might be able to fix this when ip_conntrack is loaded by using
fragmenting, but I don't think this currently works. I'll have to experiment.
Note that changing the IP destination in a vlan-embedded packet makes the
bridge code pass the packet up to higher layers (unless it can still be
bridged), but the vlan header is not yet stripped. So only if the bridge
device itself is vlan-enabled, will the packet be able to be routed. But
first the vlan tag will be stripped (by the vlan-enabled bridge device).
cheers,
Bart
-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-03-01 18:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-02-29 18:14 [PATCH] 2.6.3 fix vlan-encapsulated fragmented IP traffic Bart De Schuymer
2004-03-01 5:54 ` David S. Miller
[not found] ` <20040229215421.0ca987e8.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2004-03-01 7:06 ` Bart De Schuymer
2004-03-01 8:35 ` David S. Miller
[not found] ` <20040301003525.522d6db2.davem-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2004-03-01 18:47 ` Bart De Schuymer
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).