Skip to content

Commit 442bb4b

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) In TCP, don't register an FRTO for cumulatively ACK'd data that was previously SACK'd, from Neal Cardwell. 2) Need to hold RNL mutex in ipv4 multicast code namespace cleanup, from Cong WANG. 3) Similarly we have to hold RNL mutex for fib_rules_unregister(), also from Cong WANG. 4) Revert and rework netns nsid allocation fix, from Nicolas Dichtel. 5) When we encapsulate for a tunnel device, skb->sk still points to the user socket. So this leads to cases where we retraverse the ipv4/ipv6 output path with skb->sk being of some other address family (f.e. AF_PACKET). This can cause things to crash since the ipv4 output path is dereferencing an AF_PACKET socket as if it were an ipv4 one. The short term fix for 'net' and -stable is to elide these socket checks once we've entered an encapsulation sequence by testing xmit_recursion. Longer term we have a better solution wherein we pass the tunnel's socket down through the output paths, but that is way too invasive for 'net' and -stable. From Hannes Frederic Sowa. 6) l2tp_init() failure path forgets to unregister per-net ops, from Cong WANG. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: net/mlx4_core: Fix error message deprecation for ConnectX-2 cards net: dsa: fix filling routing table from OF description l2tp: unregister l2tp_net_ops on failure path mvneta: dont call mvneta_adjust_link() manually ipv6: protect skb->sk accesses from recursive dereference inside the stack netns: don't allocate an id for dead netns Revert "netns: don't clear nsid too early on removal" ip6mr: call del_timer_sync() in ip6mr_free_table() net: move fib_rules_unregister() under rtnl lock ipv4: take rtnl_lock and mark mrt table as freed on namespace cleanup tcp: fix FRTO undo on cumulative ACK of SACKed range xen-netfront: transmit fully GSO-sized packets
2 parents 9e44163 + fde913e commit 442bb4b

File tree

21 files changed

+78
-71
lines changed

21 files changed

+78
-71
lines changed

Documentation/devicetree/bindings/net/dsa/dsa.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ the parent DSA node. The maximum number of allowed child nodes is 4
1919
(DSA_MAX_SWITCHES).
2020
Each of these switch child nodes should have the following required properties:
2121

22-
- reg : Describes the switch address on the MII bus
22+
- reg : Contains two fields. The first one describes the
23+
address on the MII bus. The second is the switch
24+
number that must be unique in cascaded configurations
2325
- #address-cells : Must be 1
2426
- #size-cells : Must be 0
2527

drivers/net/ethernet/marvell/mvneta.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,16 +2658,11 @@ static int mvneta_stop(struct net_device *dev)
26582658
static int mvneta_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
26592659
{
26602660
struct mvneta_port *pp = netdev_priv(dev);
2661-
int ret;
26622661

26632662
if (!pp->phy_dev)
26642663
return -ENOTSUPP;
26652664

2666-
ret = phy_mii_ioctl(pp->phy_dev, ifr, cmd);
2667-
if (!ret)
2668-
mvneta_adjust_link(dev);
2669-
2670-
return ret;
2665+
return phy_mii_ioctl(pp->phy_dev, ifr, cmd);
26712666
}
26722667

26732668
/* Ethtool methods */

