aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/monitor.c2
-rw-r--r--net/tipc/name_table.c34
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c2
-rw-r--r--net/tipc/netlink.c5
-rw-r--r--net/tipc/node.c11
-rw-r--r--net/tipc/socket.c4
-rw-r--r--net/tipc/subscr.c5
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:
241static struct publication *tipc_service_remove_publ(struct net *net, 241static 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 */
668void tipc_nametbl_subscribe(struct tipc_subscription *sub) 672bool 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)
744static void tipc_service_delete(struct net *net, struct tipc_service *sc) 751static 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,
126struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type, 126struct 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);
129void tipc_nametbl_subscribe(struct tipc_subscription *s); 129bool tipc_nametbl_subscribe(struct tipc_subscription *s);
130void tipc_nametbl_unsubscribe(struct tipc_subscription *s); 130void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
131int tipc_nametbl_init(struct net *net); 131int tipc_nametbl_init(struct net *net);
132void tipc_nametbl_stop(struct net *net); 132void 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
80const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = { 80const 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
85const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { 88const 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
2259out:
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)