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 #include #include +#include /* * 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;