Skip to content

Commit 6b92d0c

Browse files
committed
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: David S. Miller <[email protected]>
2 parents e28383d + ede2059 commit 6b92d0c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+125
-155
lines changed

drivers/net/ipvlan/ipvlan_core.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
344344
{
345345
const struct iphdr *ip4h = ip_hdr(skb);
346346
struct net_device *dev = skb->dev;
347+
struct net *net = dev_net(dev);
347348
struct rtable *rt;
348349
int err, ret = NET_XMIT_DROP;
349350
struct flowi4 fl4 = {
@@ -354,7 +355,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
354355
.saddr = ip4h->saddr,
355356
};
356357

357-
rt = ip_route_output_flow(dev_net(dev), &fl4, NULL);
358+
rt = ip_route_output_flow(net, &fl4, NULL);
358359
if (IS_ERR(rt))
359360
goto err;
360361

@@ -364,7 +365,7 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
364365
}
365366
skb_dst_drop(skb);
366367
skb_dst_set(skb, &rt->dst);
367-
err = ip_local_out(skb);
368+
err = ip_local_out(net, skb->sk, skb);
368369
if (unlikely(net_xmit_eval(err)))
369370
dev->stats.tx_errors++;
370371
else
@@ -381,6 +382,7 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
381382
{
382383
const struct ipv6hdr *ip6h = ipv6_hdr(skb);
383384
struct net_device *dev = skb->dev;
385+
struct net *net = dev_net(dev);
384386
struct dst_entry *dst;
385387
int err, ret = NET_XMIT_DROP;
386388
struct flowi6 fl6 = {
@@ -393,15 +395,15 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
393395
.flowi6_proto = ip6h->nexthdr,
394396
};
395397

396-
dst = ip6_route_output(dev_net(dev), NULL, &fl6);
398+
dst = ip6_route_output(net, NULL, &fl6);
397399
if (dst->error) {
398400
ret = dst->error;
399401
dst_release(dst);
400402
goto err;
401403
}
402404
skb_dst_drop(skb);
403405
skb_dst_set(skb, dst);
404-
err = ip6_local_out(skb);
406+
err = ip6_local_out(net, skb->sk, skb);
405407
if (unlikely(net_xmit_eval(err)))
406408
dev->stats.tx_errors++;
407409
else

drivers/net/ppp/pptp.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
169169
{
170170
struct sock *sk = (struct sock *) chan->private;
171171
struct pppox_sock *po = pppox_sk(sk);
172+
struct net *net = sock_net(sk);
172173
struct pptp_opt *opt = &po->proto.pptp;
173174
struct pptp_gre_header *hdr;
174175
unsigned int header_len = sizeof(*hdr);
@@ -187,7 +188,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
187188
if (sk_pppox(po)->sk_state & PPPOX_DEAD)
188189
goto tx_error;
189190

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

281282
skb->ip_summed = CHECKSUM_NONE;
282-
ip_select_ident(sock_net(sk), skb, NULL);
283+
ip_select_ident(net, skb, NULL);
283284
ip_send_check(iph);
284285

285-
ip_local_out(skb);
286+
ip_local_out(net, skb->sk, skb);
286287
return 1;
287288

288289
tx_error:

drivers/net/vrf.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ static struct dst_entry *vrf_ip_check(struct dst_entry *dst, u32 cookie)
7474
return dst;
7575
}
7676

77-
static int vrf_ip_local_out(struct sk_buff *skb)
77+
static int vrf_ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
7878
{
79-
return ip_local_out(skb);
79+
return ip_local_out(net, sk, skb);
8080
}
8181

8282
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,
222222
RT_SCOPE_LINK);
223223
}
224224

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

315-
static int vrf_output(struct sock *sk, struct sk_buff *skb)
315+
static int vrf_output(struct net *net, struct sock *sk, struct sk_buff *skb)
316316
{
317317
struct net_device *dev = skb_dst(skb)->dev;
318-
struct net *net = dev_net(dev);
319318

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

include/net/dst.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct dst_entry {
4545
void *__pad1;
4646
#endif
4747
int (*input)(struct sk_buff *);
48-
int (*output)(struct sock *sk, struct sk_buff *skb);
48+
int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
4949

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

368-
int dst_discard_sk(struct sock *sk, struct sk_buff *skb);
368+
int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
369369
static inline int dst_discard(struct sk_buff *skb)
370370
{
371-
return dst_discard_sk(skb->sk, skb);
371+
return dst_discard_out(&init_net, skb->sk, skb);
372372
}
373373
void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref,
374374
int initial_obsolete, unsigned short flags);
@@ -454,13 +454,9 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout)
454454
}
455455

456456
/* Output packet to network from transport. */
457-
static inline int dst_output(struct sock *sk, struct sk_buff *skb)
457+
static inline int dst_output(struct net *net, struct sock *sk, struct sk_buff *skb)
458458
{
459-
return skb_dst(skb)->output(sk, skb);
460-
}
461-
static inline int dst_output_okfn(struct net *net, struct sock *sk, struct sk_buff *skb)
462-
{
463-
return dst_output(sk, skb);
459+
return skb_dst(skb)->output(net, sk, skb);
464460
}
465461

466462
/* Input packet from network to transport. */

include/net/dst_ops.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ struct kmem_cachep;
99
struct net_device;
1010
struct sk_buff;
1111
struct sock;
12+
struct net;
1213

1314
struct dst_ops {
1415
unsigned short family;
@@ -28,7 +29,7 @@ struct dst_ops {
2829
struct sk_buff *skb, u32 mtu);
2930
void (*redirect)(struct dst_entry *dst, struct sock *sk,
3031
struct sk_buff *skb);
31-
int (*local_out)(struct sk_buff *skb);
32+
int (*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb);
3233
struct neighbour * (*neigh_lookup)(const struct dst_entry *dst,
3334
struct sk_buff *skb,
3435
const void *daddr);

include/net/ip.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,17 +107,13 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
107107
struct net_device *orig_dev);
108108
int ip_local_deliver(struct sk_buff *skb);
109109
int ip_mr_input(struct sk_buff *skb);
110-
int ip_output(struct sock *sk, struct sk_buff *skb);
111-
int ip_mc_output(struct sock *sk, struct sk_buff *skb);
110+
int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb);
111+
int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb);
112112
int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
113113
int (*output)(struct net *, struct sock *, struct sk_buff *));
114114
void ip_send_check(struct iphdr *ip);
115-
int __ip_local_out(struct sk_buff *skb);
116-
int ip_local_out_sk(struct sock *sk, struct sk_buff *skb);
117-
static inline int ip_local_out(struct sk_buff *skb)
118-
{
119-
return ip_local_out_sk(skb->sk, skb);
120-
}
115+
int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
116+
int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
121117

122118
int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl);
123119
void ip_init(void);

include/net/ip6_tunnel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
8787
int pkt_len, err;
8888

8989
pkt_len = skb->len - skb_inner_network_offset(skb);
90-
err = ip6_local_out_sk(sk, skb);
90+
err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb);
9191

9292
if (net_xmit_eval(err) == 0) {
9393
struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);

include/net/ipv6.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -860,14 +860,13 @@ struct dst_entry *ip6_blackhole_route(struct net *net,
860860
* skb processing functions
861861
*/
862862

863-
int ip6_output(struct sock *sk, struct sk_buff *skb);
863+
int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
864864
int ip6_forward(struct sk_buff *skb);
865865
int ip6_input(struct sk_buff *skb);
866866
int ip6_mc_input(struct sk_buff *skb);
867867

868-
int __ip6_local_out(struct sk_buff *skb);
869-
int ip6_local_out_sk(struct sock *sk, struct sk_buff *skb);
870-
int ip6_local_out(struct sk_buff *skb);
868+
int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
869+
int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
871870

872871
/*
873872
* Extension header (options) processing

include/net/lwtunnel.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct lwtunnel_state {
1818
__u16 type;
1919
__u16 flags;
2020
atomic_t refcnt;
21-
int (*orig_output)(struct sock *sk, struct sk_buff *skb);
21+
int (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb);
2222
int (*orig_input)(struct sk_buff *);
2323
int len;
2424
__u8 data[0];
@@ -28,7 +28,7 @@ struct lwtunnel_encap_ops {
2828
int (*build_state)(struct net_device *dev, struct nlattr *encap,
2929
unsigned int family, const void *cfg,
3030
struct lwtunnel_state **ts);
31-
int (*output)(struct sock *sk, struct sk_buff *skb);
31+
int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
3232
int (*input)(struct sk_buff *skb);
3333
int (*fill_encap)(struct sk_buff *skb,
3434
struct lwtunnel_state *lwtstate);
@@ -88,7 +88,7 @@ int lwtunnel_fill_encap(struct sk_buff *skb,
8888
int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
8989
struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
9090
int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
91-
int lwtunnel_output(struct sock *sk, struct sk_buff *skb);
91+
int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb);
9292
int lwtunnel_input(struct sk_buff *skb);
9393

9494
#else
@@ -160,7 +160,7 @@ static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
160160
return 0;
161161
}
162162

163-
static inline int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
163+
static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
164164
{
165165
return -EOPNOTSUPP;
166166
}

include/net/xfrm.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ struct xfrm_state_afinfo {
333333
const xfrm_address_t *saddr);
334334
int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n);
335335
int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n);
336-
int (*output)(struct sock *sk, struct sk_buff *skb);
336+
int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
337337
int (*output_finish)(struct sock *sk, struct sk_buff *skb);
338338
int (*extract_input)(struct xfrm_state *x,
339339
struct sk_buff *skb);
@@ -1527,7 +1527,7 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
15271527

15281528
int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb);
15291529
int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
1530-
int xfrm4_output(struct sock *sk, struct sk_buff *skb);
1530+
int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb);
15311531
int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb);
15321532
int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err);
15331533
int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol);
@@ -1552,7 +1552,7 @@ __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr);
15521552
__be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr);
15531553
int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb);
15541554
int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb);
1555-
int xfrm6_output(struct sock *sk, struct sk_buff *skb);
1555+
int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb);
15561556
int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb);
15571557
int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
15581558
u8 **prevhdr);

net/core/dst.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ static void dst_gc_task(struct work_struct *work)
144144
mutex_unlock(&dst_gc_mutex);
145145
}
146146

147-
int dst_discard_sk(struct sock *sk, struct sk_buff *skb)
147+
int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb)
148148
{
149149
kfree_skb(skb);
150150
return 0;
151151
}
152-
EXPORT_SYMBOL(dst_discard_sk);
152+
EXPORT_SYMBOL(dst_discard_out);
153153

154154
const u32 dst_default_metrics[RTAX_MAX + 1] = {
155155
/* This initializer is needed to force linker to place this variable
@@ -177,7 +177,7 @@ void dst_init(struct dst_entry *dst, struct dst_ops *ops,
177177
dst->xfrm = NULL;
178178
#endif
179179
dst->input = dst_discard;
180-
dst->output = dst_discard_sk;
180+
dst->output = dst_discard_out;
181181
dst->error = 0;
182182
dst->obsolete = initial_obsolete;
183183
dst->header_len = 0;
@@ -224,7 +224,7 @@ static void ___dst_free(struct dst_entry *dst)
224224
*/
225225
if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
226226
dst->input = dst_discard;
227-
dst->output = dst_discard_sk;
227+
dst->output = dst_discard_out;
228228
}
229229
dst->obsolete = DST_OBSOLETE_DEAD;
230230
}
@@ -352,7 +352,7 @@ static struct dst_ops md_dst_ops = {
352352
.family = AF_UNSPEC,
353353
};
354354

355-
static int dst_md_discard_sk(struct sock *sk, struct sk_buff *skb)
355+
static int dst_md_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb)
356356
{
357357
WARN_ONCE(1, "Attempting to call output on metadata dst\n");
358358
kfree_skb(skb);
@@ -375,7 +375,7 @@ static void __metadata_dst_init(struct metadata_dst *md_dst, u8 optslen)
375375
DST_METADATA | DST_NOCACHE | DST_NOCOUNT);
376376

377377
dst->input = dst_md_discard;
378-
dst->output = dst_md_discard_sk;
378+
dst->output = dst_md_discard_out;
379379

380380
memset(dst + 1, 0, sizeof(*md_dst) + optslen - sizeof(*dst));
381381
}
@@ -430,7 +430,7 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
430430

431431
if (!unregister) {
432432
dst->input = dst_discard;
433-
dst->output = dst_discard_sk;
433+
dst->output = dst_discard_out;
434434
} else {
435435
dst->dev = dev_net(dst->dev)->loopback_dev;
436436
dev_hold(dst->dev);

net/core/lwtunnel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
180180
}
181181
EXPORT_SYMBOL(lwtunnel_cmp_encap);
182182

183-
int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
183+
int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb)
184184
{
185185
struct dst_entry *dst = skb_dst(skb);
186186
const struct lwtunnel_encap_ops *ops;
@@ -199,7 +199,7 @@ int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
199199
rcu_read_lock();
200200
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
201201
if (likely(ops && ops->output))
202-
ret = ops->output(sk, skb);
202+
ret = ops->output(net, sk, skb);
203203
rcu_read_unlock();
204204

205205
if (ret == -EOPNOTSUPP)

net/decnet/dn_nsp_out.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static void dn_nsp_send(struct sk_buff *skb)
8585
if (dst) {
8686
try_again:
8787
skb_dst_set(skb, dst);
88-
dst_output(skb->sk, skb);
88+
dst_output(&init_net, skb->sk, skb);
8989
return;
9090
}
9191

@@ -582,7 +582,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
582582
* associations.
583583
*/
584584
skb_dst_set(skb, dst_clone(dst));
585-
dst_output(skb->sk, skb);
585+
dst_output(&init_net, skb->sk, skb);
586586
}
587587

588588

0 commit comments

Comments
 (0)