rtnetlink: Try the outer netns attribute in rtnl_get_peer_net().

Xiao Liang reported that the cited commit changed netns handling
in newlink() of netkit, veth, and vxcan.

Before the patch, if we don't find a netns attribute in the peer
device attributes, we tried to find another netns attribute in
the outer netlink attributes by passing it to rtnl_link_get_net().

Let's restore the original behaviour.

Fixes: 4832756676 ("rtnetlink: fix double call of rtnl_link_get_net_ifla()")
Reported-by: Xiao Liang <shaw.leon@gmail.com>
Closes: https://lore.kernel.org/netdev/CABAhCORBVVU8P6AHcEkENMj+gD2d3ce9t=A_o48E0yOQp8_wUQ@mail.gmail.com/#t
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Tested-by: Xiao Liang <shaw.leon@gmail.com>
Link: https://patch.msgid.link/20241216110432.51488-1-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Kuniyuki Iwashima 2024-12-16 20:04:32 +09:00 committed by Jakub Kicinski
parent b9b8301d36
commit 954a2b4071

View File

@ -3819,6 +3819,7 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
} }
static struct net *rtnl_get_peer_net(const struct rtnl_link_ops *ops, static struct net *rtnl_get_peer_net(const struct rtnl_link_ops *ops,
struct nlattr *tbp[],
struct nlattr *data[], struct nlattr *data[],
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
@ -3826,7 +3827,7 @@ static struct net *rtnl_get_peer_net(const struct rtnl_link_ops *ops,
int err; int err;
if (!data || !data[ops->peer_type]) if (!data || !data[ops->peer_type])
return NULL; return rtnl_link_get_net_ifla(tbp);
err = rtnl_nla_parse_ifinfomsg(tb, data[ops->peer_type], extack); err = rtnl_nla_parse_ifinfomsg(tb, data[ops->peer_type], extack);
if (err < 0) if (err < 0)
@ -3971,7 +3972,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
} }
if (ops->peer_type) { if (ops->peer_type) {
peer_net = rtnl_get_peer_net(ops, data, extack); peer_net = rtnl_get_peer_net(ops, tb, data, extack);
if (IS_ERR(peer_net)) { if (IS_ERR(peer_net)) {
ret = PTR_ERR(peer_net); ret = PTR_ERR(peer_net);
goto put_ops; goto put_ops;