diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/node.c | 69 |
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 | ||
197 | void 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) | |||
377 | static void node_lost_contact(struct tipc_node *n_ptr) | 355 | static 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 | ||
423 | struct sk_buff *tipc_node_get_nodes(struct net *net, const void *req_tlv_area, | 419 | struct 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, | |||
566 | void tipc_node_unlock(struct tipc_node *node) | 562 | void 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); |