aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/node.c69
1 files changed, 29 insertions, 40 deletions
diff --git a/net/tipc/node.c b/net/tipc/node.c
index dcb83d9b2193..c7fdf3dec92c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -194,28 +194,6 @@ void tipc_node_remove_conn(struct net *net, u32 dnode, u32 port)
194 tipc_node_unlock(node); 194 tipc_node_unlock(node);
195} 195}
196 196
197void tipc_node_abort_sock_conns(struct net *net, struct list_head *conns)
198{
199 struct tipc_net *tn = net_generic(net, tipc_net_id);
200 struct tipc_sock_conn *conn, *safe;
201 struct sk_buff *skb;
202 struct sk_buff_head skbs;
203
204 skb_queue_head_init(&skbs);
205 list_for_each_entry_safe(conn, safe, conns, list) {
206 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE,
207 TIPC_CONN_MSG, SHORT_H_SIZE, 0,
208 tn->own_addr, conn->peer_node,
209 conn->port, conn->peer_port,
210 TIPC_ERR_NO_NODE);
211 if (likely(skb))
212 skb_queue_tail(&skbs, skb);
213 list_del(&conn->list);
214 kfree(conn);
215 }
216 tipc_sk_rcv(net, &skbs);
217}
218
219/** 197/**
220 * tipc_node_link_up - handle addition of link 198 * tipc_node_link_up - handle addition of link
221 * 199 *
@@ -377,7 +355,11 @@ static void node_established_contact(struct tipc_node *n_ptr)
377static void node_lost_contact(struct tipc_node *n_ptr) 355static void node_lost_contact(struct tipc_node *n_ptr)
378{ 356{
379 char addr_string[16]; 357 char addr_string[16];
380 u32 i; 358 struct tipc_sock_conn *conn, *safe;
359 struct list_head *conns = &n_ptr->conn_sks;
360 struct sk_buff *skb;
361 struct tipc_net *tn = net_generic(n_ptr->net, tipc_net_id);
362 uint i;
381 363
382 pr_debug("Lost contact with %s\n", 364 pr_debug("Lost contact with %s\n",
383 tipc_addr_string_fill(addr_string, n_ptr->addr)); 365 tipc_addr_string_fill(addr_string, n_ptr->addr));
@@ -413,11 +395,25 @@ static void node_lost_contact(struct tipc_node *n_ptr)
413 395
414 n_ptr->action_flags &= ~TIPC_WAIT_OWN_LINKS_DOWN; 396 n_ptr->action_flags &= ~TIPC_WAIT_OWN_LINKS_DOWN;
415 397
416 /* Notify subscribers and prevent re-contact with node until 398 /* Prevent re-contact with node until cleanup is done */
417 * cleanup is done. 399 n_ptr->action_flags |= TIPC_WAIT_PEER_LINKS_DOWN;
418 */ 400
419 n_ptr->action_flags |= TIPC_WAIT_PEER_LINKS_DOWN | 401 /* Notify publications from this node */
420 TIPC_NOTIFY_NODE_DOWN; 402 n_ptr->action_flags |= TIPC_NOTIFY_NODE_DOWN;
403
404 /* Notify sockets connected to node */
405 list_for_each_entry_safe(conn, safe, conns, list) {
406 skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG,
407 SHORT_H_SIZE, 0, tn->own_addr,
408 conn->peer_node, conn->port,
409 conn->peer_port, TIPC_ERR_NO_NODE);
410 if (likely(skb)) {
411 skb_queue_tail(n_ptr->inputq, skb);
412 n_ptr->action_flags |= TIPC_MSG_EVT;
413 }
414 list_del(&conn->list);
415 kfree(conn);
416 }
421} 417}
422 418
423struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, 419struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area,
@@ -566,13 +562,12 @@ int tipc_node_get_linkname(struct net *net, u32 bearer_id, u32 addr,
566void tipc_node_unlock(struct tipc_node *node) 562void tipc_node_unlock(struct tipc_node *node)
567{ 563{
568 struct net *net = node->net; 564 struct net *net = node->net;
569 LIST_HEAD(nsub_list);
570 LIST_HEAD(conn_sks);
571 u32 addr = 0; 565 u32 addr = 0;
572 u32 flags = node->action_flags; 566 u32 flags = node->action_flags;
573 u32 link_id = 0; 567 u32 link_id = 0;
568 struct list_head *publ_list;
574 struct sk_buff_head *inputq = node->inputq; 569 struct sk_buff_head *inputq = node->inputq;
575 struct sk_buff_head *namedq = node->inputq; 570 struct sk_buff_head *namedq;
576 571
577 if (likely(!flags || (flags == TIPC_MSG_EVT))) { 572 if (likely(!flags || (flags == TIPC_MSG_EVT))) {
578 node->action_flags = 0; 573 node->action_flags = 0;
@@ -585,11 +580,8 @@ void tipc_node_unlock(struct tipc_node *node)
585 addr = node->addr; 580 addr = node->addr;
586 link_id = node->link_id; 581 link_id = node->link_id;
587 namedq = node->namedq; 582 namedq = node->namedq;
583 publ_list = &node->publ_list;
588 584
589 if (flags & TIPC_NOTIFY_NODE_DOWN) {
590 list_replace_init(&node->publ_list, &nsub_list);
591 list_replace_init(&node->conn_sks, &conn_sks);
592 }
593 node->action_flags &= ~(TIPC_MSG_EVT | TIPC_NOTIFY_NODE_DOWN | 585 node->action_flags &= ~(TIPC_MSG_EVT | TIPC_NOTIFY_NODE_DOWN |
594 TIPC_NOTIFY_NODE_UP | TIPC_NOTIFY_LINK_UP | 586 TIPC_NOTIFY_NODE_UP | TIPC_NOTIFY_LINK_UP |
595 TIPC_NOTIFY_LINK_DOWN | 587 TIPC_NOTIFY_LINK_DOWN |
@@ -598,11 +590,8 @@ void tipc_node_unlock(struct tipc_node *node)
598 590
599 spin_unlock_bh(&node->lock); 591 spin_unlock_bh(&node->lock);
600 592
601 if (!list_empty(&conn_sks)) 593 if (flags & TIPC_NOTIFY_NODE_DOWN)
602 tipc_node_abort_sock_conns(net, &conn_sks); 594 tipc_publ_notify(net, publ_list, addr);
603
604 if (!list_empty(&nsub_list))
605 tipc_publ_notify(net, &nsub_list, addr);
606 595
607 if (flags & TIPC_WAKEUP_BCAST_USERS) 596 if (flags & TIPC_WAKEUP_BCAST_USERS)
608 tipc_bclink_wakeup_users(net); 597 tipc_bclink_wakeup_users(net);