Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aad88724 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

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: 8f646c92 ("vxlan: keep original skb ownership")
Reported-by: default avatarlucien xin <lucien.xin@gmail.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b0270e91
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -1755,8 +1755,8 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
	if (err)
	if (err)
		return err;
		return err;


	return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df,
	return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP,
			     false);
			     tos, ttl, df, false);
}
}
EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
EXPORT_SYMBOL_GPL(vxlan_xmit_skb);


+11 −3
Original line number Original line Diff line number Diff line
@@ -45,7 +45,7 @@ struct dst_entry {
	void			*__pad1;
	void			*__pad1;
#endif
#endif
	int			(*input)(struct sk_buff *);
	int			(*input)(struct sk_buff *);
	int			(*output)(struct sk_buff *);
	int			(*output)(struct sock *sk, struct sk_buff *skb);


	unsigned short		flags;
	unsigned short		flags;
#define DST_HOST		0x0001
#define DST_HOST		0x0001
@@ -367,7 +367,11 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
	return child;
	return child;
}
}


int dst_discard(struct sk_buff *skb);
int dst_discard_sk(struct sock *sk, struct sk_buff *skb);
static inline int dst_discard(struct sk_buff *skb)
{
	return dst_discard_sk(skb->sk, skb);
}
void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref,
void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref,
		int initial_obsolete, unsigned short flags);
		int initial_obsolete, unsigned short flags);
void __dst_free(struct dst_entry *dst);
void __dst_free(struct dst_entry *dst);
@@ -449,9 +453,13 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout)
}
}


/* Output packet to network from transport.  */
/* Output packet to network from transport.  */
static inline int dst_output_sk(struct sock *sk, struct sk_buff *skb)
{
	return skb_dst(skb)->output(sk, skb);
}
static inline int dst_output(struct sk_buff *skb)
static inline int dst_output(struct sk_buff *skb)
{
{
	return skb_dst(skb)->output(skb);
	return dst_output_sk(skb->sk, skb);
}
}


/* Input packet from network to transport.  */
/* Input packet from network to transport.  */
+8 −3
Original line number Original line Diff line number Diff line
@@ -104,13 +104,18 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
	   struct net_device *orig_dev);
	   struct net_device *orig_dev);
int ip_local_deliver(struct sk_buff *skb);
int ip_local_deliver(struct sk_buff *skb);
int ip_mr_input(struct sk_buff *skb);
int ip_mr_input(struct sk_buff *skb);
int ip_output(struct sk_buff *skb);
int ip_output(struct sock *sk, struct sk_buff *skb);
int ip_mc_output(struct sk_buff *skb);
int ip_mc_output(struct sock *sk, struct sk_buff *skb);
int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
int ip_do_nat(struct sk_buff *skb);
int ip_do_nat(struct sk_buff *skb);
void ip_send_check(struct iphdr *ip);
void ip_send_check(struct iphdr *ip);
int __ip_local_out(struct sk_buff *skb);
int __ip_local_out(struct sk_buff *skb);
int ip_local_out(struct sk_buff *skb);
int ip_local_out_sk(struct sock *sk, struct sk_buff *skb);
static inline int ip_local_out(struct sk_buff *skb)
{
	return ip_local_out_sk(skb->sk, skb);
}

int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
void ip_init(void);
void ip_init(void);
int ip_append_data(struct sock *sk, struct flowi4 *fl4,
int ip_append_data(struct sock *sk, struct flowi4 *fl4,
+1 −1
Original line number Original line Diff line number Diff line
@@ -153,7 +153,7 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
}
}


int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto);
int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
		  __be32 src, __be32 dst, __u8 proto,
		  __be32 src, __be32 dst, __u8 proto,
		  __u8 tos, __u8 ttl, __be16 df, bool xnet);
		  __u8 tos, __u8 ttl, __be16 df, bool xnet);


+1 −1
Original line number Original line Diff line number Diff line
@@ -731,7 +731,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net,
 *	skb processing functions
 *	skb processing functions
 */
 */


int ip6_output(struct sk_buff *skb);
int ip6_output(struct sock *sk, struct sk_buff *skb);
int ip6_forward(struct sk_buff *skb);
int ip6_forward(struct sk_buff *skb);
int ip6_input(struct sk_buff *skb);
int ip6_input(struct sk_buff *skb);
int ip6_mc_input(struct sk_buff *skb);
int ip6_mc_input(struct sk_buff *skb);
Loading