sctp: send pmtu probe only if packet loss in Search Complete state

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: 0dac127c05 ("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>
This commit is contained in:
Xin Long 2021-07-25 13:42:51 -04:00 committed by David S. Miller
parent 058e6e0ed0
commit eacf078cf4
2 changed files with 6 additions and 1 deletions

View File

@ -984,6 +984,7 @@ struct sctp_transport {
} cacc; } cacc;
struct { struct {
__u32 last_rtx_chunks;
__u16 pmtu; __u16 pmtu;
__u16 probe_size; __u16 probe_size;
__u16 probe_high; __u16 probe_high;

View File

@ -263,6 +263,7 @@ bool sctp_transport_pl_send(struct sctp_transport *t)
if (t->pl.probe_count < SCTP_MAX_PROBES) if (t->pl.probe_count < SCTP_MAX_PROBES)
goto out; goto out;
t->pl.last_rtx_chunks = t->asoc->rtx_data_chunks;
t->pl.probe_count = 0; t->pl.probe_count = 0;
if (t->pl.state == SCTP_PL_BASE) { if (t->pl.state == SCTP_PL_BASE) {
if (t->pl.probe_size == SCTP_BASE_PLPMTU) { /* BASE_PLPMTU Confirmation Failed */ 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: out:
if (t->pl.state == SCTP_PL_COMPLETE && t->pl.raise_count < 30 && 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++; t->pl.raise_count++;
return false;
}
pr_debug("%s: PLPMTUD: transport: %p, state: %d, pmtu: %d, size: %d, high: %d\n", 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); __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", 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); __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.pmtu = t->pl.probe_size;
t->pl.probe_count = 0; t->pl.probe_count = 0;
if (t->pl.state == SCTP_PL_BASE) { if (t->pl.state == SCTP_PL_BASE) {