Commit d3504c34 authored by Jon Paul Maloy's avatar Jon Paul Maloy Committed by David S. Miller

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: default avatarYing Xue <ying.xue@windriver.com>
Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af9b028e
...@@ -924,7 +924,6 @@ int tipc_bclink_init(struct net *net) ...@@ -924,7 +924,6 @@ int tipc_bclink_init(struct net *net)
tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
bcl->bearer_id = MAX_BEARERS; bcl->bearer_id = MAX_BEARERS;
rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer); rcu_assign_pointer(tn->bearer_list[MAX_BEARERS], &bcbearer->bearer);
bcl->state = WORKING_WORKING;
bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg; bcl->pmsg = (struct tipc_msg *)&bcl->proto_msg;
msg_set_prevnode(bcl->pmsg, tn->own_addr); msg_set_prevnode(bcl->pmsg, tn->own_addr);
strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
......
...@@ -79,19 +79,49 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = { ...@@ -79,19 +79,49 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
/* /*
* Out-of-range value for link session numbers * Out-of-range value for link session numbers
*/ */
#define INVALID_SESSION 0x10000 #define WILDCARD_SESSION 0x10000
/* /* State value stored in 'failover_pkts'
* Link state events:
*/ */
#define STARTING_EVT 856384768 /* link processing trigger */ #define FIRST_FAILOVER 0xffffu
#define TRAFFIC_MSG_EVT 560815u /* rx'd ??? */
#define SILENCE_EVT 560817u /* timer dicovered silence from peer */
/* /* Link FSM states and events:
* State value stored in 'failover_pkts'
*/ */
#define FIRST_FAILOVER 0xffffu 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, static void link_handle_out_of_seq_msg(struct tipc_link *link,
struct sk_buff *skb); struct sk_buff *skb);
...@@ -268,7 +298,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, ...@@ -268,7 +298,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
/* note: peer i/f name is updated by reset/activate message */ /* note: peer i/f name is updated by reset/activate message */
memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr));
l_ptr->owner = n_ptr; l_ptr->owner = n_ptr;
l_ptr->peer_session = INVALID_SESSION; l_ptr->peer_session = WILDCARD_SESSION;
l_ptr->bearer_id = b_ptr->identity; l_ptr->bearer_id = b_ptr->identity;
link_set_supervision_props(l_ptr, b_ptr->tolerance); link_set_supervision_props(l_ptr, b_ptr->tolerance);
l_ptr->state = RESET_UNKNOWN; l_ptr->state = RESET_UNKNOWN;
...@@ -297,8 +327,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr, ...@@ -297,8 +327,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
link_reset_statistics(l_ptr); link_reset_statistics(l_ptr);
tipc_node_attach_link(n_ptr, l_ptr); tipc_node_attach_link(n_ptr, l_ptr);
setup_timer(&l_ptr->timer, link_timeout, (unsigned long)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; return l_ptr;
} }
...@@ -311,7 +340,6 @@ void tipc_link_delete(struct tipc_link *l) ...@@ -311,7 +340,6 @@ void tipc_link_delete(struct tipc_link *l)
tipc_link_reset(l); tipc_link_reset(l);
if (del_timer(&l->timer)) if (del_timer(&l->timer))
tipc_link_put(l); tipc_link_put(l);
l->flags |= LINK_STOPPED;
/* Delete link now, or when timer is finished: */ /* Delete link now, or when timer is finished: */
tipc_link_reset_fragments(l); tipc_link_reset_fragments(l);
tipc_node_detach_link(l->owner, l); tipc_node_detach_link(l->owner, l);
...@@ -438,7 +466,7 @@ void tipc_link_reset(struct tipc_link *l_ptr) ...@@ -438,7 +466,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff)); msg_set_session(l_ptr->pmsg, ((msg_session(l_ptr->pmsg) + 1) & 0xffff));
/* Link is down, accept any session */ /* Link is down, accept any session */
l_ptr->peer_session = INVALID_SESSION; l_ptr->peer_session = WILDCARD_SESSION;
/* Prepare for renewed mtu size negotiation */ /* Prepare for renewed mtu size negotiation */
l_ptr->mtu = l_ptr->advertised_mtu; l_ptr->mtu = l_ptr->advertised_mtu;
...@@ -452,7 +480,7 @@ void tipc_link_reset(struct tipc_link *l_ptr) ...@@ -452,7 +480,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
tipc_bearer_remove_dest(owner->net, l_ptr->bearer_id, l_ptr->addr); 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)) { 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; l_ptr->failover_checkpt = l_ptr->rcv_nxt;
pl->failover_pkts = FIRST_FAILOVER; pl->failover_pkts = FIRST_FAILOVER;
pl->failover_checkpt = l_ptr->rcv_nxt; pl->failover_checkpt = l_ptr->rcv_nxt;
...@@ -496,21 +524,14 @@ static void link_activate(struct tipc_link *link) ...@@ -496,21 +524,14 @@ static void link_activate(struct tipc_link *link)
static void link_state_event(struct tipc_link *l_ptr, unsigned int event) static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
{ {
struct tipc_link *other; 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; return;
switch (l_ptr->state) { switch (l_ptr->state) {
case WORKING_WORKING: case WORKING_WORKING:
switch (event) { switch (event) {
case TRAFFIC_MSG_EVT: case TRAFFIC_EVT:
case ACTIVATE_MSG: case ACTIVATE_MSG:
l_ptr->silent_intv_cnt = 0; l_ptr->silent_intv_cnt = 0;
break; break;
...@@ -538,7 +559,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) ...@@ -538,7 +559,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
break; break;
case WORKING_UNKNOWN: case WORKING_UNKNOWN:
switch (event) { switch (event) {
case TRAFFIC_MSG_EVT: case TRAFFIC_EVT:
case ACTIVATE_MSG: case ACTIVATE_MSG:
l_ptr->state = WORKING_WORKING; l_ptr->state = WORKING_WORKING;
l_ptr->silent_intv_cnt = 0; l_ptr->silent_intv_cnt = 0;
...@@ -576,7 +597,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) ...@@ -576,7 +597,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
break; break;
case RESET_UNKNOWN: case RESET_UNKNOWN:
switch (event) { switch (event) {
case TRAFFIC_MSG_EVT: case TRAFFIC_EVT:
break; break;
case ACTIVATE_MSG: case ACTIVATE_MSG:
other = node_active_link(l_ptr->owner, 0); 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,10 +614,6 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG, tipc_link_proto_xmit(l_ptr, ACTIVATE_MSG,
1, 0, 0, 0); 1, 0, 0, 0);
break; break;
case STARTING_EVT:
l_ptr->flags |= LINK_STARTED;
link_set_timer(l_ptr, timer_intv);
break;
case SILENCE_EVT: case SILENCE_EVT:
tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0); tipc_link_proto_xmit(l_ptr, RESET_MSG, 0, 0, 0, 0);
break; break;
...@@ -606,7 +623,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) ...@@ -606,7 +623,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
break; break;
case RESET_RESET: case RESET_RESET:
switch (event) { switch (event) {
case TRAFFIC_MSG_EVT: case TRAFFIC_EVT:
case ACTIVATE_MSG: case ACTIVATE_MSG:
other = node_active_link(l_ptr->owner, 0); other = node_active_link(l_ptr->owner, 0);
if (other && link_working_unknown(other)) if (other && link_working_unknown(other))
...@@ -975,7 +992,7 @@ static bool link_synch(struct tipc_link *l) ...@@ -975,7 +992,7 @@ static bool link_synch(struct tipc_link *l)
if (skb_queue_len(pl->inputq) > post_synch) if (skb_queue_len(pl->inputq) > post_synch)
return false; return false;
synched: synched:
l->flags &= ~LINK_SYNCHING; l->exec_mode = TIPC_LINK_OPEN;
return true; return true;
} }
...@@ -1091,7 +1108,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr) ...@@ -1091,7 +1108,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
} }
/* Traffic message. Conditionally activate link */ /* 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)) { if (link_working_working(l_ptr)) {
/* Re-insert buffer in front of queue */ /* 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,7 +1129,8 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
l_ptr->silent_intv_cnt = 0; l_ptr->silent_intv_cnt = 0;
/* Synchronize with parallel link if applicable */ /* 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)) if (!link_synch(l_ptr))
goto unlock; goto unlock;
} }
...@@ -1193,7 +1211,7 @@ static void tipc_link_input(struct tipc_link *link, struct sk_buff *skb) ...@@ -1193,7 +1211,7 @@ static void tipc_link_input(struct tipc_link *link, struct sk_buff *skb)
switch (msg_user(msg)) { switch (msg_user(msg)) {
case TUNNEL_PROTOCOL: case TUNNEL_PROTOCOL:
if (msg_dup(msg)) { if (msg_dup(msg)) {
link->flags |= LINK_SYNCHING; link->exec_mode = TIPC_LINK_TUNNEL;
link->synch_point = msg_seqno(msg_get_wrapped(msg)); link->synch_point = msg_seqno(msg_get_wrapped(msg));
kfree_skb(skb); kfree_skb(skb);
break; break;
...@@ -1315,7 +1333,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg, ...@@ -1315,7 +1333,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
u16 last_rcv; u16 last_rcv;
/* Don't send protocol message during link failover */ /* Don't send protocol message during link failover */
if (l_ptr->flags & LINK_FAILINGOVER) if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
return; return;
/* Abort non-RESET send if communication with node is prohibited */ /* 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,7 +1408,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
u32 msg_tol; u32 msg_tol;
struct tipc_msg *msg = buf_msg(buf); struct tipc_msg *msg = buf_msg(buf);
if (l_ptr->flags & LINK_FAILINGOVER) if (l_ptr->exec_mode == TIPC_LINK_BLOCKED)
goto exit; goto exit;
if (l_ptr->net_plane != msg_net_plane(msg)) 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,7 +1419,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
case RESET_MSG: case RESET_MSG:
if (!link_working_unknown(l_ptr) && 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)) if (less_eq(msg_session(msg), l_ptr->peer_session))
break; /* duplicate or old reset: ignore */ break; /* duplicate or old reset: ignore */
} }
...@@ -1465,7 +1483,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, ...@@ -1465,7 +1483,7 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
/* Record reception; force mismatch at next timeout: */ /* Record reception; force mismatch at next timeout: */
l_ptr->silent_intv_cnt = 0; 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++; l_ptr->stats.recv_states++;
if (link_reset_unknown(l_ptr)) if (link_reset_unknown(l_ptr))
break; break;
...@@ -1704,7 +1722,7 @@ static bool tipc_link_failover_rcv(struct tipc_link *link, ...@@ -1704,7 +1722,7 @@ static bool tipc_link_failover_rcv(struct tipc_link *link,
} }
exit: exit:
if (!link->failover_pkts && pl) if (!link->failover_pkts && pl)
pl->flags &= ~LINK_FAILINGOVER; pl->exec_mode = TIPC_LINK_OPEN;
kfree_skb(*skb); kfree_skb(*skb);
*skb = iskb; *skb = iskb;
return *skb; return *skb;
......
...@@ -49,19 +49,14 @@ ...@@ -49,19 +49,14 @@
*/ */
#define INVALID_LINK_SEQ 0x10000 #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 enum {
#define LINK_STOPPED 0x0002 TIPC_LINK_OPEN,
#define LINK_SYNCHING 0x0004 TIPC_LINK_BLOCKED,
#define LINK_FAILINGOVER 0x0008 TIPC_LINK_TUNNEL
};
/* Starting value for maximum packet size negotiation on unicast links /* Starting value for maximum packet size negotiation on unicast links
* (unless bearer MTU is less) * (unless bearer MTU is less)
...@@ -106,7 +101,6 @@ struct tipc_stats { ...@@ -106,7 +101,6 @@ struct tipc_stats {
* @timer: link timer * @timer: link timer
* @owner: pointer to peer node * @owner: pointer to peer node
* @refcnt: reference counter for permanent references (owner node & timer) * @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_session: link session # being used by peer end of link
* @peer_bearer_id: bearer id used by link's peer endpoint * @peer_bearer_id: bearer id used by link's peer endpoint
* @bearer_id: local bearer id used by link * @bearer_id: local bearer id used by link
...@@ -119,6 +113,7 @@ struct tipc_stats { ...@@ -119,6 +113,7 @@ struct tipc_stats {
* @pmsg: convenience pointer to "proto_msg" field * @pmsg: convenience pointer to "proto_msg" field
* @priority: current link priority * @priority: current link priority
* @net_plane: current link network plane ('A' through 'H') * @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) * @backlog_limit: backlog queue congestion thresholds (indexed by importance)
* @exp_msg_count: # of tunnelled messages expected during link changeover * @exp_msg_count: # of tunnelled messages expected during link changeover
* @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset * @reset_rcv_checkpt: seq # of last acknowledged message at time of link reset
...@@ -149,7 +144,6 @@ struct tipc_link { ...@@ -149,7 +144,6 @@ struct tipc_link {
struct kref ref; struct kref ref;
/* Management and link supervision data */ /* Management and link supervision data */
unsigned int flags;
u32 peer_session; u32 peer_session;
u32 peer_bearer_id; u32 peer_bearer_id;
u32 bearer_id; u32 bearer_id;
...@@ -165,6 +159,7 @@ struct tipc_link { ...@@ -165,6 +159,7 @@ struct tipc_link {
struct tipc_msg *pmsg; struct tipc_msg *pmsg;
u32 priority; u32 priority;
char net_plane; char net_plane;
u8 exec_mode;
u16 synch_point; u16 synch_point;
/* Failover */ /* Failover */
...@@ -249,27 +244,4 @@ static inline u32 link_own_addr(struct tipc_link *l) ...@@ -249,27 +244,4 @@ static inline u32 link_own_addr(struct tipc_link *l)
return msg_prevnode(l->pmsg); 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 #endif
...@@ -403,7 +403,7 @@ static void node_lost_contact(struct tipc_node *n_ptr) ...@@ -403,7 +403,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
struct tipc_link *l_ptr = n_ptr->links[i].link; struct tipc_link *l_ptr = n_ptr->links[i].link;
if (!l_ptr) if (!l_ptr)
continue; continue;
l_ptr->flags &= ~LINK_FAILINGOVER; l_ptr->exec_mode = TIPC_LINK_OPEN;
l_ptr->failover_checkpt = 0; l_ptr->failover_checkpt = 0;
l_ptr->failover_pkts = 0; l_ptr->failover_pkts = 0;
kfree_skb(l_ptr->failover_skb); kfree_skb(l_ptr->failover_skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment