Patchwork fragment locally-generated IPsec6 packets that need it

login
register
mail settings
Submitter David Stevens
Date Dec. 13, 2010, 8:19 p.m.
Message ID <1292271571.8593.9.camel@w-dls.beaverton.ibm.com>
Download mbox | patch
Permalink /patch/75400/
State Superseded
Delegated to: David Miller
Headers show

Comments

David Stevens - Dec. 13, 2010, 8:19 p.m.
This patch modifies IPsec6 to fragment IPv6 packets that are
locally generated as needed.

Signed-off-by: David L Stevens <dlstevens@us.ibm.com>



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Herbert Xu - Dec. 14, 2010, 1:09 a.m.
On Mon, Dec 13, 2010 at 12:19:31PM -0800, David L Stevens wrote:
> This patch modifies IPsec6 to fragment IPv6 packets that are
> locally generated as needed.
> 
> Signed-off-by: David L Stevens <dlstevens@us.ibm.com>

Thanks for the patch!

> +EXPORT_SYMBOL_GPL(ip6_fragment);

There is no need to export this as xfrm6_output.c is always part
of ipv6.o.

Cheers,
David Stevens - Dec. 14, 2010, 5:56 p.m.
Herbert Xu <herbert@gondor.apana.org.au> wrote on 12/13/2010 05:09:29 PM:

> > +EXPORT_SYMBOL_GPL(ip6_fragment);
> 
> There is no need to export this as xfrm6_output.c is always part
> of ipv6.o.

Herbert, thanks! I'll remove it and repost.

                                        +-DLS

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff -ruNp linux-2.6.36-rc8/include/net/ip6_route.h linux-2.6.36-rc8DLS/include/net/ip6_route.h
--- linux-2.6.36-rc8/include/net/ip6_route.h	2010-10-14 16:26:43.000000000 -0700
+++ linux-2.6.36-rc8DLS/include/net/ip6_route.h	2010-12-12 09:22:48.582141401 -0800
@@ -164,5 +164,15 @@  static inline int ipv6_unicast_destinati
 	return rt->rt6i_flags & RTF_LOCAL;
 }
 
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+
+static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
+{
+	struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
+
+	return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
+	       skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
+}
+
 #endif
 #endif
diff -ruNp linux-2.6.36-rc8/net/ipv6/ip6_output.c linux-2.6.36-rc8DLS/net/ipv6/ip6_output.c
--- linux-2.6.36-rc8/net/ipv6/ip6_output.c	2010-10-14 16:26:43.000000000 -0700
+++ linux-2.6.36-rc8DLS/net/ipv6/ip6_output.c	2010-12-12 09:24:25.377740025 -0800
@@ -56,7 +56,7 @@ 
 #include <net/checksum.h>
 #include <linux/mroute6.h>
 
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
 
 int __ip6_local_out(struct sk_buff *skb)
 {
@@ -145,14 +145,6 @@  static int ip6_finish_output2(struct sk_
 	return -EINVAL;
 }
 
-static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
-{
-	struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
-
-	return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
-	       skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
-}
-
 static int ip6_finish_output(struct sk_buff *skb)
 {
 	if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
@@ -601,7 +593,7 @@  int ip6_find_1stfragopt(struct sk_buff *
 	return offset;
 }
 
-static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
+int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 {
 	struct sk_buff *frag;
 	struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
@@ -874,6 +866,8 @@  fail:
 	return err;
 }
 
+EXPORT_SYMBOL_GPL(ip6_fragment);
+
 static inline int ip6_rt_check(struct rt6key *rt_key,
 			       struct in6_addr *fl_addr,
 			       struct in6_addr *addr_cache)
diff -ruNp linux-2.6.36-rc8/net/ipv6/xfrm6_output.c linux-2.6.36-rc8DLS/net/ipv6/xfrm6_output.c
--- linux-2.6.36-rc8/net/ipv6/xfrm6_output.c	2010-10-14 16:26:43.000000000 -0700
+++ linux-2.6.36-rc8DLS/net/ipv6/xfrm6_output.c	2010-12-12 09:30:21.019560623 -0800
@@ -17,6 +17,7 @@ 
 #include <linux/netfilter_ipv6.h>
 #include <net/dst.h>
 #include <net/ipv6.h>
+#include <net/ip6_route.h>
 #include <net/xfrm.h>
 
 int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
@@ -88,8 +89,17 @@  static int xfrm6_output_finish(struct sk
 	return xfrm_output(skb);
 }
 
-int xfrm6_output(struct sk_buff *skb)
+static int __xfrm6_output(struct sk_buff *skb)
 {
 	return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
 		       skb_dst(skb)->dev, xfrm6_output_finish);
 }
+
+int xfrm6_output(struct sk_buff *skb)
+{
+	if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
+		dst_allfrag(skb_dst(skb))) {
+			return ip6_fragment(skb, __xfrm6_output);
+	}
+	return __xfrm6_output(skb);
+}