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

Commit 6b92d0c4 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'pass_net_through_output_path'



Eric W. Biederman says:

====================
net: Pass net through the output path v2

This is the next installment of my work to pass struct net through the
output path so the code does not need to guess how to figure out which
network namespace it is in, and ultimately routes can have output
devices in another network namespace.

The first patch in this series is a fix for a bug that came in when sk
was passed through the functions in the output path, and as such is
probably a candidate for net.  At the same time my later patches depend
on it so sending the fix separately would be confusing.

The second patch in this series is another fix that for an issue that
came in when sk was passed through the output path.  I don't think it
needs a backport as I don't think anyone uses the path where the code
was incorrect.

The rest of the patchset focuses on the path from xxx_local_out to
dst_output and in the end succeeds in passing sock_net(sk) from the
socket a packet locally originates on to the dst->output function.

Given the size reduction in the code I think this counts as a cleanup as
much as feature work.

There remain a number of helper functions (like ip option processing) to
take care of before the network stack can support destination devices in
other network namespaces but with this set of changes the backbone of
the work is done.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e28383dd ede2059d
Loading
Loading
Loading
Loading
+6 −4
Original line number Original line Diff line number Diff line
@@ -344,6 +344,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
{
{
	const struct iphdr *ip4h = ip_hdr(skb);
	const struct iphdr *ip4h = ip_hdr(skb);
	struct net_device *dev = skb->dev;
	struct net_device *dev = skb->dev;
	struct net *net = dev_net(dev);
	struct rtable *rt;
	struct rtable *rt;
	int err, ret = NET_XMIT_DROP;
	int err, ret = NET_XMIT_DROP;
	struct flowi4 fl4 = {
	struct flowi4 fl4 = {
@@ -354,7 +355,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
		.saddr = ip4h->saddr,
		.saddr = ip4h->saddr,
	};
	};


	rt = ip_route_output_flow(dev_net(dev), &fl4, NULL);
	rt = ip_route_output_flow(net, &fl4, NULL);
	if (IS_ERR(rt))
	if (IS_ERR(rt))
		goto err;
		goto err;


@@ -364,7 +365,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
	}
	}
	skb_dst_drop(skb);
	skb_dst_drop(skb);
	skb_dst_set(skb, &rt->dst);
	skb_dst_set(skb, &rt->dst);
	err = ip_local_out(skb);
	err = ip_local_out(net, skb->sk, skb);
	if (unlikely(net_xmit_eval(err)))
	if (unlikely(net_xmit_eval(err)))
		dev->stats.tx_errors++;
		dev->stats.tx_errors++;
	else
	else
@@ -381,6 +382,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
{
{
	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
	const struct ipv6hdr *ip6h = ipv6_hdr(skb);
	struct net_device *dev = skb->dev;
	struct net_device *dev = skb->dev;
	struct net *net = dev_net(dev);
	struct dst_entry *dst;
	struct dst_entry *dst;
	int err, ret = NET_XMIT_DROP;
	int err, ret = NET_XMIT_DROP;
	struct flowi6 fl6 = {
	struct flowi6 fl6 = {
@@ -393,7 +395,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
		.flowi6_proto = ip6h->nexthdr,
		.flowi6_proto = ip6h->nexthdr,
	};
	};


	dst = ip6_route_output(dev_net(dev), NULL, &fl6);
	dst = ip6_route_output(net, NULL, &fl6);
	if (dst->error) {
	if (dst->error) {
		ret = dst->error;
		ret = dst->error;
		dst_release(dst);
		dst_release(dst);
@@ -401,7 +403,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
	}
	}
	skb_dst_drop(skb);
	skb_dst_drop(skb);
	skb_dst_set(skb, dst);
	skb_dst_set(skb, dst);
	err = ip6_local_out(skb);
	err = ip6_local_out(net, skb->sk, skb);
	if (unlikely(net_xmit_eval(err)))
	if (unlikely(net_xmit_eval(err)))
		dev->stats.tx_errors++;
		dev->stats.tx_errors++;
	else
	else
+4 −3
Original line number Original line Diff line number Diff line
@@ -169,6 +169,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
{
{
	struct sock *sk = (struct sock *) chan->private;
	struct sock *sk = (struct sock *) chan->private;
	struct pppox_sock *po = pppox_sk(sk);
	struct pppox_sock *po = pppox_sk(sk);
	struct net *net = sock_net(sk);
	struct pptp_opt *opt = &po->proto.pptp;
	struct pptp_opt *opt = &po->proto.pptp;
	struct pptp_gre_header *hdr;
	struct pptp_gre_header *hdr;
	unsigned int header_len = sizeof(*hdr);
	unsigned int header_len = sizeof(*hdr);
@@ -187,7 +188,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
	if (sk_pppox(po)->sk_state & PPPOX_DEAD)
	if (sk_pppox(po)->sk_state & PPPOX_DEAD)
		goto tx_error;
		goto tx_error;


	rt = ip_route_output_ports(sock_net(sk), &fl4, NULL,
	rt = ip_route_output_ports(net, &fl4, NULL,
				   opt->dst_addr.sin_addr.s_addr,
				   opt->dst_addr.sin_addr.s_addr,
				   opt->src_addr.sin_addr.s_addr,
				   opt->src_addr.sin_addr.s_addr,
				   0, 0, IPPROTO_GRE,
				   0, 0, IPPROTO_GRE,
@@ -279,10 +280,10 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
	nf_reset(skb);
	nf_reset(skb);


	skb->ip_summed = CHECKSUM_NONE;
	skb->ip_summed = CHECKSUM_NONE;
	ip_select_ident(sock_net(sk), skb, NULL);
	ip_select_ident(net, skb, NULL);
	ip_send_check(iph);
	ip_send_check(iph);


	ip_local_out(skb);
	ip_local_out(net, skb->sk, skb);
	return 1;
	return 1;


tx_error:
tx_error:
+4 −5
Original line number Original line Diff line number Diff line
@@ -74,9 +74,9 @@ static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie)
	return dst;
	return dst;
}
}


static int vrf_ip_local_out(struct sk_buff *skb)
static int vrf_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
{
{
	return ip_local_out(skb);
	return ip_local_out(net, sk, skb);
}
}


static unsigned int vrf_v4_mtu(const struct dst_entry *dst)
static unsigned int vrf_v4_mtu(const struct dst_entry *dst)
@@ -222,7 +222,7 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
					       RT_SCOPE_LINK);
					       RT_SCOPE_LINK);
	}
	}


	ret = ip_local_out(skb);
	ret = ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb);
	if (unlikely(net_xmit_eval(ret)))
	if (unlikely(net_xmit_eval(ret)))
		vrf_dev->stats.tx_errors++;
		vrf_dev->stats.tx_errors++;
	else
	else
