summaryrefslogtreecommitdiffstats
path: root/net/ipv6/xfrm6_output.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-12-20 13:24:14 -0800
committerDavid S. Miller <davem@davemloft.net>2010-12-20 13:24:14 -0800
commitd9993be65a77f500ae926176baa264816bfe3816 (patch)
treebbb8c86114bf86e5ca3d1fbf89de3d98be5519ba /net/ipv6/xfrm6_output.c
parentc4266263249f22479eb1abb1a1709c38240b1597 (diff)
parentaa3e219997e4b949be4199660936099ded0b401f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net/ipv6/xfrm6_output.c')
-rw-r--r--net/ipv6/xfrm6_output.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6434bd5ce08..8e688b3de9a 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -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,21 @@ static int xfrm6_output_finish(struct sk_buff *skb)
return xfrm_output(skb);
}
+static int __xfrm6_output(struct sk_buff *skb)
+{
+ struct dst_entry *dst = skb_dst(skb);
+ struct xfrm_state *x = dst->xfrm;
+
+ if ((x && x->props.mode == XFRM_MODE_TUNNEL) &&
+ ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
+ dst_allfrag(skb_dst(skb)))) {
+ return ip6_fragment(skb, xfrm6_output_finish);
+ }
+ return xfrm6_output_finish(skb);
+}
+
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);
+ skb_dst(skb)->dev, __xfrm6_output);
}