|
@@ -17,6 +17,7 @@
|
|
#include <linux/netfilter_ipv6.h>
|
|
#include <linux/netfilter_ipv6.h>
|
|
#include <net/dst.h>
|
|
#include <net/dst.h>
|
|
#include <net/ipv6.h>
|
|
#include <net/ipv6.h>
|
|
|
|
+#include <net/ip6_route.h>
|
|
#include <net/xfrm.h>
|
|
#include <net/xfrm.h>
|
|
|
|
|
|
int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
|
|
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);
|
|
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)
|
|
int xfrm6_output(struct sk_buff *skb)
|
|
{
|
|
{
|
|
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
|
|
return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL,
|
|
- skb_dst(skb)->dev, xfrm6_output_finish);
|
|
|
|
|
|
+ skb_dst(skb)->dev, __xfrm6_output);
|
|
}
|
|
}
|