2019-11-05 08:12:25

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 0/5] Add namespace awareness to Netlink methods

Currently, Netlink has partial support for acting outside of the current
namespace. It appears that the intention was to extend this to all the
methods eventually, but it hasn't been done to date.

With this series RTM_SETLINK, RTM_NEWLINK, RTM_NEWADDR, and RTM_NEWNSID
are extended to respect the selection of the namespace to work in.

/Jonas

Jonas Bonn (5):
rtnetlink: allow RTM_SETLINK to reference other namespaces
rtnetlink: skip namespace change if already effect
rtnetlink: allow RTM_NEWLINK to act upon interfaces in arbitrary
namespaces
net: ipv4: allow setting address on interface outside current
namespace
net: namespace: allow setting NSIDs outside current namespace

net/core/net_namespace.c | 19 ++++++++++
net/core/rtnetlink.c | 79 ++++++++++++++++++++++++++++++++++------
net/ipv4/devinet.c | 56 ++++++++++++++++++++--------
3 files changed, 127 insertions(+), 27 deletions(-)

--
2.20.1


2019-11-05 08:12:37

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 2/5] rtnetlink: skip namespace change if already effect

RTM_SETLINK uses IFA_TARGET_NETNSID both as a selector for the device to
act upon and as a selection of the namespace to move a device in the
current namespace to. As such, one ends up in the code path for setting
the namespace every time one calls setlink on a device outside the
current namespace. This has the unfortunate side effect of setting the
'modified' flag on the device for every pass, resulting in Netlink
notifications even when nothing was changed.

This patch just makes the namespace switch dependent upon the namespace
the device currently resides in.

Signed-off-by: Jonas Bonn <[email protected]>
---
net/core/rtnetlink.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 269d1afefceb..a6ec1b4ff7cd 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2393,11 +2393,15 @@ static int do_setlink(const struct sk_buff *skb,
goto errout;
}

- err = dev_change_net_namespace(dev, net, ifname);
- put_net(net);
- if (err)
- goto errout;
- status |= DO_SETLINK_MODIFIED;
+ if (!net_eq(dev_net(dev), net)) {
+ err = dev_change_net_namespace(dev, net, ifname);
+ put_net(net);
+ if (err)
+ goto errout;
+ status |= DO_SETLINK_MODIFIED;
+ } else {
+ put_net(net);
+ }
}

if (tb[IFLA_MAP]) {
--
2.20.1

2019-11-05 08:12:48

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 5/5] net: namespace: allow setting NSIDs outside current namespace

Currently it is only possible to move an interface to a new namespace if
the destination namespace has an ID in the interface's current namespace.
If the interface already resides outside of the current namespace, then
we may need to assign the destination namespace an ID in the interface's
namespace in order to effect the move.

This patch allows namespace ID's to be created outside of the current
namespace. With this, the following is possible:

i) Our namespace is 'A'.
ii) The interface resides in namespace 'B'
iii) We can assign an ID for NS 'A' in NS 'B'
iv) We can then move the interface into our own namespace.

and

i) Our namespace is 'A'; namespaces 'B' and 'C' also exist
ii) We can assign an ID for namespace 'C' in namespace 'B'
iii) We can then create a VETH interface directly in namespace 'B' with
the other end in 'C', all without ever leaving namespace 'A'

Signed-off-by: Jonas Bonn <[email protected]>
---
net/core/net_namespace.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 6d3e4821b02d..0071f395098d 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -724,6 +724,7 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
struct nlattr *tb[NETNSA_MAX + 1];
struct nlattr *nla;
struct net *peer;
+ struct net *target = NULL;
int nsid, err;

err = nlmsg_parse_deprecated(nlh, sizeof(struct rtgenmsg), tb,
@@ -752,6 +753,21 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
return PTR_ERR(peer);
}

+ if (tb[NETNSA_TARGET_NSID]) {
+ int id = nla_get_s32(tb[NETNSA_TARGET_NSID]);
+
+ target = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, id);
+ if (IS_ERR(target)) {
+ NL_SET_BAD_ATTR(extack, tb[NETNSA_TARGET_NSID]);
+ NL_SET_ERR_MSG(extack,
+ "Target netns reference is invalid");
+ err = PTR_ERR(target);
+ goto out;
+ }
+
+ net = target;
+ }
+
spin_lock_bh(&net->nsid_lock);
if (__peernet2id(net, peer) >= 0) {
spin_unlock_bh(&net->nsid_lock);
@@ -773,6 +789,9 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
NL_SET_BAD_ATTR(extack, tb[NETNSA_NSID]);
NL_SET_ERR_MSG(extack, "The specified nsid is already used");
}
+
+ if (target)
+ put_net(target);
out:
put_net(peer);
return err;
--
2.20.1

