tipc: clean up definitions and usage of link flags

The status flag LINK_STOPPED is not needed any more, since the
mechanism for delayed deletion of links has been removed.
Likewise, LINK_STARTED and LINK_START_EVT are unnecessary,
because we can just as well start the link timer directly from
inside tipc_link_create().

We eliminate these flags in this commit.

Instead of the above flags, we now introduce three new link modes,
TIPC_LINK_OPEN, TIPC_LINK_BLOCKED and TIPC_LINK_TUNNEL. The values
indicate whether, and in the case of TIPC_LINK_TUNNEL, which, messages
the link is allowed to receive in this state. TIPC_LINK_BLOCKED also
blocks timer-driven protocol messages to be sent out, and any change
to the link FSM. Since the modes are mutually exclusive, we convert
them to state values, and rename the 'flags' field in struct tipc_link
to 'exec_mode'.

Finally, we move the #defines for link FSM states and events from link.h
into enums inside the file link.c, which is the real usage scope of
these definitions.

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>
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 295bdc2..aab4e8d 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -924,7 +924,6 @@
 	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
 	bcl->bearer_id = MAX_BEARERS;
 	rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer);
-	bcl->state = WORKING_WORKING;
 	bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg;
 	msg_set_prevnode(bcl->pmsg, tn->own_addr);
 	strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c052437..35a2da6 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -79,20 +79,50 @@
 /*
  * Out-of-range value for link session numbers
  */
-#define INVALID_SESSION 0x10000
+#define WILDCARD_SESSION 0x10000
 
-/*
- * Link state events:
- */
-#define  STARTING_EVT    856384768	/* link processing trigger */
-#define  TRAFFIC_MSG_EVT 560815u	/* rx'd ??? */
-#define  SILENCE_EVT     560817u	/* timer dicovered silence from peer */
-
-/*
- * State value stored in 'failover_pkts'
+/* State value stored in 'failover_pkts'
  */
 #define FIRST_FAILOVER 0xffffu
 
+/* Link FSM states and events:
+ */
+enum {
+	WORKING_WORKING,
+	WORKING_UNKNOWN,
+	RESET_RESET,
+	RESET_UNKNOWN
+};
+
+enum {
+	PEER_RESET_EVT    = RESET_MSG,
+	ACTIVATE_EVT      = ACTIVATE_MSG,
+	TRAFFIC_EVT,      /* Any other valid msg from peer */
+	SILENCE_EVT       /* Peer was silent during last timer interval*/
+};
+
+/* Link FSM state checking routines
+ */
+static int link_working_working(struct tipc_link *l)
+{
+	return l->state == WORKING_WORKING;
+}
+
+static int link_working_unknown(struct tipc_link *l)
+{
+	return l->state == WORKING_UNKNOWN;
+}
+
+static int link_reset_unknown(struct tipc_link *l)
+{
+	return l->state == RESET_UNKNOWN;
+}
+
+static int link_reset_reset(struct tipc_link *l)
+{
+	return l->state == RESET_RESET;
+}
+
 static void link_handle_out_of_seq_msg(struct tipc_link *link,
 				       struct sk_buff *skb);
 static void tipc_link_proto_rcv(struct tipc_link *link,
@@ -268,7 +298,7 @@
 		/* note: peer i/f name is updated by reset/activate message */
 	memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
 	l_ptr->owner = n_ptr;
-	l_ptr->peer_session = INVALID_SESSION;
+	l_ptr->peer_session = WILDCARD_SESSION;
 	l_ptr->bearer_id = b_ptr->identity;
 	link_set_supervision_props(l_ptr, b_ptr->tolerance);
 	l_ptr->state = RESET_UNKNOWN;
@@ -297,8 +327,7 @@
 	link_reset_statistics(l_ptr);
 	tipc_node_attach_link(n_ptr, l_ptr);
 	setup_timer(&l_ptr->timer, link_timeout, (unsigned long)l_ptr);
-	link_state_event(l_ptr, STARTING_EVT);
-
+	link_set_timer(l_ptr, l_ptr->keepalive_intv);
 	return l_ptr;
 }
 
@@ -311,7 +340,6 @@
 	tipc_link_reset(l);
 	if (del_timer(&l->timer))
 		tipc_link_put(l);
-	l->flags |= LINK_STOPPED;
 	/* Delete link now, or when timer is finished: */
 	tipc_link_reset_fragments(l);
 	tipc_node_detach_link(l->owner, l);
@@ -438,7 +466,7 @@
 	msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
 
 	/* Link is down, accept any session */
-	l_ptr->peer_session = INVALID_SESSION;
+	l_ptr->peer_session = WILDCARD_SESSION;
 
 	/* Prepare for renewed mtu size negotiation */
 	l_ptr->mtu = l_ptr->advertised_mtu;
@@ -452,7 +480,7 @@
 	tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr);
 
 	if (was_active_link && tipc_node_is_up(l_ptr->owner) && (pl != l_ptr)) {
-		l_ptr->flags |= LINK_FAILINGOVER;
+		l_ptr->exec_mode = TIPC_LINK_BLOCKED;
 		l_ptr->failover_checkpt = l_ptr->rcv_nxt;
 		pl->failover_pkts = FIRST_FAILOVER;
 		pl->failover_checkpt = l_ptr->rcv_nxt;
@@ -496,21 +524,14 @@
 static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
 {
 	struct tipc_link *other;
-	unsigned long timer_intv = l_ptr->keepalive_intv;
 
-	if (l_ptr->flags & LINK_STOPPED)
-		return;
-
-	if (!(l_ptr->flags & LINK_STARTED) && (event != STARTING_EVT))
-		return;		/* Not yet. */
-
-	if (l_ptr->flags & LINK_FAILINGOVER)
+	if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
 		return;
 
 	switch (l_ptr->state) {
 	case WORKING_WORKING:
 		switch (event) {
-		case TRAFFIC_MSG_EVT:
+		case TRAFFIC_EVT:
 		case ACTIVATE_MSG:
 			l_ptr->silent_intv_cnt = 0;
 			break;
@@ -538,7 +559,7 @@
 		break;
 	case WORKING_UNKNOWN:
 		switch (event) {
-		case TRAFFIC_MSG_EVT:
+		case TRAFFIC_EVT:
 		case ACTIVATE_MSG:
 			l_ptr->state = WORKING_WORKING;
 			l_ptr->silent_intv_cnt = 0;
@@ -576,7 +597,7 @@
 		break;
 	case RESET_UNKNOWN:
 		switch (event) {
-		case TRAFFIC_MSG_EVT:
+		case TRAFFIC_EVT:
 			break;
 		case ACTIVATE_MSG:
 			other = node_active_link(l_ptr->owner, 0);
@@ -593,10 +614,6 @@
 			tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
 					     1, 0, 0, 0);
 			break;
-		case STARTING_EVT:
-			l_ptr->flags |= LINK_STARTED;
-			link_set_timer(l_ptr, timer_intv);
-			break;
 		case SILENCE_EVT:
 			tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0);
 			break;
@@ -606,7 +623,7 @@
 		break;
 	case RESET_RESET:
 		switch (event) {
-		case TRAFFIC_MSG_EVT:
+		case TRAFFIC_EVT:
 		case ACTIVATE_MSG:
 			other = node_active_link(l_ptr->owner, 0);
 			if (other && link_working_unknown(other))
@@ -975,7 +992,7 @@
 	if (skb_queue_len(pl->inputq) > post_synch)
 		return false;
 synched:
-	l->flags &= ~LINK_SYNCHING;
+	l->exec_mode = TIPC_LINK_OPEN;
 	return true;
 }
 
@@ -1091,7 +1108,7 @@
 			}
 
 			/* Traffic message. Conditionally activate link */
-			link_state_event(l_ptr, TRAFFIC_MSG_EVT);
+			link_state_event(l_ptr, TRAFFIC_EVT);
 
 			if (link_working_working(l_ptr)) {
 				/* Re-insert buffer in front of queue */
@@ -1112,7 +1129,8 @@
 		l_ptr->silent_intv_cnt = 0;
 
 		/* Synchronize with parallel link if applicable */
-		if (unlikely((l_ptr->flags & LINK_SYNCHING) && !msg_dup(msg))) {
+		if (unlikely((l_ptr->exec_mode == TIPC_LINK_TUNNEL) &&
+			     !msg_dup(msg))) {
 			if (!link_synch(l_ptr))
 				goto unlock;
 		}
@@ -1193,7 +1211,7 @@
 	switch (msg_user(msg)) {
 	case TUNNEL_PROTOCOL:
 		if (msg_dup(msg)) {
-			link->flags |= LINK_SYNCHING;
+			link->exec_mode = TIPC_LINK_TUNNEL;
 			link->synch_point = msg_seqno(msg_get_wrapped(msg));
 			kfree_skb(skb);
 			break;
@@ -1315,7 +1333,7 @@
 	u16 last_rcv;
 
 	/* Don't send protocol message during link failover */
-	if (l_ptr->flags & LINK_FAILINGOVER)
+	if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
 		return;
 
 	/* Abort non-RESET send if communication with node is prohibited */
@@ -1390,7 +1408,7 @@
 	u32 msg_tol;
 	struct tipc_msg *msg = buf_msg(buf);
 
-	if (l_ptr->flags & LINK_FAILINGOVER)
+	if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
 		goto exit;
 
 	if (l_ptr->net_plane != msg_net_plane(msg))
@@ -1401,7 +1419,7 @@
 
 	case RESET_MSG:
 		if (!link_working_unknown(l_ptr) &&
-		    (l_ptr->peer_session != INVALID_SESSION)) {
+		    (l_ptr->peer_session != WILDCARD_SESSION)) {
 			if (less_eq(msg_session(msg), l_ptr->peer_session))
 				break; /* duplicate or old reset: ignore */
 		}
@@ -1465,7 +1483,7 @@
 		/* Record reception; force mismatch at next timeout: */
 		l_ptr->silent_intv_cnt = 0;
 
-		link_state_event(l_ptr, TRAFFIC_MSG_EVT);
+		link_state_event(l_ptr, TRAFFIC_EVT);
 		l_ptr->stats.recv_states++;
 		if (link_reset_unknown(l_ptr))
 			break;
@@ -1704,7 +1722,7 @@
 	}
 exit:
 	if (!link->failover_pkts && pl)
-		pl->flags &= ~LINK_FAILINGOVER;
+		pl->exec_mode = TIPC_LINK_OPEN;
 	kfree_skb(*skb);
 	*skb = iskb;
 	return *skb;
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 7add2b9..0509c6d 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -49,19 +49,14 @@
  */
 #define INVALID_LINK_SEQ 0x10000
 
-/* Link working states
- */
-#define WORKING_WORKING 560810u
-#define WORKING_UNKNOWN 560811u
-#define RESET_UNKNOWN   560812u
-#define RESET_RESET     560813u
 
-/* Link endpoint execution states
+/* Link endpoint receive states
  */
-#define LINK_STARTED     0x0001
-#define LINK_STOPPED     0x0002
-#define LINK_SYNCHING    0x0004
-#define LINK_FAILINGOVER 0x0008
+enum {
+	TIPC_LINK_OPEN,
+	TIPC_LINK_BLOCKED,
+	TIPC_LINK_TUNNEL
+};
 
 /* Starting value for maximum packet size negotiation on unicast links
  * (unless bearer MTU is less)
@@ -106,7 +101,6 @@
  * @timer: link timer
  * @owner: pointer to peer node
  * @refcnt: reference counter for permanent references (owner node & timer)
- * @flags: execution state flags for link endpoint instance
  * @peer_session: link session # being used by peer end of link
  * @peer_bearer_id: bearer id used by link's peer endpoint
  * @bearer_id: local bearer id used by link
@@ -119,6 +113,7 @@
  * @pmsg: convenience pointer to "proto_msg" field
  * @priority: current link priority
  * @net_plane: current link network plane ('A' through 'H')
+ * @exec_mode: transmit/receive mode for link endpoint instance
  * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
  * @exp_msg_count: # of tunnelled messages expected during link changeover
  * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
@@ -149,7 +144,6 @@
 	struct kref ref;
 
 	/* Management and link supervision data */
-	unsigned int flags;
 	u32 peer_session;
 	u32 peer_bearer_id;
 	u32 bearer_id;
@@ -165,6 +159,7 @@
 	struct tipc_msg *pmsg;
 	u32 priority;
 	char net_plane;
+	u8 exec_mode;
 	u16 synch_point;
 
 	/* Failover */
@@ -249,27 +244,4 @@
 	return msg_prevnode(l->pmsg);
 }
 
-/*
- * Link status checking routines
- */
-static inline int link_working_working(struct tipc_link *l_ptr)
-{
-	return l_ptr->state == WORKING_WORKING;
-}
-
-static inline int link_working_unknown(struct tipc_link *l_ptr)
-{
-	return l_ptr->state == WORKING_UNKNOWN;
-}
-
-static inline int link_reset_unknown(struct tipc_link *l_ptr)
-{
-	return l_ptr->state == RESET_UNKNOWN;
-}
-
-static inline int link_reset_reset(struct tipc_link *l_ptr)
-{
-	return l_ptr->state == RESET_RESET;
-}
-
 #endif
diff --git a/net/tipc/node.c b/net/tipc/node.c
index ad759bb..b7a4457 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -403,7 +403,7 @@
 		struct tipc_link *l_ptr = n_ptr->links[i].link;
 		if (!l_ptr)
 			continue;
-		l_ptr->flags &= ~LINK_FAILINGOVER;
+		l_ptr->exec_mode = TIPC_LINK_OPEN;
 		l_ptr->failover_checkpt = 0;
 		l_ptr->failover_pkts = 0;
 		kfree_skb(l_ptr->failover_skb);