drivers/net/ethernet/mellanox/mlx4/cmd.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,8 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param,
724724
* on the host, we deprecate the error message for this
725725
* specific command/input_mod/opcode_mod/fw-status to be debug.
726726
*/
727-
if (op == MLX4_CMD_SET_PORT && in_modifier == 1 &&
727+
if (op == MLX4_CMD_SET_PORT &&
728+
(in_modifier == 1 || in_modifier == 2) &&
728729
op_modifier == 0 && context->fw_status == CMD_STAT_BAD_SIZE)
729730
mlx4_dbg(dev, "command 0x%x failed: fw status = 0x%x\n",
730731
op, context->fw_status);

drivers/net/xen-netfront.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,8 +1008,7 @@ static int xennet_poll(struct napi_struct *napi, int budget)
10081008

10091009
static int xennet_change_mtu(struct net_device *dev, int mtu)
10101010
{
1011-
int max = xennet_can_sg(dev) ?
1012-
XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER : ETH_DATA_LEN;
1011+
int max = xennet_can_sg(dev) ? XEN_NETIF_MAX_TX_SIZE : ETH_DATA_LEN;
10131012

10141013
if (mtu > max)
10151014
return -EINVAL;
@@ -1279,8 +1278,6 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
12791278
netdev->ethtool_ops = &xennet_ethtool_ops;
12801279
SET_NETDEV_DEV(netdev, &dev->dev);
12811280

1282-
netif_set_gso_max_size(netdev, XEN_NETIF_MAX_TX_SIZE - MAX_TCP_HEADER);
1283-
12841281
np->netdev = netdev;
12851282

12861283
netif_carrier_off(netdev);

include/linux/netdevice.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,12 @@ void netdev_freemem(struct net_device *dev);
21852185
void synchronize_net(void);
21862186
int init_dummy_netdev(struct net_device *dev);
21872187

2188+
DECLARE_PER_CPU(int, xmit_recursion);
2189+
static inline int dev_recursion_level(void)
2190+
{
2191+
return this_cpu_read(xmit_recursion);
2192+
}
2193+
21882194
struct net_device *dev_get_by_index(struct net *net, int ifindex);
21892195
struct net_device *__dev_get_by_index(struct net *net, int ifindex);
21902196
struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);

include/net/ip.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -453,22 +453,6 @@ static __inline__ void inet_reset_saddr(struct sock *sk)
453453

454454
#endif
455455

456-
static inline int sk_mc_loop(struct sock *sk)
457-
{
458-
if (!sk)
459-
return 1;
460-
switch (sk->sk_family) {
461-
case AF_INET:
462-
return inet_sk(sk)->mc_loop;
463-
#if IS_ENABLED(CONFIG_IPV6)
464-
case AF_INET6:
465-
return inet6_sk(sk)->mc_loop;
466-
#endif
467-
}
468-
WARN_ON(1);
469-
return 1;
470-
}
471-
472456
bool ip_call_ra_chain(struct sk_buff *skb);
473457

474458
/*

include/net/ip6_route.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
174174

175175
static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
176176
{
177-
struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
177+
struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
178+
inet6_sk(skb->sk) : NULL;
178179

179180
return (np && np->pmtudisc >= IPV6_PMTUDISC_PROBE) ?
180181
skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));

include/net/sock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,8 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie);
17621762

17631763
struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie);
17641764

1765+
bool sk_mc_loop(struct sock *sk);
1766+
17651767
static inline bool sk_can_gso(const struct sock *sk)
17661768
{
17671769
return net_gso_ok(sk->sk_route_caps, sk->sk_gso_type);

net/core/dev.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2848,7 +2848,9 @@ static void skb_update_prio(struct sk_buff *skb)
28482848
#define skb_update_prio(skb)
28492849
#endif
28502850

2851-
static DEFINE_PER_CPU(int, xmit_recursion);
2851+
DEFINE_PER_CPU(int, xmit_recursion);
2852+
EXPORT_SYMBOL(xmit_recursion);
2853+
28522854
#define RECURSION_LIMIT 10
28532855

28542856
/**

net/core/fib_rules.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ void fib_rules_unregister(struct fib_rules_ops *ops)
175175

176176
spin_lock(&net->rules_mod_lock);
177177
list_del_rcu(&ops->list);
178-
fib_rules_cleanup_ops(ops);
179178
spin_unlock(&net->rules_mod_lock);
180179

180+
fib_rules_cleanup_ops(ops);
181181
call_rcu(&ops->rcu, fib_rules_put_rcu);
182182
}
183183
EXPORT_SYMBOL_GPL(fib_rules_unregister);

net/core/net_namespace.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,10 @@ static int __peernet2id(struct net *net, struct net *peer, bool alloc)
198198
*/
199199
int peernet2id(struct net *net, struct net *peer)
200200
{
201-
int id = __peernet2id(net, peer, true);
201+
bool alloc = atomic_read(&peer->count) == 0 ? false : true;
202+
int id;
202203

204+
id = __peernet2id(net, peer, alloc);
203205
return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED;
204206
}
205207
EXPORT_SYMBOL(peernet2id);
@@ -349,7 +351,7 @@ static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */
349351
static void cleanup_net(struct work_struct *work)
350352
{
351353
const struct pernet_operations *ops;
352-
struct net *net, *tmp, *peer;
354+
struct net *net, *tmp;
353355
struct list_head net_kill_list;
354356
LIST_HEAD(net_exit_list);
355357

@@ -365,6 +367,14 @@ static void cleanup_net(struct work_struct *work)
365367
list_for_each_entry(net, &net_kill_list, cleanup_list) {
366368
list_del_rcu(&net->list);
367369
list_add_tail(&net->exit_list, &net_exit_list);
370+
for_each_net(tmp) {
371+
int id = __peernet2id(tmp, net, false);
372+
373+
if (id >= 0)
374+
idr_remove(&tmp->netns_ids, id);
375+
}
376+
idr_destroy(&net->netns_ids);
377+
368378
}
369379
rtnl_unlock();
370380

@@ -390,26 +400,12 @@ static void cleanup_net(struct work_struct *work)
390400
*/
391401
rcu_barrier();
392402

393-
rtnl_lock();
394403
/* Finally it is safe to free my network namespace structure */
395404
list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
396-
/* Unreference net from all peers (no need to loop over
397-
* net_exit_list because idr_destroy() will be called for each
398-
* element of this list.
399-
*/
400-
for_each_net(peer) {
401-
int id = __peernet2id(peer, net, false);
402-
403-
if (id >= 0)
404-
idr_remove(&peer->netns_ids, id);
405-
}
406-
idr_destroy(&net->netns_ids);
407-
408405
list_del_init(&net->exit_list);
409406
put_user_ns(net->user_ns);
410407
net_drop_ns(net);
411408
}
412-
rtnl_unlock();
413409
}
414410
static DECLARE_WORK(net_cleanup_work, cleanup_net);
415411

