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

Merge branch 'sctp-rfc7829'

Xin Long says:

====================
sctp: update from rfc7829

SCTP-PF was implemented based on a Internet-Draft in 2012:

https://tools.ietf.org/html/draft-nishida-tsvwg-sctp-failover-05

It's been updated quite a few by rfc7829 in 2016.

This patchset adds the following features:

1. add SCTP_ADDR_POTENTIALLY_FAILED notification
2. add pf_expose per netns/sock/asoc
3. add SCTP_EXPOSE_POTENTIALLY_FAILED_STATE sockopt
4. add ps_retrans per netns/sock/asoc/transport
(Primary Path Switchover)
5. add spt_pathcpthld for SCTP_PEER_ADDR_THLDS sockopt

v1->v2:
- See Patch 2/5 and Patch 5/5.
v2->v3:
- See Patch 1/5, 2/5 and 3/5.
v3->v4:
- See Patch 1/5, 2/5, 3/5 and 4/5.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+266 -38
+34
Documentation/networking/ip-sysctl.txt
··· 2091 2091 2092 2092 Default: 1 2093 2093 2094 + pf_expose - INTEGER 2095 + Unset or enable/disable pf (pf is short for potentially failed) state 2096 + exposure. Applications can control the exposure of the PF path state 2097 + in the SCTP_PEER_ADDR_CHANGE event and the SCTP_GET_PEER_ADDR_INFO 2098 + sockopt. When it's unset, no SCTP_PEER_ADDR_CHANGE event with 2099 + SCTP_ADDR_PF state will be sent and a SCTP_PF-state transport info 2100 + can be got via SCTP_GET_PEER_ADDR_INFO sockopt; When it's enabled, 2101 + a SCTP_PEER_ADDR_CHANGE event will be sent for a transport becoming 2102 + SCTP_PF state and a SCTP_PF-state transport info can be got via 2103 + SCTP_GET_PEER_ADDR_INFO sockopt; When it's diabled, no 2104 + SCTP_PEER_ADDR_CHANGE event will be sent and it returns -EACCES when 2105 + trying to get a SCTP_PF-state transport info via SCTP_GET_PEER_ADDR_INFO 2106 + sockopt. 2107 + 2108 + 0: Unset pf state exposure, Compatible with old applications. 2109 + 2110 + 1: Disable pf state exposure. 2111 + 2112 + 2: Enable pf state exposure. 2113 + 2114 + Default: 0 2115 + 2094 2116 addip_noauth_enable - BOOLEAN 2095 2117 Dynamic Address Reconfiguration (ADD-IP) requires the use of 2096 2118 authentication to protect the operations of adding or removing new ··· 2194 2172 disable pf state. 2195 2173 2196 2174 Default: 0 2175 + 2176 + ps_retrans - INTEGER 2177 + Primary.Switchover.Max.Retrans (PSMR), it's a tunable parameter coming 2178 + from section-5 "Primary Path Switchover" in rfc7829. The primary path 2179 + will be changed to another active path when the path error counter on 2180 + the old primary path exceeds PSMR, so that "the SCTP sender is allowed 2181 + to continue data transmission on a new working path even when the old 2182 + primary destination address becomes active again". Note this feature 2183 + is disabled by initializing 'ps_retrans' per netns as 0xffff by default, 2184 + and its value can't be less than 'pf_retrans' when changing by sysctl. 2185 + 2186 + Default: 0xffff 2197 2187 2198 2188 rto_initial - INTEGER 2199 2189 The initial round trip timeout value in milliseconds that will be used
+14
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 95 101 * - >0 : enable pf 96 102 */ 97 103 int pf_enable; 104 + 105 + /* 106 + * Disable Potentially-Failed state exposure, ignored by default 107 + * pf_expose - 0 : compatible with old applications (by default) 108 + * - 1 : disable pf state exposure 109 + * - 2 : enable pf state exposure 110 + */ 111 + int pf_expose; 98 112 99 113 /* 100 114 * Policy for preforming sctp/socket accounting
+12
include/net/sctp/constants.h
··· 286 286 * functions simpler to write. 287 287 */ 288 288 289 + /* These are the values for pf exposure, UNUSED is to keep compatible with old 290 + * applications by default. 291 + */ 292 + enum { 293 + SCTP_PF_EXPOSE_UNSET, 294 + SCTP_PF_EXPOSE_DISABLE, 295 + SCTP_PF_EXPOSE_ENABLE, 296 + }; 297 + #define SCTP_PF_EXPOSE_MAX SCTP_PF_EXPOSE_ENABLE 298 + 299 + #define SCTP_PS_RETRANS_MAX 0xffff 300 + 289 301 /* These return values describe the success or failure of a number of 290 302 * routines which form the lower interface to SCTP_outqueue. 291 303 */
+10 -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; ··· 216 215 __u32 adaptation_ind; 217 216 __u32 pd_point; 218 217 __u16 nodelay:1, 218 + pf_expose:2, 219 219 reuse:1, 220 220 disable_fragments:1, 221 221 v4mapped:1, ··· 898 896 * and will be initialized from the assocs value. This can be changed 899 897 * using the SCTP_PEER_ADDR_THLDS socket option 900 898 */ 901 - int pf_retrans; 899 + __u16 pf_retrans; 900 + /* Used for primary path switchover. */ 901 + __u16 ps_retrans; 902 902 /* PMTU : The current known path MTU. */ 903 903 __u32 pathmtu; 904 904 ··· 1776 1772 * and will be initialized from the assocs value. This can be 1777 1773 * changed using the SCTP_PEER_ADDR_THLDS socket option 1778 1774 */ 1779 - int pf_retrans; 1775 + __u16 pf_retrans; 1776 + /* Used for primary path switchover. */ 1777 + __u16 ps_retrans; 1780 1778 1781 1779 /* Maximum number of times the endpoint will retransmit INIT */ 1782 1780 __u16 max_init_attempts; ··· 2059 2053 2060 2054 __u8 need_ecne:1, /* Need to send an ECNE Chunk? */ 2061 2055 temp:1, /* Is it a temporary association? */ 2056 + pf_expose:2, /* Expose pf state? */ 2062 2057 force_delay:1; 2063 2058 2064 2059 __u8 strreset_enable;
+15
include/uapi/linux/sctp.h
··· 105 105 #define SCTP_DEFAULT_SNDINFO 34 106 106 #define SCTP_AUTH_DEACTIVATE_KEY 35 107 107 #define SCTP_REUSE_PORT 36 108 + #define SCTP_PEER_ADDR_THLDS_V2 37 108 109 109 110 /* Internal Socket Options. Some of the sctp library functions are 110 111 * implemented using these socket options. ··· 138 137 #define SCTP_ASCONF_SUPPORTED 128 139 138 #define SCTP_AUTH_SUPPORTED 129 140 139 #define SCTP_ECN_SUPPORTED 130 140 + #define SCTP_EXPOSE_POTENTIALLY_FAILED_STATE 131 141 + #define SCTP_EXPOSE_PF_STATE SCTP_EXPOSE_POTENTIALLY_FAILED_STATE 141 142 142 143 /* PR-SCTP policies */ 143 144 #define SCTP_PR_SCTP_NONE 0x0000 ··· 413 410 SCTP_ADDR_ADDED, 414 411 SCTP_ADDR_MADE_PRIM, 415 412 SCTP_ADDR_CONFIRMED, 413 + SCTP_ADDR_POTENTIALLY_FAILED, 414 + #define SCTP_ADDR_PF SCTP_ADDR_POTENTIALLY_FAILED 416 415 }; 417 416 418 417 ··· 938 933 enum sctp_spinfo_state { 939 934 SCTP_INACTIVE, 940 935 SCTP_PF, 936 + #define SCTP_POTENTIALLY_FAILED SCTP_PF 941 937 SCTP_ACTIVE, 942 938 SCTP_UNCONFIRMED, 943 939 SCTP_UNKNOWN = 0xffff /* Value used for transport state unknown */ ··· 1086 1080 struct sockaddr_storage spt_address; 1087 1081 __u16 spt_pathmaxrxt; 1088 1082 __u16 spt_pathpfthld; 1083 + }; 1084 + 1085 + /* Use a new structure with spt_pathcpthld for back compatibility */ 1086 + struct sctp_paddrthlds_v2 { 1087 + sctp_assoc_t spt_assoc_id; 1088 + struct sockaddr_storage spt_address; 1089 + __u16 spt_pathmaxrxt; 1090 + __u16 spt_pathpfthld; 1091 + __u16 spt_pathcpthld; 1089 1092 }; 1090 1093 1091 1094 /*
+18 -18
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; 90 + asoc->pf_expose = sp->pf_expose; 89 91 90 92 asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial); 91 93 asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max); ··· 629 627 630 628 /* And the partial failure retrans threshold */ 631 629 peer->pf_retrans = asoc->pf_retrans; 630 + /* And the primary path switchover retrans threshold */ 631 + peer->ps_retrans = asoc->ps_retrans; 632 632 633 633 /* Initialize the peer's SACK delay timeout based on the 634 634 * association configured value. ··· 790 786 enum sctp_transport_cmd command, 791 787 sctp_sn_error_t error) 792 788 { 789 + int spc_state = SCTP_ADDR_AVAILABLE; 793 790 bool ulp_notify = true; 794 - int spc_state = 0; 795 791 796 792 /* Record the transition on the transport. */ 797 793 switch (command) { ··· 800 796 * to heartbeat success, report the SCTP_ADDR_CONFIRMED 801 797 * state to the user, otherwise report SCTP_ADDR_AVAILABLE. 802 798 */ 803 - if (SCTP_UNCONFIRMED == transport->state && 804 - SCTP_HEARTBEAT_SUCCESS == error) 805 - spc_state = SCTP_ADDR_CONFIRMED; 806 - else 807 - spc_state = SCTP_ADDR_AVAILABLE; 808 - /* Don't inform ULP about transition from PF to 809 - * active state and set cwnd to 1 MTU, see SCTP 810 - * Quick failover draft section 5.1, point 5 811 - */ 812 - if (transport->state == SCTP_PF) { 799 + if (transport->state == SCTP_PF && 800 + asoc->pf_expose != SCTP_PF_EXPOSE_ENABLE) 813 801 ulp_notify = false; 814 - transport->cwnd = asoc->pathmtu; 815 - } 802 + else if (transport->state == SCTP_UNCONFIRMED && 803 + error == SCTP_HEARTBEAT_SUCCESS) 804 + spc_state = SCTP_ADDR_CONFIRMED; 805 + 816 806 transport->state = SCTP_ACTIVE; 817 807 break; 818 808 ··· 815 817 * to inactive state. Also, release the cached route since 816 818 * there may be a better route next time. 817 819 */ 818 - if (transport->state != SCTP_UNCONFIRMED) 820 + if (transport->state != SCTP_UNCONFIRMED) { 819 821 transport->state = SCTP_INACTIVE; 820 - else { 822 + spc_state = SCTP_ADDR_UNREACHABLE; 823 + } else { 821 824 sctp_transport_dst_release(transport); 822 825 ulp_notify = false; 823 826 } 824 - 825 - spc_state = SCTP_ADDR_UNREACHABLE; 826 827 break; 827 828 828 829 case SCTP_TRANSPORT_PF: 829 830 transport->state = SCTP_PF; 830 - ulp_notify = false; 831 + if (asoc->pf_expose != SCTP_PF_EXPOSE_ENABLE) 832 + ulp_notify = false; 833 + else 834 + spc_state = SCTP_ADDR_POTENTIALLY_FAILED; 831 835 break; 832 836 833 837 default:
+6
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; 1225 + 1226 + /* Ignore pf exposure feature by default */ 1227 + net->sctp.pf_expose = SCTP_PF_EXPOSE_UNSET; 1222 1228 1223 1229 /* Association.Max.Retrans - 10 attempts 1224 1230 * Path.Max.Retrans - 5 attempts (per destination address)
+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
+131 -16
net/sctp/socket.c
··· 3943 3943 */ 3944 3944 static int sctp_setsockopt_paddr_thresholds(struct sock *sk, 3945 3945 char __user *optval, 3946 - unsigned int optlen) 3946 + unsigned int optlen, bool v2) 3947 3947 { 3948 - struct sctp_paddrthlds val; 3948 + struct sctp_paddrthlds_v2 val; 3949 3949 struct sctp_transport *trans; 3950 3950 struct sctp_association *asoc; 3951 + int len; 3951 3952 3952 - if (optlen < sizeof(struct sctp_paddrthlds)) 3953 + len = v2 ? sizeof(val) : sizeof(struct sctp_paddrthlds); 3954 + if (optlen < len) 3953 3955 return -EINVAL; 3954 - if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, 3955 - sizeof(struct sctp_paddrthlds))) 3956 + if (copy_from_user(&val, optval, len)) 3956 3957 return -EFAULT; 3958 + 3959 + if (v2 && val.spt_pathpfthld > val.spt_pathcpthld) 3960 + return -EINVAL; 3957 3961 3958 3962 if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) { 3959 3963 trans = sctp_addr_id2transport(sk, &val.spt_address, ··· 3967 3963 3968 3964 if (val.spt_pathmaxrxt) 3969 3965 trans->pathmaxrxt = val.spt_pathmaxrxt; 3966 + if (v2) 3967 + trans->ps_retrans = val.spt_pathcpthld; 3970 3968 trans->pf_retrans = val.spt_pathpfthld; 3971 3969 3972 3970 return 0; ··· 3984 3978 transports) { 3985 3979 if (val.spt_pathmaxrxt) 3986 3980 trans->pathmaxrxt = val.spt_pathmaxrxt; 3981 + if (v2) 3982 + trans->ps_retrans = val.spt_pathcpthld; 3987 3983 trans->pf_retrans = val.spt_pathpfthld; 3988 3984 } 3989 3985 3990 3986 if (val.spt_pathmaxrxt) 3991 3987 asoc->pathmaxrxt = val.spt_pathmaxrxt; 3988 + if (v2) 3989 + asoc->ps_retrans = val.spt_pathcpthld; 3992 3990 asoc->pf_retrans = val.spt_pathpfthld; 3993 3991 } else { 3994 3992 struct sctp_sock *sp = sctp_sk(sk); 3995 3993 3996 3994 if (val.spt_pathmaxrxt) 3997 3995 sp->pathmaxrxt = val.spt_pathmaxrxt; 3996 + if (v2) 3997 + sp->ps_retrans = val.spt_pathcpthld; 3998 3998 sp->pf_retrans = val.spt_pathpfthld; 3999 3999 } 4000 4000 ··· 4601 4589 return retval; 4602 4590 } 4603 4591 4592 + static int sctp_setsockopt_pf_expose(struct sock *sk, 4593 + char __user *optval, 4594 + unsigned int optlen) 4595 + { 4596 + struct sctp_assoc_value params; 4597 + struct sctp_association *asoc; 4598 + int retval = -EINVAL; 4599 + 4600 + if (optlen != sizeof(params)) 4601 + goto out; 4602 + 4603 + if (copy_from_user(&params, optval, optlen)) { 4604 + retval = -EFAULT; 4605 + goto out; 4606 + } 4607 + 4608 + if (params.assoc_value > SCTP_PF_EXPOSE_MAX) 4609 + goto out; 4610 + 4611 + asoc = sctp_id2assoc(sk, params.assoc_id); 4612 + if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC && 4613 + sctp_style(sk, UDP)) 4614 + goto out; 4615 + 4616 + if (asoc) 4617 + asoc->pf_expose = params.assoc_value; 4618 + else 4619 + sctp_sk(sk)->pf_expose = params.assoc_value; 4620 + retval = 0; 4621 + 4622 + out: 4623 + return retval; 4624 + } 4625 + 4604 4626 /* API 6.2 setsockopt(), getsockopt() 4605 4627 * 4606 4628 * Applications use setsockopt() and getsockopt() to set or retrieve ··· 4790 4744 retval = sctp_setsockopt_auto_asconf(sk, optval, optlen); 4791 4745 break; 4792 4746 case SCTP_PEER_ADDR_THLDS: 4793 - retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen); 4747 + retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen, 4748 + false); 4749 + break; 4750 + case SCTP_PEER_ADDR_THLDS_V2: 4751 + retval = sctp_setsockopt_paddr_thresholds(sk, optval, optlen, 4752 + true); 4794 4753 break; 4795 4754 case SCTP_RECVRCVINFO: 4796 4755 retval = sctp_setsockopt_recvrcvinfo(sk, optval, optlen); ··· 4848 4797 break; 4849 4798 case SCTP_ECN_SUPPORTED: 4850 4799 retval = sctp_setsockopt_ecn_supported(sk, optval, optlen); 4800 + break; 4801 + case SCTP_EXPOSE_POTENTIALLY_FAILED_STATE: 4802 + retval = sctp_setsockopt_pf_expose(sk, optval, optlen); 4851 4803 break; 4852 4804 default: 4853 4805 retval = -ENOPROTOOPT; ··· 5095 5041 sp->hbinterval = net->sctp.hb_interval; 5096 5042 sp->pathmaxrxt = net->sctp.max_retrans_path; 5097 5043 sp->pf_retrans = net->sctp.pf_retrans; 5044 + sp->ps_retrans = net->sctp.ps_retrans; 5045 + sp->pf_expose = net->sctp.pf_expose; 5098 5046 sp->pathmtu = 0; /* allow default discovery */ 5099 5047 sp->sackdelay = net->sctp.sack_timeout; 5100 5048 sp->sackfreq = 2; ··· 5577 5521 5578 5522 transport = sctp_addr_id2transport(sk, &pinfo.spinfo_address, 5579 5523 pinfo.spinfo_assoc_id); 5580 - if (!transport) 5581 - return -EINVAL; 5524 + if (!transport) { 5525 + retval = -EINVAL; 5526 + goto out; 5527 + } 5528 + 5529 + if (transport->state == SCTP_PF && 5530 + transport->asoc->pf_expose == SCTP_PF_EXPOSE_DISABLE) { 5531 + retval = -EACCES; 5532 + goto out; 5533 + } 5582 5534 5583 5535 pinfo.spinfo_assoc_id = sctp_assoc2id(transport->asoc); 5584 5536 pinfo.spinfo_state = transport->state; ··· 7234 7170 * http://www.ietf.org/id/draft-nishida-tsvwg-sctp-failover-05.txt 7235 7171 */ 7236 7172 static int sctp_getsockopt_paddr_thresholds(struct sock *sk, 7237 - char __user *optval, 7238 - int len, 7239 - int __user *optlen) 7173 + char __user *optval, int len, 7174 + int __user *optlen, bool v2) 7240 7175 { 7241 - struct sctp_paddrthlds val; 7176 + struct sctp_paddrthlds_v2 val; 7242 7177 struct sctp_transport *trans; 7243 7178 struct sctp_association *asoc; 7179 + int min; 7244 7180 7245 - if (len < sizeof(struct sctp_paddrthlds)) 7181 + min = v2 ? sizeof(val) : sizeof(struct sctp_paddrthlds); 7182 + if (len < min) 7246 7183 return -EINVAL; 7247 - len = sizeof(struct sctp_paddrthlds); 7248 - if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len)) 7184 + len = min; 7185 + if (copy_from_user(&val, optval, len)) 7249 7186 return -EFAULT; 7250 7187 7251 7188 if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) { ··· 7257 7192 7258 7193 val.spt_pathmaxrxt = trans->pathmaxrxt; 7259 7194 val.spt_pathpfthld = trans->pf_retrans; 7195 + val.spt_pathcpthld = trans->ps_retrans; 7260 7196 7261 7197 goto out; 7262 7198 } ··· 7270 7204 if (asoc) { 7271 7205 val.spt_pathpfthld = asoc->pf_retrans; 7272 7206 val.spt_pathmaxrxt = asoc->pathmaxrxt; 7207 + val.spt_pathcpthld = asoc->ps_retrans; 7273 7208 } else { 7274 7209 struct sctp_sock *sp = sctp_sk(sk); 7275 7210 7276 7211 val.spt_pathpfthld = sp->pf_retrans; 7277 7212 val.spt_pathmaxrxt = sp->pathmaxrxt; 7213 + val.spt_pathcpthld = sp->ps_retrans; 7278 7214 } 7279 7215 7280 7216 out: ··· 7968 7900 return retval; 7969 7901 } 7970 7902 7903 + static int sctp_getsockopt_pf_expose(struct sock *sk, int len, 7904 + char __user *optval, 7905 + int __user *optlen) 7906 + { 7907 + struct sctp_assoc_value params; 7908 + struct sctp_association *asoc; 7909 + int retval = -EFAULT; 7910 + 7911 + if (len < sizeof(params)) { 7912 + retval = -EINVAL; 7913 + goto out; 7914 + } 7915 + 7916 + len = sizeof(params); 7917 + if (copy_from_user(&params, optval, len)) 7918 + goto out; 7919 + 7920 + asoc = sctp_id2assoc(sk, params.assoc_id); 7921 + if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC && 7922 + sctp_style(sk, UDP)) { 7923 + retval = -EINVAL; 7924 + goto out; 7925 + } 7926 + 7927 + params.assoc_value = asoc ? asoc->pf_expose 7928 + : sctp_sk(sk)->pf_expose; 7929 + 7930 + if (put_user(len, optlen)) 7931 + goto out; 7932 + 7933 + if (copy_to_user(optval, &params, len)) 7934 + goto out; 7935 + 7936 + retval = 0; 7937 + 7938 + out: 7939 + return retval; 7940 + } 7941 + 7971 7942 static int sctp_getsockopt(struct sock *sk, int level, int optname, 7972 7943 char __user *optval, int __user *optlen) 7973 7944 { ··· 8156 8049 retval = sctp_getsockopt_auto_asconf(sk, len, optval, optlen); 8157 8050 break; 8158 8051 case SCTP_PEER_ADDR_THLDS: 8159 - retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, optlen); 8052 + retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, 8053 + optlen, false); 8054 + break; 8055 + case SCTP_PEER_ADDR_THLDS_V2: 8056 + retval = sctp_getsockopt_paddr_thresholds(sk, optval, len, 8057 + optlen, true); 8160 8058 break; 8161 8059 case SCTP_GET_ASSOC_STATS: 8162 8060 retval = sctp_getsockopt_assoc_stats(sk, len, optval, optlen); ··· 8223 8111 break; 8224 8112 case SCTP_ECN_SUPPORTED: 8225 8113 retval = sctp_getsockopt_ecn_supported(sk, len, optval, optlen); 8114 + break; 8115 + case SCTP_EXPOSE_POTENTIALLY_FAILED_STATE: 8116 + retval = sctp_getsockopt_pf_expose(sk, len, optval, optlen); 8226 8117 break; 8227 8118 default: 8228 8119 retval = -ENOPROTOOPT;
+21 -1
net/sctp/sysctl.c
··· 34 34 static int rto_beta_min = 0; 35 35 static int rto_alpha_max = 1000; 36 36 static int rto_beta_max = 1000; 37 + static int pf_expose_max = SCTP_PF_EXPOSE_MAX; 38 + static int ps_retrans_max = SCTP_PS_RETRANS_MAX; 37 39 38 40 static unsigned long max_autoclose_min = 0; 39 41 static unsigned long max_autoclose_max = ··· 214 212 .mode = 0644, 215 213 .proc_handler = proc_dointvec_minmax, 216 214 .extra1 = SYSCTL_ZERO, 217 - .extra2 = SYSCTL_INT_MAX, 215 + .extra2 = &init_net.sctp.ps_retrans, 216 + }, 217 + { 218 + .procname = "ps_retrans", 219 + .data = &init_net.sctp.ps_retrans, 220 + .maxlen = sizeof(int), 221 + .mode = 0644, 222 + .proc_handler = proc_dointvec_minmax, 223 + .extra1 = &init_net.sctp.pf_retrans, 224 + .extra2 = &ps_retrans_max, 218 225 }, 219 226 { 220 227 .procname = "sndbuf_policy", ··· 328 317 .maxlen = sizeof(int), 329 318 .mode = 0644, 330 319 .proc_handler = proc_dointvec, 320 + }, 321 + { 322 + .procname = "pf_expose", 323 + .data = &init_net.sctp.pf_expose, 324 + .maxlen = sizeof(int), 325 + .mode = 0644, 326 + .proc_handler = proc_dointvec_minmax, 327 + .extra1 = SYSCTL_ZERO, 328 + .extra2 = &pf_expose_max, 331 329 }, 332 330 333 331 { /* sentinel */ }