Skip to content

Commit 636af13

Browse files
q2venkuba-moo
authored andcommitted
rtnetlink: Register rtnl_dellink() and rtnl_setlink() with RTNL_FLAG_DOIT_PERNET_WIP.
Currently, rtnl_setlink() and rtnl_dellink() cannot be fully converted to per-netns RTNL due to a lack of handling peer/lower/upper devices in different netns. For example, when we change a device in rtnl_setlink() and need to propagate that to its upper devices, we want to avoid acquiring all netns locks, for which we do not know the upper limit. The same situation happens when we remove a device. rtnl_dellink() could be transformed to remove a single device in the requested netns and delegate other devices to per-netns work, and rtnl_setlink() might be ? Until we come up with a better idea, let's use a new flag RTNL_FLAG_DOIT_PERNET_WIP for rtnl_dellink() and rtnl_setlink(). This will unblock converting RTNL users where such devices are not related. Signed-off-by: Kuniyuki Iwashima <[email protected]> Reviewed-by: Nikolay Aleksandrov <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent d91191f commit 636af13

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

include/net/rtnetlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
1313
enum rtnl_link_flags {
1414
RTNL_FLAG_DOIT_UNLOCKED = BIT(0),
1515
#define RTNL_FLAG_DOIT_PERNET RTNL_FLAG_DOIT_UNLOCKED
16+
#define RTNL_FLAG_DOIT_PERNET_WIP RTNL_FLAG_DOIT_UNLOCKED
1617
RTNL_FLAG_BULK_DEL_SUPPORTED = BIT(1),
1718
RTNL_FLAG_DUMP_UNLOCKED = BIT(2),
1819
RTNL_FLAG_DUMP_SPLIT_NLM_DONE = BIT(3), /* legacy behavior */

net/core/rtnetlink.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3379,6 +3379,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
33793379
struct net *net = sock_net(skb->sk);
33803380
struct nlattr *tb[IFLA_MAX+1];
33813381
struct net_device *dev = NULL;
3382+
struct rtnl_nets rtnl_nets;
33823383
struct net *tgt_net;
33833384
int err;
33843385

@@ -3397,6 +3398,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
33973398
goto errout;
33983399
}
33993400

3401+
rtnl_nets_init(&rtnl_nets);
3402+
rtnl_nets_add(&rtnl_nets, get_net(net));
3403+
rtnl_nets_add(&rtnl_nets, tgt_net);
3404+
3405+
rtnl_nets_lock(&rtnl_nets);
3406+
34003407
if (ifm->ifi_index > 0)
34013408
dev = __dev_get_by_index(net, ifm->ifi_index);
34023409
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
@@ -3409,7 +3416,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
34093416
else if (!err)
34103417
err = -ENODEV;
34113418

3412-
put_net(tgt_net);
3419+
rtnl_nets_unlock(&rtnl_nets);
34133420
errout:
34143421
return err;
34153422
}
@@ -3494,6 +3501,8 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
34943501
return PTR_ERR(tgt_net);
34953502
}
34963503

3504+
rtnl_net_lock(tgt_net);
3505+
34973506
if (ifm->ifi_index > 0)
34983507
dev = __dev_get_by_index(tgt_net, ifm->ifi_index);
34993508
else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME])
@@ -3508,6 +3517,8 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh,
35083517
else
35093518
err = -EINVAL;
35103519

3520+
rtnl_net_unlock(tgt_net);
3521+
35113522
if (netnsid >= 0)
35123523
put_net(tgt_net);
35133524

@@ -6994,10 +7005,12 @@ static struct pernet_operations rtnetlink_net_ops = {
69947005
static const struct rtnl_msg_handler rtnetlink_rtnl_msg_handlers[] __initconst = {
69957006
{.msgtype = RTM_NEWLINK, .doit = rtnl_newlink,
69967007
.flags = RTNL_FLAG_DOIT_PERNET},
6997-
{.msgtype = RTM_DELLINK, .doit = rtnl_dellink},
7008+
{.msgtype = RTM_DELLINK, .doit = rtnl_dellink,
7009+
.flags = RTNL_FLAG_DOIT_PERNET_WIP},
69987010
{.msgtype = RTM_GETLINK, .doit = rtnl_getlink,
69997011
.dumpit = rtnl_dump_ifinfo, .flags = RTNL_FLAG_DUMP_SPLIT_NLM_DONE},
7000-
{.msgtype = RTM_SETLINK, .doit = rtnl_setlink},
7012+
{.msgtype = RTM_SETLINK, .doit = rtnl_setlink,
7013+
.flags = RTNL_FLAG_DOIT_PERNET_WIP},
70017014
{.msgtype = RTM_GETADDR, .dumpit = rtnl_dump_all},
70027015
{.msgtype = RTM_GETROUTE, .dumpit = rtnl_dump_all},
70037016
{.msgtype = RTM_GETNETCONF, .dumpit = rtnl_dump_all},

0 commit comments

Comments
 (0)