diff options
author | Nicolas Dichtel <nicolas.dichtel@6wind.com> | 2014-03-19 12:47:50 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-20 16:24:28 -0400 |
commit | 65886f439ab0fdc2dff20d1fa87afb98c6717472 (patch) | |
tree | f1a5c625ecdd886877b3147a35bb7fcbcde15df0 /net/ipv4/ipmr.c | |
parent | 1c104a6bebf3c16b6248408b84f91d09ac8a26b6 (diff) |
ipmr: fix mfc notification flags
Commit 8cd3ac9f9b7b ("ipmr: advertise new mfc entries via rtnl") reuses the
function ipmr_fill_mroute() to notify mfc events.
But this function was used only for dump and thus was always setting the
flag NLM_F_MULTI, which is wrong in case of a single notification.
Libraries like libnl will wait forever for NLMSG_DONE.
CC: Thomas Graf <tgraf@suug.ch>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r-- | net/ipv4/ipmr.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index b9b3472975ba..28863570dd60 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -2255,13 +2255,14 @@ int ipmr_get_route(struct net *net, struct sk_buff *skb, | |||
2255 | } | 2255 | } |
2256 | 2256 | ||
2257 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | 2257 | static int ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, |
2258 | u32 portid, u32 seq, struct mfc_cache *c, int cmd) | 2258 | u32 portid, u32 seq, struct mfc_cache *c, int cmd, |
2259 | int flags) | ||
2259 | { | 2260 | { |
2260 | struct nlmsghdr *nlh; | 2261 | struct nlmsghdr *nlh; |
2261 | struct rtmsg *rtm; | 2262 | struct rtmsg *rtm; |
2262 | int err; | 2263 | int err; |
2263 | 2264 | ||
2264 | nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), NLM_F_MULTI); | 2265 | nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags); |
2265 | if (nlh == NULL) | 2266 | if (nlh == NULL) |
2266 | return -EMSGSIZE; | 2267 | return -EMSGSIZE; |
2267 | 2268 | ||
@@ -2329,7 +2330,7 @@ static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc, | |||
2329 | if (skb == NULL) | 2330 | if (skb == NULL) |
2330 | goto errout; | 2331 | goto errout; |
2331 | 2332 | ||
2332 | err = ipmr_fill_mroute(mrt, skb, 0, 0, mfc, cmd); | 2333 | err = ipmr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0); |
2333 | if (err < 0) | 2334 | if (err < 0) |
2334 | goto errout; | 2335 | goto errout; |
2335 | 2336 | ||
@@ -2368,7 +2369,8 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) | |||
2368 | if (ipmr_fill_mroute(mrt, skb, | 2369 | if (ipmr_fill_mroute(mrt, skb, |
2369 | NETLINK_CB(cb->skb).portid, | 2370 | NETLINK_CB(cb->skb).portid, |
2370 | cb->nlh->nlmsg_seq, | 2371 | cb->nlh->nlmsg_seq, |
2371 | mfc, RTM_NEWROUTE) < 0) | 2372 | mfc, RTM_NEWROUTE, |
2373 | NLM_F_MULTI) < 0) | ||
2372 | goto done; | 2374 | goto done; |
2373 | next_entry: | 2375 | next_entry: |
2374 | e++; | 2376 | e++; |
@@ -2382,7 +2384,8 @@ next_entry: | |||
2382 | if (ipmr_fill_mroute(mrt, skb, | 2384 | if (ipmr_fill_mroute(mrt, skb, |
2383 | NETLINK_CB(cb->skb).portid, | 2385 | NETLINK_CB(cb->skb).portid, |
2384 | cb->nlh->nlmsg_seq, | 2386 | cb->nlh->nlmsg_seq, |
2385 | mfc, RTM_NEWROUTE) < 0) { | 2387 | mfc, RTM_NEWROUTE, |
2388 | NLM_F_MULTI) < 0) { | ||
2386 | spin_unlock_bh(&mfc_unres_lock); | 2389 | spin_unlock_bh(&mfc_unres_lock); |
2387 | goto done; | 2390 | goto done; |
2388 | } | 2391 | } |