netns: fix NLM_F_ECHO mechanism for RTM_NEWNSID
The flag NLM_F_ECHO aims to reply to the user the message notified to all
listeners.
It was not the case with the command RTM_NEWNSID, let's fix this.
Fixes: 0c7aecd4bd
("netns: add rtnl cmd to add and get peer netns ids")
Reported-by: Guillaume Nault <gnault@redhat.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Guillaume Nault <gnault@redhat.com>
Tested-by: Guillaume Nault <gnault@redhat.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
This commit is contained in:
Родитель
e0ae2c578d
Коммит
993e4c929a
|
@ -245,7 +245,8 @@ static int __peernet2id(struct net *net, struct net *peer)
|
||||||
return __peernet2id_alloc(net, peer, &no);
|
return __peernet2id_alloc(net, peer, &no);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtnl_net_notifyid(struct net *net, int cmd, int id);
|
static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
|
||||||
|
struct nlmsghdr *nlh);
|
||||||
/* This function returns the id of a peer netns. If no id is assigned, one will
|
/* This function returns the id of a peer netns. If no id is assigned, one will
|
||||||
* be allocated and returned.
|
* be allocated and returned.
|
||||||
*/
|
*/
|
||||||
|
@ -268,7 +269,7 @@ int peernet2id_alloc(struct net *net, struct net *peer)
|
||||||
id = __peernet2id_alloc(net, peer, &alloc);
|
id = __peernet2id_alloc(net, peer, &alloc);
|
||||||
spin_unlock_bh(&net->nsid_lock);
|
spin_unlock_bh(&net->nsid_lock);
|
||||||
if (alloc && id >= 0)
|
if (alloc && id >= 0)
|
||||||
rtnl_net_notifyid(net, RTM_NEWNSID, id);
|
rtnl_net_notifyid(net, RTM_NEWNSID, id, 0, NULL);
|
||||||
if (alive)
|
if (alive)
|
||||||
put_net(peer);
|
put_net(peer);
|
||||||
return id;
|
return id;
|
||||||
|
@ -532,7 +533,7 @@ static void unhash_nsid(struct net *net, struct net *last)
|
||||||
idr_remove(&tmp->netns_ids, id);
|
idr_remove(&tmp->netns_ids, id);
|
||||||
spin_unlock_bh(&tmp->nsid_lock);
|
spin_unlock_bh(&tmp->nsid_lock);
|
||||||
if (id >= 0)
|
if (id >= 0)
|
||||||
rtnl_net_notifyid(tmp, RTM_DELNSID, id);
|
rtnl_net_notifyid(tmp, RTM_DELNSID, id, 0, NULL);
|
||||||
if (tmp == last)
|
if (tmp == last)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -764,7 +765,8 @@ static int rtnl_net_newid(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||||
err = alloc_netid(net, peer, nsid);
|
err = alloc_netid(net, peer, nsid);
|
||||||
spin_unlock_bh(&net->nsid_lock);
|
spin_unlock_bh(&net->nsid_lock);
|
||||||
if (err >= 0) {
|
if (err >= 0) {
|
||||||
rtnl_net_notifyid(net, RTM_NEWNSID, err);
|
rtnl_net_notifyid(net, RTM_NEWNSID, err, NETLINK_CB(skb).portid,
|
||||||
|
nlh);
|
||||||
err = 0;
|
err = 0;
|
||||||
} else if (err == -ENOSPC && nsid >= 0) {
|
} else if (err == -ENOSPC && nsid >= 0) {
|
||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
|
@ -1051,9 +1053,12 @@ end:
|
||||||
return err < 0 ? err : skb->len;
|
return err < 0 ? err : skb->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtnl_net_notifyid(struct net *net, int cmd, int id)
|
static void rtnl_net_notifyid(struct net *net, int cmd, int id, u32 portid,
|
||||||
|
struct nlmsghdr *nlh)
|
||||||
{
|
{
|
||||||
struct net_fill_args fillargs = {
|
struct net_fill_args fillargs = {
|
||||||
|
.portid = portid,
|
||||||
|
.seq = nlh ? nlh->nlmsg_seq : 0,
|
||||||
.cmd = cmd,
|
.cmd = cmd,
|
||||||
.nsid = id,
|
.nsid = id,
|
||||||
};
|
};
|
||||||
|
@ -1068,7 +1073,7 @@ static void rtnl_net_notifyid(struct net *net, int cmd, int id)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
rtnl_notify(msg, net, 0, RTNLGRP_NSID, NULL, 0);
|
rtnl_notify(msg, net, portid, RTNLGRP_NSID, nlh, 0);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче