diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/monitor.c | 2 | ||||
-rw-r--r-- | net/tipc/name_table.c | 34 | ||||
-rw-r--r-- | net/tipc/name_table.h | 2 | ||||
-rw-r--r-- | net/tipc/net.c | 2 | ||||
-rw-r--r-- | net/tipc/netlink.c | 5 | ||||
-rw-r--r-- | net/tipc/node.c | 11 | ||||
-rw-r--r-- | net/tipc/socket.c | 4 | ||||
-rw-r--r-- | net/tipc/subscr.c | 5 |
8 files changed, 40 insertions, 25 deletions
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 32dc33a94bc7..5453e564da82 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c | |||
@@ -777,7 +777,7 @@ int __tipc_nl_add_monitor(struct net *net, struct tipc_nl_msg *msg, | |||
777 | 777 | ||
778 | ret = tipc_bearer_get_name(net, bearer_name, bearer_id); | 778 | ret = tipc_bearer_get_name(net, bearer_name, bearer_id); |
779 | if (ret || !mon) | 779 | if (ret || !mon) |
780 | return -EINVAL; | 780 | return 0; |
781 | 781 | ||
782 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, | 782 | hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family, |
783 | NLM_F_MULTI, TIPC_NL_MON_GET); | 783 | NLM_F_MULTI, TIPC_NL_MON_GET); |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index b1fe20972aa9..dd1c4fa2eb78 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
@@ -241,7 +241,8 @@ err: | |||
241 | static struct publication *tipc_service_remove_publ(struct net *net, | 241 | static struct publication *tipc_service_remove_publ(struct net *net, |
242 | struct tipc_service *sc, | 242 | struct tipc_service *sc, |
243 | u32 lower, u32 upper, | 243 | u32 lower, u32 upper, |
244 | u32 node, u32 key) | 244 | u32 node, u32 key, |
245 | struct service_range **rng) | ||
245 | { | 246 | { |
246 | struct tipc_subscription *sub, *tmp; | 247 | struct tipc_subscription *sub, *tmp; |
247 | struct service_range *sr; | 248 | struct service_range *sr; |
@@ -275,19 +276,15 @@ static struct publication *tipc_service_remove_publ(struct net *net, | |||
275 | 276 | ||
276 | list_del(&p->all_publ); | 277 | list_del(&p->all_publ); |
277 | list_del(&p->local_publ); | 278 | list_del(&p->local_publ); |
278 | 279 | if (list_empty(&sr->all_publ)) | |
279 | /* Remove service range item if this was its last publication */ | ||
280 | if (list_empty(&sr->all_publ)) { | ||
281 | last = true; | 280 | last = true; |
282 | rb_erase(&sr->tree_node, &sc->ranges); | ||
283 | kfree(sr); | ||
284 | } | ||
285 | 281 | ||
286 | /* Notify any waiting subscriptions */ | 282 | /* Notify any waiting subscriptions */ |
287 | list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { | 283 | list_for_each_entry_safe(sub, tmp, &sc->subscriptions, service_list) { |
288 | tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN, | 284 | tipc_sub_report_overlap(sub, p->lower, p->upper, TIPC_WITHDRAWN, |
289 | p->port, p->node, p->scope, last); | 285 | p->port, p->node, p->scope, last); |
290 | } | 286 | } |
287 | *rng = sr; | ||
291 | return p; | 288 | return p; |
292 | } | 289 | } |
293 | 290 | ||
@@ -379,13 +376,20 @@ struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, | |||
379 | u32 node, u32 key) | 376 | u32 node, u32 key) |
380 | { | 377 | { |
381 | struct tipc_service *sc = tipc_service_find(net, type); | 378 | struct tipc_service *sc = tipc_service_find(net, type); |
379 | struct service_range *sr = NULL; | ||
382 | struct publication *p = NULL; | 380 | struct publication *p = NULL; |
383 | 381 | ||
384 | if (!sc) | 382 | if (!sc) |
385 | return NULL; | 383 | return NULL; |
386 | 384 | ||
387 | spin_lock_bh(&sc->lock); | 385 | spin_lock_bh(&sc->lock); |
388 | p = tipc_service_remove_publ(net, sc, lower, upper, node, key); | 386 | p = tipc_service_remove_publ(net, sc, lower, upper, node, key, &sr); |
387 | |||
388 | /* Remove service range item if this was its last publication */ | ||
389 | if (sr && list_empty(&sr->all_publ)) { | ||
390 | rb_erase(&sr->tree_node, &sc->ranges); | ||
391 | kfree(sr); | ||
392 | } | ||
389 | 393 | ||
390 | /* Delete service item if this no more publications and subscriptions */ | 394 | /* Delete service item if this no more publications and subscriptions */ |
391 | if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { | 395 | if (RB_EMPTY_ROOT(&sc->ranges) && list_empty(&sc->subscriptions)) { |
@@ -665,13 +669,14 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, | |||
665 | /** | 669 | /** |
666 | * tipc_nametbl_subscribe - add a subscription object to the name table | 670 | * tipc_nametbl_subscribe - add a subscription object to the name table |
667 | */ | 671 | */ |
668 | void tipc_nametbl_subscribe(struct tipc_subscription *sub) | 672 | bool tipc_nametbl_subscribe(struct tipc_subscription *sub) |
669 | { | 673 | { |
670 | struct name_table *nt = tipc_name_table(sub->net); | 674 | struct name_table *nt = tipc_name_table(sub->net); |
671 | struct tipc_net *tn = tipc_net(sub->net); | 675 | struct tipc_net *tn = tipc_net(sub->net); |
672 | struct tipc_subscr *s = &sub->evt.s; | 676 | struct tipc_subscr *s = &sub->evt.s; |
673 | u32 type = tipc_sub_read(s, seq.type); | 677 | u32 type = tipc_sub_read(s, seq.type); |
674 | struct tipc_service *sc; | 678 | struct tipc_service *sc; |
679 | bool res = true; | ||
675 | 680 | ||
676 | spin_lock_bh(&tn->nametbl_lock); | 681 | spin_lock_bh(&tn->nametbl_lock); |
677 | sc = tipc_service_find(sub->net, type); | 682 | sc = tipc_service_find(sub->net, type); |
@@ -685,8 +690,10 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub) | |||
685 | pr_warn("Failed to subscribe for {%u,%u,%u}\n", type, | 690 | pr_warn("Failed to subscribe for {%u,%u,%u}\n", type, |
686 | tipc_sub_read(s, seq.lower), | 691 | tipc_sub_read(s, seq.lower), |
687 | tipc_sub_read(s, seq.upper)); | 692 | tipc_sub_read(s, seq.upper)); |
693 | res = false; | ||
688 | } | 694 | } |
689 | spin_unlock_bh(&tn->nametbl_lock); | 695 | spin_unlock_bh(&tn->nametbl_lock); |
696 | return res; | ||
690 | } | 697 | } |
691 | 698 | ||
692 | /** | 699 | /** |
@@ -744,16 +751,17 @@ int tipc_nametbl_init(struct net *net) | |||
744 | static void tipc_service_delete(struct net *net, struct tipc_service *sc) | 751 | static void tipc_service_delete(struct net *net, struct tipc_service *sc) |
745 | { | 752 | { |
746 | struct service_range *sr, *tmpr; | 753 | struct service_range *sr, *tmpr; |
747 | struct publication *p, *tmpb; | 754 | struct publication *p, *tmp; |
748 | 755 | ||
749 | spin_lock_bh(&sc->lock); | 756 | spin_lock_bh(&sc->lock); |
750 | rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { | 757 | rbtree_postorder_for_each_entry_safe(sr, tmpr, &sc->ranges, tree_node) { |
751 | list_for_each_entry_safe(p, tmpb, | 758 | list_for_each_entry_safe(p, tmp, &sr->all_publ, all_publ) { |
752 | &sr->all_publ, all_publ) { | ||
753 | tipc_service_remove_publ(net, sc, p->lower, p->upper, | 759 | tipc_service_remove_publ(net, sc, p->lower, p->upper, |
754 | p->node, p->key); | 760 | p->node, p->key, &sr); |
755 | kfree_rcu(p, rcu); | 761 | kfree_rcu(p, rcu); |
756 | } | 762 | } |
763 | rb_erase(&sr->tree_node, &sc->ranges); | ||
764 | kfree(sr); | ||
757 | } | 765 | } |
758 | hlist_del_init_rcu(&sc->service_list); | 766 | hlist_del_init_rcu(&sc->service_list); |
759 | spin_unlock_bh(&sc->lock); | 767 | spin_unlock_bh(&sc->lock); |
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h index 4b14fc28d9e2..0febba41da86 100644 --- a/net/tipc/name_table.h +++ b/net/tipc/name_table.h | |||
@@ -126,7 +126,7 @@ struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type, | |||
126 | struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, | 126 | struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, |
127 | u32 lower, u32 upper, | 127 | u32 lower, u32 upper, |
128 | u32 node, u32 key); | 128 | u32 node, u32 key); |
129 | void tipc_nametbl_subscribe(struct tipc_subscription *s); | 129 | bool tipc_nametbl_subscribe(struct tipc_subscription *s); |
130 | void tipc_nametbl_unsubscribe(struct tipc_subscription *s); | 130 | void tipc_nametbl_unsubscribe(struct tipc_subscription *s); |
131 | int tipc_nametbl_init(struct net *net); | 131 | int tipc_nametbl_init(struct net *net); |
132 | void tipc_nametbl_stop(struct net *net); | 132 | void tipc_nametbl_stop(struct net *net); |
diff --git a/net/tipc/net.c b/net/tipc/net.c index 856f9e97ea29..4fbaa0464405 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
@@ -252,6 +252,8 @@ int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info) | |||
252 | u64 *w0 = (u64 *)&node_id[0]; | 252 | u64 *w0 = (u64 *)&node_id[0]; |
253 | u64 *w1 = (u64 *)&node_id[8]; | 253 | u64 *w1 = (u64 *)&node_id[8]; |
254 | 254 | ||
255 | if (!attrs[TIPC_NLA_NET_NODEID_W1]) | ||
256 | return -EINVAL; | ||
255 | *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]); | 257 | *w0 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID]); |
256 | *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]); | 258 | *w1 = nla_get_u64(attrs[TIPC_NLA_NET_NODEID_W1]); |
257 | tipc_net_init(net, node_id, 0); | 259 | tipc_net_init(net, node_id, 0); |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index b76f13f6fea1..6ff2254088f6 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -79,7 +79,10 @@ const struct nla_policy tipc_nl_sock_policy[TIPC_NLA_SOCK_MAX + 1] = { | |||
79 | 79 | ||
80 | const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { | 80 | const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { |
81 | [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, | 81 | [TIPC_NLA_NET_UNSPEC] = { .type = NLA_UNSPEC }, |
82 | [TIPC_NLA_NET_ID] = { .type = NLA_U32 } | 82 | [TIPC_NLA_NET_ID] = { .type = NLA_U32 }, |
83 | [TIPC_NLA_NET_ADDR] = { .type = NLA_U32 }, | ||
84 | [TIPC_NLA_NET_NODEID] = { .type = NLA_U64 }, | ||
85 | [TIPC_NLA_NET_NODEID_W1] = { .type = NLA_U64 }, | ||
83 | }; | 86 | }; |
84 | 87 | ||
85 | const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { | 88 | const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { |
diff --git a/net/tipc/node.c b/net/tipc/node.c index b71e4e376bb9..e9c52e1416c5 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -2238,8 +2238,8 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb) | |||
2238 | struct net *net = sock_net(skb->sk); | 2238 | struct net *net = sock_net(skb->sk); |
2239 | u32 prev_bearer = cb->args[0]; | 2239 | u32 prev_bearer = cb->args[0]; |
2240 | struct tipc_nl_msg msg; | 2240 | struct tipc_nl_msg msg; |
2241 | int bearer_id; | ||
2241 | int err; | 2242 | int err; |
2242 | int i; | ||
2243 | 2243 | ||
2244 | if (prev_bearer == MAX_BEARERS) | 2244 | if (prev_bearer == MAX_BEARERS) |
2245 | return 0; | 2245 | return 0; |
@@ -2249,16 +2249,13 @@ int tipc_nl_node_dump_monitor(struct sk_buff *skb, struct netlink_callback *cb) | |||
2249 | msg.seq = cb->nlh->nlmsg_seq; | 2249 | msg.seq = cb->nlh->nlmsg_seq; |
2250 | 2250 | ||
2251 | rtnl_lock(); | 2251 | rtnl_lock(); |
2252 | for (i = prev_bearer; i < MAX_BEARERS; i++) { | 2252 | for (bearer_id = prev_bearer; bearer_id < MAX_BEARERS; bearer_id++) { |
2253 | prev_bearer = i; | ||
2254 | err = __tipc_nl_add_monitor(net, &msg, prev_bearer); | 2253 | err = __tipc_nl_add_monitor(net, &msg, prev_bearer); |
2255 | if (err) | 2254 | if (err) |
2256 | goto out; | 2255 | break; |
2257 | } | 2256 | } |
2258 | |||
2259 | out: | ||
2260 | rtnl_unlock(); | 2257 | rtnl_unlock(); |
2261 | cb->args[0] = prev_bearer; | 2258 | cb->args[0] = bearer_id; |
2262 | 2259 | ||
2263 | return skb->len; | 2260 | return skb->len; |
2264 | } | 2261 | } |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 1fd1c8b5ce03..252a52ae0893 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1278,7 +1278,7 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen) | |||
1278 | struct tipc_msg *hdr = &tsk->phdr; | 1278 | struct tipc_msg *hdr = &tsk->phdr; |
1279 | struct tipc_name_seq *seq; | 1279 | struct tipc_name_seq *seq; |
1280 | struct sk_buff_head pkts; | 1280 | struct sk_buff_head pkts; |
1281 | u32 dnode, dport; | 1281 | u32 dport, dnode = 0; |
1282 | u32 type, inst; | 1282 | u32 type, inst; |
1283 | int mtu, rc; | 1283 | int mtu, rc; |
1284 | 1284 | ||
@@ -1348,6 +1348,8 @@ static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dlen) | |||
1348 | msg_set_destnode(hdr, dnode); | 1348 | msg_set_destnode(hdr, dnode); |
1349 | msg_set_destport(hdr, dest->addr.id.ref); | 1349 | msg_set_destport(hdr, dest->addr.id.ref); |
1350 | msg_set_hdr_sz(hdr, BASIC_H_SIZE); | 1350 | msg_set_hdr_sz(hdr, BASIC_H_SIZE); |
1351 | } else { | ||
1352 | return -EINVAL; | ||
1351 | } | 1353 | } |
1352 | 1354 | ||
1353 | /* Block or return if destination link is congested */ | 1355 | /* Block or return if destination link is congested */ |
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index b7d80bc5f4ab..f340e53da625 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c | |||
@@ -153,7 +153,10 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net, | |||
153 | memcpy(&sub->evt.s, s, sizeof(*s)); | 153 | memcpy(&sub->evt.s, s, sizeof(*s)); |
154 | spin_lock_init(&sub->lock); | 154 | spin_lock_init(&sub->lock); |
155 | kref_init(&sub->kref); | 155 | kref_init(&sub->kref); |
156 | tipc_nametbl_subscribe(sub); | 156 | if (!tipc_nametbl_subscribe(sub)) { |
157 | kfree(sub); | ||
158 | return NULL; | ||
159 | } | ||
157 | timer_setup(&sub->timer, tipc_sub_timeout, 0); | 160 | timer_setup(&sub->timer, tipc_sub_timeout, 0); |
158 | timeout = tipc_sub_read(&sub->evt.s, timeout); | 161 | timeout = tipc_sub_read(&sub->evt.s, timeout); |
159 | if (timeout != TIPC_WAIT_FOREVER) | 162 | if (timeout != TIPC_WAIT_FOREVER) |