diff options
author | Xin Long <lucien.xin@gmail.com> | 2018-11-27 06:11:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-11-30 16:12:43 -0500 |
commit | 4135cce7fd0a0d755665c02728578c7c5afe4726 (patch) | |
tree | c2da420d89fa8f3f40f29f4671e195eacb2d11d2 /net | |
parent | 9410d386d0a829ace9558336263086c2fbbe8aed (diff) |
sctp: update frag_point when stream_interleave is set
sctp_assoc_update_frag_point() should be called whenever asoc->pathmtu
changes, but we missed one place in sctp_association_init(). It would
cause frag_point is zero when sending data.
As says in Jakub's reproducer, if sp->pathmtu is set by socketopt, the
new asoc->pathmtu inherits it in sctp_association_init(). Later when
transports are added and their pmtu >= asoc->pathmtu, it will never
call sctp_assoc_update_frag_point() to set frag_point.
This patch is to fix it by updating frag_point after asoc->pathmtu is
set as sp->pathmtu in sctp_association_init(). Note that it moved them
after sctp_stream_init(), as stream->si needs to be set first.
Frag_point's calculation is also related with datachunk's type, so it
needs to update frag_point when stream->si may be changed in
sctp_process_init().
v1->v2:
- call sctp_assoc_update_frag_point() separately in sctp_process_init
and sctp_association_init, per Marcelo's suggestion.
Fixes: 2f5e3c9df693 ("sctp: introduce sctp_assoc_update_frag_point")
Reported-by: Jakub Audykowicz <jakub.audykowicz@gmail.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sctp/associola.c | 7 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 3 |
2 files changed, 7 insertions, 3 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 6a28b96e779e..dd77ec3892b6 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
@@ -118,9 +118,6 @@ static struct sctp_association *sctp_association_init( | |||
118 | asoc->flowlabel = sp->flowlabel; | 118 | asoc->flowlabel = sp->flowlabel; |
119 | asoc->dscp = sp->dscp; | 119 | asoc->dscp = sp->dscp; |
120 | 120 | ||
121 | /* Initialize default path MTU. */ | ||
122 | asoc->pathmtu = sp->pathmtu; | ||
123 | |||
124 | /* Set association default SACK delay */ | 121 | /* Set association default SACK delay */ |
125 | asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); | 122 | asoc->sackdelay = msecs_to_jiffies(sp->sackdelay); |
126 | asoc->sackfreq = sp->sackfreq; | 123 | asoc->sackfreq = sp->sackfreq; |
@@ -252,6 +249,10 @@ static struct sctp_association *sctp_association_init( | |||
252 | 0, gfp)) | 249 | 0, gfp)) |
253 | goto fail_init; | 250 | goto fail_init; |
254 | 251 | ||
252 | /* Initialize default path MTU. */ | ||
253 | asoc->pathmtu = sp->pathmtu; | ||
254 | sctp_assoc_update_frag_point(asoc); | ||
255 | |||
255 | /* Assume that peer would support both address types unless we are | 256 | /* Assume that peer would support both address types unless we are |
256 | * told otherwise. | 257 | * told otherwise. |
257 | */ | 258 | */ |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 4a4fd1971255..f4ac6c592e13 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -2462,6 +2462,9 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, | |||
2462 | asoc->c.sinit_max_instreams, gfp)) | 2462 | asoc->c.sinit_max_instreams, gfp)) |
2463 | goto clean_up; | 2463 | goto clean_up; |
2464 | 2464 | ||
2465 | /* Update frag_point when stream_interleave may get changed. */ | ||
2466 | sctp_assoc_update_frag_point(asoc); | ||
2467 | |||
2465 | if (!asoc->temp && sctp_assoc_set_id(asoc, gfp)) | 2468 | if (!asoc->temp && sctp_assoc_set_id(asoc, gfp)) |
2466 | goto clean_up; | 2469 | goto clean_up; |
2467 | 2470 | ||