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 | |
| 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>
| -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 | } |
