aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid Miller <davem@davemloft.net>2015-04-05 22:19:04 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-07 15:25:55 -0400
commit7026b1ddb6b8d4e6ee33dc2bd06c0ca8746fa7ab (patch)
tree3e11ed0f186ea6066a3f7efecb88d85bc732ee51 /net/ipv4
parent1c984f8a5df085bcf35364a8a870bd4db4da4ed3 (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.c10
-rw-r--r--net/ipv4/ip_forward.c8
-rw-r--r--net/ipv4/ip_input.c10
-rw-r--r--net/ipv4/ip_output.c45
-rw-r--r--net/ipv4/ipmr.c7
-rw-r--r--net/ipv4/raw.c4
-rw-r--r--net/ipv4/xfrm4_input.c5
-rw-r--r--net/ipv4/xfrm4_output.c12
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);
591void arp_xmit(struct sk_buff *skb) 591void 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}
596EXPORT_SYMBOL(arp_xmit); 597EXPORT_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
628static int arp_process(struct sk_buff *skb) 629static 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
847static void parp_redo(struct sk_buff *skb) 848static 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
884consumeskb: 886consumeskb:
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
60static int ip_forward_finish(struct sk_buff *skb) 60static 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
74int ip_forward(struct sk_buff *skb) 74int 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
142sr_failed: 142sr_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
190static int ip_local_deliver_finish(struct sk_buff *skb) 190static 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:
309int sysctl_ip_early_demux __read_mostly = 1; 310int sysctl_ip_early_demux __read_mostly = 1;
310EXPORT_SYMBOL(sysctl_ip_early_demux); 311EXPORT_SYMBOL(sysctl_ip_early_demux);
311 312
312static int ip_rcv_finish(struct sk_buff *skb) 313static 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
457csum_error: 459csum_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}
92EXPORT_SYMBOL(ip_send_check); 92EXPORT_SYMBOL(ip_send_check);
93 93
94int __ip_local_out(struct sk_buff *skb) 94int __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
104int __ip_local_out(struct sk_buff *skb)
105{
106 return __ip_local_out_sk(skb->sk, skb);
102} 107}
103 108
104int ip_local_out_sk(struct sock *sk, struct sk_buff *skb) 109int 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}
164EXPORT_SYMBOL_GPL(ip_build_and_send_pkt); 169EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
165 170
166static inline int ip_finish_output2(struct sk_buff *skb) 171static 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
214static int ip_finish_output_gso(struct sk_buff *skb) 219static 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
256static int ip_finish_output(struct sk_buff *skb) 261static 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
274int ip_mc_output(struct sock *sk, struct sk_buff *skb) 279int 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
483int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 489int 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
1682static inline int ipmr_forward_finish(struct sk_buff *skb) 1682static 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
25static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) 25static 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}
70EXPORT_SYMBOL(xfrm4_prepare_output); 70EXPORT_SYMBOL(xfrm4_prepare_output);
71 71
72int xfrm4_output_finish(struct sk_buff *skb) 72int 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
83static int __xfrm4_output(struct sk_buff *skb) 83static 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
97int xfrm4_output(struct sock *sk, struct sk_buff *skb) 97int 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}