Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sctp: add support for Primary Path Switchover

This is a new feature defined in section 5 of rfc7829: "Primary Path
Switchover". By introducing a new tunable parameter:

Primary.Switchover.Max.Retrans (PSMR)

The primary path will be changed to another active path when the path
error counter on the old primary path exceeds PSMR, so that "the SCTP
sender is allowed to continue data transmission on a new working path
even when the old primary destination address becomes active again".

This patch is to add this tunable parameter, 'ps_retrans' per netns,
sock, asoc and transport. It also allows a user to change ps_retrans
per netns by sysctl, and ps_retrans per sock/asoc/transport will be
initialized with it.

The check will be done in sctp_do_8_2_transport_strike() when this
feature is enabled.

Note this feature is disabled by initializing 'ps_retrans' per netns
as 0xffff by default, and its value can't be less than 'pf_retrans'
when changing by sysctl.

v3->v4:
- add define SCTP_PS_RETRANS_MAX 0xffff, and use it on extra2 of
sysctl 'ps_retrans'.
- add a new entry for ps_retrans on ip-sysctl.txt.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xin Long and committed by
David S. Miller
34515e94 8d2a6935

+51 -4
+12
Documentation/networking/ip-sysctl.txt
··· 2195 2195 2196 2196 Default: 0 2197 2197 2198 + ps_retrans - INTEGER 2199 + Primary.Switchover.Max.Retrans (PSMR), it's a tunable parameter coming 2200 + from section-5 "Primary Path Switchover" in rfc7829. The primary path 2201 + will be changed to another active path when the path error counter on 2202 + the old primary path exceeds PSMR, so that "the SCTP sender is allowed 2203 + to continue data transmission on a new working path even when the old 2204 + primary destination address becomes active again". Note this feature 2205 + is disabled by initializing 'ps_retrans' per netns as 0xffff by default, 2206 + and its value can't be less than 'pf_retrans' when changing by sysctl. 2207 + 2208 + Default: 0xffff 2209 + 2198 2210 rto_initial - INTEGER 2199 2211 The initial round trip timeout value in milliseconds that will be used 2200 2212 in calculating round trip times. This is the initial time interval
+6
include/net/netns/sctp.h
··· 89 89 */ 90 90 int pf_retrans; 91 91 92 + /* Primary.Switchover.Max.Retrans sysctl value 93 + * taken from: 94 + * https://tools.ietf.org/html/rfc7829 95 + */ 96 + int ps_retrans; 97 + 92 98 /* 93 99 * Disable Potentially-Failed feature, the feature is enabled by default 94 100 * pf_enable - 0 : disable pf
+2
include/net/sctp/constants.h
··· 296 296 }; 297 297 #define SCTP_PF_EXPOSE_MAX SCTP_PF_EXPOSE_ENABLE 298 298 299 + #define SCTP_PS_RETRANS_MAX 0xffff 300 + 299 301 /* These return values describe the success or failure of a number of 300 302 * routines which form the lower interface to SCTP_outqueue. 301 303 */
+8 -3
include/net/sctp/structs.h
··· 184 184 __u32 flowlabel; 185 185 __u8 dscp; 186 186 187 - int pf_retrans; 187 + __u16 pf_retrans; 188 + __u16 ps_retrans; 188 189 189 190 /* The initial Path MTU to use for new associations. */ 190 191 __u32 pathmtu; ··· 898 897 * and will be initialized from the assocs value. This can be changed 899 898 * using the SCTP_PEER_ADDR_THLDS socket option 900 899 */ 901 - int pf_retrans; 900 + __u16 pf_retrans; 901 + /* Used for primary path switchover. */ 902 + __u16 ps_retrans; 902 903 /* PMTU : The current known path MTU. */ 903 904 __u32 pathmtu; 904 905 ··· 1776 1773 * and will be initialized from the assocs value. This can be 1777 1774 * changed using the SCTP_PEER_ADDR_THLDS socket option 1778 1775 */ 1779 - int pf_retrans; 1776 + __u16 pf_retrans; 1777 + /* Used for primary path switchover. */ 1778 + __u16 ps_retrans; 1780 1779 1781 1780 /* Maximum number of times the endpoint will retransmit INIT */ 1782 1781 __u16 max_init_attempts;
+3
net/sctp/associola.c
··· 86 86 */ 87 87 asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt; 88 88 asoc->pf_retrans = sp->pf_retrans; 89 + asoc->ps_retrans = sp->ps_retrans; 89 90 asoc->pf_expose = sp->pf_expose; 90 91 91 92 asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial); ··· 629 628 630 629 /* And the partial failure retrans threshold */ 631 630 peer->pf_retrans = asoc->pf_retrans; 631 + /* And the primary path switchover retrans threshold */ 632 + peer->ps_retrans = asoc->ps_retrans; 632 633 633 634 /* Initialize the peer's SACK delay timeout based on the 634 635 * association configured value.
+3
net/sctp/protocol.c
··· 1217 1217 /* Max.Burst - 4 */ 1218 1218 net->sctp.max_burst = SCTP_DEFAULT_MAX_BURST; 1219 1219 1220 + /* Disable of Primary Path Switchover by default */ 1221 + net->sctp.ps_retrans = SCTP_PS_RETRANS_MAX; 1222 + 1220 1223 /* Enable pf state by default */ 1221 1224 net->sctp.pf_enable = 1; 1222 1225
+5
net/sctp/sm_sideeffect.c
··· 567 567 SCTP_FAILED_THRESHOLD); 568 568 } 569 569 570 + if (transport->error_count > transport->ps_retrans && 571 + asoc->peer.primary_path == transport && 572 + asoc->peer.active_path != transport) 573 + sctp_assoc_set_primary(asoc, asoc->peer.active_path); 574 + 570 575 /* E2) For the destination address for which the timer 571 576 * expires, set RTO <- RTO * 2 ("back off the timer"). The 572 577 * maximum value discussed in rule C7 above (RTO.max) may be
+1
net/sctp/socket.c
··· 5078 5078 sp->hbinterval = net->sctp.hb_interval; 5079 5079 sp->pathmaxrxt = net->sctp.max_retrans_path; 5080 5080 sp->pf_retrans = net->sctp.pf_retrans; 5081 + sp->ps_retrans = net->sctp.ps_retrans; 5081 5082 sp->pf_expose = net->sctp.pf_expose; 5082 5083 sp->pathmtu = 0; /* allow default discovery */ 5083 5084 sp->sackdelay = net->sctp.sack_timeout;
+11 -1
net/sctp/sysctl.c
··· 35 35 static int rto_alpha_max = 1000; 36 36 static int rto_beta_max = 1000; 37 37 static int pf_expose_max = SCTP_PF_EXPOSE_MAX; 38 + static int ps_retrans_max = SCTP_PS_RETRANS_MAX; 38 39 39 40 static unsigned long max_autoclose_min = 0; 40 41 static unsigned long max_autoclose_max = ··· 214 213 .mode = 0644, 215 214 .proc_handler = proc_dointvec_minmax, 216 215 .extra1 = SYSCTL_ZERO, 217 - .extra2 = SYSCTL_INT_MAX, 216 + .extra2 = &init_net.sctp.ps_retrans, 217 + }, 218 + { 219 + .procname = "ps_retrans", 220 + .data = &init_net.sctp.ps_retrans, 221 + .maxlen = sizeof(int), 222 + .mode = 0644, 223 + .proc_handler = proc_dointvec_minmax, 224 + .extra1 = &init_net.sctp.pf_retrans, 225 + .extra2 = &ps_retrans_max, 218 226 }, 219 227 { 220 228 .procname = "sndbuf_policy",