diff options
-rw-r--r-- | net/tipc/link.c | 38 | ||||
-rw-r--r-- | net/tipc/link.h | 7 | ||||
-rw-r--r-- | net/tipc/msg.h | 1 |
3 files changed, 34 insertions, 12 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index f0cf768a59f3..dfc738e5cff9 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -221,6 +221,7 @@ bool tipc_link_create(struct tipc_node *n, char *if_name, int bearer_id, | |||
221 | l->mtu = mtu; | 221 | l->mtu = mtu; |
222 | l->priority = priority; | 222 | l->priority = priority; |
223 | tipc_link_set_queue_limits(l, window); | 223 | tipc_link_set_queue_limits(l, window); |
224 | l->ackers = 1; | ||
224 | l->inputq = inputq; | 225 | l->inputq = inputq; |
225 | l->namedq = namedq; | 226 | l->namedq = namedq; |
226 | l->state = LINK_RESETTING; | 227 | l->state = LINK_RESETTING; |
@@ -647,6 +648,7 @@ void tipc_link_reset(struct tipc_link *l) | |||
647 | l->rcv_unacked = 0; | 648 | l->rcv_unacked = 0; |
648 | l->snd_nxt = 1; | 649 | l->snd_nxt = 1; |
649 | l->rcv_nxt = 1; | 650 | l->rcv_nxt = 1; |
651 | l->acked = 0; | ||
650 | l->silent_intv_cnt = 0; | 652 | l->silent_intv_cnt = 0; |
651 | l->stats.recv_info = 0; | 653 | l->stats.recv_info = 0; |
652 | l->stale_count = 0; | 654 | l->stale_count = 0; |
@@ -769,6 +771,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list, | |||
769 | __skb_dequeue(list); | 771 | __skb_dequeue(list); |
770 | __skb_queue_tail(transmq, skb); | 772 | __skb_queue_tail(transmq, skb); |
771 | __skb_queue_tail(xmitq, _skb); | 773 | __skb_queue_tail(xmitq, _skb); |
774 | TIPC_SKB_CB(skb)->ackers = l->ackers; | ||
772 | l->rcv_unacked = 0; | 775 | l->rcv_unacked = 0; |
773 | seqno++; | 776 | seqno++; |
774 | continue; | 777 | continue; |
@@ -829,6 +832,7 @@ void tipc_link_push_packets(struct tipc_link *link) | |||
829 | skb = __skb_dequeue(&link->backlogq); | 832 | skb = __skb_dequeue(&link->backlogq); |
830 | if (!skb) | 833 | if (!skb) |
831 | break; | 834 | break; |
835 | TIPC_SKB_CB(skb)->ackers = link->ackers; | ||
832 | msg = buf_msg(skb); | 836 | msg = buf_msg(skb); |
833 | link->backlog[msg_importance(msg)].len--; | 837 | link->backlog[msg_importance(msg)].len--; |
834 | msg_set_ack(msg, ack); | 838 | msg_set_ack(msg, ack); |
@@ -862,6 +866,7 @@ void tipc_link_advance_backlog(struct tipc_link *l, struct sk_buff_head *xmitq) | |||
862 | l->backlog[msg_importance(hdr)].len--; | 866 | l->backlog[msg_importance(hdr)].len--; |
863 | __skb_queue_tail(&l->transmq, skb); | 867 | __skb_queue_tail(&l->transmq, skb); |
864 | __skb_queue_tail(xmitq, _skb); | 868 | __skb_queue_tail(xmitq, _skb); |
869 | TIPC_SKB_CB(skb)->ackers = l->ackers; | ||
865 | msg_set_ack(hdr, ack); | 870 | msg_set_ack(hdr, ack); |
866 | msg_set_seqno(hdr, seqno); | 871 | msg_set_seqno(hdr, seqno); |
867 | msg_set_bcast_ack(hdr, l->owner->bclink.last_in); | 872 | msg_set_bcast_ack(hdr, l->owner->bclink.last_in); |
@@ -947,11 +952,13 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *skb, | |||
947 | } | 952 | } |
948 | } | 953 | } |
949 | 954 | ||
950 | static int tipc_link_retransm(struct tipc_link *l, int retransm, | 955 | int tipc_link_retrans(struct tipc_link *l, u16 from, u16 to, |
951 | struct sk_buff_head *xmitq) | 956 | struct sk_buff_head *xmitq) |
952 | { | 957 | { |
953 | struct sk_buff *_skb, *skb = skb_peek(&l->transmq); | 958 | struct sk_buff *_skb, *skb = skb_peek(&l->transmq); |
954 | struct tipc_msg *hdr; | 959 | struct tipc_msg *hdr; |
960 | u16 ack = l->rcv_nxt - 1; | ||
961 | u16 bc_ack = l->owner->bclink.last_in; | ||
955 | 962 | ||
956 | if (!skb) | 963 | if (!skb) |
957 | return 0; | 964 | return 0; |
@@ -964,19 +971,25 @@ static int tipc_link_retransm(struct tipc_link *l, int retransm, | |||
964 | link_retransmit_failure(l, skb); | 971 | link_retransmit_failure(l, skb); |
965 | return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); | 972 | return tipc_link_fsm_evt(l, LINK_FAILURE_EVT); |
966 | } | 973 | } |
974 | |||
975 | /* Move forward to where retransmission should start */ | ||
967 | skb_queue_walk(&l->transmq, skb) { | 976 | skb_queue_walk(&l->transmq, skb) { |
968 | if (!retransm) | 977 | if (!less(buf_seqno(skb), from)) |
969 | return 0; | 978 | break; |
979 | } | ||
980 | |||
981 | skb_queue_walk_from(&l->transmq, skb) { | ||
982 | if (more(buf_seqno(skb), to)) | ||
983 | break; | ||
970 | hdr = buf_msg(skb); | 984 | hdr = buf_msg(skb); |
971 | _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); | 985 | _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); |
972 | if (!_skb) | 986 | if (!_skb) |
973 | return 0; | 987 | return 0; |
974 | hdr = buf_msg(_skb); | 988 | hdr = buf_msg(_skb); |
975 | msg_set_ack(hdr, l->rcv_nxt - 1); | 989 | msg_set_ack(hdr, ack); |
976 | msg_set_bcast_ack(hdr, l->owner->bclink.last_in); | 990 | msg_set_bcast_ack(hdr, bc_ack); |
977 | _skb->priority = TC_PRIO_CONTROL; | 991 | _skb->priority = TC_PRIO_CONTROL; |
978 | __skb_queue_tail(xmitq, _skb); | 992 | __skb_queue_tail(xmitq, _skb); |
979 | retransm--; | ||
980 | l->stats.retransmitted++; | 993 | l->stats.retransmitted++; |
981 | } | 994 | } |
982 | return 0; | 995 | return 0; |
@@ -1390,7 +1403,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1390 | { | 1403 | { |
1391 | struct tipc_msg *hdr = buf_msg(skb); | 1404 | struct tipc_msg *hdr = buf_msg(skb); |
1392 | u16 rcvgap = 0; | 1405 | u16 rcvgap = 0; |
1393 | u16 nacked_gap = msg_seq_gap(hdr); | 1406 | u16 ack = msg_ack(hdr); |
1407 | u16 gap = msg_seq_gap(hdr); | ||
1394 | u16 peers_snd_nxt = msg_next_sent(hdr); | 1408 | u16 peers_snd_nxt = msg_next_sent(hdr); |
1395 | u16 peers_tol = msg_link_tolerance(hdr); | 1409 | u16 peers_tol = msg_link_tolerance(hdr); |
1396 | u16 peers_prio = msg_linkprio(hdr); | 1410 | u16 peers_prio = msg_linkprio(hdr); |
@@ -1469,11 +1483,11 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb, | |||
1469 | if (rcvgap || (msg_probe(hdr))) | 1483 | if (rcvgap || (msg_probe(hdr))) |
1470 | tipc_link_build_proto_msg(l, STATE_MSG, 0, rcvgap, | 1484 | tipc_link_build_proto_msg(l, STATE_MSG, 0, rcvgap, |
1471 | 0, 0, xmitq); | 1485 | 0, 0, xmitq); |
1472 | tipc_link_release_pkts(l, msg_ack(hdr)); | 1486 | tipc_link_release_pkts(l, ack); |
1473 | 1487 | ||
1474 | /* If NACK, retransmit will now start at right position */ | 1488 | /* If NACK, retransmit will now start at right position */ |
1475 | if (nacked_gap) { | 1489 | if (gap) { |
1476 | rc = tipc_link_retransm(l, nacked_gap, xmitq); | 1490 | rc = tipc_link_retrans(l, ack + 1, ack + gap, xmitq); |
1477 | l->stats.recv_nacks++; | 1491 | l->stats.recv_nacks++; |
1478 | } | 1492 | } |
1479 | 1493 | ||
@@ -1550,7 +1564,7 @@ static void link_reset_statistics(struct tipc_link *l_ptr) | |||
1550 | static void link_print(struct tipc_link *l, const char *str) | 1564 | static void link_print(struct tipc_link *l, const char *str) |
1551 | { | 1565 | { |
1552 | struct sk_buff *hskb = skb_peek(&l->transmq); | 1566 | struct sk_buff *hskb = skb_peek(&l->transmq); |
1553 | u16 head = hskb ? msg_seqno(buf_msg(hskb)) : l->snd_nxt; | 1567 | u16 head = hskb ? msg_seqno(buf_msg(hskb)) : l->snd_nxt - 1; |
1554 | u16 tail = l->snd_nxt - 1; | 1568 | u16 tail = l->snd_nxt - 1; |
1555 | 1569 | ||
1556 | pr_info("%s Link <%s> state %x\n", str, l->name, l->state); | 1570 | pr_info("%s Link <%s> state %x\n", str, l->name, l->state); |
diff --git a/net/tipc/link.h b/net/tipc/link.h index 9e4e3673da76..be24d1fd5132 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h | |||
@@ -134,6 +134,8 @@ struct tipc_stats { | |||
134 | * @snt_nxt: next sequence number to use for outbound messages | 134 | * @snt_nxt: next sequence number to use for outbound messages |
135 | * @last_retransmitted: sequence number of most recently retransmitted message | 135 | * @last_retransmitted: sequence number of most recently retransmitted message |
136 | * @stale_count: # of identical retransmit requests made by peer | 136 | * @stale_count: # of identical retransmit requests made by peer |
137 | * @ackers: # of peers that needs to ack each packet before it can be released | ||
138 | * @acked: # last packet acked by a certain peer. Used for broadcast. | ||
137 | * @rcv_nxt: next sequence number to expect for inbound messages | 139 | * @rcv_nxt: next sequence number to expect for inbound messages |
138 | * @deferred_queue: deferred queue saved OOS b'cast message received from node | 140 | * @deferred_queue: deferred queue saved OOS b'cast message received from node |
139 | * @unacked_window: # of inbound messages rx'd without ack'ing back to peer | 141 | * @unacked_window: # of inbound messages rx'd without ack'ing back to peer |
@@ -143,6 +145,7 @@ struct tipc_stats { | |||
143 | * @wakeupq: linked list of wakeup msgs waiting for link congestion to abate | 145 | * @wakeupq: linked list of wakeup msgs waiting for link congestion to abate |
144 | * @long_msg_seq_no: next identifier to use for outbound fragmented messages | 146 | * @long_msg_seq_no: next identifier to use for outbound fragmented messages |
145 | * @reasm_buf: head of partially reassembled inbound message fragments | 147 | * @reasm_buf: head of partially reassembled inbound message fragments |
148 | * @bc_rcvr: marks that this is a broadcast receiver link | ||
146 | * @stats: collects statistics regarding link activity | 149 | * @stats: collects statistics regarding link activity |
147 | */ | 150 | */ |
148 | struct tipc_link { | 151 | struct tipc_link { |
@@ -201,6 +204,10 @@ struct tipc_link { | |||
201 | /* Fragmentation/reassembly */ | 204 | /* Fragmentation/reassembly */ |
202 | struct sk_buff *reasm_buf; | 205 | struct sk_buff *reasm_buf; |
203 | 206 | ||
207 | /* Broadcast */ | ||
208 | u16 ackers; | ||
209 | u16 acked; | ||
210 | |||
204 | /* Statistics */ | 211 | /* Statistics */ |
205 | struct tipc_stats stats; | 212 | struct tipc_stats stats; |
206 | }; | 213 | }; |
diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 9f0ef54be612..799782c47f6c 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h | |||
@@ -112,6 +112,7 @@ struct tipc_skb_cb { | |||
112 | bool wakeup_pending; | 112 | bool wakeup_pending; |
113 | u16 chain_sz; | 113 | u16 chain_sz; |
114 | u16 chain_imp; | 114 | u16 chain_imp; |
115 | u16 ackers; | ||
115 | }; | 116 | }; |
116 | 117 | ||
117 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) | 118 | #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) |