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>
This commit is contained in:
Jon Paul Maloy 2015-07-16 16:54:25 -04:00 committed by David S. Miller
parent af9b028e27
commit d3504c3449
4 changed files with 68 additions and 79 deletions

View File

@ -924,7 +924,6 @@ int tipc_bclink_init(struct net *net)
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);

View File

@ -79,20 +79,50 @@ static const struct nla_policy tipc_nl_prop_policy[TIPC_NLA_PROP_MAX + 1] = {
/*
* 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 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
/* 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 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
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 @@ void tipc_link_delete(struct tipc_link *l)
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 @@ void tipc_link_reset(struct tipc_link *l_ptr)
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 @@ void tipc_link_reset(struct tipc_link *l_ptr)
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_activate(struct tipc_link *link)
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 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
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 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
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 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
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 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
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 @@ static bool link_synch(struct tipc_link *l)
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 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
}
/* 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 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b_ptr)
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 @@ static void tipc_link_input(struct tipc_link *link, struct sk_buff *skb)
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 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
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 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
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 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
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 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr,
/* 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 @@ static bool tipc_link_failover_rcv(struct tipc_link *link,
}
exit:
if (!link->failover_pkts && pl)
pl->flags &= ~LINK_FAILINGOVER;
pl->exec_mode = TIPC_LINK_OPEN;
kfree_skb(*skb);
*skb = iskb;
return *skb;

View File

@ -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 @@ struct tipc_stats {
* @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 @@ struct tipc_stats {
* @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 tipc_link {
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_link {
struct tipc_msg *pmsg;
u32 priority;
char net_plane;
u8 exec_mode;
u16 synch_point;
/* Failover */
@ -249,27 +244,4 @@ static inline u32 link_own_addr(struct tipc_link *l)
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

View File

@ -403,7 +403,7 @@ static void node_lost_contact(struct tipc_node *n_ptr)
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);