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) u32 seq_no; u32 ackd; u32 released = 0; - int type; head = head->next; buf->next = NULL; @@ -1525,7 +1524,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) } /* Now (finally!) process the incoming message */ -protocol_check: if (unlikely(!link_working_working(l_ptr))) { if (msg_user(msg) == LINK_PROTOCOL) { link_recv_proto_msg(l_ptr, buf); @@ -1599,15 +1597,11 @@ deliver: tipc_node_unlock(n_ptr); continue; case CHANGEOVER_PROTOCOL: - type = msg_type(msg); - if (tipc_link_tunnel_rcv(&l_ptr, &buf)) { - msg = buf_msg(buf); - seq_no = msg_seqno(msg); - if (type == ORIGINAL_MSG) - goto deliver; - goto protocol_check; - } - break; + if (!tipc_link_tunnel_rcv(&l_ptr, &buf)) + break; + msg = buf_msg(buf); + seq_no = msg_seqno(msg); + goto deliver; default: kfree_skb(buf); buf = NULL; @@ -2107,7 +2101,30 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos) return eb; } -/* tipc_link_tunnel_rcv(): Receive a tunneled packet, sent + + +/* tipc_link_dup_rcv(): Receive a tunnelled DUPLICATE_MSG packet. + * Owner node is locked. + */ +static void tipc_link_dup_rcv(struct tipc_link *l_ptr, + struct sk_buff *t_buf) +{ + struct sk_buff *buf; + + if (!tipc_link_is_up(l_ptr)) + return; + + buf = buf_extract(t_buf, INT_H_SIZE); + if (buf == NULL) { + pr_warn("%sfailed to extract inner dup pkt\n", link_co_err); + return; + } + + /* Add buffer to deferred queue, if applicable: */ + link_handle_out_of_seq_msg(l_ptr, buf); +} + +/* tipc_link_tunnel_rcv(): Receive a tunnelled packet, sent * via other link as result of a failover (ORIGINAL_MSG) or * a new active link (DUPLICATE_MSG). Failover packets are * returned to the active link for delivery upwards. @@ -2126,6 +2143,7 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr, if (bearer_id >= MAX_BEARERS) goto exit; + dest_link = (*l_ptr)->owner->links[bearer_id]; if (!dest_link) goto exit; @@ -2138,15 +2156,8 @@ static int tipc_link_tunnel_rcv(struct tipc_link **l_ptr, msg = msg_get_wrapped(tunnel_msg); if (msg_typ == DUPLICATE_MSG) { - if (less(msg_seqno(msg), mod(dest_link->next_in_no))) - goto exit; - *buf = buf_extract(tunnel_buf, INT_H_SIZE); - if (*buf == NULL) { - pr_warn("%sduplicate msg dropped\n", link_co_err); - goto exit; - } - kfree_skb(tunnel_buf); - return 1; + tipc_link_dup_rcv(dest_link, tunnel_buf); + goto exit; } /* First original message ?: */ |