2019-11-05 08:13:41

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 1/5] rtnetlink: allow RTM_SETLINK to reference other namespaces

Netlink currently has partial support for acting on interfaces outside
the current namespace. This patch extends RTM_SETLINK with this
functionality.

The current implementation has an unfortunate semantic ambiguity in the
IFLA_TARGET_NETNSID attribute. For setting the interface namespace, one
may pass the IFLA_TARGET_NETNSID attribute with the namespace to move the
interface to. This conflicts with the meaning of this attribute for all
other methods where IFLA_TARGET_NETNSID identifies the namespace in
which to search for the interface to act upon: the pair (namespace,
ifindex) is generally given by (IFLA_TARGET_NETNSID, ifi->ifi_index).

In order to change the namespace of an interface outside the current
namespace, we would need to specify both an IFLA_TARGET_NETNSID
attribute and a namespace to move to using IFLA_NET_NS_[PID|FD]. This is
currently now allowed as only one of these three flags may be specified.

This patch loosens the restrictions a bit but tries to maintain
compatibility with the previous behaviour:
i) IFLA_TARGET_NETNSID may be passed together with one of
IFLA_NET_NS_[PID|FD]
ii) IFLA_TARGET_NETNSID is primarily defined to be the namespace in
which to find the interface to act upon
iii) In order to maintain backwards compatibility, if the device is not
found in the specified namespace, we also look for it in the current
namespace
iv) If only IFLA_TARGET_NETNSID is given, the device is still moved to
that namespace, as before; and, as before, IFLA_NET_NS_[PID|FD] take
precedence as namespace selectors

Ideally, IFLA_TARGET_NETNSID would only ever have been used to select the
namespace of the device to act upon. A separate flag, IFLA_NET_NS_ID
would have been made available for changing namespaces

Signed-off-by: Jonas Bonn <[email protected]>
---
net/core/rtnetlink.c | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1ee6460f8275..269d1afefceb 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2109,13 +2109,7 @@ static int rtnl_ensure_unique_netns(struct nlattr *tb[],
return -EOPNOTSUPP;
}

- if (tb[IFLA_TARGET_NETNSID] && (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]))
- goto invalid_attr;
-
- if (tb[IFLA_NET_NS_PID] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_FD]))
- goto invalid_attr;
-
- if (tb[IFLA_NET_NS_FD] && (tb[IFLA_TARGET_NETNSID] || tb[IFLA_NET_NS_PID]))
+ if (tb[IFLA_NET_NS_PID] && tb[IFLA_NET_NS_FD])
goto invalid_attr;

return 0;
@@ -2726,6 +2720,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
+ struct net *tgt_net = NULL;
struct ifinfomsg *ifm;
struct net_device *dev;
int err;
@@ -2741,6 +2736,14 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err < 0)
goto errout;

+ if (tb[IFLA_TARGET_NETNSID]) {
+ int32_t netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
+ if (IS_ERR(net))
+ return PTR_ERR(net);
+ net = tgt_net;
+ }
+
if (tb[IFLA_IFNAME])
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
else
@@ -2755,6 +2758,23 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
else
goto errout;

+ /* A hack to preserve kernel<->userspace interface.
+ * It was previously allowed to pass the IFLA_TARGET_NETNSID
+ * attribute as a way to _set_ the network namespace. In this
+ * case, the device interface was assumed to be in the _current_
+ * namespace.
+ * If the device cannot be found in the target namespace then we
+ * assume that the request is to set the device in the current
+ * namespace and thus we attempt to find the device there.
+ */
+ if (!dev && tgt_net) {
+ net = sock_net(skb->sk);
+ if (ifm->ifi_index > 0)
+ dev = __dev_get_by_index(net, ifm->ifi_index);
+ else if (tb[IFLA_IFNAME])
+ dev = __dev_get_by_name(net, ifname);
+ }
+
if (dev == NULL) {
err = -ENODEV;
goto errout;
@@ -2762,6 +2782,8 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,

err = do_setlink(skb, dev, ifm, extack, tb, ifname, 0);
errout:
+ if (tgt_net)
+ put_net(tgt_net);
return err;
}

--
2.20.1

2019-11-05 08:14:41

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 3/5] rtnetlink: allow RTM_NEWLINK to act upon interfaces in arbitrary namespaces

RTM_NEWLINK can be used mostly interchangeably with RTM_SETLINK for
modifying device configuration. As such, this method requires the same
logic as RTM_SETLINK for finding the device to act on.

