Received: by 10.223.148.5 with SMTP id 5csp8007074wrq; Thu, 18 Jan 2018 12:22:59 -0800 (PST) X-Google-Smtp-Source: ACJfBotJTitTD4XRDX/saq4pE21WFWWYM9q60EDbgScj8b3bgeH/4WZs230ileUZGZ5bSVZ+5LQa X-Received: by 10.98.223.29 with SMTP id u29mr39301794pfg.166.1516306979319; Thu, 18 Jan 2018 12:22:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516306979; cv=none; d=google.com; s=arc-20160816; b=Dha9+d80EDuS/shPj++QP1kV6ML5pHI3EOcwnApya9C3NzQwZOPHUuNr8JiIcap3gn DXQttDHLsP4P4bAO61+oePBAwMKRXdIMz9TBQayG7PHyuqz0wiMSyrJytwCVm07358TJ /gOCb1Cp0EdNhy0IL5yDf2e2kOk9SCqUKJWCbwFt4xWvs7RyJEr9fbfctRXH7LodFF7B TRn/lOScC1sWdeVbDcT/vOiwdTXheI8EjcB/kP1fFi5dASYaCH6KsmJxi8zKepNC0TSc mKVUkz2cTTBAz693GQ37lBADUU3jq4OnK8B2kCowefpmweTMjV+NAFehDfNd2FEduFTe 3e0Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=4IPokrB4RGV/lemqEzxa+S6U6DkOB2sEriJAIVbrlfE=; b=WND5cjZ/zIBWIKaMnl8ATnX7tv463pDdWLyBG13JsExl+o8EjfTagYZgYbWbLHedNz IJIePFM5phg+SxOZU9lXQNrh/R5njzt7WwLmE/05aFWzoceFVD5oaHZFttm99tMPLq85 YD1b9GMqTt/d/RnTHaHYsYNNj/lQ/yM52xS8fdZfcI6InToV0aFVeaLN3f8qbfIwdr/W 6Onk2bvby+PthllQZI5jXRWKq1DaoAsJETBB/Qb0nx7E+vSIOSN/J90TbUWJFNut6gx1 idnVV7jEyiNh67LFMQYeVI7EANetmIYZTB9PdMOwjIdgr4/WHtS6uz/N89wkGAopYraO uv4Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i2si7836154pfd.57.2018.01.18.12.22.45; Thu, 18 Jan 2018 12:22:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932891AbeARUWI (ORCPT + 99 others); Thu, 18 Jan 2018 15:22:08 -0500 Received: from mx2.mailbox.org ([80.241.60.215]:43120 "EHLO mx2.mailbox.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932384AbeARUWG (ORCPT ); Thu, 18 Jan 2018 15:22:06 -0500 Received: from smtp2.mailbox.org (smtp2.mailbox.org [80.241.60.241]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx2.mailbox.org (Postfix) with ESMTPS id 7D6464100B; Thu, 18 Jan 2018 21:22:03 +0100 (CET) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp2.mailbox.org ([80.241.60.241]) by gerste.heinlein-support.de (gerste.heinlein-support.de [91.198.250.173]) (amavisd-new, port 10030) with ESMTP id eozlztsfmQiI; Thu, 18 Jan 2018 21:21:49 +0100 (CET) From: Christian Brauner To: davem@davemloft.net, dsahern@gmail.com, fw@strlen.de, daniel@iogearbox.net, lucien.xin@gmail.com, mschiffer@universe-factory.net, jakub.kicinski@netronome.com, vyasevich@gmail.com, jbenc@redhat.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Christian Brauner Subject: [PATCH net-next 1/1] rtnetlink: request RTM_GETLINK by pid or fd Date: Thu, 18 Jan 2018 21:21:24 +0100 Message-Id: <20180118202124.21616-2-christian.brauner@ubuntu.com> In-Reply-To: <20180118202124.21616-1-christian.brauner@ubuntu.com> References: <20180118202124.21616-1-christian.brauner@ubuntu.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This makes it possible to identify the target network namespace of a RTM_GETLINK message by pid or fd. Often userspace tools that make heavy use of network namespaces need a simple and cheap way of querying network devices and network device properties. This becomes even more crucial when the network namespaces in question are transient. In such scenarios setting a netns id property is not really wanted and it is preferable to avoid the hit of (possibly multiple) setns() syscalls (e.g. attaching to the target network namespace and back to the original network namespace.). This commit lets userspace set the IFLA_NET_NS_{FD,PID} property to identify a target network namespace where the device in question is to be queried. Signed-off-by: Christian Brauner --- net/core/rtnetlink.c | 63 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 16d644a4f974..5210448dcf1f 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1509,7 +1509,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, struct net *src_net, int type, u32 pid, u32 seq, u32 change, unsigned int flags, u32 ext_filter_mask, - u32 event, int *new_nsid, int tgt_netnsid) + u32 event, int *new_nsid, int tgt_netnsid, + int tgt_netnsid_type) { struct ifinfomsg *ifm; struct nlmsghdr *nlh; @@ -1527,8 +1528,23 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, ifm->ifi_flags = dev_get_flags(dev); ifm->ifi_change = change; - if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_IF_NETNSID, tgt_netnsid)) - goto nla_put_failure; + if (tgt_netnsid >= 0) { + u32 err = -1; + + switch (tgt_netnsid_type) { + case IFLA_IF_NETNSID: + err = nla_put_s32(skb, IFLA_IF_NETNSID, tgt_netnsid); + break; + case IFLA_NET_NS_PID: + err = nla_put_s32(skb, IFLA_NET_NS_PID, tgt_netnsid); + break; + case IFLA_NET_NS_FD: + err = nla_put_s32(skb, IFLA_NET_NS_FD, tgt_netnsid); + break; + } + if (err) + goto nla_put_failure; + } if (nla_put_string(skb, IFLA_IFNAME, dev->name) || nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) || @@ -1791,6 +1807,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) unsigned int flags = NLM_F_MULTI; int master_idx = 0; int netnsid = -1; + int netnsid_type = -1; int err; int hdrlen; @@ -1810,12 +1827,22 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) if (nlmsg_parse(cb->nlh, hdrlen, tb, IFLA_MAX, ifla_policy, NULL) >= 0) { if (tb[IFLA_IF_NETNSID]) { + netnsid_type = IFLA_IF_NETNSID; netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); tgt_net = get_target_net(skb->sk, netnsid); - if (IS_ERR(tgt_net)) { - tgt_net = net; - netnsid = -1; - } + } else if (tb[IFLA_NET_NS_PID]) { + netnsid_type = IFLA_NET_NS_PID; + netnsid = nla_get_s32(tb[IFLA_NET_NS_PID]); + tgt_net = get_net_ns_by_pid(netnsid); + } else if (tb[IFLA_NET_NS_FD]) { + netnsid_type = IFLA_NET_NS_FD; + netnsid = nla_get_s32(tb[IFLA_NET_NS_FD]); + tgt_net = get_net_ns_by_fd(netnsid); + } + if (IS_ERR(tgt_net)) { + tgt_net = net; + netnsid = -1; + netnsid_type = -1; } if (tb[IFLA_EXT_MASK]) @@ -1845,7 +1872,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) cb->nlh->nlmsg_seq, 0, flags, ext_filter_mask, 0, NULL, - netnsid); + netnsid, netnsid_type); if (err < 0) { if (likely(skb->len)) @@ -2984,6 +3011,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, struct net_device *dev = NULL; struct sk_buff *nskb; int netnsid = -1; + int netnsid_type = -1; int err; u32 ext_filter_mask = 0; @@ -2992,11 +3020,20 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, return err; if (tb[IFLA_IF_NETNSID]) { + netnsid_type = IFLA_IF_NETNSID; netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid); - if (IS_ERR(tgt_net)) - return PTR_ERR(tgt_net); - } + } else if (tb[IFLA_NET_NS_PID]) { + netnsid_type = IFLA_NET_NS_PID; + netnsid = nla_get_s32(tb[IFLA_NET_NS_PID]); + tgt_net = get_net_ns_by_pid(netnsid); + } else if (tb[IFLA_NET_NS_FD]) { + netnsid_type = IFLA_NET_NS_FD; + netnsid = nla_get_s32(tb[IFLA_NET_NS_FD]); + tgt_net = get_net_ns_by_fd(netnsid); + } + if (IS_ERR(tgt_net)) + return PTR_ERR(tgt_net); if (tb[IFLA_IFNAME]) nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); @@ -3025,7 +3062,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, err = rtnl_fill_ifinfo(nskb, dev, net, RTM_NEWLINK, NETLINK_CB(skb).portid, nlh->nlmsg_seq, 0, 0, ext_filter_mask, - 0, NULL, netnsid); + 0, NULL, netnsid, netnsid_type); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size */ WARN_ON(err == -EMSGSIZE); @@ -3134,7 +3171,7 @@ struct sk_buff *rtmsg_ifinfo_build_skb(int type, struct net_device *dev, err = rtnl_fill_ifinfo(skb, dev, dev_net(dev), type, 0, 0, change, 0, 0, event, - new_nsid, -1); + new_nsid, -1, -1); if (err < 0) { /* -EMSGSIZE implies BUG in if_nlmsg_size() */ WARN_ON(err == -EMSGSIZE); -- 2.14.1