aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/outqueue.c
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-07-09 10:17:04 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-09 15:49:56 -0400
commit8c2f414ad1b3aa3af05791cd7312eb8ff9d80e0d (patch)
tree5d4281f3fbb68256211eaa2d39e45dc85c0874d8 /net/sctp/outqueue.c
parente1d6fbc3dedbb463fc79b48ddb05ab6b20fd088a (diff)
net: sctp: confirm route during forward progress
This fix has been proposed originally by Vlad Yasevich. He says: When SCTP makes forward progress (receives a SACK that acks new chunks, renegs, or answeres 0-window probes) or when HB-ACK arrives, mark the route as confirmed so we don't unnecessarily send NUD probes. Having a simple SCTP client/server that exchange data chunks every 1sec, without this patch ARP requests are sent periodically every 40-60sec. With this fix applied, an ARP request is only done once right at the "session" beginning. Also, when clearing the related ARP cache entry manually during the session, a new request is correctly done. I have only "backported" this to net-next and tested that it works, so full credit goes to Vlad. Signed-off-by: Vlad Yasevich <vyasevich@gmail.com> Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r--net/sctp/outqueue.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index cb80a8e060b7..ef9e2bbc0f2f 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1334,6 +1334,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1334 __u8 restart_timer = 0; 1334 __u8 restart_timer = 0;
1335 int bytes_acked = 0; 1335 int bytes_acked = 0;
1336 int migrate_bytes = 0; 1336 int migrate_bytes = 0;
1337 bool forward_progress = false;
1337 1338
1338 sack_ctsn = ntohl(sack->cum_tsn_ack); 1339 sack_ctsn = ntohl(sack->cum_tsn_ack);
1339 1340
@@ -1400,6 +1401,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1400 bytes_acked += sctp_data_size(tchunk); 1401 bytes_acked += sctp_data_size(tchunk);
1401 if (!tchunk->transport) 1402 if (!tchunk->transport)
1402 migrate_bytes += sctp_data_size(tchunk); 1403 migrate_bytes += sctp_data_size(tchunk);
1404 forward_progress = true;
1403 } 1405 }
1404 1406
1405 if (TSN_lte(tsn, sack_ctsn)) { 1407 if (TSN_lte(tsn, sack_ctsn)) {
@@ -1413,6 +1415,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1413 * current RTO. 1415 * current RTO.
1414 */ 1416 */
1415 restart_timer = 1; 1417 restart_timer = 1;
1418 forward_progress = true;
1416 1419
1417 if (!tchunk->tsn_gap_acked) { 1420 if (!tchunk->tsn_gap_acked) {
1418 /* 1421 /*
@@ -1503,6 +1506,7 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1503 */ 1506 */
1504 transport->error_count = 0; 1507 transport->error_count = 0;
1505 transport->asoc->overall_error_count = 0; 1508 transport->asoc->overall_error_count = 0;
1509 forward_progress = true;
1506 1510
1507 /* 1511 /*
1508 * While in SHUTDOWN PENDING, we may have started 1512 * While in SHUTDOWN PENDING, we may have started
@@ -1576,6 +1580,11 @@ static void sctp_check_transmitted(struct sctp_outq *q,
1576 jiffies + transport->rto)) 1580 jiffies + transport->rto))
1577 sctp_transport_hold(transport); 1581 sctp_transport_hold(transport);
1578 } 1582 }
1583
1584 if (forward_progress) {
1585 if (transport->dst)
1586 dst_confirm(transport->dst);
1587 }
1579 } 1588 }
1580 1589
1581 list_splice(&tlist, transmitted_queue); 1590 list_splice(&tlist, transmitted_queue);