With this patch, the IFLA_TARGET_NETNSID selects the namespace in which
to search for the interface to act upon. This allows, for example, to
set the namespace of an interface outside the current namespace by
selecting it with the (IFLA_TARGET_NETNSID,ifi->ifi_index) pair and
specifying the namespace with one of IFLA_NET_NS_[PID|FD].

Since rtnl_newlink branches off into do_setlink, we need to provide the
same backwards compatibility check as we do for RTM_SETLINK: if the
device is not found in the namespace given by IFLA_TARGET_NETNSID then
we search for it in the current namespace. If found there, it's
namespace will be changed, as before.

Signed-off-by: Jonas Bonn <[email protected]>
---
net/core/rtnetlink.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a6ec1b4ff7cd..3aba9e9d2c32 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3019,6 +3019,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
const struct rtnl_link_ops *m_ops = NULL;
struct net_device *master_dev = NULL;
struct net *net = sock_net(skb->sk);
+ struct net *tgt_net = NULL;
const struct rtnl_link_ops *ops;
struct nlattr *tb[IFLA_MAX + 1];
struct net *dest_net, *link_net;
@@ -3047,6 +3048,15 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
else
ifname[0] = '\0';

+ if (tb[IFLA_TARGET_NETNSID]) {
+ int32_t netnsid;
+ netnsid = nla_get_s32(tb[IFLA_TARGET_NETNSID]);
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
+ if (IS_ERR(tgt_net))
+ return PTR_ERR(tgt_net);
+ net = tgt_net;
+ }
+
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
@@ -3057,6 +3067,23 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
dev = NULL;
}

+ /* A hack to preserve kernel<->userspace interface.
+ * It was previously allowed to pass the IFLA_TARGET_NETNSID
+ * attribute as a way to _set_ the network namespace. In this
+ * case, the device interface was assumed to be in the _current_
+ * namespace.
+ * If the device cannot be found in the target namespace then we
+ * assume that the request is to set the device in the current
+ * namespace and thus we attempt to find the device there.
+ */
+ if (!dev && tgt_net) {
+ net = sock_net(skb->sk);
+ if (ifm->ifi_index > 0)
+ dev = __dev_get_by_index(net, ifm->ifi_index);
+ else if (tb[IFLA_IFNAME])
+ dev = __dev_get_by_name(net, ifname);
+ }
+
if (dev) {
master_dev = netdev_master_upper_dev_get(dev);
if (master_dev)
@@ -3251,6 +3278,8 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
goto out_unregister;
}
out:
+ if (tgt_net)
+ put_net(tgt_net);
if (link_net)
put_net(link_net);
put_net(dest_net);
--
2.20.1

2019-11-05 08:14:57

by Jonas Bonn

[permalink] [raw]
Subject: [PATCH 4/5] net: ipv4: allow setting address on interface outside current namespace

This patch allows an interface outside of the current namespace to be
selected when setting a new IPv4 address for a device. This uses the
IFA_TARGET_NETNSID attribute to select the namespace in which to search
for the interface to act upon.

Signed-off-by: Jonas Bonn <[email protected]>
---
net/ipv4/devinet.c | 56 +++++++++++++++++++++++++++++++++-------------
1 file changed, 41 insertions(+), 15 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a4b5bd4d2c89..459fb39b4a56 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -813,22 +813,17 @@ static void set_ifa_lifetime(struct in_ifaddr *ifa, __u32 valid_lft,
ifa->ifa_cstamp = ifa->ifa_tstamp;
}

