Skip to content

Commit e622517

Browse files
q2vengregkh
authored andcommitted
gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
[ Upstream commit 46841c7 ] gtp_newlink() links the gtp device to a list in dev_net(dev). However, even after the gtp device is moved to another netns, it stays on the list but should be invisible. Let's use for_each_netdev_rcu() for netdev traversal in gtp_genl_dump_pdp(). Note that gtp_dev_list is no longer used under RCU, so list helpers are converted to the non-RCU variant. Fixes: 459aa66 ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") Reported-by: Xiao Liang <[email protected]> Closes: https://lore.kernel.org/netdev/CABAhCOQdBL6h9M2C+kd+bGivRJ9Q72JUxW+-gur0nub_=PmFPA@mail.gmail.com/ Signed-off-by: Kuniyuki Iwashima <[email protected]> Signed-off-by: Paolo Abeni <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent d0fb574 commit e622517

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

drivers/net/gtp.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
15271527
}
15281528

15291529
gn = net_generic(dev_net(dev), gtp_net_id);
1530-
list_add_rcu(&gtp->list, &gn->gtp_dev_list);
1530+
list_add(&gtp->list, &gn->gtp_dev_list);
15311531
dev->priv_destructor = gtp_destructor;
15321532

15331533
netdev_dbg(dev, "registered new GTP interface\n");
@@ -1553,7 +1553,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head)
15531553
hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid)
15541554
pdp_context_delete(pctx);
15551555

1556-
list_del_rcu(&gtp->list);
1556+
list_del(&gtp->list);
15571557
unregister_netdevice_queue(dev, head);
15581558
}
15591559

@@ -2279,16 +2279,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
22792279
struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
22802280
int i, j, bucket = cb->args[0], skip = cb->args[1];
22812281
struct net *net = sock_net(skb->sk);
2282+
struct net_device *dev;
22822283
struct pdp_ctx *pctx;
2283-
struct gtp_net *gn;
2284-
2285-
gn = net_generic(net, gtp_net_id);
22862284

22872285
if (cb->args[4])
22882286
return 0;
22892287

22902288
rcu_read_lock();
2291-
list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
2289+
for_each_netdev_rcu(net, dev) {
2290+
if (dev->rtnl_link_ops != &gtp_link_ops)
2291+
continue;
2292+
2293+
gtp = netdev_priv(dev);
2294+
22922295
if (last_gtp && last_gtp != gtp)
22932296
continue;
22942297
else
@@ -2483,9 +2486,9 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
24832486

24842487
list_for_each_entry(net, net_list, exit_list) {
24852488
struct gtp_net *gn = net_generic(net, gtp_net_id);
2486-
struct gtp_dev *gtp;
2489+
struct gtp_dev *gtp, *gtp_next;
24872490

2488-
list_for_each_entry(gtp, &gn->gtp_dev_list, list)
2491+
list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
24892492
gtp_dellink(gtp->dev, dev_to_kill);
24902493
}
24912494
}

0 commit comments

Comments
 (0)