Commit 0dac127c authored by Xin Long's avatar Xin Long Committed by David S. Miller

sctp: do black hole detection in search complete state

Currently the PLPMUTD probe will stop for a long period (interval * 30)
after it enters search complete state. If there's a pmtu change on the
route path, it takes a long time to be aware if the ICMP TooBig packet
is lost or filtered.

As it says in rfc8899#section-4.3:

  "A DPLPMTUD method MUST NOT rely solely on this method."
  (ICMP PTB message).

This patch is to enable the other method for search complete state:

  "A PL can use the DPLPMTUD probing mechanism to periodically
   generate probe packets of the size of the current PLPMTU."

With this patch, the probe will continue with the current pmtu every
'interval' until the PMTU_RAISE_TIMER 'timeout', which we implement
by adding raise_count to raise the probe size when it counts to 30
and removing the SCTP_PL_COMPLETE check for PMTU_RAISE_TIMER.
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 98ebad48
...@@ -987,7 +987,8 @@ struct sctp_transport { ...@@ -987,7 +987,8 @@ struct sctp_transport {
__u16 pmtu; __u16 pmtu;
__u16 probe_size; __u16 probe_size;
__u16 probe_high; __u16 probe_high;
__u8 probe_count; __u8 probe_count:3;
__u8 raise_count:5;
__u8 state; __u8 state;
} pl; /* plpmtud related */ } pl; /* plpmtud related */
......
...@@ -213,15 +213,10 @@ void sctp_transport_reset_reconf_timer(struct sctp_transport *transport) ...@@ -213,15 +213,10 @@ void sctp_transport_reset_reconf_timer(struct sctp_transport *transport)
void sctp_transport_reset_probe_timer(struct sctp_transport *transport) void sctp_transport_reset_probe_timer(struct sctp_transport *transport)
{ {
int scale = 1;
if (timer_pending(&transport->probe_timer)) if (timer_pending(&transport->probe_timer))
return; return;
if (transport->pl.state == SCTP_PL_COMPLETE &&
transport->pl.probe_count == 1)
scale = 30; /* works as PMTU_RAISE_TIMER */
if (!mod_timer(&transport->probe_timer, if (!mod_timer(&transport->probe_timer,
jiffies + transport->probe_interval * scale)) jiffies + transport->probe_interval))
sctp_transport_hold(transport); sctp_transport_hold(transport);
} }
...@@ -333,13 +328,15 @@ void sctp_transport_pl_recv(struct sctp_transport *t) ...@@ -333,13 +328,15 @@ void sctp_transport_pl_recv(struct sctp_transport *t)
t->pl.probe_size += SCTP_PL_MIN_STEP; t->pl.probe_size += SCTP_PL_MIN_STEP;
if (t->pl.probe_size >= t->pl.probe_high) { if (t->pl.probe_size >= t->pl.probe_high) {
t->pl.probe_high = 0; t->pl.probe_high = 0;
t->pl.raise_count = 0;
t->pl.state = SCTP_PL_COMPLETE; /* Search -> Search Complete */ t->pl.state = SCTP_PL_COMPLETE; /* Search -> Search Complete */
t->pl.probe_size = t->pl.pmtu; t->pl.probe_size = t->pl.pmtu;
t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t); t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
sctp_assoc_sync_pmtu(t->asoc); sctp_assoc_sync_pmtu(t->asoc);
} }
} else if (t->pl.state == SCTP_PL_COMPLETE) { } else if (t->pl.state == SCTP_PL_COMPLETE && ++t->pl.raise_count == 30) {
/* Raise probe_size again after 30 * interval in Search Complete */
t->pl.state = SCTP_PL_SEARCH; /* Search Complete -> Search */ t->pl.state = SCTP_PL_SEARCH; /* Search Complete -> Search */
t->pl.probe_size += SCTP_PL_MIN_STEP; t->pl.probe_size += SCTP_PL_MIN_STEP;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment