Skip to content

Commit 4585a79

Browse files
committed
Merge branch 'sctp'
Wang Weidong says: ==================== sctp: check the rto_min and rto_max v6 -> v7: -patch2: fix the whitespace issues which pointed out by Daniel v5 -> v6: split the v5' first patch to patch1 and patch2, and remove the macro in constants.h -patch1: do rto_min/max socket option handling in its own patch, and fix the check of rto_min/max. -patch2: do rto_min/max sysctl handling in its own patch. -patch3: add Suggested-by Daniel. v4 -> v5: - patch1: add marco in constants.h and fix up spacing as suggested by Daniel - patch2: add a patch for fix up do_hmac_alg for according to do_rto_min[max] v3 -> v4: -patch1: fix use init_net directly which suggested by Vlad. v2 -> v3: -patch1: add proc_handler for check rto_min and rto_max which suggested by Vlad v1 -> v2: -patch1: fix the From Name which pointed out by David, and add the ACK by Neil ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents ce7a3bd + b486b22 commit 4585a79

File tree

2 files changed

+89
-19
lines changed

2 files changed

+89
-19
lines changed

net/sctp/socket.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2815,6 +2815,8 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
28152815
{
28162816
struct sctp_rtoinfo rtoinfo;
28172817
struct sctp_association *asoc;
2818+
unsigned long rto_min, rto_max;
2819+
struct sctp_sock *sp = sctp_sk(sk);
28182820

28192821
if (optlen != sizeof (struct sctp_rtoinfo))
28202822
return -EINVAL;
@@ -2828,26 +2830,36 @@ static int sctp_setsockopt_rtoinfo(struct sock *sk, char __user *optval, unsigne
28282830
if (!asoc && rtoinfo.srto_assoc_id && sctp_style(sk, UDP))
28292831
return -EINVAL;
28302832

2833+
rto_max = rtoinfo.srto_max;
2834+
rto_min = rtoinfo.srto_min;
2835+
2836+
if (rto_max)
2837+
rto_max = asoc ? msecs_to_jiffies(rto_max) : rto_max;
2838+
else
2839+
rto_max = asoc ? asoc->rto_max : sp->rtoinfo.srto_max;
2840+
2841+
if (rto_min)
2842+
rto_min = asoc ? msecs_to_jiffies(rto_min) : rto_min;
2843+
else
2844+
rto_min = asoc ? asoc->rto_min : sp->rtoinfo.srto_min;
2845+
2846+
if (rto_min > rto_max)
2847+
return -EINVAL;
2848+
28312849
if (asoc) {
28322850
if (rtoinfo.srto_initial != 0)
28332851
asoc->rto_initial =
28342852
msecs_to_jiffies(rtoinfo.srto_initial);
2835-
if (rtoinfo.srto_max != 0)
2836-
asoc->rto_max = msecs_to_jiffies(rtoinfo.srto_max);
2837-
if (rtoinfo.srto_min != 0)
2838-
asoc->rto_min = msecs_to_jiffies(rtoinfo.srto_min);
2853+
asoc->rto_max = rto_max;
2854+
asoc->rto_min = rto_min;
28392855
} else {
28402856
/* If there is no association or the association-id = 0
28412857
* set the values to the endpoint.
28422858
*/
2843-
struct sctp_sock *sp = sctp_sk(sk);
2844-
28452859
if (rtoinfo.srto_initial != 0)
28462860
sp->rtoinfo.srto_initial = rtoinfo.srto_initial;
2847-
if (rtoinfo.srto_max != 0)
2848-
sp->rtoinfo.srto_max = rtoinfo.srto_max;
2849-
if (rtoinfo.srto_min != 0)
2850-
sp->rtoinfo.srto_min = rtoinfo.srto_min;
2861+
sp->rtoinfo.srto_max = rto_max;
2862+
sp->rtoinfo.srto_min = rto_min;
28512863
}
28522864

28532865
return 0;

net/sctp/sysctl.c

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,16 @@ extern long sysctl_sctp_mem[3];
5656
extern int sysctl_sctp_rmem[3];
5757
extern int sysctl_sctp_wmem[3];
5858

59-
static int proc_sctp_do_hmac_alg(struct ctl_table *ctl,
60-
int write,
59+
static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
60+
void __user *buffer, size_t *lenp,
61+
loff_t *ppos);
62+
static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
63+
void __user *buffer, size_t *lenp,
64+
loff_t *ppos);
65+
static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
6166
void __user *buffer, size_t *lenp,
62-
6367
loff_t *ppos);
68+
6469
static struct ctl_table sctp_table[] = {
6570
{
6671
.procname = "sctp_mem",
@@ -102,17 +107,17 @@ static struct ctl_table sctp_net_table[] = {
102107
.data = &init_net.sctp.rto_min,
103108
.maxlen = sizeof(unsigned int),
104109
.mode = 0644,
105-
.proc_handler = proc_dointvec_minmax,
110+
.proc_handler = proc_sctp_do_rto_min,
106111
.extra1 = &one,
107-
.extra2 = &timer_max
112+
.extra2 = &init_net.sctp.rto_max
108113
},
109114
{
110115
.procname = "rto_max",
111116
.data = &init_net.sctp.rto_max,
112117
.maxlen = sizeof(unsigned int),
113118
.mode = 0644,
114-
.proc_handler = proc_dointvec_minmax,
115-
.extra1 = &one,
119+
.proc_handler = proc_sctp_do_rto_max,
120+
.extra1 = &init_net.sctp.rto_min,
116121
.extra2 = &timer_max
117122
},
118123
{
@@ -294,8 +299,7 @@ static struct ctl_table sctp_net_table[] = {
294299
{ /* sentinel */ }
295300
};
296301

297-
static int proc_sctp_do_hmac_alg(struct ctl_table *ctl,
298-
int write,
302+
static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
299303
void __user *buffer, size_t *lenp,
300304
loff_t *ppos)
301305
{
@@ -342,6 +346,60 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl,
342346
return ret;
343347
}
344348

349+
static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
350+
void __user *buffer, size_t *lenp,
351+
loff_t *ppos)
352+
{
353+
struct net *net = current->nsproxy->net_ns;
354+
int new_value;
355+
struct ctl_table tbl;
356+
unsigned int min = *(unsigned int *) ctl->extra1;
357+
unsigned int max = *(unsigned int *) ctl->extra2;
358+
int ret;
359+
360+
memset(&tbl, 0, sizeof(struct ctl_table));
361+
tbl.maxlen = sizeof(unsigned int);
362+
363+
if (write)
364+
tbl.data = &new_value;
365+
else
366+
tbl.data = &net->sctp.rto_min;
367+
ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
368+
if (write) {
369+
if (ret || new_value > max || new_value < min)
370+
return -EINVAL;
371+
net->sctp.rto_min = new_value;
372+
}
373+
return ret;
374+
}
375+
376+
static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
377+
void __user *buffer, size_t *lenp,
378+
loff_t *ppos)
379+
{
380+
struct net *net = current->nsproxy->net_ns;
381+
int new_value;
382+
struct ctl_table tbl;
383+
unsigned int min = *(unsigned int *) ctl->extra1;
384+
unsigned int max = *(unsigned int *) ctl->extra2;
385+
int ret;
386+
387+
memset(&tbl, 0, sizeof(struct ctl_table));
388+
tbl.maxlen = sizeof(unsigned int);
389+
390+
if (write)
391+
tbl.data = &new_value;
392+
else
393+
tbl.data = &net->sctp.rto_max;
394+
ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
395+
if (write) {
396+
if (ret || new_value > max || new_value < min)
397+
return -EINVAL;
398+
net->sctp.rto_max = new_value;
399+
}
400+
return ret;
401+
}
402+
345403
int sctp_sysctl_net_register(struct net *net)
346404
{
347405
struct ctl_table *table;

0 commit comments

Comments
 (0)