aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/node.c46
-rw-r--r--net/tipc/node.h7
-rw-r--r--net/tipc/socket.c6
3 files changed, 37 insertions, 22 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 90cee4a6fce4..5781634e957d 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -219,11 +219,11 @@ void tipc_node_abort_sock_conns(struct list_head *conns)
219void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 219void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
220{ 220{
221 struct tipc_link **active = &n_ptr->active_links[0]; 221 struct tipc_link **active = &n_ptr->active_links[0];
222 u32 addr = n_ptr->addr;
223 222
224 n_ptr->working_links++; 223 n_ptr->working_links++;
225 tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE, 224 n_ptr->action_flags |= TIPC_NOTIFY_LINK_UP;
226 l_ptr->bearer_id, addr); 225 n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id;
226
227 pr_info("Established link <%s> on network plane %c\n", 227 pr_info("Established link <%s> on network plane %c\n",
228 l_ptr->name, l_ptr->net_plane); 228 l_ptr->name, l_ptr->net_plane);
229 229
@@ -284,10 +284,10 @@ static void node_select_active_links(struct tipc_node *n_ptr)
284void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr) 284void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
285{ 285{
286 struct tipc_link **active; 286 struct tipc_link **active;
287 u32 addr = n_ptr->addr;
288 287
289 n_ptr->working_links--; 288 n_ptr->working_links--;
290 tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr); 289 n_ptr->action_flags |= TIPC_NOTIFY_LINK_DOWN;
290 n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id;
291 291
292 if (!tipc_link_is_active(l_ptr)) { 292 if (!tipc_link_is_active(l_ptr)) {
293 pr_info("Lost standby link <%s> on network plane %c\n", 293 pr_info("Lost standby link <%s> on network plane %c\n",
@@ -552,28 +552,30 @@ void tipc_node_unlock(struct tipc_node *node)
552 LIST_HEAD(conn_sks); 552 LIST_HEAD(conn_sks);
553 struct sk_buff_head waiting_sks; 553 struct sk_buff_head waiting_sks;
554 u32 addr = 0; 554 u32 addr = 0;
555 unsigned int flags = node->action_flags; 555 int flags = node->action_flags;
556 u32 link_id = 0;
556 557
557 if (likely(!node->action_flags)) { 558 if (likely(!flags)) {
558 spin_unlock_bh(&node->lock); 559 spin_unlock_bh(&node->lock);
559 return; 560 return;
560 } 561 }
561 562
563 addr = node->addr;
564 link_id = node->link_id;
562 __skb_queue_head_init(&waiting_sks); 565 __skb_queue_head_init(&waiting_sks);
563 if (node->action_flags & TIPC_WAKEUP_USERS) { 566
567 if (flags & TIPC_WAKEUP_USERS)
564 skb_queue_splice_init(&node->waiting_sks, &waiting_sks); 568 skb_queue_splice_init(&node->waiting_sks, &waiting_sks);
565 node->action_flags &= ~TIPC_WAKEUP_USERS; 569
566 } 570 if (flags & TIPC_NOTIFY_NODE_DOWN) {
567 if (node->action_flags & TIPC_NOTIFY_NODE_DOWN) {
568 list_replace_init(&node->nsub, &nsub_list); 571 list_replace_init(&node->nsub, &nsub_list);
569 list_replace_init(&node->conn_sks, &conn_sks); 572 list_replace_init(&node->conn_sks, &conn_sks);
570 node->action_flags &= ~TIPC_NOTIFY_NODE_DOWN;
571 } 573 }
572 if (node->action_flags & TIPC_NOTIFY_NODE_UP) { 574 node->action_flags &= ~(TIPC_WAKEUP_USERS | TIPC_NOTIFY_NODE_DOWN |
573 node->action_flags &= ~TIPC_NOTIFY_NODE_UP; 575 TIPC_NOTIFY_NODE_UP | TIPC_NOTIFY_LINK_UP |
574 addr = node->addr; 576 TIPC_NOTIFY_LINK_DOWN |
575 } 577 TIPC_WAKEUP_BCAST_USERS);
576 node->action_flags &= ~TIPC_WAKEUP_BCAST_USERS; 578
577 spin_unlock_bh(&node->lock); 579 spin_unlock_bh(&node->lock);
578 580
579 while (!skb_queue_empty(&waiting_sks)) 581 while (!skb_queue_empty(&waiting_sks))
@@ -588,6 +590,14 @@ void tipc_node_unlock(struct tipc_node *node)
588 if (flags & TIPC_WAKEUP_BCAST_USERS) 590 if (flags & TIPC_WAKEUP_BCAST_USERS)
589 tipc_bclink_wakeup_users(); 591 tipc_bclink_wakeup_users();
590 592
591 if (addr) 593 if (flags & TIPC_NOTIFY_NODE_UP)
592 tipc_named_node_up(addr); 594 tipc_named_node_up(addr);
595
596 if (flags & TIPC_NOTIFY_LINK_UP)
597 tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr,
598 TIPC_NODE_SCOPE, link_id, addr);
599
600 if (flags & TIPC_NOTIFY_LINK_DOWN)
601 tipc_nametbl_withdraw(TIPC_LINK_STATE, addr,
602 link_id, addr);
593} 603}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 67513c3c852c..04e91458bb29 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -53,6 +53,7 @@
53 * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down 53 * TIPC_WAIT_OWN_LINKS_DOWN: wait until peer node is declared down
54 * TIPC_NOTIFY_NODE_DOWN: notify node is down 54 * TIPC_NOTIFY_NODE_DOWN: notify node is down
55 * TIPC_NOTIFY_NODE_UP: notify node is up 55 * TIPC_NOTIFY_NODE_UP: notify node is up
56 * TIPC_DISTRIBUTE_NAME: publish or withdraw link state name type
56 */ 57 */
57enum { 58enum {
58 TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1), 59 TIPC_WAIT_PEER_LINKS_DOWN = (1 << 1),
@@ -60,7 +61,9 @@ enum {
60 TIPC_NOTIFY_NODE_DOWN = (1 << 3), 61 TIPC_NOTIFY_NODE_DOWN = (1 << 3),
61 TIPC_NOTIFY_NODE_UP = (1 << 4), 62 TIPC_NOTIFY_NODE_UP = (1 << 4),
62 TIPC_WAKEUP_USERS = (1 << 5), 63 TIPC_WAKEUP_USERS = (1 << 5),
63 TIPC_WAKEUP_BCAST_USERS = (1 << 6) 64 TIPC_WAKEUP_BCAST_USERS = (1 << 6),
65 TIPC_NOTIFY_LINK_UP = (1 << 7),
66 TIPC_NOTIFY_LINK_DOWN = (1 << 8)
64}; 67};
65 68
66/** 69/**
@@ -100,6 +103,7 @@ struct tipc_node_bclink {
100 * @working_links: number of working links to node (both active and standby) 103 * @working_links: number of working links to node (both active and standby)
101 * @link_cnt: number of links to node 104 * @link_cnt: number of links to node
102 * @signature: node instance identifier 105 * @signature: node instance identifier
106 * @link_id: local and remote bearer ids of changing link, if any
103 * @nsub: list of "node down" subscriptions monitoring node 107 * @nsub: list of "node down" subscriptions monitoring node
104 * @rcu: rcu struct for tipc_node 108 * @rcu: rcu struct for tipc_node
105 */ 109 */
@@ -116,6 +120,7 @@ struct tipc_node {
116 int link_cnt; 120 int link_cnt;
117 int working_links; 121 int working_links;
118 u32 signature; 122 u32 signature;
123 u32 link_id;
119 struct list_head nsub; 124 struct list_head nsub;
120 struct sk_buff_head waiting_sks; 125 struct sk_buff_head waiting_sks;
121 struct list_head conn_sks; 126 struct list_head conn_sks;
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 75275c5cf929..51bddc236a15 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -1776,7 +1776,7 @@ int tipc_sk_rcv(struct sk_buff *buf)
1776 sk = &tsk->sk; 1776 sk = &tsk->sk;
1777 1777
1778 /* Queue message */ 1778 /* Queue message */
1779 bh_lock_sock(sk); 1779 spin_lock_bh(&sk->sk_lock.slock);
1780 1780
1781 if (!sock_owned_by_user(sk)) { 1781 if (!sock_owned_by_user(sk)) {
1782 rc = filter_rcv(sk, buf); 1782 rc = filter_rcv(sk, buf);
@@ -1787,7 +1787,7 @@ int tipc_sk_rcv(struct sk_buff *buf)
1787 if (sk_add_backlog(sk, buf, limit)) 1787 if (sk_add_backlog(sk, buf, limit))
1788 rc = -TIPC_ERR_OVERLOAD; 1788 rc = -TIPC_ERR_OVERLOAD;
1789 } 1789 }
1790 bh_unlock_sock(sk); 1790 spin_unlock_bh(&sk->sk_lock.slock);
1791 tipc_sk_put(tsk); 1791 tipc_sk_put(tsk);
1792 if (likely(!rc)) 1792 if (likely(!rc))
1793 return 0; 1793 return 0;
@@ -2673,7 +2673,7 @@ static int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg)
2673 case SIOCGETLINKNAME: 2673 case SIOCGETLINKNAME:
2674 if (copy_from_user(&lnr, argp, sizeof(lnr))) 2674 if (copy_from_user(&lnr, argp, sizeof(lnr)))
2675 return -EFAULT; 2675 return -EFAULT;
2676 if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer, 2676 if (!tipc_node_get_linkname(lnr.bearer_id & 0xffff, lnr.peer,
2677 lnr.linkname, TIPC_MAX_LINK_NAME)) { 2677 lnr.linkname, TIPC_MAX_LINK_NAME)) {
2678 if (copy_to_user(argp, &lnr, sizeof(lnr))) 2678 if (copy_to_user(argp, &lnr, sizeof(lnr)))
2679 return -EFAULT; 2679 return -EFAULT;