aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-02-13 17:29:11 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-13 17:57:06 -0500
commitf006c9c70fda4676157e00caa2efa74646709d72 (patch)
treec2322f4588d384427812068086d7cb6511d39e84 /net/tipc/link.c
parent1dab3d5ac22217241ca5c5bb7d0132602b465938 (diff)
tipc: change reception of tunnelled failover packets
When a link is reset, and there is a redundant link available, all sender sockets will steer their subsequent traffic through the remaining link. In order to guarantee preserved packet order and cardinality during the transition, we tunnel the failing link's send queue through the remaining link before we allow any sockets to use it. In this commit, we change the algorithm for receiving failover ("ORIGINAL_MSG") packets in tipc_link_tunnel_rcv(), at the same time delegating it to a new subfuncton, tipc_link_failover_rcv(). Instead of directly returning an extracted inner packet to the packet reception loop in tipc_rcv(), we first check if it is a message fragment, in which case we append it to the reset link's fragment chain. If the fragment chain is complete, we return the whole chain instead of the individual buffer, eliminating any need for the tipc_rcv() loop to do reassembly of tunneled packets. This change makes it possible to further simplify tipc_link_tunnel_rcv(), as well as the calling tipc_rcv() loop. We will do that in later commits. It also makes it possible to identify a single spot in the code where we can tell that a failover procedure is finished, something that is useful when we are deleting links after a failover. This will also be done in a later commit. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c75
1 files changed, 47 insertions, 28 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index f227a389e36e..26a54f4f3c63 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -2124,6 +2124,50 @@ static void tipc_link_dup_rcv(struct tipc_link *l_ptr,
2124 link_handle_out_of_seq_msg(l_ptr, buf); 2124 link_handle_out_of_seq_msg(l_ptr, buf);
2125} 2125}
2126 2126
2127/* tipc_link_failover_rcv(): Receive a tunnelled ORIGINAL_MSG packet
2128 * Owner node is locked.
2129 */
2130static struct sk_buff *tipc_link_failover_rcv(struct tipc_link *l_ptr,
2131 struct sk_buff *t_buf)
2132{
2133 struct tipc_msg *t_msg = buf_msg(t_buf);
2134 struct sk_buff *buf = NULL;
2135 struct tipc_msg *msg;
2136
2137 if (tipc_link_is_up(l_ptr))
2138 tipc_link_reset(l_ptr);
2139
2140 /* First failover packet? */
2141 if (l_ptr->exp_msg_count == START_CHANGEOVER)
2142 l_ptr->exp_msg_count = msg_msgcnt(t_msg);
2143
2144 /* Should there be an inner packet? */
2145 if (l_ptr->exp_msg_count) {
2146 l_ptr->exp_msg_count--;
2147 buf = buf_extract(t_buf, INT_H_SIZE);
2148 if (buf == NULL) {
2149 pr_warn("%sno inner failover pkt\n", link_co_err);
2150 goto exit;
2151 }
2152 msg = buf_msg(buf);
2153
2154 if (less(msg_seqno(msg), l_ptr->reset_checkpoint)) {
2155 kfree_skb(buf);
2156 buf = NULL;
2157 goto exit;
2158 }
2159 if (msg_user(msg) == MSG_FRAGMENTER) {
2160 l_ptr->stats.recv_fragments++;
2161 tipc_link_frag_rcv(&l_ptr->reasm_head,
2162 &l_ptr->reasm_tail,
2163 &buf);
2164 }
2165 }
2166
2167exit:
2168 return buf;
2169}
2170
2127/* tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent 2171/* tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent
2128 * via other link as result of a failover (ORIGINAL_MSG) or 2172 * via other link as result of a failover (ORIGINAL_MSG) or
2129 * a new active link (DUPLICATE_MSG). Failover packets are 2173 * a new active link (DUPLICATE_MSG). Failover packets are
@@ -2135,10 +2179,8 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
2135{ 2179{
2136 struct sk_buff *tunnel_buf = *buf; 2180 struct sk_buff *tunnel_buf = *buf;
2137 struct tipc_link *dest_link; 2181 struct tipc_link *dest_link;
2138 struct tipc_msg *msg;
2139 struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf); 2182 struct tipc_msg *tunnel_msg = buf_msg(tunnel_buf);
2140 u32 msg_typ = msg_type(tunnel_msg); 2183 u32 msg_typ = msg_type(tunnel_msg);
2141 u32 msg_count = msg_msgcnt(tunnel_msg);
2142 u32 bearer_id = msg_bearer_id(tunnel_msg); 2184 u32 bearer_id = msg_bearer_id(tunnel_msg);
2143 2185
2144 if (bearer_id >= MAX_BEARERS) 2186 if (bearer_id >= MAX_BEARERS)
@@ -2153,42 +2195,19 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
2153 goto exit; 2195 goto exit;
2154 } 2196 }
2155 *l_ptr = dest_link; 2197 *l_ptr = dest_link;
2156 msg = msg_get_wrapped(tunnel_msg);
2157 2198
2158 if (msg_typ == DUPLICATE_MSG) { 2199 if (msg_typ == DUPLICATE_MSG) {
2159 tipc_link_dup_rcv(dest_link, tunnel_buf); 2200 tipc_link_dup_rcv(dest_link, tunnel_buf);
2160 goto exit; 2201 goto exit;
2161 } 2202 }
2162 2203
2163 /* First original message ?: */ 2204 if (msg_type(tunnel_msg) == ORIGINAL_MSG) {
2164 if (tipc_link_is_up(dest_link)) { 2205 *buf = tipc_link_failover_rcv(dest_link, tunnel_buf);
2165 pr_info("%s<%s>, changeover initiated by peer\n", link_rst_msg,
2166 dest_link->name);
2167 tipc_link_reset(dest_link);
2168 dest_link->exp_msg_count = msg_count;
2169 if (!msg_count)
2170 goto exit;
2171 } else if (dest_link->exp_msg_count == START_CHANGEOVER) {
2172 dest_link->exp_msg_count = msg_count;
2173 if (!msg_count)
2174 goto exit;
2175 }
2176 2206
2177 /* Receive original message */ 2207 /* Do we have a buffer/buffer chain to return? */
2178 if (dest_link->exp_msg_count == 0) {
2179 pr_warn("%sgot too many tunnelled messages\n", link_co_err);
2180 goto exit;
2181 }
2182 dest_link->exp_msg_count--;
2183 if (less(msg_seqno(msg), dest_link->reset_checkpoint)) {
2184 goto exit;
2185 } else {
2186 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2187 if (*buf != NULL) { 2208 if (*buf != NULL) {
2188 kfree_skb(tunnel_buf); 2209 kfree_skb(tunnel_buf);
2189 return 1; 2210 return 1;
2190 } else {
2191 pr_warn("%soriginal msg dropped\n", link_co_err);
2192 } 2211 }
2193 } 2212 }
2194exit: 2213exit: