summaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2019-01-28 02:08:29 -0500
committerDavid S. Miller <davem@davemloft.net>2019-01-30 03:44:06 -0500
commit8add543e369d67ccd42f7e67d68866b4d606f632 (patch)
tree5be0430f4ac1b07c34de4204237ce61b2ef35412 /net/sctp/socket.c
parent48c072174dea73c4c36ba95df87c1b4d6083df11 (diff)
sctp: add SCTP_FUTURE_ASSOC for SCTP_PEER_ADDR_THLDS sockopt
Check with SCTP_FUTURE_ASSOC instead in sctp_set/getsockopt_paddr_thresholds, it's compatible with 0. It also adds pf_retrans in sctp_sock to support SCTP_FUTURE_ASSOC. Signed-off-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c58
1 files changed, 40 insertions, 18 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 7df2123ae64c..1d49b7dfcba2 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3888,11 +3888,25 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
3888 sizeof(struct sctp_paddrthlds))) 3888 sizeof(struct sctp_paddrthlds)))
3889 return -EFAULT; 3889 return -EFAULT;
3890 3890
3891 3891 if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
3892 if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) { 3892 trans = sctp_addr_id2transport(sk, &val.spt_address,
3893 asoc = sctp_id2assoc(sk, val.spt_assoc_id); 3893 val.spt_assoc_id);
3894 if (!asoc) 3894 if (!trans)
3895 return -ENOENT; 3895 return -ENOENT;
3896
3897 if (val.spt_pathmaxrxt)
3898 trans->pathmaxrxt = val.spt_pathmaxrxt;
3899 trans->pf_retrans = val.spt_pathpfthld;
3900
3901 return 0;
3902 }
3903
3904 asoc = sctp_id2assoc(sk, val.spt_assoc_id);
3905 if (!asoc && val.spt_assoc_id != SCTP_FUTURE_ASSOC &&
3906 sctp_style(sk, UDP))
3907 return -EINVAL;
3908
3909 if (asoc) {
3896 list_for_each_entry(trans, &asoc->peer.transport_addr_list, 3910 list_for_each_entry(trans, &asoc->peer.transport_addr_list,
3897 transports) { 3911 transports) {
3898 if (val.spt_pathmaxrxt) 3912 if (val.spt_pathmaxrxt)
@@ -3904,14 +3918,11 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
3904 asoc->pathmaxrxt = val.spt_pathmaxrxt; 3918 asoc->pathmaxrxt = val.spt_pathmaxrxt;
3905 asoc->pf_retrans = val.spt_pathpfthld; 3919 asoc->pf_retrans = val.spt_pathpfthld;
3906 } else { 3920 } else {
3907 trans = sctp_addr_id2transport(sk, &val.spt_address, 3921 struct sctp_sock *sp = sctp_sk(sk);
3908 val.spt_assoc_id);
3909 if (!trans)
3910 return -ENOENT;
3911 3922
3912 if (val.spt_pathmaxrxt) 3923 if (val.spt_pathmaxrxt)
3913 trans->pathmaxrxt = val.spt_pathmaxrxt; 3924 sp->pathmaxrxt = val.spt_pathmaxrxt;
3914 trans->pf_retrans = val.spt_pathpfthld; 3925 sp->pf_retrans = val.spt_pathpfthld;
3915 } 3926 }
3916 3927
3917 return 0; 3928 return 0;
@@ -4781,6 +4792,7 @@ static int sctp_init_sock(struct sock *sk)
4781 */ 4792 */
4782 sp->hbinterval = net->sctp.hb_interval; 4793 sp->hbinterval = net->sctp.hb_interval;
4783 sp->pathmaxrxt = net->sctp.max_retrans_path; 4794 sp->pathmaxrxt = net->sctp.max_retrans_path;
4795 sp->pf_retrans = net->sctp.pf_retrans;
4784 sp->pathmtu = 0; /* allow default discovery */ 4796 sp->pathmtu = 0; /* allow default discovery */
4785 sp->sackdelay = net->sctp.sack_timeout; 4797 sp->sackdelay = net->sctp.sack_timeout;
4786 sp->sackfreq = 2; 4798 sp->sackfreq = 2;
@@ -6917,14 +6929,7 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
6917 if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len)) 6929 if (copy_from_user(&val, (struct sctp_paddrthlds __user *)optval, len))
6918 return -EFAULT; 6930 return -EFAULT;
6919 6931
6920 if (sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) { 6932 if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
6921 asoc = sctp_id2assoc(sk, val.spt_assoc_id);
6922 if (!asoc)
6923 return -ENOENT;
6924
6925 val.spt_pathpfthld = asoc->pf_retrans;
6926 val.spt_pathmaxrxt = asoc->pathmaxrxt;
6927 } else {
6928 trans = sctp_addr_id2transport(sk, &val.spt_address, 6933 trans = sctp_addr_id2transport(sk, &val.spt_address,
6929 val.spt_assoc_id); 6934 val.spt_assoc_id);
6930 if (!trans) 6935 if (!trans)
@@ -6932,6 +6937,23 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
6932 6937
6933 val.spt_pathmaxrxt = trans->pathmaxrxt; 6938 val.spt_pathmaxrxt = trans->pathmaxrxt;
6934 val.spt_pathpfthld = trans->pf_retrans; 6939 val.spt_pathpfthld = trans->pf_retrans;
6940
6941 return 0;
6942 }
6943
6944 asoc = sctp_id2assoc(sk, val.spt_assoc_id);
6945 if (!asoc && val.spt_assoc_id != SCTP_FUTURE_ASSOC &&
6946 sctp_style(sk, UDP))
6947 return -EINVAL;
6948
6949 if (asoc) {
6950 val.spt_pathpfthld = asoc->pf_retrans;
6951 val.spt_pathmaxrxt = asoc->pathmaxrxt;
6952 } else {
6953 struct sctp_sock *sp = sctp_sk(sk);
6954
6955 val.spt_pathpfthld = sp->pf_retrans;
6956 val.spt_pathmaxrxt = sp->pathmaxrxt;
6935 } 6957 }
6936 6958
6937 if (put_user(len, optlen) || copy_to_user(optval, &val, len)) 6959 if (put_user(len, optlen) || copy_to_user(optval, &val, len))