sctp: send pmtu probe only if packet loss in Search Complete state
authorXin Long <lucien.xin@gmail.com>
Sun, 25 Jul 2021 17:42:51 +0000 (13:42 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 25 Jul 2021 22:06:02 +0000 (23:06 +0100)
This patch is to introduce last_rtx_chunks into sctp_transport to detect
if there's any packet retransmission/loss happened by checking against
asoc's rtx_data_chunks in sctp_transport_pl_send().

If there is, namely, transport->last_rtx_chunks != asoc->rtx_data_chunks,
the pmtu probe will be sent out. Otherwise, increment the pl.raise_count
and return when it's in Search Complete state.

With this patch, if in Search Complete state, which is a long period, it
doesn't need to keep probing the current pmtu unless there's data packet
loss. This will save quite some traffic.

v1->v2:
  - add the missing Fixes tag.

Fixes: 0dac127c0557 ("sctp: do black hole detection in search complete state")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sctp/structs.h
net/sctp/transport.c

index f3d414e..651bba6 100644 (file)
@@ -984,6 +984,7 @@ struct sctp_transport {
        } cacc;
 
        struct {
+               __u32 last_rtx_chunks;
                __u16 pmtu;
                __u16 probe_size;
                __u16 probe_high;
index 23e7bd3..a3d3ca6 100644 (file)
@@ -263,6 +263,7 @@ bool sctp_transport_pl_send(struct sctp_transport *t)
        if (t->pl.probe_count < SCTP_MAX_PROBES)
                goto out;
 
+       t->pl.last_rtx_chunks = t->asoc->rtx_data_chunks;
        t->pl.probe_count = 0;
        if (t->pl.state == SCTP_PL_BASE) {
                if (t->pl.probe_size == SCTP_BASE_PLPMTU) { /* BASE_PLPMTU Confirmation Failed */
@@ -298,8 +299,10 @@ bool sctp_transport_pl_send(struct sctp_transport *t)
 
 out:
        if (t->pl.state == SCTP_PL_COMPLETE && t->pl.raise_count < 30 &&
-           !t->pl.probe_count)
+           !t->pl.probe_count && t->pl.last_rtx_chunks == t->asoc->rtx_data_chunks) {
                t->pl.raise_count++;
+               return false;
+       }
 
        pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n",
                 __func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high);
@@ -313,6 +316,7 @@ bool sctp_transport_pl_recv(struct sctp_transport *t)
        pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n",
                 __func__, t, t->pl.state, t->pl.pmtu, t->pl.probe_size, t->pl.probe_high);
 
+       t->pl.last_rtx_chunks = t->asoc->rtx_data_chunks;
        t->pl.pmtu = t->pl.probe_size;
        t->pl.probe_count = 0;
        if (t->pl.state == SCTP_PL_BASE) {