-static struct in_ifaddr *rtm_to_ifaddr(struct net *net, struct nlmsghdr *nlh,
+static struct in_ifaddr *rtm_to_ifaddr(struct nlattr* tb[],
+ struct net *net, struct nlmsghdr *nlh,
__u32 *pvalid_lft, __u32 *pprefered_lft,
struct netlink_ext_ack *extack)
{
- struct nlattr *tb[IFA_MAX+1];
struct in_ifaddr *ifa;
struct ifaddrmsg *ifm;
struct net_device *dev;
struct in_device *in_dev;
int err;

- err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
- ifa_ipv4_policy, extack);
- if (err < 0)
- goto errout;
-
ifm = nlmsg_data(nlh);
err = -EINVAL;
if (ifm->ifa_prefixlen > 32 || !tb[IFA_LOCAL])
@@ -922,16 +917,37 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
+ struct net *tgt_net = NULL;
struct in_ifaddr *ifa;
struct in_ifaddr *ifa_existing;
__u32 valid_lft = INFINITY_LIFE_TIME;
__u32 prefered_lft = INFINITY_LIFE_TIME;
+ struct nlattr *tb[IFA_MAX+1];
+ int err;

ASSERT_RTNL();

- ifa = rtm_to_ifaddr(net, nlh, &valid_lft, &prefered_lft, extack);
- if (IS_ERR(ifa))
- return PTR_ERR(ifa);
+ err = nlmsg_parse_deprecated(nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX,
+ ifa_ipv4_policy, extack);
+ if (err < 0)
+ return err;
+
+ if (tb[IFA_TARGET_NETNSID]) {
+ int32_t netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]);
+
+ tgt_net = rtnl_get_net_ns_capable(NETLINK_CB(skb).sk, netnsid);
+ if (IS_ERR(net)) {
+ NL_SET_ERR_MSG(extack, "ipv4: Invalid target network namespace id");
+ return PTR_ERR(net);
+ }
+ net = tgt_net;
+ }
+
+ ifa = rtm_to_ifaddr(tb, net, nlh, &valid_lft, &prefered_lft, extack);
+ if (IS_ERR(ifa)) {
+ err = PTR_ERR(ifa);
+ goto out;
+ }

ifa_existing = find_matching_ifa(ifa);
if (!ifa_existing) {
@@ -945,10 +961,11 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,

if (ret < 0) {
inet_free_ifa(ifa);
- return ret;
+ err = ret;
+ goto out;
}
}
- return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid,
+ err = __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid,
extack);
} else {
u32 new_metric = ifa->ifa_rt_priority;
@@ -956,8 +973,10 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
inet_free_ifa(ifa);

if (nlh->nlmsg_flags & NLM_F_EXCL ||
- !(nlh->nlmsg_flags & NLM_F_REPLACE))
- return -EEXIST;
+ !(nlh->nlmsg_flags & NLM_F_REPLACE)) {
+ err = -EEXIST;
+ goto out;
+ }
ifa = ifa_existing;

if (ifa->ifa_rt_priority != new_metric) {
@@ -971,7 +990,14 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
&check_lifetime_work, 0);
rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
}
- return 0;
+
+ err = 0;
+
+out:
+ if (tgt_net)
+ put_net(tgt_net);
+
+ return err;
}

