struct sk_buff *buf;
u32 prev_state = l_ptr->state;
u32 checkpoint = l_ptr->next_in_no;
+ int was_active_link = tipc_link_is_active(l_ptr);
msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1);
tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
dbg_link_dump();
#endif
- if (tipc_node_has_active_links(l_ptr->owner) &&
+ if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
l_ptr->owner->permit_changeover) {
l_ptr->reset_checkpoint = checkpoint;
l_ptr->exp_msg_count = START_CHANGEOVER;
static void link_activate(struct link *l_ptr)
{
- l_ptr->next_in_no = 1;
+ l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
tipc_node_link_up(l_ptr->owner, l_ptr);
tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
link_send_event(tipc_cfg_link_event, l_ptr, 1);
u32 length = msg_size(msg);
tunnel = l_ptr->owner->active_links[selector & 1];
- if (!tipc_link_is_up(tunnel))
+ if (!tipc_link_is_up(tunnel)) {
+ warn("Link changeover error, "
+ "tunnel link no longer available\n");
return;
+ }
msg_set_size(tunnel_hdr, length + INT_H_SIZE);
buf = buf_acquire(length + INT_H_SIZE);
- if (!buf)
+ if (!buf) {
+ warn("Link changeover error, "
+ "unable to send tunnel msg\n");
return;
+ }
memcpy(buf->data, (unchar *)tunnel_hdr, INT_H_SIZE);
memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length);
dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
u32 msgcount = l_ptr->out_queue_size;
struct sk_buff *crs = l_ptr->first_out;
struct link *tunnel = l_ptr->owner->active_links[0];
- int split_bundles = tipc_node_has_redundant_links(l_ptr->owner);
struct tipc_msg tunnel_hdr;
+ int split_bundles;
if (!tunnel)
return;
- if (!l_ptr->owner->permit_changeover)
+ if (!l_ptr->owner->permit_changeover) {
+ warn("Link changeover error, "
+ "peer did not permit changeover\n");
return;
+ }
msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr);
msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
msg_set_msgcnt(&tunnel_hdr, msgcount);
+ dbg("Link changeover requires %u tunnel messages\n", msgcount);
if (!l_ptr->first_out) {
struct sk_buff *buf;
return;
}
+ split_bundles = (l_ptr->owner->active_links[0] !=
+ l_ptr->owner->active_links[1]);
+
while (crs) {
struct tipc_msg *msg = buf_msg(crs);
dest_link->name);
tipc_link_reset(dest_link);
dest_link->exp_msg_count = msg_count;
+ dbg("Expecting %u tunnelled messages\n", msg_count);
if (!msg_count)
goto exit;
} else if (dest_link->exp_msg_count == START_CHANGEOVER) {
msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
dest_link->exp_msg_count = msg_count;
+ dbg("Expecting %u tunnelled messages\n", msg_count);
if (!msg_count)
goto exit;
}
/* Receive original message */
if (dest_link->exp_msg_count == 0) {
+ warn("Link switchover error, "
+ "got too many tunnelled messages\n");
msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
dbg_print_link(dest_link, "LINK:");
goto exit;
{
struct link **active = &n_ptr->active_links[0];
+ n_ptr->working_links++;
+
info("Established link <%s> on network plane %c\n",
l_ptr->name, l_ptr->b_ptr->net_plane);
{
struct link **active;
+ n_ptr->working_links--;
+
if (!tipc_link_is_active(l_ptr)) {
info("Lost standby link <%s> on network plane %c\n",
l_ptr->name, l_ptr->b_ptr->net_plane);
int tipc_node_has_redundant_links(struct node *n_ptr)
{
- return (tipc_node_has_active_links(n_ptr) &&
- (n_ptr->active_links[0] != n_ptr->active_links[1]));
+ return (n_ptr->working_links > 1);
}
static int tipc_node_has_active_routes(struct node *n_ptr)