aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c1
-rw-r--r--net/tipc/link.c98
-rw-r--r--net/tipc/link.h44
-rw-r--r--net/tipc/node.c2
4 files changed, 67 insertions, 78 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 295bdc26f103..aab4e8dd7b32 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -924,7 +924,6 @@ int tipc_bclink_init(struct net *net)
924 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); 924 tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
925 bcl->bearer_id = MAX_BEARERS; 925 bcl->bearer_id = MAX_BEARERS;
926 rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer); 926 rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer);
927 bcl->state = WORKING_WORKING;
928 bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg; 927 bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg;
929 msg_set_prevnode(bcl->pmsg, tn->own_addr); 928 msg_set_prevnode(bcl->pmsg, tn->own_addr);
930 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); 929 strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c052437a7cfa..35a2da688db1 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -79,19 +79,49 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
79/* 79/*
80 * Out-of-range value for link session numbers 80 * Out-of-range value for link session numbers
81 */ 81 */
82#define INVALID_SESSION 0x10000 82#define WILDCARD_SESSION 0x10000
83 83
84/* 84/* State value stored in 'failover_pkts'
85 * Link state events:
86 */ 85 */
87#define STARTING_EVT 856384768 /* link processing trigger */ 86#define FIRST_FAILOVER 0xffffu
88#define TRAFFIC_MSG_EVT 560815u /* rx'd ??? */
89#define SILENCE_EVT 560817u /* timer dicovered silence from peer */
90 87
91/* 88/* Link FSM states and events:
92 * State value stored in 'failover_pkts'
93 */ 89 */
94#define FIRST_FAILOVER 0xffffu 90enum {
91 WORKING_WORKING,
92 WORKING_UNKNOWN,
93 RESET_RESET,
94 RESET_UNKNOWN
95};
96
97enum {
98 PEER_RESET_EVT = RESET_MSG,
99 ACTIVATE_EVT = ACTIVATE_MSG,
100 TRAFFIC_EVT, /* Any other valid msg from peer */
101 SILENCE_EVT /* Peer was silent during last timer interval*/
102};
103
104/* Link FSM state checking routines
105 */
106static int link_working_working(struct tipc_link *l)
107{
108 return l->state == WORKING_WORKING;
109}
110
111static int link_working_unknown(struct tipc_link *l)
112{
113 return l->state == WORKING_UNKNOWN;
114}
115
116static int link_reset_unknown(struct tipc_link *l)
117{
118 return l->state == RESET_UNKNOWN;
119}
120
121static int link_reset_reset(struct tipc_link *l)
122{
123 return l->state == RESET_RESET;
124}
95 125
96static void link_handle_out_of_seq_msg(struct tipc_link *link, 126static void link_handle_out_of_seq_msg(struct tipc_link *link,
97 struct sk_buff *skb); 127 struct sk_buff *skb);
@@ -268,7 +298,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
268 /* note: peer i/f name is updated by reset/activate message */ 298 /* note: peer i/f name is updated by reset/activate message */
269 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 299 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
270 l_ptr->owner = n_ptr; 300 l_ptr->owner = n_ptr;
271 l_ptr->peer_session = INVALID_SESSION; 301 l_ptr->peer_session = WILDCARD_SESSION;
272 l_ptr->bearer_id = b_ptr->identity; 302 l_ptr->bearer_id = b_ptr->identity;
273 link_set_supervision_props(l_ptr, b_ptr->tolerance); 303 link_set_supervision_props(l_ptr, b_ptr->tolerance);
274 l_ptr->state = RESET_UNKNOWN; 304 l_ptr->state = RESET_UNKNOWN;
@@ -297,8 +327,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
297 link_reset_statistics(l_ptr); 327 link_reset_statistics(l_ptr);
298 tipc_node_attach_link(n_ptr, l_ptr); 328 tipc_node_attach_link(n_ptr, l_ptr);
299 setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr); 329 setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
300 link_state_event(l_ptr, STARTING_EVT); 330 link_set_timer(l_ptr, l_ptr->keepalive_intv);
301
302 return l_ptr; 331 return l_ptr;
303} 332}
304 333
@@ -311,7 +340,6 @@ void tipc_link_delete(struct tipc_link *l)
311 tipc_link_reset(l); 340 tipc_link_reset(l);
312 if (del_timer(&l->timer)) 341 if (del_timer(&l->timer))
313 tipc_link_put(l); 342 tipc_link_put(l);
314 l->flags |= LINK_STOPPED;
315 /* Delete link now, or when timer is finished: */ 343 /* Delete link now, or when timer is finished: */
316 tipc_link_reset_fragments(l); 344 tipc_link_reset_fragments(l);
317 tipc_node_detach_link(l->owner, l); 345 tipc_node_detach_link(l->owner, l);
@@ -438,7 +466,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
438 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff)); 466 msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
439 467
440 /* Link is down, accept any session */ 468 /* Link is down, accept any session */
441 l_ptr->peer_session = INVALID_SESSION; 469 l_ptr->peer_session = WILDCARD_SESSION;
442 470
443 /* Prepare for renewed mtu size negotiation */ 471 /* Prepare for renewed mtu size negotiation */
444 l_ptr->mtu = l_ptr->advertised_mtu; 472 l_ptr->mtu = l_ptr->advertised_mtu;
@@ -452,7 +480,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
452 tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr); 480 tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr);
453 481
454 if (was_active_link && tipc_node_is_up(l_ptr->owner) && (pl != l_ptr)) { 482 if (was_active_link && tipc_node_is_up(l_ptr->owner) && (pl != l_ptr)) {
455 l_ptr->flags |= LINK_FAILINGOVER; 483 l_ptr->exec_mode = TIPC_LINK_BLOCKED;
456 l_ptr->failover_checkpt = l_ptr->rcv_nxt; 484 l_ptr->failover_checkpt = l_ptr->rcv_nxt;
457 pl->failover_pkts = FIRST_FAILOVER; 485 pl->failover_pkts = FIRST_FAILOVER;
458 pl->failover_checkpt = l_ptr->rcv_nxt; 486 pl->failover_checkpt = l_ptr->rcv_nxt;
@@ -496,21 +524,14 @@ static void link_activate(struct tipc_link *link)
496static void link_state_event(struct tipc_link *l_ptr, unsigned int event) 524static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
497{ 525{
498 struct tipc_link *other; 526 struct tipc_link *other;
499 unsigned long timer_intv = l_ptr->keepalive_intv;
500
501 if (l_ptr->flags & LINK_STOPPED)
502 return;
503
504 if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
505 return; /* Not yet. */
506 527
507 if (l_ptr->flags & LINK_FAILINGOVER) 528 if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
508 return; 529 return;
509 530
510 switch (l_ptr->state) { 531 switch (l_ptr->state) {
511 case WORKING_WORKING: 532 case WORKING_WORKING:
512 switch (event) { 533 switch (event) {
513 case TRAFFIC_MSG_EVT: 534 case TRAFFIC_EVT:
514 case ACTIVATE_MSG: 535 case ACTIVATE_MSG:
515 l_ptr->silent_intv_cnt = 0; 536 l_ptr->silent_intv_cnt = 0;
516 break; 537 break;
@@ -538,7 +559,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
538 break; 559 break;
539 case WORKING_UNKNOWN: 560 case WORKING_UNKNOWN:
540 switch (event) { 561 switch (event) {
541 case TRAFFIC_MSG_EVT: 562 case TRAFFIC_EVT:
542 case ACTIVATE_MSG: 563 case ACTIVATE_MSG:
543 l_ptr->state = WORKING_WORKING; 564 l_ptr->state = WORKING_WORKING;
544 l_ptr->silent_intv_cnt = 0; 565 l_ptr->silent_intv_cnt = 0;
@@ -576,7 +597,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
576 break; 597 break;
577 case RESET_UNKNOWN: 598 case RESET_UNKNOWN:
578 switch (event) { 599 switch (event) {
579 case TRAFFIC_MSG_EVT: 600 case TRAFFIC_EVT:
580 break; 601 break;
581 case ACTIVATE_MSG: 602 case ACTIVATE_MSG:
582 other = node_active_link(l_ptr->owner, 0); 603 other = node_active_link(l_ptr->owner, 0);
@@ -593,10 +614,6 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
593 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG, 614 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
594 1, 0, 0, 0); 615 1, 0, 0, 0);
595 break; 616 break;
596 case STARTING_EVT:
597 l_ptr->flags |= LINK_STARTED;
598 link_set_timer(l_ptr, timer_intv);
599 break;
600 case SILENCE_EVT: 617 case SILENCE_EVT:
601 tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0); 618 tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0);
602 break; 619 break;
@@ -606,7 +623,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
606 break; 623 break;
607 case RESET_RESET: 624 case RESET_RESET:
608 switch (event) { 625 switch (event) {
609 case TRAFFIC_MSG_EVT: 626 case TRAFFIC_EVT:
610 case ACTIVATE_MSG: 627 case ACTIVATE_MSG:
611 other = node_active_link(l_ptr->owner, 0); 628 other = node_active_link(l_ptr->owner, 0);
612 if (other && link_working_unknown(other)) 629 if (other && link_working_unknown(other))
@@ -975,7 +992,7 @@ static bool link_synch(struct tipc_link *l)
975 if (skb_queue_len(pl->inputq) > post_synch) 992 if (skb_queue_len(pl->inputq) > post_synch)
976 return false; 993 return false;
977synched: 994synched:
978 l->flags &= ~LINK_SYNCHING; 995 l->exec_mode = TIPC_LINK_OPEN;
979 return true; 996 return true;
980} 997}
981 998
@@ -1091,7 +1108,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1091 } 1108 }
1092 1109
1093 /* Traffic message. Conditionally activate link */ 1110 /* Traffic message. Conditionally activate link */
1094 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1111 link_state_event(l_ptr, TRAFFIC_EVT);
1095 1112
1096 if (link_working_working(l_ptr)) { 1113 if (link_working_working(l_ptr)) {
1097 /* Re-insert buffer in front of queue */ 1114 /* Re-insert buffer in front of queue */
@@ -1112,7 +1129,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1112 l_ptr->silent_intv_cnt = 0; 1129 l_ptr->silent_intv_cnt = 0;
1113 1130
1114 /* Synchronize with parallel link if applicable */ 1131 /* Synchronize with parallel link if applicable */
1115 if (unlikely((l_ptr->flags & LINK_SYNCHING) && !msg_dup(msg))) { 1132 if (unlikely((l_ptr->exec_mode == TIPC_LINK_TUNNEL) &&
1133 !msg_dup(msg))) {
1116 if (!link_synch(l_ptr)) 1134 if (!link_synch(l_ptr))
1117 goto unlock; 1135 goto unlock;
1118 } 1136 }
@@ -1193,7 +1211,7 @@ static void tipc_link_input(struct tipc_link *link, struct sk_buff *skb)
1193 switch (msg_user(msg)) { 1211 switch (msg_user(msg)) {
1194 case TUNNEL_PROTOCOL: 1212 case TUNNEL_PROTOCOL:
1195 if (msg_dup(msg)) { 1213 if (msg_dup(msg)) {
1196 link->flags |= LINK_SYNCHING; 1214 link->exec_mode = TIPC_LINK_TUNNEL;
1197 link->synch_point = msg_seqno(msg_get_wrapped(msg)); 1215 link->synch_point = msg_seqno(msg_get_wrapped(msg));
1198 kfree_skb(skb); 1216 kfree_skb(skb);
1199 break; 1217 break;
@@ -1315,7 +1333,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
1315 u16 last_rcv; 1333 u16 last_rcv;
1316 1334
1317 /* Don't send protocol message during link failover */ 1335 /* Don't send protocol message during link failover */
1318 if (l_ptr->flags & LINK_FAILINGOVER) 1336 if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
1319 return; 1337 return;
1320 1338
1321 /* Abort non-RESET send if communication with node is prohibited */ 1339 /* Abort non-RESET send if communication with node is prohibited */
@@ -1390,7 +1408,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1390 u32 msg_tol; 1408 u32 msg_tol;
1391 struct tipc_msg *msg = buf_msg(buf); 1409 struct tipc_msg *msg = buf_msg(buf);
1392 1410
1393 if (l_ptr->flags & LINK_FAILINGOVER) 1411 if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
1394 goto exit; 1412 goto exit;
1395 1413
1396 if (l_ptr->net_plane != msg_net_plane(msg)) 1414 if (l_ptr->net_plane != msg_net_plane(msg))
@@ -1401,7 +1419,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1401 1419
1402 case RESET_MSG: 1420 case RESET_MSG:
1403 if (!link_working_unknown(l_ptr) && 1421 if (!link_working_unknown(l_ptr) &&
1404 (l_ptr->peer_session != INVALID_SESSION)) { 1422 (l_ptr->peer_session != WILDCARD_SESSION)) {
1405 if (less_eq(msg_session(msg), l_ptr->peer_session)) 1423 if (less_eq(msg_session(msg), l_ptr->peer_session))
1406 break; /* duplicate or old reset: ignore */ 1424 break; /* duplicate or old reset: ignore */
1407 } 1425 }
@@ -1465,7 +1483,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1465 /* Record reception; force mismatch at next timeout: */ 1483 /* Record reception; force mismatch at next timeout: */
1466 l_ptr->silent_intv_cnt = 0; 1484 l_ptr->silent_intv_cnt = 0;
1467 1485
1468 link_state_event(l_ptr, TRAFFIC_MSG_EVT); 1486 link_state_event(l_ptr, TRAFFIC_EVT);
1469 l_ptr->stats.recv_states++; 1487 l_ptr->stats.recv_states++;
1470 if (link_reset_unknown(l_ptr)) 1488 if (link_reset_unknown(l_ptr))
1471 break; 1489 break;
@@ -1704,7 +1722,7 @@ static bool tipc_link_failover_rcv(struct tipc_link *link,
1704 } 1722 }
1705exit: 1723exit:
1706 if (!link->failover_pkts && pl) 1724 if (!link->failover_pkts && pl)
1707 pl->flags &= ~LINK_FAILINGOVER; 1725 pl->exec_mode = TIPC_LINK_OPEN;
1708 kfree_skb(*skb); 1726 kfree_skb(*skb);
1709 *skb = iskb; 1727 *skb = iskb;
1710 return *skb; 1728 return *skb;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 7add2b90361d..0509c6de03cd 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -49,19 +49,14 @@
49 */ 49 */
50#define INVALID_LINK_SEQ 0x10000 50#define INVALID_LINK_SEQ 0x10000
51 51
52/* Link working states
53 */
54#define WORKING_WORKING 560810u
55#define WORKING_UNKNOWN 560811u
56#define RESET_UNKNOWN 560812u
57#define RESET_RESET 560813u
58 52
59/* Link endpoint execution states 53/* Link endpoint receive states
60 */ 54 */
61#define LINK_STARTED 0x0001 55enum {
62#define LINK_STOPPED 0x0002 56 TIPC_LINK_OPEN,
63#define LINK_SYNCHING 0x0004 57 TIPC_LINK_BLOCKED,
64#define LINK_FAILINGOVER 0x0008 58 TIPC_LINK_TUNNEL
59};
65 60
66/* Starting value for maximum packet size negotiation on unicast links 61/* Starting value for maximum packet size negotiation on unicast links
67 * (unless bearer MTU is less) 62 * (unless bearer MTU is less)
@@ -106,7 +101,6 @@ struct tipc_stats {
106 * @timer: link timer 101 * @timer: link timer
107 * @owner: pointer to peer node 102 * @owner: pointer to peer node
108 * @refcnt: reference counter for permanent references (owner node & timer) 103 * @refcnt: reference counter for permanent references (owner node & timer)
109 * @flags: execution state flags for link endpoint instance
110 * @peer_session: link session # being used by peer end of link 104 * @peer_session: link session # being used by peer end of link
111 * @peer_bearer_id: bearer id used by link's peer endpoint 105 * @peer_bearer_id: bearer id used by link's peer endpoint
112 * @bearer_id: local bearer id used by link 106 * @bearer_id: local bearer id used by link
@@ -119,6 +113,7 @@ struct tipc_stats {
119 * @pmsg: convenience pointer to "proto_msg" field 113 * @pmsg: convenience pointer to "proto_msg" field
120 * @priority: current link priority 114 * @priority: current link priority
121 * @net_plane: current link network plane ('A' through 'H') 115 * @net_plane: current link network plane ('A' through 'H')
116 * @exec_mode: transmit/receive mode for link endpoint instance
122 * @backlog_limit: backlog queue congestion thresholds (indexed by importance) 117 * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
123 * @exp_msg_count: # of tunnelled messages expected during link changeover 118 * @exp_msg_count: # of tunnelled messages expected during link changeover
124 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset 119 * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
@@ -149,7 +144,6 @@ struct tipc_link {
149 struct kref ref; 144 struct kref ref;
150 145
151 /* Management and link supervision data */ 146 /* Management and link supervision data */
152 unsigned int flags;
153 u32 peer_session; 147 u32 peer_session;
154 u32 peer_bearer_id; 148 u32 peer_bearer_id;
155 u32 bearer_id; 149 u32 bearer_id;
@@ -165,6 +159,7 @@ struct tipc_link {
165 struct tipc_msg *pmsg; 159 struct tipc_msg *pmsg;
166 u32 priority; 160 u32 priority;
167 char net_plane; 161 char net_plane;
162 u8 exec_mode;
168 u16 synch_point; 163 u16 synch_point;
169 164
170 /* Failover */ 165 /* Failover */
@@ -249,27 +244,4 @@ static inline u32 link_own_addr(struct tipc_link *l)
249 return msg_prevnode(l->pmsg); 244 return msg_prevnode(l->pmsg);
250} 245}
251 246
252/*
253 * Link status checking routines
254 */
255static inline int link_working_working(struct tipc_link *l_ptr)
256{
257 return l_ptr->state == WORKING_WORKING;
258}
259
260static inline int link_working_unknown(struct tipc_link *l_ptr)
261{
262 return l_ptr->state == WORKING_UNKNOWN;
263}
264
265static inline int link_reset_unknown(struct tipc_link *l_ptr)
266{
267 return l_ptr->state == RESET_UNKNOWN;
268}
269
270static inline int link_reset_reset(struct tipc_link *l_ptr)
271{
272 return l_ptr->state == RESET_RESET;
273}
274
275#endif 247#endif
diff --git a/net/tipc/node.c b/net/tipc/node.c
index ad759bb034e7..b7a4457f653c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -403,7 +403,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
403 struct tipc_link *l_ptr = n_ptr->links[i].link; 403 struct tipc_link *l_ptr = n_ptr->links[i].link;
404 if (!l_ptr) 404 if (!l_ptr)
405 continue; 405 continue;
406 l_ptr->flags &= ~LINK_FAILINGOVER; 406 l_ptr->exec_mode = TIPC_LINK_OPEN;
407 l_ptr->failover_checkpt = 0; 407 l_ptr->failover_checkpt = 0;
408 l_ptr->failover_pkts = 0; 408 l_ptr->failover_pkts = 0;
409 kfree_skb(l_ptr->failover_skb); 409 kfree_skb(l_ptr->failover_skb);