mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* kernel oops, fast ethernet bridge, 2.4.31
@ 2005-07-20 15:00 Lukasz Spaleniak
  2005-07-20 19:44 ` Willy Tarreau
  0 siblings, 1 reply; 6+ messages in thread
From: Lukasz Spaleniak @ 2005-07-20 15:00 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 919 bytes --]

Hello,

I have bridge firewall (linux box) with three fast ethernet cards (one
rtl8139 for management and two e100 for bridge). It is running 2.4.31
kernel and iptables v1.2.11. It works ok about one month. Few weeks
ago It started ooopsing. First thought was hardware, but it was
replaced with a new one and problem still exist. I'm attaching 
ksymoops analysis of ooops message. I hope I'll help.

Some facts:
Traffic over this bridge is about ~30 MBit/sec and every frame is
tagged with VID (802.1q). Problem exist also on 2.4.30 kernel.
Kernel is patched with ebtables patch. Ooops completeley freezes
machine, only hard reset takes effect. Nothing is placed into syslog.

The ksymooops analisis is attached as text file.

Anyone know this bug/problem ?

Regards,
Lukasz Spaleniak

-- 
spalek on wroc zigzag pl
GCM dpu s: a--- C++ UL++++ P+ L+++ E--- W+ N+ K- w O- M V-
PGP t--- 5 X+ R- tv-- b DI- D- G e-- h! r y+

[-- Attachment #2: lalala --]
[-- Type: application/octet-stream, Size: 6060 bytes --]

ksymoops 2.4.9 on i686 2.4.31.  Options used
     -V (default)
     -k ksyms (specified)
     -l moduly (specified)
     -o /lib/modules/2.4.31/ (default)
     -m /boot/System.map-2.4.31 (default)

skput:under: e08e7c48:1518 put:14 dev:eth2kernel BUG at skbuff.c:109!
invalid operand: 0000
CPU:    0
EIP:    0010:[<c01cd1cb>]    Not tainted
Using defaults from ksymoops -t elf32-i386 -a i386
EFLAGS: 00010282
eax: 0000002a   ebx: df3b8c80   ecx: c0286000   edx: df3c3f84
esi: ddbb3ba6   edi: ddf9b810   ebp: df3b8c80   esp: c0287b48
ds: 0018   es: 0018   ss: 0018
Process swapper (pid: 0, stackpage=c0287000)
Stack: c023b4e0 e08e7c48 000005ee 0000000e dfae8c00 e08e7c51 df3b8c80 0000000e
       e08e7c48 df3b8c80 ddf9b810 ddf9b824 000005c8 c01e634c df3b8c80 00000014
       ddf9b824 000005c8 000005dc 00000014 00000000 000005c8 00000009 000005c8
Call Trace:    [<e08e7c48>] [<e08e7c51>] [<e08e7c48>] [<c01e634c>] [<e08ecec0>]
  [<e08ed020>] [<e08e7bb0>] [<e0900684>] [<e08e7bb0>] [<e08e7bb0>] [<e09073d0>]
  [<c01d9c6a>] [<e08e7bb0>] [<c01d9fd9>] [<e08e7bb0>] [<e09073d0>] [<e08ec34d>]
  [<e08e7bb0>] [<e08ed140>] [<c01d9c6a>] [<e08e7bb0>] [<c01d9fd9>] [<e08e7bb0>]
  [<e08ed140>] [<e08e7cf3>] [<e08e7bb0>] [<e08ebd0c>] [<e08e7cb0>] [<e08ebe6f>]
  [<e08ebc80>] [<e08ed110>] [<c01d9c6a>] [<e08e7cb0>] [<c01d9fd9>] [<e08e7cb0>]
  [<e08ed110>] [<e08e7dea>] [<e08e7cb0>] [<e08e88df>] [<e08e8820>] [<e08eb362>]
  [<e08e8820>] [<e08eb250>] [<e08ebade>] [<e08eb250>] [<e08ed0e0>] [<c01d9c6a>]
  [<e08e8820>] [<c01d9fd9>] [<e08e8820>] [<e08ed0e0>] [<e08e8820>] [<e08e8aa2>]
  [<e08e8820>] [<c01d1289>] [<c01d1463>] [<c01d1564>] [<c0118b05>] [<c01088fb>]
  [<c01052c0>] [<c010ac78>] [<c01052c0>] [<c01052e3>] [<c0105372>] [<c0105000>]
Code: 0f 0b 6d 00 5f a5 23 c0 83 c4 14 c3 89 f6 8d bc 27 00 00 00


>>EIP; c01cd1cb <skb_under_panic+3b/50>   <=====

>>ebx; df3b8c80 <_end+1f0f4ffc/205f83dc>
>>ecx; c0286000 <init_task_union+0/2000>
>>edx; df3c3f84 <_end+1f100300/205f83dc>
>>esi; ddbb3ba6 <_end+1d8eff22/205f83dc>
>>edi; ddf9b810 <_end+1dcd7b8c/205f83dc>
>>ebp; df3b8c80 <_end+1f0f4ffc/205f83dc>
>>esp; c0287b48 <init_task_union+1b48/2000>

Trace; e08e7c48 <[bridge]br_dev_queue_push_xmit+98/100>
Trace; e08e7c51 <[bridge]br_dev_queue_push_xmit+a1/100>
Trace; e08e7c48 <[bridge]br_dev_queue_push_xmit+98/100>
Trace; c01e634c <ip_fragment+2ec/3e0>
Trace; e08ecec0 <[bridge]__fake_net_device+0/160>
Trace; e08ed020 <[bridge]__fake_rtable+0/c0>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e0900684 <[ip_conntrack]ip_refrag+74/80>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e09073d0 <[ip_conntrack]ip_conntrack_out_ops+0/18>
Trace; c01d9c6a <nf_iterate+6a/b0>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; c01d9fd9 <nf_hook_slow+99/1f0>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e09073d0 <[ip_conntrack]ip_conntrack_out_ops+0/18>
Trace; e08ec34d <[bridge]br_nf_post_routing+13d/240>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e08ed140 <[bridge]br_nf_ops+60/140>
Trace; c01d9c6a <nf_iterate+6a/b0>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; c01d9fd9 <nf_hook_slow+99/1f0>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e08ed140 <[bridge]br_nf_ops+60/140>
Trace; e08e7cf3 <[bridge]br_forward_finish+43/60>
Trace; e08e7bb0 <[bridge]br_dev_queue_push_xmit+0/100>
Trace; e08ebd0c <[bridge]br_nf_forward_finish+8c/e0>
Trace; e08e7cb0 <[bridge]br_forward_finish+0/60>
Trace; e08ebe6f <[bridge]br_nf_forward_ip+10f/160>
Trace; e08ebc80 <[bridge]br_nf_forward_finish+0/e0>
Trace; e08ed110 <[bridge]br_nf_ops+30/140>
Trace; c01d9c6a <nf_iterate+6a/b0>
Trace; e08e7cb0 <[bridge]br_forward_finish+0/60>
Trace; c01d9fd9 <nf_hook_slow+99/1f0>
Trace; e08e7cb0 <[bridge]br_forward_finish+0/60>
Trace; e08ed110 <[bridge]br_nf_ops+30/140>
Trace; e08e7dea <[bridge]__br_forward+5a/70>
Trace; e08e7cb0 <[bridge]br_forward_finish+0/60>
Trace; e08e88df <[bridge]br_handle_frame_finish+bf/160>
Trace; e08e8820 <[bridge]br_handle_frame_finish+0/160>
Trace; e08eb362 <[bridge]br_nf_pre_routing_finish+112/2b0>
Trace; e08e8820 <[bridge]br_handle_frame_finish+0/160>
Trace; e08eb250 <[bridge]br_nf_pre_routing_finish+0/2b0>
Trace; e08ebade <[bridge]br_nf_pre_routing+29e/410>
Trace; e08eb250 <[bridge]br_nf_pre_routing_finish+0/2b0>
Trace; e08ed0e0 <[bridge]br_nf_ops+0/140>
Trace; c01d9c6a <nf_iterate+6a/b0>
Trace; e08e8820 <[bridge]br_handle_frame_finish+0/160>
Trace; c01d9fd9 <nf_hook_slow+99/1f0>
Trace; e08e8820 <[bridge]br_handle_frame_finish+0/160>
Trace; e08ed0e0 <[bridge]br_nf_ops+0/140>
Trace; e08e8820 <[bridge]br_handle_frame_finish+0/160>
Trace; e08e8aa2 <[bridge]br_handle_frame+122/1e0>
Trace; e08e8820 <[bridge]br_handle_frame_finish+0/160>
Trace; c01d1289 <netif_receive_skb+b9/210>
Trace; c01d1463 <process_backlog+83/110>
Trace; c01d1564 <net_rx_action+74/110>
Trace; c0118b05 <do_softirq+95/a0>
Trace; c01088fb <do_IRQ+9b/a0>
Trace; c01052c0 <default_idle+0/40>
Trace; c010ac78 <call_do_IRQ+5/d>
Trace; c01052c0 <default_idle+0/40>
Trace; c01052e3 <default_idle+23/40>
Trace; c0105372 <cpu_idle+52/70>
Trace; c0105000 <_stext+0/0>

Code;  c01cd1cb <skb_under_panic+3b/50>
00000000 <_EIP>:
Code;  c01cd1cb <skb_under_panic+3b/50>   <=====
   0:   0f 0b                     ud2a      <=====
Code;  c01cd1cd <skb_under_panic+3d/50>
   2:   6d                        insl   (%dx),%es:(%edi)
Code;  c01cd1ce <skb_under_panic+3e/50>
   3:   00 5f a5                  add    %bl,0xffffffa5(%edi)
Code;  c01cd1d1 <skb_under_panic+41/50>
   6:   23 c0                     and    %eax,%eax
Code;  c01cd1d3 <skb_under_panic+43/50>
   8:   83 c4 14                  add    $0x14,%esp
Code;  c01cd1d6 <skb_under_panic+46/50>
   b:   c3                        ret    
Code;  c01cd1d7 <skb_under_panic+47/50>
   c:   89 f6                     mov    %esi,%esi
Code;  c01cd1d9 <skb_under_panic+49/50>
   e:   8d bc 27 00 00 00 00      lea    0x0(%edi),%edi

 <0>Kernel panic: Aiee, killing interrupt handler!

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: kernel oops, fast ethernet bridge, 2.4.31
  2005-07-20 15:00 kernel oops, fast ethernet bridge, 2.4.31 Lukasz Spaleniak
@ 2005-07-20 19:44 ` Willy Tarreau
  2005-07-20 20:33   ` Re[2]: " Lukasz Spaleniak
  0 siblings, 1 reply; 6+ messages in thread
From: Willy Tarreau @ 2005-07-20 19:44 UTC (permalink / raw)
  To: Lukasz Spaleniak; +Cc: linux-kernel

Hello,

just some basic questions :
  - did your configuration change before the oopses started ? (eg: new
    matches, etc...)

  - did the traffic change recently (protocols, data rate) ? eg: new
    applications on the network, etc...

  - is it possible that it's being targetted by an attack where it is
    installed (unfiltered internet, holiday employees who like to play
    with the network, etc...) ?

I really find it strange that it suddenly started oopsing if nothing
changed. At least it should have been oopsing from day one.

Regards,
willy

On Wed, Jul 20, 2005 at 05:00:25PM +0200, Lukasz Spaleniak wrote:
> Hello,
> 
> I have bridge firewall (linux box) with three fast ethernet cards (one
> rtl8139 for management and two e100 for bridge). It is running 2.4.31
> kernel and iptables v1.2.11. It works ok about one month. Few weeks
> ago It started ooopsing. First thought was hardware, but it was
> replaced with a new one and problem still exist. I'm attaching 
> ksymoops analysis of ooops message. I hope I'll help.
> 
> Some facts:
> Traffic over this bridge is about ~30 MBit/sec and every frame is
> tagged with VID (802.1q). Problem exist also on 2.4.30 kernel.
> Kernel is patched with ebtables patch. Ooops completeley freezes
> machine, only hard reset takes effect. Nothing is placed into syslog.
> 
> The ksymooops analisis is attached as text file.
> 
> Anyone know this bug/problem ?
> 
> Regards,
> Lukasz Spaleniak
> 
> -- 
> spalek on wroc zigzag pl
> GCM dpu s: a--- C++ UL++++ P+ L+++ E--- W+ N+ K- w O- M V-
> PGP t--- 5 X+ R- tv-- b DI- D- G e-- h! r y+



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re[2]: kernel oops, fast ethernet bridge, 2.4.31
  2005-07-20 19:44 ` Willy Tarreau