@@ -312,10 +312,9 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
	return ret;
	return ret;
}
}


static int vrf_output(struct sock *sk, struct sk_buff *skb)
static int vrf_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
{
	struct net_device *dev = skb_dst(skb)->dev;
	struct net_device *dev = skb_dst(skb)->dev;
	struct net *net = dev_net(dev);


	IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);
	IP_UPD_PO_STATS(net, IPSTATS_MIB_OUT, skb->len);


+5 −9
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 sock *sk, struct sk_buff *skb);
	int			(*output)(struct net *net, struct sock *sk, struct sk_buff *skb);


	unsigned short		flags;
	unsigned short		flags;
#define DST_HOST		0x0001
#define DST_HOST		0x0001
@@ -365,10 +365,10 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
	__skb_tunnel_rx(skb, dev, net);
	__skb_tunnel_rx(skb, dev, net);
}
}


int dst_discard_sk(struct sock *sk, struct sk_buff *skb);
int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
static inline int dst_discard(struct sk_buff *skb)
static inline int dst_discard(struct sk_buff *skb)
{
{
	return dst_discard_sk(skb->sk, skb);
	return dst_discard_out(&init_net, 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);
@@ -454,13 +454,9 @@ 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(struct sock *sk, struct sk_buff *skb)
static inline int dst_output(struct net *net, struct sock *sk, struct sk_buff *skb)
{
{
	return skb_dst(skb)->output(sk, skb);
	return skb_dst(skb)->output(net, sk, skb);
}
static inline int dst_output_okfn(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	return dst_output(sk, skb);
}
}


/* Input packet from network to transport.  */
/* Input packet from network to transport.  */
+2 −1
Original line number Original line Diff line number Diff line
@@ -9,6 +9,7 @@ struct kmem_cachep;
struct net_device;
struct net_device;
struct sk_buff;
struct sk_buff;
struct sock;
struct sock;
struct net;


struct dst_ops {
struct dst_ops {
	unsigned short		family;
	unsigned short		family;
@@ -28,7 +29,7 @@ struct dst_ops {
					       struct sk_buff *skb, u32 mtu);
					       struct sk_buff *skb, u32 mtu);
	void			(*redirect)(struct dst_entry *dst, struct sock *sk,
	void			(*redirect)(struct dst_entry *dst, struct sock *sk,
					    struct sk_buff *skb);
					    struct sk_buff *skb);
	int			(*local_out)(struct sk_buff *skb);
	int			(*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb);
	struct neighbour *	(*neigh_lookup)(const struct dst_entry *dst,
	struct neighbour *	(*neigh_lookup)(const struct dst_entry *dst,
						struct sk_buff *skb,
						struct sk_buff *skb,
						const void *daddr);
						const void *daddr);
Loading