diff options
Diffstat (limited to 'net/ipv6/xfrm6_output.c')
| -rw-r--r-- | net/ipv6/xfrm6_output.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 19ef329bdbf8..b930d080c66f 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
| @@ -114,12 +114,6 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 114 | if (err) | 114 | if (err) |
| 115 | return err; | 115 | return err; |
| 116 | 116 | ||
| 117 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||
| 118 | #ifdef CONFIG_NETFILTER | ||
| 119 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | ||
| 120 | #endif | ||
| 121 | |||
| 122 | skb->protocol = htons(ETH_P_IPV6); | ||
| 123 | skb->local_df = 1; | 117 | skb->local_df = 1; |
| 124 | 118 | ||
| 125 | return x->outer_mode->output2(x, skb); | 119 | return x->outer_mode->output2(x, skb); |
| @@ -128,11 +122,13 @@ EXPORT_SYMBOL(xfrm6_prepare_output); | |||
| 128 | 122 | ||
| 129 | int xfrm6_output_finish(struct sk_buff *skb) | 123 | int xfrm6_output_finish(struct sk_buff *skb) |
| 130 | { | 124 | { |
| 125 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | ||
| 126 | skb->protocol = htons(ETH_P_IPV6); | ||
| 127 | |||
| 131 | #ifdef CONFIG_NETFILTER | 128 | #ifdef CONFIG_NETFILTER |
| 132 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | 129 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; |
| 133 | #endif | 130 | #endif |
| 134 | 131 | ||
| 135 | skb->protocol = htons(ETH_P_IPV6); | ||
| 136 | return xfrm_output(skb); | 132 | return xfrm_output(skb); |
| 137 | } | 133 | } |
| 138 | 134 | ||
| @@ -142,6 +138,13 @@ static int __xfrm6_output(struct sk_buff *skb) | |||
| 142 | struct xfrm_state *x = dst->xfrm; | 138 | struct xfrm_state *x = dst->xfrm; |
| 143 | int mtu; | 139 | int mtu; |
| 144 | 140 | ||
| 141 | #ifdef CONFIG_NETFILTER | ||
| 142 | if (!x) { | ||
| 143 | IP6CB(skb)->flags |= IP6SKB_REROUTED; | ||
| 144 | return dst_output(skb); | ||
| 145 | } | ||
| 146 | #endif | ||
| 147 | |||
| 145 | if (skb->protocol == htons(ETH_P_IPV6)) | 148 | if (skb->protocol == htons(ETH_P_IPV6)) |
| 146 | mtu = ip6_skb_dst_mtu(skb); | 149 | mtu = ip6_skb_dst_mtu(skb); |
| 147 | else | 150 | else |
| @@ -165,6 +168,7 @@ static int __xfrm6_output(struct sk_buff *skb) | |||
| 165 | 168 | ||
| 166 | int xfrm6_output(struct sock *sk, struct sk_buff *skb) | 169 | int xfrm6_output(struct sock *sk, struct sk_buff *skb) |
| 167 | { | 170 | { |
| 168 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, | 171 | return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, |
| 169 | skb_dst(skb)->dev, __xfrm6_output); | 172 | NULL, skb_dst(skb)->dev, __xfrm6_output, |
| 173 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); | ||
| 170 | } | 174 | } |