@ 2005-07-20 20:33   ` Lukasz Spaleniak
  2005-07-22 15:13     ` Joy Leima
  0 siblings, 1 reply; 6+ messages in thread
From: Lukasz Spaleniak @ 2005-07-20 20:33 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: linux-kernel

On Wednesday, July 20, 2005, 9:44:57 PM, Willy Tarreau wrote:

> Hello,
Hello Willy,

> just some basic questions :
>   - did your configuration change before the oopses started ? (eg: new
>     matches, etc...)
One new machine appears but it generates small traffic rate (by now
it's almost unused).

>   - did the traffic change recently (protocols, data rate) ? eg: new
>     applications on the network, etc...
No - firewall is bridging IPv4 only. There was no dramatic topology
change. Those VLANs which are going through this firewall were
untouched.

>   - is it possible that it's being targetted by an attack where it is
>     installed (unfiltered internet, holiday employees who like to play
>     with the network, etc...) ?
I don't think so that managed IP of firewall was targetet, maybe
machines behid firewall but problem appears on eth2 interface which
is:
internet <-trunk-> eth1(firewall/iptables)eth2<-trunk->(switch
ports) <-> servers
So it's after iptables ...

> I really find it strange that it suddenly started oopsing if nothing
> changed. At least it should have been oopsing from day one.
It is strange to me too. There is no dependency when it happens.
Sometimes traffic is small, sometimes it's normal. Packet rates are
around ~2000-3000 pkt/sec - so not so high.


Regards,
Lukasz

-- 
lspaleniak on wroc zigzag pl
GCM dpu s: a--- C++ UL++++ P+ L+++ E--- W+ N+ K- w O- M V-
PGP t--- 5 X+ R- tv-- b DI- D- G e-- h! r y+



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Re[2]: kernel oops, fast ethernet bridge, 2.4.31
  2005-07-20 20:33   ` Re[2]: " Lukasz Spaleniak
@ 2005-07-22 15:13     ` Joy Leima
  2005-07-28 11:03       ` Lukasz Spaleniak
  0 siblings, 1 reply; 6+ messages in thread
From: Joy Leima @ 2005-07-22 15:13 UTC (permalink / raw)
  To: linux-kernel

Lukasz Spaleniak <lspaleniak <at> wroc.zigzag.pl> writes:

> 
> On Wednesday, July 20, 2005, 9:44:57 PM, Willy Tarreau wrote:
 > changed. At least it should have been oopsing from day one.
> It is strange to me too. There is no dependency when it happens.
> Sometimes traffic is small, sometimes it's normal. Packet rates are
> around ~2000-3000 pkt/sec - so not so high.
> 
> Regards,
> Lukasz
> 
Lukasz,

I think I have a fix for you.  Verify for me that it is the same problem.  Send
a large UDP packet through the bridge.  I believe the problem is the ip_fragment
code is not taking into account the VLAN header that needs to be added to the
packet when it gets fragmented on the way out.   

Just send the large UDP packet through the bridge.  I use ttcp.  If it panics
then I can send you the fix.  There are further changed to ip_output.c



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Re[2]: kernel oops, fast ethernet bridge, 2.4.31
  2005-07-22 15:13     ` Joy Leima
@ 2005-07-28 11:03       ` Lukasz Spaleniak
  0 siblings, 0 replies; 6+ messages in thread
From: Lukasz Spaleniak @ 2005-07-28 11:03 UTC (permalink / raw)
  To: Joy Leima; +Cc: linux-kernel

On Fri, 22 Jul 2005 15:13:33 +0000 (UTC)
Joy Leima <jleima@comcast.net> wrote:

> Lukasz,
> 
> I think I have a fix for you.  Verify for me that it is the same
> problem.  Send a large UDP packet through the bridge.  I believe the
> problem is the ip_fragment code is not taking into account the VLAN
> header that needs to be added to the packet when it gets fragmented
> on the way out.   
> 
> Just send the large UDP packet through the bridge.  I use ttcp.  If
> it panics then I can send you the fix.  There are further changed to
> ip_output.c

Hello Joy,

This is exactly this situation which you described.
Could you be so kind to send me this patch ?

Best regards,
Lukasz Spaleniak

-- 
lspaleniak on wroc zigzag pl
GCM dpu s: a--- C++ UL++++ P+ L+++ E--- W+ N+ K- w O- M V-
PGP t--- 5 X+ R- tv-- b DI- D- G e-- h! r y+

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Re[2]: kernel oops, fast ethernet bridge, 2.4.31
@ 2005-07-28 14:19 jleima
  0 siblings, 0 replies; 6+ messages in thread
From: jleima @ 2005-07-28 14:19 UTC (permalink / raw)
  To: Lukasz Spaleniak; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2086 bytes --]

I have included a patch that adds Cisco ISL support to the ethernet bridge code.  When I first debugged it I had to make changes to ip_output.c and netfilter_bridge.h to leave room for the ISL header.  The changes to ip_output.c I got from looking at the 2.6 changes and tweeking them a bit.   The same problem I had w/ large UDP packets are going to happen to you as we need to reserve space for the extra bytes that the VLAN uses when fragmenting the UDP packet that is being forwarded.

I think if you take the ip_output.c diffs, along with the nf_bridge_pad()  from netfilter_bridge.h you should be fine.  nf_bridge_tail() is only needed for ISL as it has an extra checksum at the end of the packet.    That can be removed for VLAN only

I have attached the patch,  patch.isl is the patch that I have running w/ ISL support and is working for me.  fix.vlan is just the code I think you need to add.  It wasn't generated by diff so you will need to hand edit it.

If you have questions let me know.  If it fixes your problem, we need to submit it to the ebtables person that is maintaining the 2.4.31 tree as it needs to be released from them.  These changes are in 2.6 already.  

- joy leima - 


> On Fri, 22 Jul 2005 15:13:33 +0000 (UTC)
> Joy Leima <jleima@comcast.net> wrote:
> 
> > Lukasz,
> > 
> > I think I have a fix for you.  Verify for me that it is the same
> > problem.  Send a large UDP packet through the bridge.  I believe the
> > problem is the ip_fragment code is not taking into account the VLAN
> > header that needs to be added to the packet when it gets fragmented
> > on the way out.   
> > 
> > Just send the large UDP packet through the bridge.  I use ttcp.  If
> > it panics then I can send you the fix.  There are further changed to
> > ip_output.c
> 
> Hello Joy,
> 
> This is exactly this situation which you described.
> Could you be so kind to send me this patch ?
> 
> Best regards,
> Lukasz Spaleniak
> 
> -- 
> lspaleniak on wroc zigzag pl
> GCM dpu s: a--- C++ UL++++ P+ L+++ E--- W+ N+ K- w O- M V-
> PGP t--- 5 X+ R- tv-- b DI- D- G e-- h! r y+

[-- Attachment #2: patch.isl --]
[-- Type: application/octet-stream, Size: 18598 bytes --]

diff -ru /usr/src/linux-2.4.31/drivers/net/e100/e100.h /home/joy/svn/trunk/kernel/source/drivers/net/e100/e100.h
--- /usr/src/linux-2.4.31/drivers/net/e100/e100.h	2004-11-17 06:54:21.000000000 -0500
+++ /home/joy/svn/trunk/kernel/source/drivers/net/e100/e100.h	2005-07-27 16:34:44.000000000 -0400
@@ -463,7 +463,7 @@
 #define TCPUDP_CHECKSUM_VALID		BIT_5
 #define CHECKSUM_PROTOCOL_MASK		0x03
 
-#define VLAN_SIZE   4
+#define VLAN_SIZE   30
 #define CHKSUM_SIZE 2
 #define RFD_DATA_SIZE (ETH_FRAME_LEN + CHKSUM_SIZE + VLAN_SIZE)
 
diff -ru /usr/src/linux-2.4.31/include/linux/netfilter_bridge.h /home/joy/svn/trunk/kernel/source/include/linux/netfilter_bridge.h
--- /usr/src/linux-2.4.31/include/linux/netfilter_bridge.h	2005-07-28 09:13:55.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/include/linux/netfilter_bridge.h	2005-07-22 14:54:16.000000000 -0400
@@ -33,6 +33,9 @@
 #define BRNF_DONT_TAKE_PARENT		0x04
 #define BRNF_BRIDGED			0x08
 #define BRNF_NF_BRIDGE_PREROUTING	0x10
+#define BRNF_ISL_CRC                    0x40
+#define BRNF_ISL_PKT                    0x80
+
 
 enum nf_br_hook_priorities {
 	NF_BR_PRI_FIRST = INT_MIN,
@@ -45,6 +48,27 @@
 	NF_BR_PRI_LAST = INT_MAX,
 };
 
+#define ISL_HLEN 26
+#define IS_ISL_IP(skb) (((skb->mac.ethernet) && \
+        (skb->mac.ethernet->h_dest[0] == 0x01) && \
+        (skb->mac.ethernet->h_dest[1] == 0x00) && \
+        (skb->mac.ethernet->h_dest[2] == 0x0c) && \
+        (skb->mac.ethernet->h_dest[3] == 0x00) && \
+        (skb->mac.ethernet->h_dest[4] == 0x00) && \
+        (((struct ethhdr *) ((unsigned char *) skb->mac.raw + ISL_HLEN))->h_proto == __constant_htons(ETH_P_IP))))
+#define IS_ISL_FRAME(skb) ((skb->nf_bridge && skb->nf_bridge->mask & BRNF_ISL_PKT))
+
+#define ISL_CRC(skb) ((skb->nf_bridge && skb->nf_bridge->mask & BRNF_ISL_CRC))
+                                                                                
+#define IS_ISL_ETH(ethernet) ((ethernet) && \
+        (ethernet->h_dest[0] == 0x01) && \
+        (ethernet->h_dest[1] == 0x00) && \
+        (ethernet->h_dest[2] == 0x0c) && \
+        (ethernet->h_dest[3] == 0x00) && \
+        (ethernet->h_dest[4] == 0x00) && \
+        (((struct ethhdr *) ((unsigned char *) ethernet + ISL_HLEN))->h_proto == __constant_htons(ETH_P_IP)))
+                                                                                
+
 #ifdef CONFIG_NETFILTER
 static inline
 struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
@@ -71,7 +95,15 @@
 		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
 			memcpy(skb->data - 18, skb->nf_bridge->data, 18);
 			skb_push(skb, 4);
-		} else
+		}
+                else if (IS_ISL_ETH(((struct ethhdr *)skb->nf_bridge->data))) {
+                       memcpy(skb->data - 40, skb->nf_bridge->data, 40);
+                       skb_push(skb, ISL_HLEN);
+                                                                                
+                        // Save space for the checksum at the end
+                       skb_put(skb, 4);
+                } 
+		else
 			memcpy(skb->data - 16, skb->nf_bridge->data, 16);
 	}
 }
@@ -83,9 +115,38 @@
 
 	if (skb->protocol == __constant_htons(ETH_P_8021Q))
 		header_size = 18;
+	else if (IS_ISL_IP(skb))
+		header_size = 40;
+
 	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->nf_bridge) {
+                if (skb->protocol == __constant_htons(ETH_P_8021Q))
+                        return 4;
+                else if (IS_ISL_ETH(((struct ethhdr *)skb->nf_bridge->data)))
+                        return ISL_HLEN;
+        }
+        return 0;
+}
+
+/* This is called by the IP fragmenting code and it ensures there is
+ * enough room for the ISL checksum - if there is one */
+static inline
+int nf_bridge_tail(struct sk_buff *skb)
+{
+        if (skb->nf_bridge) {
+                if (IS_ISL_ETH(((struct ethhdr *)skb->nf_bridge->data)))
+                    return 4;
+        }
+        return 0;
+}
+
 struct bridge_skb_cb {
 	union {
 		__u32 ipv4;
diff -ru /usr/src/linux-2.4.31/include/linux/skbuff.h /home/joy/svn/trunk/kernel/source/include/linux/skbuff.h
--- /usr/src/linux-2.4.31/include/linux/skbuff.h	2005-07-28 09:13:56.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/include/linux/skbuff.h	2005-07-22 14:34:46.000000000 -0400
@@ -102,7 +102,7 @@
 	struct net_device *netoutdev;
 #endif
 	unsigned int mask;
-	unsigned long data[32 / sizeof(unsigned long)];
+	unsigned long data[48 / sizeof(unsigned long)];
 };
 #endif
 
diff -ru /usr/src/linux-2.4.31/net/bridge/br_forward.c /home/joy/svn/trunk/kernel/source/net/bridge/br_forward.c
--- /usr/src/linux-2.4.31/net/bridge/br_forward.c	2005-07-28 09:13:55.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/net/bridge/br_forward.c	2005-07-22 14:54:16.000000000 -0400
@@ -20,6 +20,131 @@
 #include <linux/if_bridge.h>
 #include <linux/netfilter_bridge.h>
 #include "br_private.h"
+#include <linux/ip.h>
+
+struct islhdr {
+        unsigned char daddr[5];
+        __u8 typ:4,
+            user:4;
+        unsigned char saddr[6];
+        __u16 len;
+        unsigned char aaaa[3];
+        unsigned char hsa[3];
+        __u16 vlan:15,
+              bpdu:1;
+        __u16 index;
+        __u16 res;
+};
+
+/*
+ * Table for the AUTODIN/HDLC/802.x CRC.
+ *
+ * Polynomial is
+ *
+ *	x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^8 + x^7 +
+ *	    x^5 + x^4 + x^2 + x + 1
+ */
+static const __u32 crc32_table[256] = {
+        0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+        0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+        0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+        0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+        0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+        0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+        0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+        0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+        0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+        0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+        0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+        0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+        0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+        0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+        0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+        0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+        0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+        0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+        0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+        0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+        0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+        0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+        0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+        0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+        0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+        0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+        0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+        0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+        0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+        0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+        0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+        0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+        0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+        0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+        0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+        0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+        0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+        0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+        0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+        0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+        0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+        0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+        0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+        0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+        0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+        0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+        0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+        0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+        0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+        0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+        0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+        0x2d02ef8d
+};
+
+inline static uint32_t
+crc32(unsigned char *buf, unsigned int len)
+{
+  unsigned int i;
+  __u32 crc32 = 0xFFFFFFFF;
+
+  for (i = 0; i < len; i++)
+    crc32 = crc32_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
+
+  return ( ~crc32 );
+}
+
+/*
+ * IEEE 802.x version (Ethernet and 802.11, at least) - byte-swap
+ * the result of "crc32()".
+ */
+
+inline static __u32
+crc32_802(unsigned char *buf, unsigned int len)
+{
+  __u32 c_crc;
+
+  c_crc = crc32(buf, len);
+
+  /* Byte reverse. */
+  c_crc = ((unsigned char)(c_crc>>0)<<24) |
+    ((unsigned char)(c_crc>>8)<<16) |
+    ((unsigned char)(c_crc>>16)<<8) |
+    ((unsigned char)(c_crc>>24)<<0);
+
+  return ( c_crc );
+}
+
+/*
+ * Calculate the FCS at the end of an ISL frame
+ * The calculation is done from the start of the encapsulated frame.
+ */
+void
+calc_ISL_frame(const struct sk_buff *skb) 
+{
+	struct islhdr *isl = (struct islhdr *) skb->mac.raw;
+        __u32 *fcs = (__u32 *) (skb->mac.raw + skb->len - 4); 
+
+	*fcs = htonl(crc32_802(((unsigned char *) isl + ISL_HLEN), 
+							ntohs(isl->len) - 16));
+}
 
 static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb)
 {
@@ -32,10 +157,28 @@
 
 int br_dev_queue_push_xmit(struct sk_buff *skb)
 {
+        struct islhdr *isl;
 #ifdef CONFIG_NETFILTER
 	nf_bridge_maybe_copy_header(skb);
 #endif
 	skb_push(skb, ETH_HLEN);
+#ifdef CONFIG_NETFILTER
+        skb->mac.raw = skb->data;
+        if (skb->nf_bridge) {
+           if (IS_ISL_IP(skb)) {
+              int my_mac_len = skb->len - ISL_HLEN -4;
+              if (my_mac_len < 64) {
+                skb_put(skb, 64 - my_mac_len);
+                skb->nf_bridge->mask |= BRNF_ISL_CRC;
+              }
+              if (ISL_CRC(skb)) {
+                isl = (struct islhdr *) skb->mac.raw;
+                isl->len = htons(skb->len - 18 + 4);
+                calc_ISL_frame(skb);
+              }
+           }
+        }
+#endif
 	dev_queue_xmit(skb);
 
 	return 0;
diff -ru /usr/src/linux-2.4.31/net/bridge/br_netfilter.c /home/joy/svn/trunk/kernel/source/net/bridge/br_netfilter.c
--- /usr/src/linux-2.4.31/net/bridge/br_netfilter.c	2005-07-28 09:13:56.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/net/bridge/br_netfilter.c	2005-07-22 14:34:46.000000000 -0400
@@ -122,6 +122,11 @@
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
+	else if (IS_ISL_FRAME(skb)) {
+		skb->nf_bridge->mask |= BRNF_ISL_PKT;
+		skb_push(skb, ISL_HLEN);
+		skb->nh.raw -= ISL_HLEN;
+	}
 	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
 		       br_handle_frame_finish, 1);
 
@@ -202,6 +207,10 @@
 		skb_pull(skb, VLAN_HLEN);
 		skb->nh.raw += VLAN_HLEN;
 	}
+	else if (IS_ISL_FRAME(skb)) {
+		skb_pull(skb, ISL_HLEN);
+		skb->nh.raw += ISL_HLEN;
+	}
 	skb->dst->output(skb);
 	return 0;
 }
@@ -253,6 +262,12 @@
 					skb_push(skb, VLAN_HLEN);
 					skb->nh.raw -= VLAN_HLEN;
 				}
+				else if (IS_ISL_IP(skb)) {
+					skb->nf_bridge->mask |= BRNF_ISL_PKT;
+					skb_push(skb, ISL_HLEN);
+					skb->nh.raw -= ISL_HLEN;
+				}
+
 				NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING,
 					       skb, skb->dev, NULL,
 					       br_nf_pre_routing_finish_bridge,
@@ -273,6 +288,12 @@
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
+	else if (IS_ISL_FRAME(skb)) {
+		skb->nf_bridge->mask |= BRNF_ISL_PKT;
+		skb_push(skb, ISL_HLEN);
+		skb->nh.raw -= ISL_HLEN;
+	}
+
 	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
 		       br_handle_frame_finish, 1);
 
@@ -432,15 +453,18 @@
 			skb_pull(skb, VLAN_HLEN);
 			(skb)->nh.raw += VLAN_HLEN;
 		}
+		else if (IS_ISL_IP((*pskb))) {
+			skb_pull(skb, ISL_HLEN);
+			(skb)->nh.raw += ISL_HLEN;
+		}
 		return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
 	}
-
 #ifdef CONFIG_SYSCTL
 	if (!brnf_call_iptables)
 		return NF_ACCEPT;
 #endif
 
-	if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
+	if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP && !IS_ISL_IP((*pskb)))
 		return NF_ACCEPT;
 	if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
 		goto out;
@@ -449,6 +473,10 @@
 		skb_pull(skb, VLAN_HLEN);
 		(skb)->nh.raw += VLAN_HLEN;
 	}
+	else if (IS_ISL_IP((*pskb))) {
+		skb_pull(skb, ISL_HLEN);
+		(skb)->nh.raw += ISL_HLEN;
+	}
 
 	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
 		goto inhdr_error;
@@ -483,6 +511,9 @@
 	setup_pre_routing(skb);
 	store_orig_dstaddr(skb);
 
+	if (IS_ISL_IP(skb))
+		nf_bridge->mask |= BRNF_ISL_PKT;
+
 	NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,
 		br_nf_pre_routing_finish);
 
@@ -541,6 +572,10 @@
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
+	else if (IS_ISL_FRAME(skb)) {
+		skb_push(skb, ISL_HLEN);
+		skb->nh.raw -= ISL_HLEN;
+	}
 	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
 			skb->dev, br_forward_finish, 1);
 	return 0;
@@ -564,7 +599,7 @@
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
+	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP || IS_ISL_IP((*pskb)))
 		pf = PF_INET;
 	else
 		pf = PF_INET6;
@@ -573,6 +608,10 @@
 		skb_pull(*pskb, VLAN_HLEN);
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
+	else if (IS_ISL_IP((*pskb))) {
+		skb_pull(*pskb, ISL_HLEN);
+		(*pskb)->nh.raw += ISL_HLEN;
+	}
 
 #ifdef CONFIG_NETFILTER_DEBUG
 	skb->nf_debug ^= (1 << NF_BR_FORWARD);
@@ -641,6 +680,10 @@
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
+	else if (IS_ISL_FRAME(skb)) {
+		skb_push(skb, ISL_HLEN);
+		skb->nh.raw -= ISL_HLEN;
+	}
 
 	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
 			br_forward_finish, NF_BR_PRI_FIRST + 1);
@@ -684,7 +727,7 @@
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
+	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP || IS_ISL_IP((*pskb)))
 		pf = PF_INET;
 	else
 		pf = PF_INET6;
@@ -715,6 +758,10 @@
 			skb_push(skb, VLAN_HLEN);
 			skb->nh.raw -= VLAN_HLEN;
 		}
+		else if (IS_ISL_IP(skb)) {
+			skb_push(skb, ISL_HLEN);
+			skb->nh.raw -= ISL_HLEN;
+		}
 
 		NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev,
 			skb->dev, br_forward_finish);
@@ -727,10 +774,18 @@
 	if (nf_bridge->netoutdev)
 		realoutdev = nf_bridge->netoutdev;
 #endif
+	if (nf_bridge->netoutdev && IS_ISL_IP((skb)))
+		realoutdev = nf_bridge->netoutdev;
+
 	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
 		skb_pull(skb, VLAN_HLEN);
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
+	else if (IS_ISL_IP(skb)) {
+		skb->nf_bridge->mask |= BRNF_ISL_PKT;
+		skb_pull(skb, ISL_HLEN);
+		(*pskb)->nh.raw += ISL_HLEN;
+	}
 	/* IP forwarded traffic has a physindev, locally
 	 * generated traffic hasn't.
 	 */
@@ -780,7 +835,7 @@
 	if (!nf_bridge)
 		return NF_ACCEPT;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
+	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP || IS_ISL_IP(skb))
 		pf = PF_INET;
 	else
 		pf = PF_INET6;
@@ -816,6 +871,10 @@
 		skb_pull(skb, VLAN_HLEN);
 		skb->nh.raw += VLAN_HLEN;
 	}
+	else if (IS_ISL_FRAME(skb)) {
+		skb_pull(skb, ISL_HLEN);
+		skb->nh.raw += ISL_HLEN;
+	}
 
 	nf_bridge_save_header(skb);
 
@@ -823,6 +882,9 @@
 	if (nf_bridge->netoutdev)
 		realoutdev = nf_bridge->netoutdev;
 #endif
+	if (nf_bridge->netoutdev && IS_ISL_FRAME(skb))
+		realoutdev = nf_bridge->netoutdev;
+
 	NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL,
 		realoutdev, br_dev_queue_push_xmit);
 
diff -ru /usr/src/linux-2.4.31/net/ipv4/ip_output.c /home/joy/svn/trunk/kernel/source/net/ipv4/ip_output.c
--- /usr/src/linux-2.4.31/net/ipv4/ip_output.c	2005-07-28 09:13:56.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/net/ipv4/ip_output.c	2005-07-22 14:54:16.000000000 -0400
@@ -77,6 +77,7 @@
 #include <linux/netfilter_ipv4.h>
 #include <linux/mroute.h>
 #include <linux/netlink.h>
+#include <linux/netfilter_bridge.h>
 
 /*
  *      Shall we try to damage output packets if routing dev changes?
@@ -769,6 +770,7 @@
 	int not_last_frag;
 	struct rtable *rt = (struct rtable*)skb->dst;
 	int err = 0;
+        unsigned int ll_rs = 0, ll_end = 0;
 
 	dev = rt->u.dst.dev;
 
@@ -785,6 +787,11 @@
 	hlen = iph->ihl * 4;
 	left = skb->len - hlen;		/* Space per frame */
 	mtu = rt->u.dst.pmtu - hlen;	/* Size of data space */
+#ifdef CONFIG_NETFILTER
+	ll_rs = nf_bridge_pad(skb);
+	ll_end = nf_bridge_tail(skb);
+	mtu -= ll_rs - ll_end;
+#endif
 	ptr = raw + hlen;		/* Where to start from */
 
 	/*
@@ -794,6 +801,9 @@
 	offset = (ntohs(iph->frag_off) & IP_OFFSET) << 3;
 	not_last_frag = iph->frag_off & htons(IP_MF);
 
+	if (skb->nf_bridge)
+		skb->nf_bridge->mask |= BRNF_ISL_CRC;
+
 	/*
 	 *	Keep copying data until we run out.
 	 */
@@ -812,7 +822,7 @@
 		 *	Allocate buffer.
 		 */
 
-		if ((skb2 = alloc_skb(len+hlen+dev->hard_header_len+15,GFP_ATOMIC)) == NULL) {
+		if ((skb2 = alloc_skb(len+hlen+dev->hard_header_len+15+ll_rs+ll_end,GFP_ATOMIC)) == NULL) {
 			NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
 			err = -ENOMEM;
 			goto fail;
@@ -824,7 +834,7 @@
 
 		skb2->pkt_type = skb->pkt_type;
 		skb2->priority = skb->priority;
-		skb_reserve(skb2, (dev->hard_header_len+15)&~15);
+		skb_reserve(skb2, (dev->hard_header_len+15+ll_rs)&~15);
 		skb_put(skb2, len + hlen);
 		skb2->nh.raw = skb2->data;
 		skb2->h.raw = skb2->data + hlen;
Only in /home/joy/svn/trunk/kernel/source: patch.out

[-- Attachment #3: fix.vlan --]
[-- Type: application/octet-stream, Size: 2225 bytes --]

diff -ru /usr/src/linux-2.4.31/include/linux/netfilter_bridge.h /home/joy/svn/trunk/kernel/source/include/linux/netfilter_bridge.h
--- /usr/src/linux-2.4.31/include/linux/netfilter_bridge.h	2005-07-28 09:13:55.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/include/linux/netfilter_bridge.h	2005-07-22 14:54:16.000000000 -0400
+/* 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->nf_bridge) {
+                if (skb->protocol == __constant_htons(ETH_P_8021Q))
+                        return 4;
+        }
+        return 0;
+}
diff -ru /usr/src/linux-2.4.31/net/ipv4/ip_output.c /home/joy/svn/trunk/kernel/source/net/ipv4/ip_output.c
--- /usr/src/linux-2.4.31/net/ipv4/ip_output.c	2005-07-28 09:13:56.000000000 -0400
+++ /home/joy/svn/trunk/kernel/source/net/ipv4/ip_output.c	2005-07-22 14:54:16.000000000 -0400
@@ -77,6 +77,7 @@
 #include <linux/netfilter_ipv4.h>
 #include <linux/mroute.h>
 #include <linux/netlink.h>
+#include <linux/netfilter_bridge.h>
 
 /*
  *      Shall we try to damage output packets if routing dev changes?
@@ -769,6 +770,7 @@
 	int not_last_frag;
 	struct rtable *rt = (struct rtable*)skb->dst;
 	int err = 0;
+        unsigned int ll_rs = 0;
 
 	dev = rt->u.dst.dev;
 
@@ -785,6 +787,11 @@
 	hlen = iph->ihl * 4;
 	left = skb->len - hlen;		/* Space per frame */
 	mtu = rt->u.dst.pmtu - hlen;	/* Size of data space */
+#ifdef CONFIG_NETFILTER
+	ll_rs = nf_bridge_pad(skb);
+	mtu -= ll_rs;
+#endif
 	ptr = raw + hlen;		/* Where to start from */
 
 
-		if ((skb2 = alloc_skb(len+hlen+dev->hard_header_len+15,GFP_ATOMIC)) == NULL) {
+		if ((skb2 = alloc_skb(len+hlen+dev->hard_header_len+15+ll_rs,GFP_ATOMIC)) == NULL) {
 			NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
 			err = -ENOMEM;
 			goto fail;
@@ -824,7 +834,7 @@
 
 		skb2->pkt_type = skb->pkt_type;
 		skb2->priority = skb->priority;
-		skb_reserve(skb2, (dev->hard_header_len+15)&~15);
+		skb_reserve(skb2, (dev->hard_header_len+15+ll_rs)&~15);
 		skb_put(skb2, len + hlen);
 		skb2->nh.raw = skb2->data;
 		skb2->h.raw = skb2->data + hlen;

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-07-28 14:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-20 15:00 kernel oops, fast ethernet bridge, 2.4.31 Lukasz Spaleniak
2005-07-20 19:44 ` Willy Tarreau
2005-07-20 20:33   ` Re[2]: " Lukasz Spaleniak
2005-07-22 15:13     ` Joy Leima
2005-07-28 11:03       ` Lukasz Spaleniak
2005-07-28 14:19 jleima

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®