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.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 5aee1ed23ba9..1f2cde0d025f 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -209,6 +209,7 @@ enum {
209}; 209};
210 210
211#define TIPC_BC_RETR_LIM msecs_to_jiffies(10) /* [ms] */ 211#define TIPC_BC_RETR_LIM msecs_to_jiffies(10) /* [ms] */
212#define TIPC_UC_RETR_TIME (jiffies + msecs_to_jiffies(1))
212 213
213/* 214/*
214 * Interval between NACKs when packets arrive out of order 215 * Interval between NACKs when packets arrive out of order
@@ -1305,6 +1306,10 @@ next_gap_ack:
1305 kfree_skb(skb); 1306 kfree_skb(skb);
1306 } else if (less_eq(seqno, acked + gap)) { 1307 } else if (less_eq(seqno, acked + gap)) {
1307 /* retransmit skb */ 1308 /* retransmit skb */
1309 if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr))
1310 continue;
1311 TIPC_SKB_CB(skb)->nxt_retr = TIPC_UC_RETR_TIME;
1312
1308 _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC); 1313 _skb = __pskb_copy(skb, MIN_H_SIZE, GFP_ATOMIC);
1309 if (!_skb) 1314 if (!_skb)
1310 continue; 1315 continue;
@@ -1380,6 +1385,7 @@ static int tipc_link_build_nack_msg(struct tipc_link *l,
1380 struct sk_buff_head *xmitq) 1385 struct sk_buff_head *xmitq)
1381{ 1386{
1382 u32 def_cnt = ++l->stats.deferred_recv; 1387 u32 def_cnt = ++l->stats.deferred_recv;
1388 u32 defq_len = skb_queue_len(&l->deferdq);
1383 int match1, match2; 1389 int match1, match2;
1384 1390
1385 if (link_is_bc_rcvlink(l)) { 1391 if (link_is_bc_rcvlink(l)) {
@@ -1390,7 +1396,7 @@ static int tipc_link_build_nack_msg(struct tipc_link *l,
1390 return 0; 1396 return 0;
1391 } 1397 }
1392 1398
1393 if ((skb_queue_len(&l->deferdq) == 1) || !(def_cnt % TIPC_NACK_INTV)) 1399 if (defq_len >= 3 && !((defq_len - 3) % 16))
1394 tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, 0, xmitq); 1400 tipc_link_build_proto_msg(l, STATE_MSG, 0, 0, 0, 0, 0, xmitq);
1395 return 0; 1401 return 0;
1396} 1402}
@@ -1404,29 +1410,29 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
1404 struct sk_buff_head *xmitq) 1410 struct sk_buff_head *xmitq)
1405{ 1411{
1406 struct sk_buff_head *defq = &l->deferdq; 1412 struct sk_buff_head *defq = &l->deferdq;
1407 struct tipc_msg *hdr; 1413 struct tipc_msg *hdr = buf_msg(skb);
1408 u16 seqno, rcv_nxt, win_lim; 1414 u16 seqno, rcv_nxt, win_lim;
1409 int rc = 0; 1415 int rc = 0;
1410 1416
1417 /* Verify and update link state */
1418 if (unlikely(msg_user(hdr) == LINK_PROTOCOL))
1419 return tipc_link_proto_rcv(l, skb, xmitq);
1420
1421 /* Don't send probe at next timeout expiration */
1422 l->silent_intv_cnt = 0;
1423
1411 do { 1424 do {
1412 hdr = buf_msg(skb); 1425 hdr = buf_msg(skb);
1413 seqno = msg_seqno(hdr); 1426 seqno = msg_seqno(hdr);
1414 rcv_nxt = l->rcv_nxt; 1427 rcv_nxt = l->rcv_nxt;
1415 win_lim = rcv_nxt + TIPC_MAX_LINK_WIN; 1428 win_lim = rcv_nxt + TIPC_MAX_LINK_WIN;
1416 1429
1417 /* Verify and update link state */
1418 if (unlikely(msg_user(hdr) == LINK_PROTOCOL))
1419 return tipc_link_proto_rcv(l, skb, xmitq);
1420
1421 if (unlikely(!link_is_up(l))) { 1430 if (unlikely(!link_is_up(l))) {
1422 if (l->state == LINK_ESTABLISHING) 1431 if (l->state == LINK_ESTABLISHING)
1423 rc = TIPC_LINK_UP_EVT; 1432 rc = TIPC_LINK_UP_EVT;
1424 goto drop; 1433 goto drop;
1425 } 1434 }
1426 1435
1427 /* Don't send probe at next timeout expiration */
1428 l->silent_intv_cnt = 0;
1429
1430 /* Drop if outside receive window */ 1436 /* Drop if outside receive window */
1431 if (unlikely(less(seqno, rcv_nxt) || more(seqno, win_lim))) { 1437 if (unlikely(less(seqno, rcv_nxt) || more(seqno, win_lim))) {
1432 l->stats.duplicates++; 1438 l->stats.duplicates++;
@@ -1457,7 +1463,7 @@ int tipc_link_rcv(struct tipc_link *l, struct sk_buff *skb,
1457 rc |= tipc_link_build_state_msg(l, xmitq); 1463 rc |= tipc_link_build_state_msg(l, xmitq);
1458 if (unlikely(rc & ~TIPC_LINK_SND_STATE)) 1464 if (unlikely(rc & ~TIPC_LINK_SND_STATE))
1459 break; 1465 break;
1460 } while ((skb = __skb_dequeue(defq))); 1466 } while ((skb = __tipc_skb_dequeue(defq, l->rcv_nxt)));
1461 1467
1462 return rc; 1468 return rc;
1463drop: 1469drop: