]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
rtnetlink: Lookup device in target netns when creating link
authorXiao Liang <shaw.leon@gmail.com>
Wed, 19 Feb 2025 12:50:27 +0000 (20:50 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 May 2025 09:13:11 +0000 (11:13 +0200)
[ Upstream commit ec061546c6cffbb8929495bba3953f0cc5e177fa ]

When creating link, lookup for existing device in target net namespace
instead of current one.
For example, two links created by:

  # ip link add dummy1 type dummy
  # ip link add netns ns1 dummy1 type dummy

should have no conflict since they are in different namespaces.

Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250219125039.18024-2-shaw.leon@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/core/rtnetlink.c

index 80e006940f51a91a4985e3e9b77d74281c7c9a85..ab7041150f2955a597bde74878b3ff5a932c74d9 100644 (file)
@@ -3865,20 +3865,26 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
 {
        struct nlattr ** const tb = tbs->tb;
        struct net *net = sock_net(skb->sk);
+       struct net *device_net;
        struct net_device *dev;
        struct ifinfomsg *ifm;
        bool link_specified;
 
+       /* When creating, lookup for existing device in target net namespace */
+       device_net = (nlh->nlmsg_flags & NLM_F_CREATE) &&
+                    (nlh->nlmsg_flags & NLM_F_EXCL) ?
+                    tgt_net : net;
+
        ifm = nlmsg_data(nlh);
        if (ifm->ifi_index > 0) {
                link_specified = true;
-               dev = __dev_get_by_index(net, ifm->ifi_index);
+               dev = __dev_get_by_index(device_net, ifm->ifi_index);
        } else if (ifm->ifi_index < 0) {
                NL_SET_ERR_MSG(extack, "ifindex can't be negative");
                return -EINVAL;
        } else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) {
                link_specified = true;
-               dev = rtnl_dev_get(net, tb);
+               dev = rtnl_dev_get(device_net, tb);
        } else {
                link_specified = false;
                dev = NULL;