summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorXin Long <lucien.xin@gmail.com>2018-11-27 06:11:50 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-30 16:12:43 -0500
commit4135cce7fd0a0d755665c02728578c7c5afe4726 (patch)
treec2da420d89fa8f3f40f29f4671e195eacb2d11d2 /net
parent9410d386d0a829ace9558336263086c2fbbe8aed (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.c7
-rw-r--r--net/sctp/sm_make_chunk.c3
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