Skip to content

Commit 46841c7

Browse files
q2venPaolo Abeni
authored and
Paolo Abeni
committed
gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
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]>
1 parent 644f910 commit 46841c7

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

drivers/net/gtp.c

+11-8
Original file line numberDiff line numberDiff line change
@@ -1525,7 +1525,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
15251525
}
15261526

15271527
gn = net_generic(dev_net(dev), gtp_net_id);
1528-
list_add_rcu(&gtp->list, &gn->gtp_dev_list);
1528+
list_add(&gtp->list, &gn->gtp_dev_list);
15291529
dev->priv_destructor = gtp_destructor;
15301530

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

1554-
list_del_rcu(&gtp->list);
1554+
list_del(&gtp->list);
15551555
unregister_netdevice_queue(dev, head);
15561556
}
15571557

@@ -2271,16 +2271,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb,
22712271
struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
22722272
int i, j, bucket = cb->args[0], skip = cb->args[1];
22732273
struct net *net = sock_net(skb->sk);
2274+
struct net_device *dev;
22742275
struct pdp_ctx *pctx;
2275-
struct gtp_net *gn;
2276-
2277-
gn = net_generic(net, gtp_net_id);
22782276

22792277
if (cb->args[4])
22802278
return 0;
22812279

22822280
rcu_read_lock();
2283-
list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
2281+
for_each_netdev_rcu(net, dev) {
2282+
if (dev->rtnl_link_ops != &gtp_link_ops)
2283+
continue;
2284+
2285+
gtp = netdev_priv(dev);
2286+
22842287
if (last_gtp && last_gtp != gtp)
22852288
continue;
22862289
else
@@ -2475,9 +2478,9 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
24752478

24762479
list_for_each_entry(net, net_list, exit_list) {
24772480
struct gtp_net *gn = net_generic(net, gtp_net_id);
2478-
struct gtp_dev *gtp;
2481+
struct gtp_dev *gtp, *gtp_next;
24792482

2480-
list_for_each_entry(gtp, &gn->gtp_dev_list, list)
2483+
list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
24812484
gtp_dellink(gtp->dev, dev_to_kill);
24822485
}
24832486
}

0 commit comments

Comments
 (0)