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 /include | |
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>
Diffstat (limited to 'include')
-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 |
5 files changed, 24 insertions, 11 deletions
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); |