netlink: ensure to loop over all netns in genlmsg_multicast_allns()

Nowadays, nlmsg_multicast() returns only 0 or -ESRCH but this was not the
case when commit 134e63756d was pushed.
However, there was no reason to stop the loop if a netns does not have
listeners.
Returns -ESRCH only if there was no listeners in all netns.

To avoid having the same problem in the future, I didn't take the
assumption that nlmsg_multicast() returns only 0 or -ESRCH.

Fixes: 134e63756d ("genetlink: make netns aware")
CC: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Nicolas Dichtel 2018-02-06 14:48:32 +01:00 коммит произвёл David S. Miller
Родитель 8c2f826dc3
Коммит cb9f7a9a5c
1 изменённых файлов: 10 добавлений и 2 удалений

Просмотреть файл

@ -1081,6 +1081,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
{ {
struct sk_buff *tmp; struct sk_buff *tmp;
struct net *net, *prev = NULL; struct net *net, *prev = NULL;
bool delivered = false;
int err; int err;
for_each_net_rcu(net) { for_each_net_rcu(net) {
@ -1092,14 +1093,21 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
} }
err = nlmsg_multicast(prev->genl_sock, tmp, err = nlmsg_multicast(prev->genl_sock, tmp,
portid, group, flags); portid, group, flags);
if (err) if (!err)
delivered = true;
else if (err != -ESRCH)
goto error; goto error;
} }
prev = net; prev = net;
} }
return nlmsg_multicast(prev->genl_sock, skb, portid, group, flags); err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
if (!err)
delivered = true;
else if (err != -ESRCH)
goto error;
return delivered ? 0 : -ESRCH;
error: error:
kfree_skb(skb); kfree_skb(skb);
return err; return err;