aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/link.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r--net/tipc/link.c53
1 files changed, 32 insertions, 21 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index e7e44ab008ec..f227a389e36e 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1437,7 +1437,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
1437 u32 seq_no; 1437 u32 seq_no;
1438 u32 ackd; 1438 u32 ackd;
1439 u32 released = 0; 1439 u32 released = 0;
1440 int type;
1441 1440
1442 head = head->next; 1441 head = head->next;
1443 buf->next = NULL; 1442 buf->next = NULL;
@@ -1525,7 +1524,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
1525 } 1524 }
1526 1525
1527 /* Now (finally!) process the incoming message */ 1526 /* Now (finally!) process the incoming message */
1528protocol_check:
1529 if (unlikely(!link_working_working(l_ptr))) { 1527 if (unlikely(!link_working_working(l_ptr))) {
1530 if (msg_user(msg) == LINK_PROTOCOL) { 1528 if (msg_user(msg) == LINK_PROTOCOL) {
1531 link_recv_proto_msg(l_ptr, buf); 1529 link_recv_proto_msg(l_ptr, buf);
@@ -1599,15 +1597,11 @@ deliver:
1599 tipc_node_unlock(n_ptr); 1597 tipc_node_unlock(n_ptr);
1600 continue; 1598 continue;
1601 case CHANGEOVER_PROTOCOL: 1599 case CHANGEOVER_PROTOCOL:
1602 type = msg_type(msg); 1600 if (!tipc_link_tunnel_rcv(&l_ptr, &buf))
1603 if (tipc_link_tunnel_rcv(&l_ptr, &buf)) { 1601 break;
1604 msg = buf_msg(buf); 1602 msg = buf_msg(buf);
1605 seq_no = msg_seqno(msg); 1603 seq_no = msg_seqno(msg);
1606 if (type == ORIGINAL_MSG) 1604 goto deliver;
1607 goto deliver;
1608 goto protocol_check;
1609 }
1610 break;
1611 default: 1605 default:
1612 kfree_skb(buf); 1606 kfree_skb(buf);
1613 buf = NULL; 1607 buf = NULL;
@@ -2107,7 +2101,30 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos)
2107 return eb; 2101 return eb;
2108} 2102}
2109 2103
2110/* tipc_link_tunnel_rcv(): Receive a tunneled packet, sent 2104
2105
2106/* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet.
2107 * Owner node is locked.
2108 */
2109static void tipc_link_dup_rcv(struct tipc_link *l_ptr,
2110 struct sk_buff *t_buf)
2111{
2112 struct sk_buff *buf;
2113
2114 if (!tipc_link_is_up(l_ptr))
2115 return;
2116
2117 buf = buf_extract(t_buf, INT_H_SIZE);
2118 if (buf == NULL) {
2119 pr_warn("%sfailed to extract inner dup pkt\n", link_co_err);
2120 return;
2121 }
2122
2123 /* Add buffer to deferred queue, if applicable: */
2124 link_handle_out_of_seq_msg(l_ptr, buf);
2125}
2126
2127/* tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent
2111 * via other link as result of a failover (ORIGINAL_MSG) or 2128 * via other link as result of a failover (ORIGINAL_MSG) or
2112 * a new active link (DUPLICATE_MSG). Failover packets are 2129 * a new active link (DUPLICATE_MSG). Failover packets are
2113 * returned to the active link for delivery upwards. 2130 * returned to the active link for delivery upwards.
@@ -2126,6 +2143,7 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
2126 2143
2127 if (bearer_id >= MAX_BEARERS) 2144 if (bearer_id >= MAX_BEARERS)
2128 goto exit; 2145 goto exit;
2146
2129 dest_link = (*l_ptr)->owner->links[bearer_id]; 2147 dest_link = (*l_ptr)->owner->links[bearer_id];
2130 if (!dest_link) 2148 if (!dest_link)
2131 goto exit; 2149 goto exit;
@@ -2138,15 +2156,8 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr,
2138 msg = msg_get_wrapped(tunnel_msg); 2156 msg = msg_get_wrapped(tunnel_msg);
2139 2157
2140 if (msg_typ == DUPLICATE_MSG) { 2158 if (msg_typ == DUPLICATE_MSG) {
2141 if (less(msg_seqno(msg), mod(dest_link->next_in_no))) 2159 tipc_link_dup_rcv(dest_link, tunnel_buf);
2142 goto exit; 2160 goto exit;
2143 *buf = buf_extract(tunnel_buf, INT_H_SIZE);
2144 if (*buf == NULL) {
2145 pr_warn("%sduplicate msg dropped\n", link_co_err);
2146 goto exit;
2147 }
2148 kfree_skb(tunnel_buf);
2149 return 1;
2150 } 2161 }
2151 2162
2152 /* First original message ?: */ 2163 /* First original message ?: */