aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-02-05 08:36:42 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-05 19:00:02 -0500
commit708ac32cb5e1305cf3670e147eedcc699d110ed0 (patch)
tree5b8d52c787ffa48758eb0ee974dac9489b254280
parentc637c1035534867b85b78b453c38c495b58e2c5a (diff)
tipc: simplify connection abort notifications when links break
The new input message queue in struct tipc_link can be used for delivering connection abort messages to subscribing sockets. This makes it possible to simplify the code for such cases. This commit removes the temporary list in tipc_node_unlock() used for transforming abort subscriptions to messages. Instead, the abort messages are now created at the moment of lost contact, and then added to the last failed link's generic input queue for delivery to the sockets concerned. Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-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);