aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2015-07-16 16:54:27 -0400
committerDavid S. Miller <davem@davemloft.net>2015-07-20 23:41:15 -0400
commit6ab30f9cbe134d19559f48dc748587d036529aaf (patch)
tree8eb7b335d5c29d6c6e629df973b888433dc83442 /net/tipc
parent426cc2b86d1813959497d608dcb52c32df2d448a (diff)
tipc: improve link FSM implementation
The link FSM implementation is currently unnecessarily complex. It sometimes checks for conditional state outside the FSM data before deciding next state, and often performs actions directly inside the FSM logics. In this commit, we create a second, simpler FSM implementation, that as far as possible acts only on states and events that it is strictly defined for, and postpone any actions until it is finished with its decisions. It also returns an event flag field and an a buffer queue which may potentially contain a protocol message to be sent by the caller. Unfortunately, we cannot yet make the FSM "clean", in the sense that its decisions are only based on FSM state and event, and that state changes happen only here. That will have to wait until the activate/reset logics has been cleaned up in a future commit. We also rename the link states as follows: WORKING_WORKING -> TIPC_LINK_WORKING WORKING_UNKNOWN -> TIPC_LINK_PROBING RESET_UNKNOWN -> TIPC_LINK_RESETTING RESET_RESET -> TIPC_LINK_ESTABLISHING The existing FSM function, link_state_event(), is still needed for a while, so we redesign it to make use of the new function. 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>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c344
-rw-r--r--net/tipc/link.h7
2 files changed, 195 insertions, 156 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 657ba91fde41..5d2f9198c6bc 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -88,10 +88,10 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
88/* Link FSM states and events: 88/* Link FSM states and events:
89 */ 89 */
90enum { 90enum {
91 WORKING_WORKING, 91 TIPC_LINK_WORKING,
92 WORKING_UNKNOWN, 92 TIPC_LINK_PROBING,
93 RESET_RESET, 93 TIPC_LINK_RESETTING,
94 RESET_UNKNOWN 94 TIPC_LINK_ESTABLISHING
95}; 95};
96 96
97enum { 97enum {
@@ -103,24 +103,24 @@ enum {
103 103
104/* Link FSM state checking routines 104/* Link FSM state checking routines
105 */ 105 */
106static int link_working_working(struct tipc_link *l) 106static int link_working(struct tipc_link *l)
107{ 107{
108 return l->state == WORKING_WORKING; 108 return l->state == TIPC_LINK_WORKING;
109} 109}
110 110
111static int link_working_unknown(struct tipc_link *l) 111static int link_probing(struct tipc_link *l)
112{ 112{
113 return l->state == WORKING_UNKNOWN; 113 return l->state == TIPC_LINK_PROBING;
114} 114}
115 115
116static int link_reset_unknown(struct tipc_link *l) 116static int link_resetting(struct tipc_link *l)
117{ 117{
118 return l->state == RESET_UNKNOWN; 118 return l->state == TIPC_LINK_RESETTING;
119} 119}
120 120
121static int link_reset_reset(struct tipc_link *l) 121static int link_establishing(struct tipc_link *l)
122{ 122{
123 return l->state == RESET_RESET; 123 return l->state == TIPC_LINK_ESTABLISHING;
124} 124}
125 125
126static void link_handle_out_of_seq_msg(struct tipc_link *link, 126static void link_handle_out_of_seq_msg(struct tipc_link *link,
@@ -140,6 +140,8 @@ static void tipc_link_input(struct tipc_link *l, struct sk_buff *skb);
140static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb); 140static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb);
141static bool tipc_link_failover_rcv(struct tipc_link *l, struct sk_buff **skb); 141static bool tipc_link_failover_rcv(struct tipc_link *l, struct sk_buff **skb);
142static void link_set_timer(struct tipc_link *link, unsigned long time); 142static void link_set_timer(struct tipc_link *link, unsigned long time);
143static void link_activate(struct tipc_link *link);
144
143/* 145/*
144 * Simple link routines 146 * Simple link routines
145 */ 147 */
@@ -179,7 +181,7 @@ int tipc_link_is_up(struct tipc_link *l_ptr)
179{ 181{
180 if (!l_ptr) 182 if (!l_ptr)
181 return 0; 183 return 0;
182 return link_working_working(l_ptr) || link_working_unknown(l_ptr); 184 return link_working(l_ptr) || link_probing(l_ptr);
183} 185}
184 186
185int tipc_link_is_active(struct tipc_link *l) 187int tipc_link_is_active(struct tipc_link *l)
@@ -234,8 +236,11 @@ static void link_timeout(unsigned long data)
234 } 236 }
235 237
236 /* do all other link processing performed on a periodic basis */ 238 /* do all other link processing performed on a periodic basis */
237 if (l_ptr->silent_intv_cnt || tipc_bclink_acks_missing(l_ptr->owner)) 239 if (l_ptr->silent_intv_cnt)
238 link_state_event(l_ptr, SILENCE_EVT); 240 link_state_event(l_ptr, SILENCE_EVT);
241 else if (link_working(l_ptr) && tipc_bclink_acks_missing(l_ptr->owner))
242 tipc_link_proto_xmit(l_ptr, STATE_MSG, 0, 0, 0, 0);
243
239 l_ptr->silent_intv_cnt++; 244 l_ptr->silent_intv_cnt++;
240 if (skb_queue_len(&l_ptr->backlogq)) 245 if (skb_queue_len(&l_ptr->backlogq))
241 tipc_link_push_packets(l_ptr); 246 tipc_link_push_packets(l_ptr);
@@ -304,7 +309,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
304 l_ptr->peer_session = WILDCARD_SESSION; 309 l_ptr->peer_session = WILDCARD_SESSION;
305 l_ptr->bearer_id = b_ptr->identity; 310 l_ptr->bearer_id = b_ptr->identity;
306 link_set_supervision_props(l_ptr, b_ptr->tolerance); 311 link_set_supervision_props(l_ptr, b_ptr->tolerance);
307 l_ptr->state = RESET_UNKNOWN; 312 l_ptr->state = TIPC_LINK_RESETTING;
308 313
309 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg; 314 l_ptr->pmsg = (struct tipc_msg *)&l_ptr->proto_msg;
310 msg = l_ptr->pmsg; 315 msg = l_ptr->pmsg;
@@ -367,6 +372,134 @@ void tipc_link_delete_list(struct net *net, unsigned int bearer_id)
367} 372}
368 373
369/** 374/**
375 * tipc_link_fsm_evt - link finite state machine
376 * @l: pointer to link
377 * @evt: state machine event to be processed
378 * @xmitq: queue to prepend created protocol message, if any
379 */
380static int tipc_link_fsm_evt(struct tipc_link *l, int evt,
381 struct sk_buff_head *xmitq)
382{
383 int mtyp = 0, rc = 0;
384 struct tipc_link *pl;
385 enum {
386 LINK_RESET = 1,
387 LINK_ACTIVATE = (1 << 1),
388 SND_PROBE = (1 << 2),
389 SND_STATE = (1 << 3),
390 SND_RESET = (1 << 4),
391 SND_ACTIVATE = (1 << 5)
392 } actions = 0;
393
394 if (l->exec_mode == TIPC_LINK_BLOCKED)
395 return rc;
396
397 switch (l->state) {
398 case TIPC_LINK_WORKING:
399 switch (evt) {
400 case TRAFFIC_EVT:
401 case ACTIVATE_EVT:
402 break;
403 case SILENCE_EVT:
404 l->state = TIPC_LINK_PROBING;
405 actions |= SND_PROBE;
406 break;
407 case PEER_RESET_EVT:
408 actions |= LINK_RESET | SND_ACTIVATE;
409 break;
410 default:
411 pr_debug("%s%u WORKING\n", link_unk_evt, evt);
412 }
413 break;
414 case TIPC_LINK_PROBING:
415 switch (evt) {
416 case TRAFFIC_EVT:
417 case ACTIVATE_EVT:
418 l->state = TIPC_LINK_WORKING;
419 break;
420 case PEER_RESET_EVT:
421 actions |= LINK_RESET | SND_ACTIVATE;
422 break;
423 case SILENCE_EVT:
424 if (l->silent_intv_cnt <= l->abort_limit) {
425 actions |= SND_PROBE;
426 break;
427 }
428 actions |= LINK_RESET | SND_RESET;
429 break;
430 default:
431 pr_err("%s%u PROBING\n", link_unk_evt, evt);
432 }
433 break;
434 case TIPC_LINK_RESETTING:
435 switch (evt) {
436 case TRAFFIC_EVT:
437 break;
438 case ACTIVATE_EVT:
439 pl = node_active_link(l->owner, 0);
440 if (pl && link_probing(pl))
441 break;
442 actions |= LINK_ACTIVATE;
443 if (l->owner->working_links == 1)
444 tipc_link_sync_xmit(l);
445 break;
446 case PEER_RESET_EVT:
447 l->state = TIPC_LINK_ESTABLISHING;
448 actions |= SND_ACTIVATE;
449 break;
450 case SILENCE_EVT:
451 actions |= SND_RESET;
452 break;
453 default:
454 pr_err("%s%u in RESETTING\n", link_unk_evt, evt);
455 }
456 break;
457 case TIPC_LINK_ESTABLISHING:
458 switch (evt) {
459 case TRAFFIC_EVT:
460 case ACTIVATE_EVT:
461 pl = node_active_link(l->owner, 0);
462 if (pl && link_probing(pl))
463 break;
464 actions |= LINK_ACTIVATE;
465 if (l->owner->working_links == 1)
466 tipc_link_sync_xmit(l);
467 break;
468 case PEER_RESET_EVT:
469 break;
470 case SILENCE_EVT:
471 actions |= SND_ACTIVATE;
472 break;
473 default:
474 pr_err("%s%u ESTABLISHING\n", link_unk_evt, evt);
475 }
476 break;
477 default:
478 pr_err("Unknown link state %u/%u\n", l->state, evt);
479 }
480
481 /* Perform actions as decided by FSM */
482 if (actions & LINK_RESET) {
483 l->exec_mode = TIPC_LINK_BLOCKED;
484 rc |= TIPC_LINK_DOWN_EVT;
485 }
486 if (actions & LINK_ACTIVATE) {
487 l->exec_mode = TIPC_LINK_OPEN;
488 rc |= TIPC_LINK_UP_EVT;
489 }
490 if (actions & (SND_STATE | SND_PROBE))
491 mtyp = STATE_MSG;
492 if (actions & SND_RESET)
493 mtyp = RESET_MSG;
494 if (actions & SND_ACTIVATE)
495 mtyp = ACTIVATE_MSG;
496 if (actions & (SND_PROBE | SND_STATE | SND_RESET | SND_ACTIVATE))
497 tipc_link_build_proto_msg(l, mtyp, actions & SND_PROBE,
498 0, 0, 0, xmitq);
499 return rc;
500}
501
502/**
370 * link_schedule_user - schedule a message sender for wakeup after congestion 503 * link_schedule_user - schedule a message sender for wakeup after congestion
371 * @link: congested link 504 * @link: congested link
372 * @list: message that was attempted sent 505 * @list: message that was attempted sent
@@ -474,9 +607,10 @@ void tipc_link_reset(struct tipc_link *l_ptr)
474 /* Prepare for renewed mtu size negotiation */ 607 /* Prepare for renewed mtu size negotiation */
475 l_ptr->mtu = l_ptr->advertised_mtu; 608 l_ptr->mtu = l_ptr->advertised_mtu;
476 609
477 l_ptr->state = RESET_UNKNOWN; 610 l_ptr->state = TIPC_LINK_RESETTING;
478 611
479 if ((prev_state == RESET_UNKNOWN) || (prev_state == RESET_RESET)) 612 if ((prev_state == TIPC_LINK_RESETTING) ||
613 (prev_state == TIPC_LINK_ESTABLISHING))
480 return; 614 return;
481 615
482 tipc_node_link_down(l_ptr->owner, l_ptr->bearer_id); 616 tipc_node_link_down(l_ptr->owner, l_ptr->bearer_id);
@@ -515,6 +649,8 @@ static void link_activate(struct tipc_link *link)
515 link->rcv_nxt = 1; 649 link->rcv_nxt = 1;
516 link->stats.recv_info = 1; 650 link->stats.recv_info = 1;
517 link->silent_intv_cnt = 0; 651 link->silent_intv_cnt = 0;
652 link->state = TIPC_LINK_WORKING;
653 link->exec_mode = TIPC_LINK_OPEN;
518 tipc_node_link_up(node, link->bearer_id); 654 tipc_node_link_up(node, link->bearer_id);
519 tipc_bearer_add_dest(node->net, link->bearer_id, link->addr); 655 tipc_bearer_add_dest(node->net, link->bearer_id, link->addr);
520} 656}
@@ -524,132 +660,29 @@ static void link_activate(struct tipc_link *link)
524 * @l_ptr: pointer to link 660 * @l_ptr: pointer to link
525 * @event: state machine event to process 661 * @event: state machine event to process
526 */ 662 */
527static void link_state_event(struct tipc_link *l_ptr, unsigned int event) 663static void link_state_event(struct tipc_link *l, unsigned int evt)
528{ 664{
529 struct tipc_link *other; 665 int rc;
666 struct sk_buff_head xmitq;
667 struct sk_buff *skb;
530 668
531 if (l_ptr->exec_mode == TIPC_LINK_BLOCKED) 669 if (l->exec_mode == TIPC_LINK_BLOCKED)
532 return; 670 return;
533 671
534 switch (l_ptr->state) { 672 __skb_queue_head_init(&xmitq);
535 case WORKING_WORKING: 673
536 switch (event) { 674 rc = tipc_link_fsm_evt(l, evt, &xmitq);
537 case TRAFFIC_EVT: 675
538 case ACTIVATE_MSG: 676 if (rc & TIPC_LINK_UP_EVT)
539 l_ptr->silent_intv_cnt = 0; 677 link_activate(l);
540 break; 678
541 case SILENCE_EVT: 679 if (rc & TIPC_LINK_DOWN_EVT)
542 if (!l_ptr->silent_intv_cnt) { 680 tipc_link_reset(l);
543 if (tipc_bclink_acks_missing(l_ptr->owner)) 681
544 tipc_link_proto_xmit(l_ptr, STATE_MSG, 682 skb = __skb_dequeue(&xmitq);
545 0, 0, 0, 0); 683 if (!skb)
546 break; 684 return;
547 } 685 tipc_bearer_send(l->owner->net, l->bearer_id, skb, &l->media_addr);
548 l_ptr->state = WORKING_UNKNOWN;
549 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0);
550 break;
551 case RESET_MSG:
552 pr_debug("%s<%s>, requested by peer\n",
553 link_rst_msg, l_ptr->name);
554 tipc_link_reset(l_ptr);
555 l_ptr->state = RESET_RESET;
556 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
557 0, 0, 0, 0);
558 break;
559 default:
560 pr_debug("%s%u in WW state\n", link_unk_evt, event);
561 }
562 break;
563 case WORKING_UNKNOWN:
564 switch (event) {
565 case TRAFFIC_EVT:
566 case ACTIVATE_MSG:
567 l_ptr->state = WORKING_WORKING;
568 l_ptr->silent_intv_cnt = 0;
569 break;
570 case RESET_MSG:
571 pr_debug("%s<%s>, requested by peer while probing\n",
572 link_rst_msg, l_ptr->name);
573 tipc_link_reset(l_ptr);
574 l_ptr->state = RESET_RESET;
575 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
576 0, 0, 0, 0);
577 break;
578 case SILENCE_EVT:
579 if (!l_ptr->silent_intv_cnt) {
580 l_ptr->state = WORKING_WORKING;
581 if (tipc_bclink_acks_missing(l_ptr->owner))
582 tipc_link_proto_xmit(l_ptr, STATE_MSG,
583 0, 0, 0, 0);
584 } else if (l_ptr->silent_intv_cnt <
585 l_ptr->abort_limit) {
586 tipc_link_proto_xmit(l_ptr, STATE_MSG,
587 1, 0, 0, 0);
588 } else { /* Link has failed */
589 pr_debug("%s<%s>, peer not responding\n",
590 link_rst_msg, l_ptr->name);
591 tipc_link_reset(l_ptr);
592 l_ptr->state = RESET_UNKNOWN;
593 tipc_link_proto_xmit(l_ptr, RESET_MSG,
594 0, 0, 0, 0);
595 }
596 break;
597 default:
598 pr_err("%s%u in WU state\n", link_unk_evt, event);
599 }
600 break;
601 case RESET_UNKNOWN:
602 switch (event) {
603 case TRAFFIC_EVT:
604 break;
605 case ACTIVATE_MSG:
606 other = node_active_link(l_ptr->owner, 0);
607 if (other && link_working_unknown(other))
608 break;
609 l_ptr->state = WORKING_WORKING;
610 link_activate(l_ptr);
611 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0);
612 if (l_ptr->owner->working_links == 1)
613 tipc_link_sync_xmit(l_ptr);
614 break;
615 case RESET_MSG:
616 l_ptr->state = RESET_RESET;
617 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
618 1, 0, 0, 0);
619 break;
620 case SILENCE_EVT:
621 tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0);
622 break;
623 default:
624 pr_err("%s%u in RU state\n", link_unk_evt, event);
625 }
626 break;
627 case RESET_RESET:
628 switch (event) {
629 case TRAFFIC_EVT:
630 case ACTIVATE_MSG:
631 other = node_active_link(l_ptr->owner, 0);
632 if (other && link_working_unknown(other))
633 break;
634 l_ptr->state = WORKING_WORKING;
635 link_activate(l_ptr);
636 tipc_link_proto_xmit(l_ptr, STATE_MSG, 1, 0, 0, 0);
637 if (l_ptr->owner->working_links == 1)
638 tipc_link_sync_xmit(l_ptr);
639 break;
640 case RESET_MSG:
641 break;
642 case SILENCE_EVT:
643 tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
644 0, 0, 0, 0);
645 break;
646 default:
647 pr_err("%s%u in RR state\n", link_unk_evt, event);
648 }
649 break;
650 default:
651 pr_err("Unknown link state %u/%u\n", l_ptr->state, event);
652 }
653} 686}
654 687
655/** 688/**
@@ -1102,7 +1135,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1102 link_prepare_wakeup(l_ptr); 1135 link_prepare_wakeup(l_ptr);
1103 1136
1104 /* Process the incoming packet */ 1137 /* Process the incoming packet */
1105 if (unlikely(!link_working_working(l_ptr))) { 1138 if (unlikely(!link_working(l_ptr))) {
1106 if (msg_user(msg) == LINK_PROTOCOL) { 1139 if (msg_user(msg) == LINK_PROTOCOL) {
1107 tipc_link_proto_rcv(l_ptr, skb); 1140 tipc_link_proto_rcv(l_ptr, skb);
1108 link_retrieve_defq(l_ptr, &head); 1141 link_retrieve_defq(l_ptr, &head);
@@ -1113,7 +1146,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1113 /* Traffic message. Conditionally activate link */ 1146 /* Traffic message. Conditionally activate link */
1114 link_state_event(l_ptr, TRAFFIC_EVT); 1147 link_state_event(l_ptr, TRAFFIC_EVT);
1115 1148
1116 if (link_working_working(l_ptr)) { 1149 if (link_working(l_ptr)) {
1117 /* Re-insert buffer in front of queue */ 1150 /* Re-insert buffer in front of queue */
1118 __skb_queue_head(&head, skb); 1151 __skb_queue_head(&head, skb);
1119 skb = NULL; 1152 skb = NULL;
@@ -1122,7 +1155,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
1122 goto unlock; 1155 goto unlock;
1123 } 1156 }
1124 1157
1125 /* Link is now in state WORKING_WORKING */ 1158 /* Link is now in state TIPC_LINK_WORKING */
1126 if (unlikely(seq_no != l_ptr->rcv_nxt)) { 1159 if (unlikely(seq_no != l_ptr->rcv_nxt)) {
1127 link_handle_out_of_seq_msg(l_ptr, skb); 1160 link_handle_out_of_seq_msg(l_ptr, skb);
1128 link_retrieve_defq(l_ptr, &head); 1161 link_retrieve_defq(l_ptr, &head);
@@ -1365,16 +1398,15 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1365 switch (msg_type(msg)) { 1398 switch (msg_type(msg)) {
1366 1399
1367 case RESET_MSG: 1400 case RESET_MSG:
1368 if (!link_working_unknown(l_ptr) && 1401 if (!link_probing(l_ptr) &&
1369 (l_ptr->peer_session != WILDCARD_SESSION)) { 1402 (l_ptr->peer_session != WILDCARD_SESSION)) {
1370 if (less_eq(msg_session(msg), l_ptr->peer_session)) 1403 if (less_eq(msg_session(msg), l_ptr->peer_session))
1371 break; /* duplicate or old reset: ignore */ 1404 break; /* duplicate or old reset: ignore */
1372 } 1405 }
1373 1406
1374 if (!msg_redundant_link(msg) && (link_working_working(l_ptr) || 1407 if (!msg_redundant_link(msg) && (link_working(l_ptr) ||
1375 link_working_unknown(l_ptr))) { 1408 link_probing(l_ptr))) {
1376 /* 1409 /* peer has lost contact -- don't allow peer's links
1377 * peer has lost contact -- don't allow peer's links
1378 * to reactivate before we recognize loss & clean up 1410 * to reactivate before we recognize loss & clean up
1379 */ 1411 */
1380 l_ptr->owner->action_flags |= TIPC_WAIT_OWN_LINKS_DOWN; 1412 l_ptr->owner->action_flags |= TIPC_WAIT_OWN_LINKS_DOWN;
@@ -1432,7 +1464,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
1432 1464
1433 link_state_event(l_ptr, TRAFFIC_EVT); 1465 link_state_event(l_ptr, TRAFFIC_EVT);
1434 l_ptr->stats.recv_states++; 1466 l_ptr->stats.recv_states++;
1435 if (link_reset_unknown(l_ptr)) 1467 if (link_resetting(l_ptr))
1436 break; 1468 break;
1437 1469
1438 if (less_eq(l_ptr->rcv_nxt, msg_next_sent(msg))) 1470 if (less_eq(l_ptr->rcv_nxt, msg_next_sent(msg)))
@@ -1822,14 +1854,14 @@ static void link_print(struct tipc_link *l_ptr, const char *str)
1822 pr_info("%s Link %x<%s>:", str, l_ptr->addr, b_ptr->name); 1854 pr_info("%s Link %x<%s>:", str, l_ptr->addr, b_ptr->name);
1823 rcu_read_unlock(); 1855 rcu_read_unlock();
1824 1856
1825 if (link_working_unknown(l_ptr)) 1857 if (link_probing(l_ptr))
1826 pr_cont(":WU\n"); 1858 pr_cont(":P\n");
1827 else if (link_reset_reset(l_ptr)) 1859 else if (link_establishing(l_ptr))
1828 pr_cont(":RR\n"); 1860 pr_cont(":E\n");
1829 else if (link_reset_unknown(l_ptr)) 1861 else if (link_resetting(l_ptr))
1830 pr_cont(":RU\n"); 1862 pr_cont(":R\n");
1831 else if (link_working_working(l_ptr)) 1863 else if (link_working(l_ptr))
1832 pr_cont(":WW\n"); 1864 pr_cont(":W\n");
1833 else 1865 else
1834 pr_cont("\n"); 1866 pr_cont("\n");
1835} 1867}
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 0509c6de03cd..ef68424f492d 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -58,6 +58,13 @@ enum {
58 TIPC_LINK_TUNNEL 58 TIPC_LINK_TUNNEL
59}; 59};
60 60
61/* Events occurring at packet reception or at timeout
62 */
63enum {
64 TIPC_LINK_UP_EVT = 1,
65 TIPC_LINK_DOWN_EVT = (1 << 1)
66};
67
61/* Starting value for maximum packet size negotiation on unicast links 68/* Starting value for maximum packet size negotiation on unicast links
62 * (unless bearer MTU is less) 69 * (unless bearer MTU is less)
63 */ 70 */