]> git.ipfire.org Git - thirdparty/linux.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)
committerJakub Kicinski <kuba@kernel.org>
Fri, 21 Feb 2025 23:28:01 +0000 (15:28 -0800)
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>
net/core/rtnetlink.c

index abe1a461ea67bb94805328436063e00ce5d1716d..0f3e2c6021de0792e587aebb56102705d0d60e74 100644 (file)
@@ -3867,20 +3867,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;