Commit 5392d646886d8f1ae01be69c10600b8df5284c41

Authored by Allan Stephens
Committed by David S. Miller
1 parent a10bd924a4

[TIPC]: Fixed link switchover bugs

Incorporates several related fixes:
- switchover now occurs when switching from an active link to a standby link
- failure of a standby link no longer initiates switchover
- links now display correct # of received packtes following reactivation

Signed-off-by: Allan Stephens <allan.stephens@windriver.com>
Signed-off-by: Per Liden <per.liden@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files with 31 additions and 8 deletions Side-by-side Diff

... ... @@ -690,6 +690,7 @@
690 690 struct sk_buff *buf;
691 691 u32 prev_state = l_ptr->state;
692 692 u32 checkpoint = l_ptr->next_in_no;
  693 + int was_active_link = tipc_link_is_active(l_ptr);
693 694  
694 695 msg_set_session(l_ptr->pmsg, msg_session(l_ptr->pmsg) + 1);
695 696  
... ... @@ -711,7 +712,7 @@
711 712 tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name);
712 713 dbg_link_dump();
713 714 #endif
714   - if (tipc_node_has_active_links(l_ptr->owner) &&
  715 + if (was_active_link && tipc_node_has_active_links(l_ptr->owner) &&
715 716 l_ptr->owner->permit_changeover) {
716 717 l_ptr->reset_checkpoint = checkpoint;
717 718 l_ptr->exp_msg_count = START_CHANGEOVER;
... ... @@ -754,7 +755,7 @@
754 755  
755 756 static void link_activate(struct link *l_ptr)
756 757 {
757   - l_ptr->next_in_no = 1;
  758 + l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
758 759 tipc_node_link_up(l_ptr->owner, l_ptr);
759 760 tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
760 761 link_send_event(tipc_cfg_link_event, l_ptr, 1);
761 762  
762 763  
763 764  
... ... @@ -2303,12 +2304,18 @@
2303 2304 u32 length = msg_size(msg);
2304 2305  
2305 2306 tunnel = l_ptr->owner->active_links[selector & 1];
2306   - if (!tipc_link_is_up(tunnel))
  2307 + if (!tipc_link_is_up(tunnel)) {
  2308 + warn("Link changeover error, "
  2309 + "tunnel link no longer available\n");
2307 2310 return;
  2311 + }
2308 2312 msg_set_size(tunnel_hdr, length + INT_H_SIZE);
2309 2313 buf = buf_acquire(length + INT_H_SIZE);
2310   - if (!buf)
  2314 + if (!buf) {
  2315 + warn("Link changeover error, "
  2316 + "unable to send tunnel msg\n");
2311 2317 return;
  2318 + }
2312 2319 memcpy(buf->data, (unchar *)tunnel_hdr, INT_H_SIZE);
2313 2320 memcpy(buf->data + INT_H_SIZE, (unchar *)msg, length);
2314 2321 dbg("%c->%c:", l_ptr->b_ptr->net_plane, tunnel->b_ptr->net_plane);
2315 2322  
2316 2323  
2317 2324  
2318 2325  
... ... @@ -2328,19 +2335,23 @@
2328 2335 u32 msgcount = l_ptr->out_queue_size;
2329 2336 struct sk_buff *crs = l_ptr->first_out;
2330 2337 struct link *tunnel = l_ptr->owner->active_links[0];
2331   - int split_bundles = tipc_node_has_redundant_links(l_ptr->owner);
2332 2338 struct tipc_msg tunnel_hdr;
  2339 + int split_bundles;
2333 2340  
2334 2341 if (!tunnel)
2335 2342 return;
2336 2343  
2337   - if (!l_ptr->owner->permit_changeover)
  2344 + if (!l_ptr->owner->permit_changeover) {
  2345 + warn("Link changeover error, "
  2346 + "peer did not permit changeover\n");
2338 2347 return;
  2348 + }
2339 2349  
2340 2350 msg_init(&tunnel_hdr, CHANGEOVER_PROTOCOL,
2341 2351 ORIGINAL_MSG, TIPC_OK, INT_H_SIZE, l_ptr->addr);
2342 2352 msg_set_bearer_id(&tunnel_hdr, l_ptr->peer_bearer_id);
2343 2353 msg_set_msgcnt(&tunnel_hdr, msgcount);
  2354 + dbg("Link changeover requires %u tunnel messages\n", msgcount);
2344 2355  
2345 2356 if (!l_ptr->first_out) {
2346 2357 struct sk_buff *buf;
... ... @@ -2360,6 +2371,9 @@
2360 2371 return;
2361 2372 }
2362 2373  
  2374 + split_bundles = (l_ptr->owner->active_links[0] !=
  2375 + l_ptr->owner->active_links[1]);
  2376 +
2363 2377 while (crs) {
2364 2378 struct tipc_msg *msg = buf_msg(crs);
2365 2379  
2366 2380  
... ... @@ -2497,11 +2511,13 @@
2497 2511 dest_link->name);
2498 2512 tipc_link_reset(dest_link);
2499 2513 dest_link->exp_msg_count = msg_count;
  2514 + dbg("Expecting %u tunnelled messages\n", msg_count);
2500 2515 if (!msg_count)
2501 2516 goto exit;
2502 2517 } else if (dest_link->exp_msg_count == START_CHANGEOVER) {
2503 2518 msg_dbg(tunnel_msg, "BLK/FIRST/<REC<");
2504 2519 dest_link->exp_msg_count = msg_count;
  2520 + dbg("Expecting %u tunnelled messages\n", msg_count);
2505 2521 if (!msg_count)
2506 2522 goto exit;
2507 2523 }
... ... @@ -2509,6 +2525,8 @@
2509 2525 /* Receive original message */
2510 2526  
2511 2527 if (dest_link->exp_msg_count == 0) {
  2528 + warn("Link switchover error, "
  2529 + "got too many tunnelled messages\n");
2512 2530 msg_dbg(tunnel_msg, "OVERDUE/DROP/<REC<");
2513 2531 dbg_print_link(dest_link, "LINK:");
2514 2532 goto exit;
... ... @@ -125,6 +125,8 @@
125 125 {
126 126 struct link **active = &n_ptr->active_links[0];
127 127  
  128 + n_ptr->working_links++;
  129 +
128 130 info("Established link <%s> on network plane %c\n",
129 131 l_ptr->name, l_ptr->b_ptr->net_plane);
130 132  
... ... @@ -185,6 +187,8 @@
185 187 {
186 188 struct link **active;
187 189  
  190 + n_ptr->working_links--;
  191 +
188 192 if (!tipc_link_is_active(l_ptr)) {
189 193 info("Lost standby link <%s> on network plane %c\n",
190 194 l_ptr->name, l_ptr->b_ptr->net_plane);
... ... @@ -214,8 +218,7 @@
214 218  
215 219 int tipc_node_has_redundant_links(struct node *n_ptr)
216 220 {
217   - return (tipc_node_has_active_links(n_ptr) &&
218   - (n_ptr->active_links[0] != n_ptr->active_links[1]));
  221 + return (n_ptr->working_links > 1);
219 222 }
220 223  
221 224 static int tipc_node_has_active_routes(struct node *n_ptr)
... ... @@ -51,6 +51,7 @@
51 51 * @nsub: list of "node down" subscriptions monitoring node
52 52 * @active_links: pointers to active links to node
53 53 * @links: pointers to all links to node
  54 + * @working_links: number of working links to node (both active and standby)
54 55 * @link_cnt: number of links to node
55 56 * @permit_changeover: non-zero if node has redundant links to this system
56 57 * @routers: bitmap (used for multicluster communication)
... ... @@ -76,6 +77,7 @@
76 77 struct link *active_links[2];
77 78 struct link *links[MAX_BEARERS];
78 79 int link_cnt;
  80 + int working_links;
79 81 int permit_changeover;
80 82 u32 routers[512/32];
81 83 int last_router;