aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2018-02-06 08:48:32 -0500
committerDavid S. Miller <davem@davemloft.net>2018-02-08 14:03:18 -0500
commitcb9f7a9a5c96a773bbc9c70660dc600cfff82f82 (patch)
treebbd5a31b8a13d94e94321dcf56960e6f91f88000
parent8c2f826dc36314059ac146c78d3bf8056b626446 (diff)
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 134e63756d5f 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: 134e63756d5f ("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>
-rw-r--r--net/netlink/genetlink.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index d444daf1ac04..6f02499ef007 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1081,6 +1081,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
1081{ 1081{
1082 struct sk_buff *tmp; 1082 struct sk_buff *tmp;
1083 struct net *net, *prev = NULL; 1083 struct net *net, *prev = NULL;
1084 bool delivered = false;
1084 int err; 1085 int err;
1085 1086
1086 for_each_net_rcu(net) { 1087 for_each_net_rcu(net) {
@@ -1092,14 +1093,21 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
1092 } 1093 }
1093 err = nlmsg_multicast(prev->genl_sock, tmp, 1094 err = nlmsg_multicast(prev->genl_sock, tmp,
1094 portid, group, flags); 1095 portid, group, flags);
1095 if (err) 1096 if (!err)
1097 delivered = true;
1098 else if (err != -ESRCH)
1096 goto error; 1099 goto error;
1097 } 1100 }
1098 1101
1099 prev = net; 1102 prev = net;
1100 } 1103 }
1101 1104
1102 return nlmsg_multicast(prev->genl_sock, skb, portid, group, flags); 1105 err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
1106 if (!err)
1107 delivered = true;
1108 else if (err != -ESRCH)
1109 goto error;
1110 return delivered ? 0 : -ESRCH;
1103 error: 1111 error:
1104 kfree_skb(skb); 1112 kfree_skb(skb);
1105 return err; 1113 return err;