diff options
author | David Miller <davem@davemloft.net> | 2015-04-05 22:19:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-07 15:25:55 -0400 |
commit | 7026b1ddb6b8d4e6ee33dc2bd06c0ca8746fa7ab (patch) | |
tree | 3e11ed0f186ea6066a3f7efecb88d85bc732ee51 /net/ipv4 | |
parent | 1c984f8a5df085bcf35364a8a870bd4db4da4ed3 (diff) |
netfilter: Pass socket pointer down through okfn().
On the output paths in particular, we have to sometimes deal with two
socket contexts. First, and usually skb->sk, is the local socket that
generated the frame.
And second, is potentially the socket used to control a tunneling
socket, such as one the encapsulates using UDP.
We do not want to disassociate skb->sk when encapsulating in order
to fix this, because that would break socket memory accounting.
The most extreme case where this can cause huge problems is an
AF_PACKET socket transmitting over a vxlan device. We hit code
paths doing checks that assume they are dealing with an ipv4
socket, but are actually operating upon the AF_PACKET one.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/arp.c | 10 | ||||
-rw-r--r-- | net/ipv4/ip_forward.c | 8 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 10 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 45 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 7 | ||||
-rw-r--r-- | net/ipv4/raw.c | 4 | ||||
-rw-r--r-- | net/ipv4/xfrm4_input.c | 5 | ||||
-rw-r--r-- | net/ipv4/xfrm4_output.c | 12 |
8 files changed, 57 insertions, 44 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c6e67aa46c32..933a92820d26 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -591,7 +591,8 @@ EXPORT_SYMBOL(arp_create); | |||
591 | void arp_xmit(struct sk_buff *skb) | 591 | void arp_xmit(struct sk_buff *skb) |
592 | { | 592 | { |
593 | /* Send it off, maybe filter it using firewalling first. */ | 593 | /* Send it off, maybe filter it using firewalling first. */ |
594 | NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit); | 594 | NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, NULL, skb, |
595 | NULL, skb->dev, dev_queue_xmit_sk); | ||
595 | } | 596 | } |
596 | EXPORT_SYMBOL(arp_xmit); | 597 | EXPORT_SYMBOL(arp_xmit); |
597 | 598 | ||
@@ -625,7 +626,7 @@ EXPORT_SYMBOL(arp_send); | |||
625 | * Process an arp request. | 626 | * Process an arp request. |
626 | */ | 627 | */ |
627 | 628 | ||
628 | static int arp_process(struct sk_buff *skb) | 629 | static int arp_process(struct sock *sk, struct sk_buff *skb) |
629 | { | 630 | { |
630 | struct net_device *dev = skb->dev; | 631 | struct net_device *dev = skb->dev; |
631 | struct in_device *in_dev = __in_dev_get_rcu(dev); | 632 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
@@ -846,7 +847,7 @@ out: | |||
846 | 847 | ||
847 | static void parp_redo(struct sk_buff *skb) | 848 | static void parp_redo(struct sk_buff *skb) |
848 | { | 849 | { |
849 | arp_process(skb); | 850 | arp_process(NULL, skb); |
850 | } | 851 | } |
851 | 852 | ||
852 | 853 | ||
@@ -879,7 +880,8 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev, | |||
879 | 880 | ||
880 | memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); | 881 | memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); |
881 | 882 | ||
882 | return NF_HOOK(NFPROTO_ARP, NF_ARP_IN, skb, dev, NULL, arp_process); | 883 | return NF_HOOK(NFPROTO_ARP, NF_ARP_IN, NULL, skb, |
884 | dev, NULL, arp_process); | ||
883 | 885 | ||
884 | consumeskb: | 886 | consumeskb: |
885 | consume_skb(skb); | 887 | consume_skb(skb); |
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index d9bc28ac5d1b..939992c456f3 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
@@ -57,7 +57,7 @@ static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | 59 | ||
60 | static int ip_forward_finish(struct sk_buff *skb) | 60 | static int ip_forward_finish(struct sock *sk, struct sk_buff *skb) |
61 | { | 61 | { |
62 | struct ip_options *opt = &(IPCB(skb)->opt); | 62 | struct ip_options *opt = &(IPCB(skb)->opt); |
63 | 63 | ||
@@ -68,7 +68,7 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
68 | ip_forward_options(skb); | 68 | ip_forward_options(skb); |
69 | 69 | ||
70 | skb_sender_cpu_clear(skb); | 70 | skb_sender_cpu_clear(skb); |
71 | return dst_output(skb); | 71 | return dst_output_sk(sk, skb); |
72 | } | 72 | } |
73 | 73 | ||
74 | int ip_forward(struct sk_buff *skb) | 74 | int ip_forward(struct sk_buff *skb) |
@@ -136,8 +136,8 @@ int ip_forward(struct sk_buff *skb) | |||
136 | 136 | ||
137 | skb->priority = rt_tos2priority(iph->tos); | 137 | skb->priority = rt_tos2priority(iph->tos); |
138 | 138 | ||
139 | return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, | 139 | return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, NULL, skb, |
140 | rt->dst.dev, ip_forward_finish); | 140 | skb->dev, rt->dst.dev, ip_forward_finish); |
141 | 141 | ||
142 | sr_failed: | 142 | sr_failed: |
143 | /* | 143 | /* |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 2e0410ed8f16..2db4c8773c1b 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -187,7 +187,7 @@ bool ip_call_ra_chain(struct sk_buff *skb) | |||
187 | return false; | 187 | return false; |
188 | } | 188 | } |
189 | 189 | ||
190 | static int ip_local_deliver_finish(struct sk_buff *skb) | 190 | static int ip_local_deliver_finish(struct sock *sk, struct sk_buff *skb) |
191 | { | 191 | { |
192 | struct net *net = dev_net(skb->dev); | 192 | struct net *net = dev_net(skb->dev); |
193 | 193 | ||
@@ -253,7 +253,8 @@ int ip_local_deliver(struct sk_buff *skb) | |||
253 | return 0; | 253 | return 0; |
254 | } | 254 | } |
255 | 255 | ||
256 | return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, skb, skb->dev, NULL, | 256 | return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, NULL, skb, |
257 | skb->dev, NULL, | ||
257 | ip_local_deliver_finish); | 258 | ip_local_deliver_finish); |
258 | } | 259 | } |
259 | 260 | ||
@@ -309,7 +310,7 @@ drop: | |||
309 | int sysctl_ip_early_demux __read_mostly = 1; | 310 | int sysctl_ip_early_demux __read_mostly = 1; |
310 | EXPORT_SYMBOL(sysctl_ip_early_demux); | 311 | EXPORT_SYMBOL(sysctl_ip_early_demux); |
311 | 312 | ||
312 | static int ip_rcv_finish(struct sk_buff *skb) | 313 | static int ip_rcv_finish(struct sock *sk, struct sk_buff *skb) |
313 | { | 314 | { |
314 | const struct iphdr *iph = ip_hdr(skb); | 315 | const struct iphdr *iph = ip_hdr(skb); |
315 | struct rtable *rt; | 316 | struct rtable *rt; |
@@ -451,7 +452,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
451 | /* Must drop socket now because of tproxy. */ | 452 | /* Must drop socket now because of tproxy. */ |
452 | skb_orphan(skb); | 453 | skb_orphan(skb); |
453 | 454 | ||
454 | return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, dev, NULL, | 455 | return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, NULL, skb, |
456 | dev, NULL, | ||
455 | ip_rcv_finish); | 457 | ip_rcv_finish); |
456 | 458 | ||
457 | csum_error: | 459 | csum_error: |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 26f6f7956168..5da4d15262fd 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -91,14 +91,19 @@ void ip_send_check(struct iphdr *iph) | |||
91 | } | 91 | } |
92 | EXPORT_SYMBOL(ip_send_check); | 92 | EXPORT_SYMBOL(ip_send_check); |
93 | 93 | ||
94 | int __ip_local_out(struct sk_buff *skb) | 94 | int __ip_local_out_sk(struct sock *sk, struct sk_buff *skb) |
95 | { | 95 | { |
96 | struct iphdr *iph = ip_hdr(skb); | 96 | struct iphdr *iph = ip_hdr(skb); |
97 | 97 | ||
98 | iph->tot_len = htons(skb->len); | 98 | iph->tot_len = htons(skb->len); |
99 | ip_send_check(iph); | 99 | ip_send_check(iph); |
100 | return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL, | 100 | return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb, NULL, |
101 | skb_dst(skb)->dev, dst_output); | 101 | skb_dst(skb)->dev, dst_output_sk); |
102 | } | ||
103 | |||
104 | int __ip_local_out(struct sk_buff *skb) | ||
105 | { | ||
106 | return __ip_local_out_sk(skb->sk, skb); | ||
102 | } | 107 | } |
103 | 108 | ||
104 | int ip_local_out_sk(struct sock *sk, struct sk_buff *skb) | 109 | int ip_local_out_sk(struct sock *sk, struct sk_buff *skb) |
@@ -163,7 +168,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, | |||
163 | } | 168 | } |
164 | EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); | 169 | EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); |
165 | 170 | ||
166 | static inline int ip_finish_output2(struct sk_buff *skb) | 171 | static inline int ip_finish_output2(struct sock *sk, struct sk_buff *skb) |
167 | { | 172 | { |
168 | struct dst_entry *dst = skb_dst(skb); | 173 | struct dst_entry *dst = skb_dst(skb); |
169 | struct rtable *rt = (struct rtable *)dst; | 174 | struct rtable *rt = (struct rtable *)dst; |
@@ -211,7 +216,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
211 | return -EINVAL; | 216 | return -EINVAL; |
212 | } | 217 | } |
213 | 218 | ||
214 | static int ip_finish_output_gso(struct sk_buff *skb) | 219 | static int ip_finish_output_gso(struct sock *sk, struct sk_buff *skb) |
215 | { | 220 | { |
216 | netdev_features_t features; | 221 | netdev_features_t features; |
217 | struct sk_buff *segs; | 222 | struct sk_buff *segs; |
@@ -220,7 +225,7 @@ static int ip_finish_output_gso(struct sk_buff *skb) | |||
220 | /* common case: locally created skb or seglen is <= mtu */ | 225 | /* common case: locally created skb or seglen is <= mtu */ |
221 | if (((IPCB(skb)->flags & IPSKB_FORWARDED) == 0) || | 226 | if (((IPCB(skb)->flags & IPSKB_FORWARDED) == 0) || |
222 | skb_gso_network_seglen(skb) <= ip_skb_dst_mtu(skb)) | 227 | skb_gso_network_seglen(skb) <= ip_skb_dst_mtu(skb)) |
223 | return ip_finish_output2(skb); | 228 | return ip_finish_output2(sk, skb); |
224 | 229 | ||
225 | /* Slowpath - GSO segment length is exceeding the dst MTU. | 230 | /* Slowpath - GSO segment length is exceeding the dst MTU. |
226 | * | 231 | * |
@@ -243,7 +248,7 @@ static int ip_finish_output_gso(struct sk_buff *skb) | |||
243 | int err; | 248 | int err; |
244 | 249 | ||
245 | segs->next = NULL; | 250 | segs->next = NULL; |
246 | err = ip_fragment(segs, ip_finish_output2); | 251 | err = ip_fragment(sk, segs, ip_finish_output2); |
247 | 252 | ||
248 | if (err && ret == 0) | 253 | if (err && ret == 0) |
249 | ret = err; | 254 | ret = err; |
@@ -253,22 +258,22 @@ static int ip_finish_output_gso(struct sk_buff *skb) | |||
253 | return ret; | 258 | return ret; |
254 | } | 259 | } |
255 | 260 | ||
256 | static int ip_finish_output(struct sk_buff *skb) | 261 | static int ip_finish_output(struct sock *sk, struct sk_buff *skb) |
257 | { | 262 | { |
258 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) | 263 | #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM) |
259 | /* Policy lookup after SNAT yielded a new policy */ | 264 | /* Policy lookup after SNAT yielded a new policy */ |
260 | if (skb_dst(skb)->xfrm) { | 265 | if (skb_dst(skb)->xfrm) { |
261 | IPCB(skb)->flags |= IPSKB_REROUTED; | 266 | IPCB(skb)->flags |= IPSKB_REROUTED; |
262 | return dst_output(skb); | 267 | return dst_output_sk(sk, skb); |
263 | } | 268 | } |
264 | #endif | 269 | #endif |
265 | if (skb_is_gso(skb)) | 270 | if (skb_is_gso(skb)) |
266 | return ip_finish_output_gso(skb); | 271 | return ip_finish_output_gso(sk, skb); |
267 | 272 | ||
268 | if (skb->len > ip_skb_dst_mtu(skb)) | 273 | if (skb->len > ip_skb_dst_mtu(skb)) |
269 | return ip_fragment(skb, ip_finish_output2); | 274 | return ip_fragment(sk, skb, ip_finish_output2); |
270 | 275 | ||
271 | return ip_finish_output2(skb); | 276 | return ip_finish_output2(sk, skb); |
272 | } | 277 | } |
273 | 278 | ||
274 | int ip_mc_output(struct sock *sk, struct sk_buff *skb) | 279 | int ip_mc_output(struct sock *sk, struct sk_buff *skb) |
@@ -307,7 +312,7 @@ int ip_mc_output(struct sock *sk, struct sk_buff *skb) | |||
307 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); | 312 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); |
308 | if (newskb) | 313 | if (newskb) |
309 | NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, | 314 | NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, |
310 | newskb, NULL, newskb->dev, | 315 | sk, newskb, NULL, newskb->dev, |
311 | dev_loopback_xmit); | 316 | dev_loopback_xmit); |
312 | } | 317 | } |
313 | 318 | ||
@@ -322,11 +327,11 @@ int ip_mc_output(struct sock *sk, struct sk_buff *skb) | |||
322 | if (rt->rt_flags&RTCF_BROADCAST) { | 327 | if (rt->rt_flags&RTCF_BROADCAST) { |
323 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); | 328 | struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); |
324 | if (newskb) | 329 | if (newskb) |
325 | NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, newskb, | 330 | NF_HOOK(NFPROTO_IPV4, NF_INET_POST_ROUTING, sk, newskb, |
326 | NULL, newskb->dev, dev_loopback_xmit); | 331 | NULL, newskb->dev, dev_loopback_xmit); |
327 | } | 332 | } |
328 | 333 | ||
329 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, | 334 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, sk, skb, NULL, |
330 | skb->dev, ip_finish_output, | 335 | skb->dev, ip_finish_output, |
331 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 336 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
332 | } | 337 | } |
@@ -340,7 +345,8 @@ int ip_output(struct sock *sk, struct sk_buff *skb) | |||
340 | skb->dev = dev; | 345 | skb->dev = dev; |
341 | skb->protocol = htons(ETH_P_IP); | 346 | skb->protocol = htons(ETH_P_IP); |
342 | 347 | ||
343 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, NULL, dev, | 348 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, sk, skb, |
349 | NULL, dev, | ||
344 | ip_finish_output, | 350 | ip_finish_output, |
345 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 351 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
346 | } | 352 | } |
@@ -480,7 +486,8 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
480 | * single device frame, and queue such a frame for sending. | 486 | * single device frame, and queue such a frame for sending. |
481 | */ | 487 | */ |
482 | 488 | ||
483 | int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | 489 | int ip_fragment(struct sock *sk, struct sk_buff *skb, |
490 | int (*output)(struct sock *, struct sk_buff *)) | ||
484 | { | 491 | { |
485 | struct iphdr *iph; | 492 | struct iphdr *iph; |
486 | int ptr; | 493 | int ptr; |
@@ -593,7 +600,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
593 | ip_send_check(iph); | 600 | ip_send_check(iph); |
594 | } | 601 | } |
595 | 602 | ||
596 | err = output(skb); | 603 | err = output(sk, skb); |
597 | 604 | ||
598 | if (!err) | 605 | if (!err) |
599 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGCREATES); | 606 | IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGCREATES); |
@@ -730,7 +737,7 @@ slow_path: | |||
730 | 737 | ||
731 | ip_send_check(iph); | 738 | ip_send_check(iph); |
732 | 739 | ||
733 | err = output(skb2); | 740 | err = output(sk, skb2); |
734 | if (err) | 741 | if (err) |
735 | goto fail; | 742 | goto fail; |
736 | 743 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 5f17d0e78071..3a2c0162c3ba 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1679,7 +1679,7 @@ static void ip_encap(struct net *net, struct sk_buff *skb, | |||
1679 | nf_reset(skb); | 1679 | nf_reset(skb); |
1680 | } | 1680 | } |
1681 | 1681 | ||
1682 | static inline int ipmr_forward_finish(struct sk_buff *skb) | 1682 | static inline int ipmr_forward_finish(struct sock *sk, struct sk_buff *skb) |
1683 | { | 1683 | { |
1684 | struct ip_options *opt = &(IPCB(skb)->opt); | 1684 | struct ip_options *opt = &(IPCB(skb)->opt); |
1685 | 1685 | ||
@@ -1689,7 +1689,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb) | |||
1689 | if (unlikely(opt->optlen)) | 1689 | if (unlikely(opt->optlen)) |
1690 | ip_forward_options(skb); | 1690 | ip_forward_options(skb); |
1691 | 1691 | ||
1692 | return dst_output(skb); | 1692 | return dst_output_sk(sk, skb); |
1693 | } | 1693 | } |
1694 | 1694 | ||
1695 | /* | 1695 | /* |
@@ -1788,7 +1788,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, | |||
1788 | * not mrouter) cannot join to more than one interface - it will | 1788 | * not mrouter) cannot join to more than one interface - it will |
1789 | * result in receiving multiple packets. | 1789 | * result in receiving multiple packets. |
1790 | */ | 1790 | */ |
1791 | NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, skb, skb->dev, dev, | 1791 | NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD, NULL, skb, |
1792 | skb->dev, dev, | ||
1792 | ipmr_forward_finish); | 1793 | ipmr_forward_finish); |
1793 | return; | 1794 | return; |
1794 | 1795 | ||
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 6d0fa8fb8af0..c0bb648fb2f9 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -412,8 +412,8 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4, | |||
412 | icmp_out_count(net, ((struct icmphdr *) | 412 | icmp_out_count(net, ((struct icmphdr *) |
413 | skb_transport_header(skb))->type); | 413 | skb_transport_header(skb))->type); |
414 | 414 | ||
415 | err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, skb, NULL, | 415 | err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb, |
416 | rt->dst.dev, dst_output); | 416 | NULL, rt->dst.dev, dst_output_sk); |
417 | if (err > 0) | 417 | if (err > 0) |
418 | err = net_xmit_errno(err); | 418 | err = net_xmit_errno(err); |
419 | if (err) | 419 | if (err) |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index cac7468db0a1..60b032f58ccc 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -22,7 +22,7 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
22 | return xfrm4_extract_header(skb); | 22 | return xfrm4_extract_header(skb); |
23 | } | 23 | } |
24 | 24 | ||
25 | static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) | 25 | static inline int xfrm4_rcv_encap_finish(struct sock *sk, struct sk_buff *skb) |
26 | { | 26 | { |
27 | if (!skb_dst(skb)) { | 27 | if (!skb_dst(skb)) { |
28 | const struct iphdr *iph = ip_hdr(skb); | 28 | const struct iphdr *iph = ip_hdr(skb); |
@@ -52,7 +52,8 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async) | |||
52 | iph->tot_len = htons(skb->len); | 52 | iph->tot_len = htons(skb->len); |
53 | ip_send_check(iph); | 53 | ip_send_check(iph); |
54 | 54 | ||
55 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, skb, skb->dev, NULL, | 55 | NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, NULL, skb, |
56 | skb->dev, NULL, | ||
56 | xfrm4_rcv_encap_finish); | 57 | xfrm4_rcv_encap_finish); |
57 | return 0; | 58 | return 0; |
58 | } | 59 | } |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index dab73813cb92..2878dbfffeb7 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
@@ -69,7 +69,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
69 | } | 69 | } |
70 | EXPORT_SYMBOL(xfrm4_prepare_output); | 70 | EXPORT_SYMBOL(xfrm4_prepare_output); |
71 | 71 | ||
72 | int xfrm4_output_finish(struct sk_buff *skb) | 72 | int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb) |
73 | { | 73 | { |
74 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | 74 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
75 | 75 | ||
@@ -77,26 +77,26 @@ int xfrm4_output_finish(struct sk_buff *skb) | |||
77 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; | 77 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | return xfrm_output(skb); | 80 | return xfrm_output(sk, skb); |
81 | } | 81 | } |
82 | 82 | ||
83 | static int __xfrm4_output(struct sk_buff *skb) | 83 | static int __xfrm4_output(struct sock *sk, struct sk_buff *skb) |
84 | { | 84 | { |
85 | struct xfrm_state *x = skb_dst(skb)->xfrm; | 85 | struct xfrm_state *x = skb_dst(skb)->xfrm; |
86 | 86 | ||
87 | #ifdef CONFIG_NETFILTER | 87 | #ifdef CONFIG_NETFILTER |
88 | if (!x) { | 88 | if (!x) { |
89 | IPCB(skb)->flags |= IPSKB_REROUTED; | 89 | IPCB(skb)->flags |= IPSKB_REROUTED; |
90 | return dst_output(skb); | 90 | return dst_output_sk(sk, skb); |
91 | } | 91 | } |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | return x->outer_mode->afinfo->output_finish(skb); | 94 | return x->outer_mode->afinfo->output_finish(sk, skb); |
95 | } | 95 | } |
96 | 96 | ||
97 | int xfrm4_output(struct sock *sk, struct sk_buff *skb) | 97 | int xfrm4_output(struct sock *sk, struct sk_buff *skb) |
98 | { | 98 | { |
99 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, skb, | 99 | return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, sk, skb, |
100 | NULL, skb_dst(skb)->dev, __xfrm4_output, | 100 | NULL, skb_dst(skb)->dev, __xfrm4_output, |
101 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 101 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
102 | } | 102 | } |