Vlan patch for large UDP packets

[email protected]
Newsgroups gmane.linux.network.bridge.ebtables.devel
Message-ID <081620051253.29796.4301E1E1000B1E200000746422070215530E03070A0406@comcast.net>
If you send a large UDP packet through a bridge that is running over a VLAN, the kernel will panic.  The attached patch will fix the problem.  This fix was back ported from a working 2.6 kernel.  Basically the fragments that are created in ip_fragment() need to leave room in the refragmented packets for the VLAN data.    This patch applies to the 2.4.31 kernel.

- Joy Leima -
vlan.patch (application/octet-stream, 2.1 KB)
--- /usr/src/not_correct/linux-2.4.31/include/linux/netfilter_bridge.h	2005-08-16 09:10:04.000000000 +0200
+++ /usr/src/linux-2.4.31/include/linux/netfilter_bridge.h	2005-08-01 09:40:01.000000000 +0200
@@ -91,6 +91,19 @@
 		__u32 ipv4;
 	} daddr;
 };
+
+
+/* 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;
+}
 #endif /* CONFIG_NETFILTER */
 
 #endif /* __KERNEL__ */
--- /usr/src/not_correct/linux-2.4.31/net/ipv4/ip_output.c	2005-08-16 09:10:04.000000000 +0200
+++ /usr/src/linux-2.4.31/net/ipv4/ip_output.c	2005-08-01 09:43:32.000000000 +0200
@@ -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,7 +770,8 @@
 	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,10 @@
 	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 */
 
 	/*
@@ -812,7 +818,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,GFP_ATOMIC)) == NULL) {
 			NETDEBUG(printk(KERN_INFO "IP: frag: no memory for new fragment!\n"));
 			err = -ENOMEM;
 			goto fail;
@@ -824,7 +830,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;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.