/*
--
2.20.1

2019-11-05 15:44:19

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: [PATCH 2/5] rtnetlink: skip namespace change if already effect

Le 05/11/2019 à 09:11, Jonas Bonn a écrit :
> RTM_SETLINK uses IFA_TARGET_NETNSID both as a selector for the device to
> act upon and as a selection of the namespace to move a device in the
> current namespace to. As such, one ends up in the code path for setting
> the namespace every time one calls setlink on a device outside the
> current namespace. This has the unfortunate side effect of setting the
> 'modified' flag on the device for every pass, resulting in Netlink
> notifications even when nothing was changed.
>
> This patch just makes the namespace switch dependent upon the namespace
> the device currently resides in.
>
> Signed-off-by: Jonas Bonn <[email protected]>
Acked-by: Nicolas Dichtel <[email protected]>

2019-11-05 15:44:44

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: [PATCH 1/5] rtnetlink: allow RTM_SETLINK to reference other namespaces

Le 05/11/2019 à 09:11, Jonas Bonn a écrit :
> Netlink currently has partial support for acting on interfaces outside
> the current namespace. This patch extends RTM_SETLINK with this
> functionality.
>
> The current implementation has an unfortunate semantic ambiguity in the
> IFLA_TARGET_NETNSID attribute. For setting the interface namespace, one
> may pass the IFLA_TARGET_NETNSID attribute with the namespace to move the
> interface to. This conflicts with the meaning of this attribute for all
> other methods where IFLA_TARGET_NETNSID identifies the namespace in
> which to search for the interface to act upon: the pair (namespace,
> ifindex) is generally given by (IFLA_TARGET_NETNSID, ifi->ifi_index).
>
> In order to change the namespace of an interface outside the current
> namespace, we would need to specify both an IFLA_TARGET_NETNSID
> attribute and a namespace to move to using IFLA_NET_NS_[PID|FD]. This is
> currently now allowed as only one of these three flags may be specified.
>
> This patch loosens the restrictions a bit but tries to maintain
> compatibility with the previous behaviour:
> i) IFLA_TARGET_NETNSID may be passed together with one of
> IFLA_NET_NS_[PID|FD]
> ii) IFLA_TARGET_NETNSID is primarily defined to be the namespace in
> which to find the interface to act upon
> iii) In order to maintain backwards compatibility, if the device is not
> found in the specified namespace, we also look for it in the current
> namespace
> iv) If only IFLA_TARGET_NETNSID is given, the device is still moved to
> that namespace, as before; and, as before, IFLA_NET_NS_[PID|FD] take
> precedence as namespace selectors
>
> Ideally, IFLA_TARGET_NETNSID would only ever have been used to select the
> namespace of the device to act upon. A separate flag, IFLA_NET_NS_ID
> would have been made available for changing namespaces
>
> Signed-off-by: Jonas Bonn <[email protected]>
Acked-by: Nicolas Dichtel <[email protected]>

2019-11-05 15:44:54

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: [PATCH 3/5] rtnetlink: allow RTM_NEWLINK to act upon interfaces in arbitrary namespaces

Le 05/11/2019 à 09:11, Jonas Bonn a écrit :
> RTM_NEWLINK can be used mostly interchangeably with RTM_SETLINK for
> modifying device configuration. As such, this method requires the same
> logic as RTM_SETLINK for finding the device to act on.
>
> With this patch, the IFLA_TARGET_NETNSID selects the namespace in which
> to search for the interface to act upon. This allows, for example, to
> set the namespace of an interface outside the current namespace by
> selecting it with the (IFLA_TARGET_NETNSID,ifi->ifi_index) pair and
> specifying the namespace with one of IFLA_NET_NS_[PID|FD].
>
> Since rtnl_newlink branches off into do_setlink, we need to provide the
> same backwards compatibility check as we do for RTM_SETLINK: if the
> device is not found in the namespace given by IFLA_TARGET_NETNSID then
> we search for it in the current namespace. If found there, it's
> namespace will be changed, as before.
>
> Signed-off-by: Jonas Bonn <[email protected]>
Acked-by: Nicolas Dichtel <[email protected]>

2019-11-05 15:48:50

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: [PATCH 4/5] net: ipv4: allow setting address on interface outside current namespace

Le 05/11/2019 à 09:11, Jonas Bonn a écrit :
> This patch allows an interface outside of the current namespace to be
> selected when setting a new IPv4 address for a device. This uses the
> IFA_TARGET_NETNSID attribute to select the namespace in which to search
> for the interface to act upon.
>
> Signed-off-by: Jonas Bonn <[email protected]>
> ---
[snip]
> @@ -945,10 +961,11 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
>
> if (ret < 0) {
> inet_free_ifa(ifa);
> - return ret;
> + err = ret;
> + goto out;
> }
> }
> - return __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid,
> + err = __inet_insert_ifa(ifa, nlh, NETLINK_CB(skb).portid,
> extack);
if (err < 0)
goto out;
?
else err is set to 0 later.

> } else {
> u32 new_metric = ifa->ifa_rt_priority;
> @@ -956,8 +973,10 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
> inet_free_ifa(ifa);
>
> if (nlh->nlmsg_flags & NLM_F_EXCL ||
> - !(nlh->nlmsg_flags & NLM_F_REPLACE))
> - return -EEXIST;
> + !(nlh->nlmsg_flags & NLM_F_REPLACE)) {
> + err = -EEXIST;
> + goto out;
> + }
> ifa = ifa_existing;
>
> if (ifa->ifa_rt_priority != new_metric) {
> @@ -971,7 +990,14 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
> &check_lifetime_work, 0);
> rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid);
> }
> - return 0;
> +
> + err = 0;
here.


Regards,
Nicolas

2019-11-05 15:53:36

by Nicolas Dichtel

[permalink] [raw]
Subject: Re: [PATCH 5/5] net: namespace: allow setting NSIDs outside current namespace

Le 05/11/2019 à 09:11, Jonas Bonn a écrit :
> Currently it is only possible to move an interface to a new namespace if
> the destination namespace has an ID in the interface's current namespace.
> If the interface already resides outside of the current namespace, then
> we may need to assign the destination namespace an ID in the interface's
> namespace in order to effect the move.
>
> This patch allows namespace ID's to be created outside of the current
> namespace. With this, the following is possible:
>
> i) Our namespace is 'A'.
> ii) The interface resides in namespace 'B'
> iii) We can assign an ID for NS 'A' in NS 'B'
> iv) We can then move the interface into our own namespace.
>
> and
>
> i) Our namespace is 'A'; namespaces 'B' and 'C' also exist
> ii) We can assign an ID for namespace 'C' in namespace 'B'
> iii) We can then create a VETH interface directly in namespace 'B' with
> the other end in 'C', all without ever leaving namespace 'A'
>
> Signed-off-by: Jonas Bonn <[email protected]>
Acked-by: Nicolas Dichtel <[email protected]>