diff options
-rw-r--r-- | net/tipc/link.c | 53 |
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 */ |
1528 | protocol_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 | */ | ||
2109 | static 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 ?: */ |