net/core/sock.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,25 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
653653
sock_reset_flag(sk, bit);
654654
}
655655

656+
bool sk_mc_loop(struct sock *sk)
657+
{
658+
if (dev_recursion_level())
659+
return false;
660+
if (!sk)
661+
return true;
662+
switch (sk->sk_family) {
663+
case AF_INET:
664+
return inet_sk(sk)->mc_loop;
665+
#if IS_ENABLED(CONFIG_IPV6)
666+
case AF_INET6:
667+
return inet6_sk(sk)->mc_loop;
668+
#endif
669+
}
670+
WARN_ON(1);
671+
return true;
672+
}
673+
EXPORT_SYMBOL(sk_mc_loop);
674+
656675
/*
657676
* This is meant for all protocols to use and covers goings on
658677
* at the socket level. Everything here is generic.

net/decnet/dn_rules.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,9 @@ void __init dn_fib_rules_init(void)
248248

249249
void __exit dn_fib_rules_cleanup(void)
250250
{
251+
rtnl_lock();
251252
fib_rules_unregister(dn_fib_rules_ops);
253+
rtnl_unlock();
252254
rcu_barrier();
253255
}
254256

net/dsa/dsa.c

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -501,12 +501,10 @@ static struct net_device *dev_to_net_device(struct device *dev)
501501
#ifdef CONFIG_OF
502502
static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
503503
struct dsa_chip_data *cd,
504-
int chip_index,
504+
int chip_index, int port_index,
505505
struct device_node *link)
506506
{
507-
int ret;
508507
const __be32 *reg;
509-
int link_port_addr;
510508
int link_sw_addr;
511509
struct device_node *parent_sw;
512510
int len;
@@ -519,6 +517,10 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
519517
if (!reg || (len != sizeof(*reg) * 2))
520518
return -EINVAL;
521519

520+
/*
521+
* Get the destination switch number from the second field of its 'reg'
522+
* property, i.e. for "reg = <0x19 1>" sw_addr is '1'.
523+
*/
522524
link_sw_addr = be32_to_cpup(reg + 1);
523525

524526
if (link_sw_addr >= pd->nr_chips)
@@ -535,20 +537,9 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd,
535537
memset(cd->rtable, -1, pd->nr_chips * sizeof(s8));
536538
}
537539

538-
reg = of_get_property(link, "reg", NULL);
539-
if (!reg) {
540-
ret = -EINVAL;
541-
goto out;
542-
}
543-
544-
link_port_addr = be32_to_cpup(reg);
545-
546-
cd->rtable[link_sw_addr] = link_port_addr;
540+
cd->rtable[link_sw_addr] = port_index;
547541

548542
return 0;
549-
out:
550-
kfree(cd->rtable);
551-
return ret;
552543
}
553544

554545
static void dsa_of_free_platform_data(struct dsa_platform_data *pd)
@@ -658,7 +649,7 @@ static int dsa_of_probe(struct platform_device *pdev)
658649
if (!strcmp(port_name, "dsa") && link &&
659650
pd->nr_chips > 1) {
660651
ret = dsa_of_setup_routing_table(pd, cd,
661-
chip_index, link);
652+
chip_index, port_index, link);
662653
if (ret)
663654
goto out_free_chip;
664655
}

net/ipv4/fib_frontend.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,11 +1111,10 @@ static void ip_fib_net_exit(struct net *net)
11111111
{
11121112
unsigned int i;
11131113

1114+
rtnl_lock();
11141115
#ifdef CONFIG_IP_MULTIPLE_TABLES
11151116
fib4_rules_exit(net);
11161117
#endif
1117-
1118-
rtnl_lock();
11191118
for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
11201119
struct fib_table *tb;
11211120
struct hlist_head *head;

net/ipv4/ipmr.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,13 @@ static void __net_exit ipmr_rules_exit(struct net *net)
278278
{
279279
struct mr_table *mrt, *next;
280280

281+
rtnl_lock();
281282
list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) {
282283
list_del(&mrt->list);
283284
ipmr_free_table(mrt);
284285
}
285286
fib_rules_unregister(net->ipv4.mr_rules_ops);
287+
rtnl_unlock();
286288
}
287289
#else
288290
#define ipmr_for_each_table(mrt, net) \
@@ -308,7 +310,10 @@ static int __net_init ipmr_rules_init(struct net *net)
308310

309311
static void __net_exit ipmr_rules_exit(struct net *net)
310312
{
313+
rtnl_lock();
311314
ipmr_free_table(net->ipv4.mrt);
315+
net->ipv4.mrt = NULL;
316+
rtnl_unlock();
312317
}
313318
#endif
314319

net/ipv4/tcp_input.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3105,10 +3105,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
31053105
if (!first_ackt.v64)
31063106
first_ackt = last_ackt;
31073107

3108-
if (!(sacked & TCPCB_SACKED_ACKED))
3108+
if (!(sacked & TCPCB_SACKED_ACKED)) {
31093109
reord = min(pkts_acked, reord);
3110-
if (!after(scb->end_seq, tp->high_seq))
3111-
flag |= FLAG_ORIG_SACK_ACKED;
3110+
if (!after(scb->end_seq, tp->high_seq))
3111+
flag |= FLAG_ORIG_SACK_ACKED;
3112+
}
31123113
}
31133114

31143115
if (sacked & TCPCB_SACKED_ACKED)

net/ipv6/fib6_rules.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,9 @@ static int __net_init fib6_rules_net_init(struct net *net)
322322

323323
static void __net_exit fib6_rules_net_exit(struct net *net)
324324
{
325+
rtnl_lock();
325326
fib_rules_unregister(net->ipv6.fib6_rules_ops);
327+
rtnl_unlock();
326328
}
327329

328330
static struct pernet_operations fib6_rules_net_ops = {

net/ipv6/ip6_output.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,8 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
542542
{
543543
struct sk_buff *frag;
544544
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
545-
struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
545+
struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
546+
inet6_sk(skb->sk) : NULL;
546547
struct ipv6hdr *tmp_hdr;
547548
struct frag_hdr *fh;
548549
unsigned int mtu, hlen, left, len;

net/ipv6/ip6mr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ static void __net_exit ip6mr_rules_exit(struct net *net)
267267
list_del(&mrt->list);
268268
ip6mr_free_table(mrt);
269269
}
270-
rtnl_unlock();
271270
fib_rules_unregister(net->ipv6.mr6_rules_ops);
271+
rtnl_unlock();
272272
}
273273
#else
274274
#define ip6mr_for_each_table(mrt, net) \
@@ -336,7 +336,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
336336

337337
static void ip6mr_free_table(struct mr6_table *mrt)
338338
{
339-
del_timer(&mrt->ipmr_expire_timer);
339+
del_timer_sync(&mrt->ipmr_expire_timer);
340340
mroute_clean_tables(mrt);
341341
kfree(mrt);
342342
}

net/l2tp/l2tp_core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,7 @@ static int __init l2tp_init(void)
18711871
l2tp_wq = alloc_workqueue("l2tp", WQ_UNBOUND, 0);
18721872
if (!l2tp_wq) {
18731873
pr_err("alloc_workqueue failed\n");
1874+
unregister_pernet_device(&l2tp_net_ops);
18741875
rc = -ENOMEM;
18751876
goto out;
18761877
}

0 commit comments

Comments
 (0)