diff options
| author | Eric Dumazet <edumazet@google.com> | 2014-04-15 13:47:15 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-04-15 13:47:15 -0400 |
| commit | aad88724c9d54acb1a9737cb6069d8470fa85f74 (patch) | |
| tree | 78cc7b925f3d05338373898f018892b8f434a948 | |
| parent | b0270e91014dabfceaf37f5b40ad51bbf21a1302 (diff) | |
ipv4: add a sock pointer to dst->output() path.
In the dst->output() path for ipv4, the code assumes the skb it has to
transmit is attached to an inet socket, specifically via
ip_mc_output() : The sk_mc_loop() test triggers a WARN_ON() when the
provider of the packet is an AF_PACKET socket.
The dst->output() method gets an additional 'struct sock *sk'
parameter. This needs a cascade of changes so that this parameter can
be propagated from vxlan to final consumer.
Fixes: 8f646c922d55 ("vxlan: keep original skb ownership")
Reported-by: lucien xin <lucien.xin@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/vxlan.c | 4 | ||||
| -rw-r--r-- | include/net/dst.h | 14 | ||||
| -rw-r--r-- | include/net/ip.h | 11 | ||||
| -rw-r--r-- | include/net/ip_tunnels.h | 2 | ||||
| -rw-r--r-- | include/net/ipv6.h | 2 | ||||
| -rw-r--r-- | include/net/xfrm.h | 6 | ||||
| -rw-r--r-- | net/core/dst.c | 15 | ||||
| -rw-r--r-- | net/decnet/dn_route.c | 16 | ||||
| -rw-r--r-- | net/ipv4/ip_output.c | 11 | ||||
| -rw-r--r-- | net/ipv4/ip_tunnel.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ip_tunnel_core.c | 4 | ||||
| -rw-r--r-- | net/ipv4/route.c | 4 | ||||
| -rw-r--r-- | net/ipv4/xfrm4_output.c | 2 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
| -rw-r--r-- | net/ipv6/route.c | 14 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 5 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_output.c | 2 | ||||
| -rw-r--r-- | net/openvswitch/vport-gre.c | 2 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 2 |
19 files changed, 74 insertions, 46 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index c55e316373a1..82355d5d155a 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -1755,8 +1755,8 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
| 1755 | if (err) | 1755 | if (err) |
| 1756 | return err; | 1756 | return err; |
| 1757 | 1757 | ||
| 1758 | return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, | 1758 | return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP, |
| 1759 | false); | 1759 | tos, ttl, df, false); |
| 1760 | } | 1760 | } |
| 1761 | EXPORT_SYMBOL_GPL(vxlan_xmit_skb); | 1761 | EXPORT_SYMBOL_GPL(vxlan_xmit_skb); |
| 1762 | 1762 | ||
diff --git a/include/net/dst.h b/include/net/dst.h index 46ed958e0c6e..71c60f42be48 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
| @@ -45,7 +45,7 @@ struct dst_entry { | |||
| 45 | void *__pad1; | 45 | void *__pad1; |
| 46 | #endif | 46 | #endif |
| 47 | int (*input)(struct sk_buff *); | 47 | int (*input)(struct sk_buff *); |
| 48 | int (*output)(struct sk_buff *); | 48 | int (*output)(struct sock *sk, struct sk_buff *skb); |
| 49 | 49 | ||
| 50 | unsigned short flags; | 50 | unsigned short flags; |
| 51 | #define DST_HOST 0x0001 | 51 | #define DST_HOST 0x0001 |
| @@ -367,7 +367,11 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) | |||
| 367 | return child; | 367 | return child; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | int dst_discard(struct sk_buff *skb); | 370 | int dst_discard_sk(struct sock *sk, struct sk_buff *skb); |
| 371 | static inline int dst_discard(struct sk_buff *skb) | ||
| 372 | { | ||
| 373 | return dst_discard_sk(skb->sk, skb); | ||
| 374 | } | ||
| 371 | void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, | 375 | void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, |
| 372 | int initial_obsolete, unsigned short flags); | 376 | int initial_obsolete, unsigned short flags); |
| 373 | void __dst_free(struct dst_entry *dst); | 377 | void __dst_free(struct dst_entry *dst); |
| @@ -449,9 +453,13 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) | |||
| 449 | } | 453 | } |
| 450 | 454 | ||
| 451 | /* Output packet to network from transport. */ | 455 | /* Output packet to network from transport. */ |
| 456 | static inline int dst_output_sk(struct sock *sk, struct sk_buff *skb) | ||
| 457 | { | ||
| 458 | return skb_dst(skb)->output(sk, skb); | ||
| 459 | } | ||
| 452 | static inline int dst_output(struct sk_buff *skb) | 460 | static inline int dst_output(struct sk_buff *skb) |
| 453 | { | 461 | { |
| 454 | return skb_dst(skb)->output(skb); | 462 | return dst_output_sk(skb->sk, skb); |
| 455 | } | 463 | } |
| 456 | 464 | ||
| 457 | /* Input packet from network to transport. */ | 465 | /* Input packet from network to transport. */ |
diff --git a/include/net/ip.h b/include/net/ip.h index 77e73d293e09..3ec2b0fb9d83 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
| @@ -104,13 +104,18 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
| 104 | struct net_device *orig_dev); | 104 | struct net_device *orig_dev); |
| 105 | int ip_local_deliver(struct sk_buff *skb); | 105 | int ip_local_deliver(struct sk_buff *skb); |
| 106 | int ip_mr_input(struct sk_buff *skb); | 106 | int ip_mr_input(struct sk_buff *skb); |
| 107 | int ip_output(struct sk_buff *skb); | 107 | int ip_output(struct sock *sk, struct sk_buff *skb); |
| 108 | int ip_mc_output(struct sk_buff *skb); | 108 | int ip_mc_output(struct sock *sk, struct sk_buff *skb); |
| 109 | int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); | 109 | int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); |
| 110 | int ip_do_nat(struct sk_buff *skb); | 110 | int ip_do_nat(struct sk_buff *skb); |
| 111 | void ip_send_check(struct iphdr *ip); | 111 | void ip_send_check(struct iphdr *ip); |
| 112 | int __ip_local_out(struct sk_buff *skb); | 112 | int __ip_local_out(struct sk_buff *skb); |
| 113 | int ip_local_out(struct sk_buff *skb); | 113 | int ip_local_out_sk(struct sock *sk, struct sk_buff *skb); |
| 114 | static inline int ip_local_out(struct sk_buff *skb) | ||
| 115 | { | ||
| 116 | return ip_local_out_sk(skb->sk, skb); | ||
| 117 | } | ||
| 118 | |||
| 114 | int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); | 119 | int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); |
| 115 | void ip_init(void); | 120 | void ip_init(void); |
| 116 | int ip_append_data(struct sock *sk, struct flowi4 *fl4, | 121 | int ip_append_data(struct sock *sk, struct flowi4 *fl4, |
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index e77c10405d51..a4daf9eb8562 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h | |||
| @@ -153,7 +153,7 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph, | |||
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto); | 155 | int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto); |
| 156 | int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, | 156 | int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, |
| 157 | __be32 src, __be32 dst, __u8 proto, | 157 | __be32 src, __be32 dst, __u8 proto, |
| 158 | __u8 tos, __u8 ttl, __be16 df, bool xnet); | 158 | __u8 tos, __u8 ttl, __be16 df, bool xnet); |
| 159 | 159 | ||
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 4f541f11ce63..d640925bc454 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
| @@ -731,7 +731,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, | |||
| 731 | * skb processing functions | 731 | * skb processing functions |
| 732 | */ | 732 | */ |
| 733 | 733 | ||
| 734 | int ip6_output(struct sk_buff *skb); | 734 | int ip6_output(struct sock *sk, struct sk_buff *skb); |
| 735 | int ip6_forward(struct sk_buff *skb); | 735 | int ip6_forward(struct sk_buff *skb); |
| 736 | int ip6_input(struct sk_buff *skb); | 736 | int ip6_input(struct sk_buff *skb); |
| 737 | int ip6_mc_input(struct sk_buff *skb); | 737 | int ip6_mc_input(struct sk_buff *skb); |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 32682ae47b3f..116e9c7e19cb 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -333,7 +333,7 @@ struct xfrm_state_afinfo { | |||
| 333 | const xfrm_address_t *saddr); | 333 | const xfrm_address_t *saddr); |
| 334 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); | 334 | int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); |
| 335 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); | 335 | int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); |
| 336 | int (*output)(struct sk_buff *skb); | 336 | int (*output)(struct sock *sk, struct sk_buff *skb); |
| 337 | int (*output_finish)(struct sk_buff *skb); | 337 | int (*output_finish)(struct sk_buff *skb); |
| 338 | int (*extract_input)(struct xfrm_state *x, | 338 | int (*extract_input)(struct xfrm_state *x, |
| 339 | struct sk_buff *skb); | 339 | struct sk_buff *skb); |
| @@ -1540,7 +1540,7 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) | |||
| 1540 | 1540 | ||
| 1541 | int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb); | 1541 | int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb); |
| 1542 | int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb); | 1542 | int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb); |
| 1543 | int xfrm4_output(struct sk_buff *skb); | 1543 | int xfrm4_output(struct sock *sk, struct sk_buff *skb); |
| 1544 | int xfrm4_output_finish(struct sk_buff *skb); | 1544 | int xfrm4_output_finish(struct sk_buff *skb); |
| 1545 | int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err); | 1545 | int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err); |
| 1546 | int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol); | 1546 | int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol); |
| @@ -1565,7 +1565,7 @@ __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); | |||
| 1565 | __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); | 1565 | __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); |
| 1566 | int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); | 1566 | int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); |
| 1567 | int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); | 1567 | int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); |
| 1568 | int xfrm6_output(struct sk_buff *skb); | 1568 | int xfrm6_output(struct sock *sk, struct sk_buff *skb); |
| 1569 | int xfrm6_output_finish(struct sk_buff *skb); | 1569 | int xfrm6_output_finish(struct sk_buff *skb); |
| 1570 | int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, | 1570 | int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, |
| 1571 | u8 **prevhdr); | 1571 | u8 **prevhdr); |
diff --git a/net/core/dst.c b/net/core/dst.c index ca4231ec7347..80d6286c8b62 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
| @@ -142,12 +142,12 @@ loop: | |||
| 142 | mutex_unlock(&dst_gc_mutex); | 142 | mutex_unlock(&dst_gc_mutex); |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | int dst_discard(struct sk_buff *skb) | 145 | int dst_discard_sk(struct sock *sk, struct sk_buff *skb) |
| 146 | { | 146 | { |
| 147 | kfree_skb(skb); | 147 | kfree_skb(skb); |
| 148 | return 0; | 148 | return 0; |
| 149 | } | 149 | } |
| 150 | EXPORT_SYMBOL(dst_discard); | 150 | EXPORT_SYMBOL(dst_discard_sk); |
| 151 | 151 | ||
| 152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { | 152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { |
| 153 | /* This initializer is needed to force linker to place this variable | 153 | /* This initializer is needed to force linker to place this variable |
| @@ -184,7 +184,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
| 184 | dst->xfrm = NULL; | 184 | dst->xfrm = NULL; |
| 185 | #endif | 185 | #endif |
| 186 | dst->input = dst_discard; | 186 | dst->input = dst_discard; |
| 187 | dst->output = dst_discard; | 187 | dst->output = dst_discard_sk; |
| 188 | dst->error = 0; | 188 | dst->error = 0; |
| 189 | dst->obsolete = initial_obsolete; | 189 | dst->obsolete = initial_obsolete; |
| 190 | dst->header_len = 0; | 190 | dst->header_len = 0; |
| @@ -209,8 +209,10 @@ static void ___dst_free(struct dst_entry *dst) | |||
| 209 | /* The first case (dev==NULL) is required, when | 209 | /* The first case (dev==NULL) is required, when |
| 210 | protocol module is unloaded. | 210 | protocol module is unloaded. |
| 211 | */ | 211 | */ |
| 212 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) | 212 | if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { |
| 213 | dst->input = dst->output = dst_discard; | 213 | dst->input = dst_discard; |
| 214 | dst->output = dst_discard_sk; | ||
| 215 | } | ||
| 214 | dst->obsolete = DST_OBSOLETE_DEAD; | 216 | dst->obsolete = DST_OBSOLETE_DEAD; |
| 215 | } | 217 | } |
| 216 | 218 | ||
| @@ -361,7 +363,8 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, | |||
| 361 | return; | 363 | return; |
| 362 | 364 | ||
| 363 | if (!unregister) { | 365 | if (!unregister) { |
| 364 | dst->input = dst->output = dst_discard; | 366 | dst->input = dst_discard; |
| 367 | dst->output = dst_discard_sk; | ||
| 365 | } else { | 368 | } else { |
| 366 | dst->dev = dev_net(dst->dev)->loopback_dev; | 369 | dst->dev = dev_net(dst->dev)->loopback_dev; |
| 367 | dev_hold(dst->dev); | 370 | dev_hold(dst->dev); |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index ce0cbbfe0f43..daccc4a36d80 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
| @@ -752,7 +752,7 @@ static int dn_to_neigh_output(struct sk_buff *skb) | |||
| 752 | return n->output(n, skb); | 752 | return n->output(n, skb); |
| 753 | } | 753 | } |
| 754 | 754 | ||
| 755 | static int dn_output(struct sk_buff *skb) | 755 | static int dn_output(struct sock *sk, struct sk_buff *skb) |
| 756 | { | 756 | { |
| 757 | struct dst_entry *dst = skb_dst(skb); | 757 | struct dst_entry *dst = skb_dst(skb); |
| 758 | struct dn_route *rt = (struct dn_route *)dst; | 758 | struct dn_route *rt = (struct dn_route *)dst; |
| @@ -838,6 +838,18 @@ drop: | |||
| 838 | * Used to catch bugs. This should never normally get | 838 | * Used to catch bugs. This should never normally get |
| 839 | * called. | 839 | * called. |
| 840 | */ | 840 | */ |
| 841 | static int dn_rt_bug_sk(struct sock *sk, struct sk_buff *skb) | ||
| 842 | { | ||
| 843 | struct dn_skb_cb *cb = DN_SKB_CB(skb); | ||
| 844 | |||
| 845 | net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n", | ||
| 846 | le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); | ||
| 847 | |||
| 848 | kfree_skb(skb); | ||
| 849 | |||
| 850 | return NET_RX_DROP; | ||
| 851 | } | ||
| 852 | |||
| 841 | static int dn_rt_bug(struct sk_buff *skb) | 853 | static int dn_rt_bug(struct sk_buff *skb) |
| 842 | { | 854 | { |
| 843 | struct dn_skb_cb *cb = DN_SKB_CB(skb); | 855 | struct dn_skb_cb *cb = DN_SKB_CB(skb); |
| @@ -1463,7 +1475,7 @@ make_route: | |||
| 1463 | 1475 | ||
| 1464 | rt->n = neigh; | 1476 | rt->n = neigh; |
| 1465 | rt->dst.lastuse = jiffies; | 1477 | rt->dst.lastuse = jiffies; |
| 1466 | rt->dst.output = dn_rt_bug; | 1478 | rt->dst.output = dn_rt_bug_sk; |
| 1467 | switch (res.type) { | 1479 | switch (res.type) { |
| 1468 | case RTN_UNICAST: | 1480 | case RTN_UNICAST: |
| 1469 | rt->dst.input = dn_forward; | 1481 | rt->dst.input = dn_forward; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 7ad68b860935..1cbeba5edff9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -101,17 +101,17 @@ int __ip_local_out(struct sk_buff *skb) | |||
| 101 | skb_dst(skb)->dev, dst_output); | 101 | skb_dst(skb)->dev, dst_output); |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | int ip_local_out(struct sk_buff *skb) | 104 | int ip_local_out_sk(struct sock *sk, struct sk_buff *skb) |
| 105 | { | 105 | { |
| 106 | int err; | 106 | int err; |
| 107 | 107 | ||
| 108 | err = __ip_local_out(skb); | 108 | err = __ip_local_out(skb); |
| 109 | if (likely(err == 1)) | 109 | if (likely(err == 1)) |
| 110 | err = dst_output(skb); | 110 | err = dst_output_sk(sk, skb); |
| 111 | 111 | ||
| 112 | return err; | 112 | return err; |
| 113 | } | 113 | } |
| 114 | EXPORT_SYMBOL_GPL(ip_local_out); | 114 | EXPORT_SYMBOL_GPL(ip_local_out_sk); |
| 115 | 115 | ||
| 116 | static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) | 116 | static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) |
| 117 | { | 117 | { |
| @@ -226,9 +226,8 @@ static int ip_finish_output(struct sk_buff *skb) | |||
| 226 | return ip_finish_output2(skb); | 226 | return ip_finish_output2(skb); |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | int ip_mc_output(struct sk_buff *skb) | 229 | int ip_mc_output(struct sock *sk, struct sk_buff *skb) |
| 230 | { | 230 | { |
| 231 | struct sock *sk = skb->sk; | ||
| 232 | struct rtable *rt = skb_rtable(skb); | 231 | struct rtable *rt = skb_rtable(skb); |
| 233 | struct net_device *dev = rt->dst.dev; | 232 | struct net_device *dev = rt->dst.dev; |
| 234 | 233 | ||
| @@ -287,7 +286,7 @@ int ip_mc_output(struct sk_buff *skb) | |||
| 287 | !(IPCB(skb)->flags & IPSKB_REROUTED)); | 286 | !(IPCB(skb)->flags & IPSKB_REROUTED)); |
| 288 | } | 287 | } |
| 289 | 288 | ||
| 290 | int ip_output(struct sk_buff *skb) | 289 | int ip_output(struct sock *sk, struct sk_buff *skb) |
| 291 | { | 290 | { |
| 292 | struct net_device *dev = skb_dst(skb)->dev; | 291 | struct net_device *dev = skb_dst(skb)->dev; |
| 293 | 292 | ||
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e77381d1df9a..484d0ce27ef7 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
| @@ -670,7 +670,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
| 670 | return; | 670 | return; |
| 671 | } | 671 | } |
| 672 | 672 | ||
| 673 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol, | 673 | err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol, |
| 674 | tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 674 | tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); |
| 675 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 675 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
| 676 | 676 | ||
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index e0c2b1d2ea4e..bcf206c79005 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | #include <net/netns/generic.h> | 46 | #include <net/netns/generic.h> |
| 47 | #include <net/rtnetlink.h> | 47 | #include <net/rtnetlink.h> |
| 48 | 48 | ||
| 49 | int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, | 49 | int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, |
| 50 | __be32 src, __be32 dst, __u8 proto, | 50 | __be32 src, __be32 dst, __u8 proto, |
| 51 | __u8 tos, __u8 ttl, __be16 df, bool xnet) | 51 | __u8 tos, __u8 ttl, __be16 df, bool xnet) |
| 52 | { | 52 | { |
| @@ -76,7 +76,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, | |||
| 76 | iph->ttl = ttl; | 76 | iph->ttl = ttl; |
| 77 | __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); | 77 | __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); |
| 78 | 78 | ||
| 79 | err = ip_local_out(skb); | 79 | err = ip_local_out_sk(sk, skb); |
| 80 | if (unlikely(net_xmit_eval(err))) | 80 | if (unlikely(net_xmit_eval(err))) |
| 81 | pkt_len = 0; | 81 | pkt_len = 0; |
| 82 | return pkt_len; | 82 | return pkt_len; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 20a59c388e6e..1485aafcad59 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1129,7 +1129,7 @@ static void ipv4_link_failure(struct sk_buff *skb) | |||
| 1129 | dst_set_expires(&rt->dst, 0); | 1129 | dst_set_expires(&rt->dst, 0); |
| 1130 | } | 1130 | } |
| 1131 | 1131 | ||
| 1132 | static int ip_rt_bug(struct sk_buff *skb) | 1132 | static int ip_rt_bug(struct sock *sk, struct sk_buff *skb) |
| 1133 | { | 1133 | { |
| 1134 | pr_debug("%s: %pI4 -> %pI4, %s\n", | 1134 | pr_debug("%s: %pI4 -> %pI4, %s\n", |
| 1135 | __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, | 1135 | __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, |
| @@ -2218,7 +2218,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
| 2218 | 2218 | ||
| 2219 | new->__use = 1; | 2219 | new->__use = 1; |
| 2220 | new->input = dst_discard; | 2220 | new->input = dst_discard; |
| 2221 | new->output = dst_discard; | 2221 | new->output = dst_discard_sk; |
| 2222 | 2222 | ||
| 2223 | new->dev = ort->dst.dev; | 2223 | new->dev = ort->dst.dev; |
| 2224 | if (new->dev) | 2224 | if (new->dev) |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index baa0f63731fd..40e701f2e1e0 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -86,7 +86,7 @@ int xfrm4_output_finish(struct sk_buff *skb) | |||
| 86 | return xfrm_output(skb); | 86 | return xfrm_output(skb); |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | int xfrm4_output(struct sk_buff *skb) | 89 | int xfrm4_output(struct sock *sk, struct sk_buff *skb) |
| 90 | { | 90 | { |
| 91 | struct dst_entry *dst = skb_dst(skb); | 91 | struct dst_entry *dst = skb_dst(skb); |
| 92 | struct xfrm_state *x = dst->xfrm; | 92 | struct xfrm_state *x = dst->xfrm; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 3284d61577c0..40e7581374f7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -132,7 +132,7 @@ static int ip6_finish_output(struct sk_buff *skb) | |||
| 132 | return ip6_finish_output2(skb); | 132 | return ip6_finish_output2(skb); |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | int ip6_output(struct sk_buff *skb) | 135 | int ip6_output(struct sock *sk, struct sk_buff *skb) |
| 136 | { | 136 | { |
| 137 | struct net_device *dev = skb_dst(skb)->dev; | 137 | struct net_device *dev = skb_dst(skb)->dev; |
| 138 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); | 138 | struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5ea462eacd9f..4011617cca68 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -84,9 +84,9 @@ static void ip6_dst_ifdown(struct dst_entry *, | |||
| 84 | static int ip6_dst_gc(struct dst_ops *ops); | 84 | static int ip6_dst_gc(struct dst_ops *ops); |
| 85 | 85 | ||
| 86 | static int ip6_pkt_discard(struct sk_buff *skb); | 86 | static int ip6_pkt_discard(struct sk_buff *skb); |
| 87 | static int ip6_pkt_discard_out(struct sk_buff *skb); | 87 | static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb); |
| 88 | static int ip6_pkt_prohibit(struct sk_buff *skb); | 88 | static int ip6_pkt_prohibit(struct sk_buff *skb); |
| 89 | static int ip6_pkt_prohibit_out(struct sk_buff *skb); | 89 | static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb); |
| 90 | static void ip6_link_failure(struct sk_buff *skb); | 90 | static void ip6_link_failure(struct sk_buff *skb); |
| 91 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 91 | static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
| 92 | struct sk_buff *skb, u32 mtu); | 92 | struct sk_buff *skb, u32 mtu); |
| @@ -290,7 +290,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = { | |||
| 290 | .obsolete = DST_OBSOLETE_FORCE_CHK, | 290 | .obsolete = DST_OBSOLETE_FORCE_CHK, |
| 291 | .error = -EINVAL, | 291 | .error = -EINVAL, |
| 292 | .input = dst_discard, | 292 | .input = dst_discard, |
| 293 | .output = dst_discard, | 293 | .output = dst_discard_sk, |
| 294 | }, | 294 | }, |
| 295 | .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), | 295 | .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), |
| 296 | .rt6i_protocol = RTPROT_KERNEL, | 296 | .rt6i_protocol = RTPROT_KERNEL, |
| @@ -1058,7 +1058,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori | |||
| 1058 | 1058 | ||
| 1059 | new->__use = 1; | 1059 | new->__use = 1; |
| 1060 | new->input = dst_discard; | 1060 | new->input = dst_discard; |
| 1061 | new->output = dst_discard; | 1061 | new->output = dst_discard_sk; |
| 1062 | 1062 | ||
| 1063 | if (dst_metrics_read_only(&ort->dst)) | 1063 | if (dst_metrics_read_only(&ort->dst)) |
| 1064 | new->_metrics = ort->dst._metrics; | 1064 | new->_metrics = ort->dst._metrics; |
| @@ -1577,7 +1577,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
| 1577 | switch (cfg->fc_type) { | 1577 | switch (cfg->fc_type) { |
| 1578 | case RTN_BLACKHOLE: | 1578 | case RTN_BLACKHOLE: |
| 1579 | rt->dst.error = -EINVAL; | 1579 | rt->dst.error = -EINVAL; |
| 1580 | rt->dst.output = dst_discard; | 1580 | rt->dst.output = dst_discard_sk; |
| 1581 | rt->dst.input = dst_discard; | 1581 | rt->dst.input = dst_discard; |
| 1582 | break; | 1582 | break; |
| 1583 | case RTN_PROHIBIT: | 1583 | case RTN_PROHIBIT: |
| @@ -2129,7 +2129,7 @@ static int ip6_pkt_discard(struct sk_buff *skb) | |||
| 2129 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); | 2129 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); |
| 2130 | } | 2130 | } |
| 2131 | 2131 | ||
| 2132 | static int ip6_pkt_discard_out(struct sk_buff *skb) | 2132 | static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb) |
| 2133 | { | 2133 | { |
| 2134 | skb->dev = skb_dst(skb)->dev; | 2134 | skb->dev = skb_dst(skb)->dev; |
| 2135 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); | 2135 | return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); |
| @@ -2140,7 +2140,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb) | |||
| 2140 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); | 2140 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); |
| 2141 | } | 2141 | } |
| 2142 | 2142 | ||
| 2143 | static int ip6_pkt_prohibit_out(struct sk_buff *skb) | 2143 | static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb) |
| 2144 | { | 2144 | { |
| 2145 | skb->dev = skb_dst(skb)->dev; | 2145 | skb->dev = skb_dst(skb)->dev; |
| 2146 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); | 2146 | return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1693c8d885f0..8da8268d65f8 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -974,8 +974,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
| 974 | goto out; | 974 | goto out; |
| 975 | } | 975 | } |
| 976 | 976 | ||
| 977 | err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, | 977 | err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, |
| 978 | ttl, df, !net_eq(tunnel->net, dev_net(dev))); | 978 | IPPROTO_IPV6, tos, ttl, df, |
| 979 | !net_eq(tunnel->net, dev_net(dev))); | ||
| 979 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); | 980 | iptunnel_xmit_stats(err, &dev->stats, dev->tstats); |
| 980 | return NETDEV_TX_OK; | 981 | return NETDEV_TX_OK; |
| 981 | 982 | ||
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 6cd625e37706..19ef329bdbf8 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
| @@ -163,7 +163,7 @@ static int __xfrm6_output(struct sk_buff *skb) | |||
| 163 | return x->outer_mode->afinfo->output_finish(skb); | 163 | return x->outer_mode->afinfo->output_finish(skb); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | int xfrm6_output(struct sk_buff *skb) | 166 | int xfrm6_output(struct sock *sk, struct sk_buff *skb) |
| 167 | { | 167 | { |
| 168 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, | 168 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, |
| 169 | skb_dst(skb)->dev, __xfrm6_output); | 169 | skb_dst(skb)->dev, __xfrm6_output); |
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index a3d6951602db..ebb6e2442554 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
| @@ -174,7 +174,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 174 | 174 | ||
| 175 | skb->local_df = 1; | 175 | skb->local_df = 1; |
| 176 | 176 | ||
| 177 | return iptunnel_xmit(rt, skb, fl.saddr, | 177 | return iptunnel_xmit(skb->sk, rt, skb, fl.saddr, |
| 178 | OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, | 178 | OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, |
| 179 | OVS_CB(skb)->tun_key->ipv4_tos, | 179 | OVS_CB(skb)->tun_key->ipv4_tos, |
| 180 | OVS_CB(skb)->tun_key->ipv4_ttl, df, false); | 180 | OVS_CB(skb)->tun_key->ipv4_ttl, df, false); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f02f511b7107..c08fbd11ceff 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1842,7 +1842,7 @@ purge_queue: | |||
| 1842 | xfrm_pol_put(pol); | 1842 | xfrm_pol_put(pol); |
| 1843 | } | 1843 | } |
| 1844 | 1844 | ||
| 1845 | static int xdst_queue_output(struct sk_buff *skb) | 1845 | static int xdst_queue_output(struct sock *sk, struct sk_buff *skb) |
| 1846 | { | 1846 | { |
| 1847 | unsigned long sched_next; | 1847 | unsigned long sched_next; |
| 1848 | struct dst_entry *dst = skb_dst(skb); | 1848 | struct dst_entry *dst = skb_dst(skb); |
