diff options
author | Xin Long <lucien.xin@gmail.com> | 2019-01-28 02:08:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-30 03:44:06 -0500 |
commit | 8add543e369d67ccd42f7e67d68866b4d606f632 (patch) | |
tree | 5be0430f4ac1b07c34de4204237ce61b2ef35412 | |
parent | 48c072174dea73c4c36ba95df87c1b4d6083df11 (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>
-rw-r--r-- | include/net/sctp/structs.h | 2 | ||||
-rw-r--r-- | net/sctp/associola.c | 2 | ||||
-rw-r--r-- | net/sctp/socket.c | 58 |
3 files changed, 43 insertions, 19 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 003020eb6e66..a5a46b1c9261 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -199,6 +199,8 @@ struct sctp_sock { | |||
199 | __u32 flowlabel; | 199 | __u32 flowlabel; |
200 | __u8 dscp; | 200 | __u8 dscp; |
201 | 201 | ||
202 | int pf_retrans; | ||
203 | |||
202 | /* The initial Path MTU to use for new associations. */ | 204 | /* The initial Path MTU to use for new associations. */ |
203 | __u32 pathmtu; | 205 | __u32 pathmtu; |
204 | 206 | ||
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index b99f163e33ac..d2c7d0d2abc1 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -101,7 +101,7 @@ static struct sctp_association *sctp_association_init( | |||
101 | * socket values. | 101 | * socket values. |
102 | */ | 102 | */ |
103 | asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt; | 103 | asoc->max_retrans = sp->assocparams.sasoc_asocmaxrxt; |
104 | asoc->pf_retrans = net->sctp.pf_retrans; | 104 | asoc->pf_retrans = sp->pf_retrans; |
105 | 105 | ||
106 | asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial); | 106 | asoc->rto_initial = msecs_to_jiffies(sp->rtoinfo.srto_initial); |
107 | asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max); | 107 | asoc->rto_max = msecs_to_jiffies(sp->rtoinfo.srto_max); |
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)) |