diff options
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/link.c | 35 | ||||
-rw-r--r-- | net/tipc/link.h | 3 | ||||
-rw-r--r-- | net/tipc/node.c | 11 |
3 files changed, 49 insertions, 0 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 26cc033ee167..4ed650ce6e61 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -410,6 +410,11 @@ char *tipc_link_name(struct tipc_link *l) | |||
410 | return l->name; | 410 | return l->name; |
411 | } | 411 | } |
412 | 412 | ||
413 | u32 tipc_link_state(struct tipc_link *l) | ||
414 | { | ||
415 | return l->state; | ||
416 | } | ||
417 | |||
413 | /** | 418 | /** |
414 | * tipc_link_create - create a new link | 419 | * tipc_link_create - create a new link |
415 | * @n: pointer to associated node | 420 | * @n: pointer to associated node |
@@ -1385,6 +1390,36 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe, | |||
1385 | __skb_queue_tail(xmitq, skb); | 1390 | __skb_queue_tail(xmitq, skb); |
1386 | } | 1391 | } |
1387 | 1392 | ||
1393 | void tipc_link_create_dummy_tnl_msg(struct tipc_link *l, | ||
1394 | struct sk_buff_head *xmitq) | ||
1395 | { | ||
1396 | u32 onode = tipc_own_addr(l->net); | ||
1397 | struct tipc_msg *hdr, *ihdr; | ||
1398 | struct sk_buff_head tnlq; | ||
1399 | struct sk_buff *skb; | ||
1400 | u32 dnode = l->addr; | ||
1401 | |||
1402 | skb_queue_head_init(&tnlq); | ||
1403 | skb = tipc_msg_create(TUNNEL_PROTOCOL, FAILOVER_MSG, | ||
1404 | INT_H_SIZE, BASIC_H_SIZE, | ||
1405 | dnode, onode, 0, 0, 0); | ||
1406 | if (!skb) { | ||
1407 | pr_warn("%sunable to create tunnel packet\n", link_co_err); | ||
1408 | return; | ||
1409 | } | ||
1410 | |||
1411 | hdr = buf_msg(skb); | ||
1412 | msg_set_msgcnt(hdr, 1); | ||
1413 | msg_set_bearer_id(hdr, l->peer_bearer_id); | ||
1414 | |||
1415 | ihdr = (struct tipc_msg *)msg_data(hdr); | ||
1416 | tipc_msg_init(onode, ihdr, TIPC_LOW_IMPORTANCE, TIPC_DIRECT_MSG, | ||
1417 | BASIC_H_SIZE, dnode); | ||
1418 | msg_set_errcode(ihdr, TIPC_ERR_NO_PORT); | ||
1419 | __skb_queue_tail(&tnlq, skb); | ||
1420 | tipc_link_xmit(l, &tnlq, xmitq); | ||
1421 | } | ||
1422 | |||
1388 | /* tipc_link_tnl_prepare(): prepare and return a list of tunnel packets | 1423 | /* tipc_link_tnl_prepare(): prepare and return a list of tunnel packets |
1389 | * with contents of the link's transmit and backlog queues. | 1424 | * with contents of the link's transmit and backlog queues. |
1390 | */ | 1425 | */ |
diff --git a/net/tipc/link.h b/net/tipc/link.h index 7bc494a33fdf..90488c538a4e 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h | |||
@@ -88,6 +88,8 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, | |||
88 | struct tipc_link **link); | 88 | struct tipc_link **link); |
89 | void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, | 89 | void tipc_link_tnl_prepare(struct tipc_link *l, struct tipc_link *tnl, |
90 | int mtyp, struct sk_buff_head *xmitq); | 90 | int mtyp, struct sk_buff_head *xmitq); |
91 | void tipc_link_create_dummy_tnl_msg(struct tipc_link *tnl, | ||
92 | struct sk_buff_head *xmitq); | ||
91 | void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq); | 93 | void tipc_link_build_reset_msg(struct tipc_link *l, struct sk_buff_head *xmitq); |
92 | int tipc_link_fsm_evt(struct tipc_link *l, int evt); | 94 | int tipc_link_fsm_evt(struct tipc_link *l, int evt); |
93 | bool tipc_link_is_up(struct tipc_link *l); | 95 | bool tipc_link_is_up(struct tipc_link *l); |
@@ -107,6 +109,7 @@ u16 tipc_link_rcv_nxt(struct tipc_link *l); | |||
107 | u16 tipc_link_acked(struct tipc_link *l); | 109 | u16 tipc_link_acked(struct tipc_link *l); |
108 | u32 tipc_link_id(struct tipc_link *l); | 110 | u32 tipc_link_id(struct tipc_link *l); |
109 | char *tipc_link_name(struct tipc_link *l); | 111 | char *tipc_link_name(struct tipc_link *l); |
112 | u32 tipc_link_state(struct tipc_link *l); | ||
110 | char tipc_link_plane(struct tipc_link *l); | 113 | char tipc_link_plane(struct tipc_link *l); |
111 | int tipc_link_prio(struct tipc_link *l); | 114 | int tipc_link_prio(struct tipc_link *l); |
112 | int tipc_link_window(struct tipc_link *l); | 115 | int tipc_link_window(struct tipc_link *l); |
diff --git a/net/tipc/node.c b/net/tipc/node.c index 68014f1b6976..b0ee25f1f2e6 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -111,6 +111,7 @@ struct tipc_node { | |||
111 | int action_flags; | 111 | int action_flags; |
112 | struct list_head list; | 112 | struct list_head list; |
113 | int state; | 113 | int state; |
114 | bool failover_sent; | ||
114 | u16 sync_point; | 115 | u16 sync_point; |
115 | int link_cnt; | 116 | int link_cnt; |
116 | u16 working_links; | 117 | u16 working_links; |
@@ -680,6 +681,7 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
680 | *slot0 = bearer_id; | 681 | *slot0 = bearer_id; |
681 | *slot1 = bearer_id; | 682 | *slot1 = bearer_id; |
682 | tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT); | 683 | tipc_node_fsm_evt(n, SELF_ESTABL_CONTACT_EVT); |
684 | n->failover_sent = false; | ||
683 | n->action_flags |= TIPC_NOTIFY_NODE_UP; | 685 | n->action_flags |= TIPC_NOTIFY_NODE_UP; |
684 | tipc_link_set_active(nl, true); | 686 | tipc_link_set_active(nl, true); |
685 | tipc_bcast_add_peer(n->net, nl, xmitq); | 687 | tipc_bcast_add_peer(n->net, nl, xmitq); |
@@ -1615,6 +1617,15 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, | |||
1615 | tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl), | 1617 | tipc_skb_queue_splice_tail_init(tipc_link_inputq(pl), |
1616 | tipc_link_inputq(l)); | 1618 | tipc_link_inputq(l)); |
1617 | } | 1619 | } |
1620 | /* If parallel link was already down, and this happened before | ||
1621 | * the tunnel link came up, FAILOVER was never sent. Ensure that | ||
1622 | * FAILOVER is sent to get peer out of NODE_FAILINGOVER state. | ||
1623 | */ | ||
1624 | if (n->state != NODE_FAILINGOVER && !n->failover_sent) { | ||
1625 | tipc_link_create_dummy_tnl_msg(l, xmitq); | ||
1626 | n->failover_sent = true; | ||
1627 | } | ||
1628 | |||
1618 | /* If pkts arrive out of order, use lowest calculated syncpt */ | 1629 | /* If pkts arrive out of order, use lowest calculated syncpt */ |
1619 | if (less(syncpt, n->sync_point)) | 1630 | if (less(syncpt, n->sync_point)) |
1620 | n->sync_point = syncpt; | 1631 | n->sync_point = syncpt; |