diff options
author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2009-09-05 00:21:00 +0200 |
---|---|---|
committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2009-09-05 00:21:00 +0200 |
commit | f68b2e05f326971cd76c65aa91a1a41771dd7485 (patch) | |
tree | 2940d83f3787570cc030791378ee23b89b941662 /net/sctp/socket.c | |
parent | sctp: Don't do NAGLE delay on large writes that were fragmented small (diff) | |
download | linux-f68b2e05f326971cd76c65aa91a1a41771dd7485.tar.xz linux-f68b2e05f326971cd76c65aa91a1a41771dd7485.zip |
sctp: Fix SCTP_MAXSEG socket option to comply to spec.
We had a bug that we never stored the user-defined value for
MAXSEG when setting the value on an association. Thus future
PMTU events ended up re-writing the frag point and increasing
it past user limit. Additionally, when setting the option on
the socket/endpoint, we effect all current associations, which
is against spec.
Now, we store the user 'maxseg' value along with the computed
'frag_point'. We inherit 'maxseg' from the socket at association
creation and use it as an upper limit for 'frag_point' when its
set.
Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 95a5623d79a0..89af37a6c871 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2243,7 +2243,7 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params, sctp_assoc_sync_pmtu(asoc); } else if (asoc) { asoc->pathmtu = params->spp_pathmtu; - sctp_frag_point(sp, params->spp_pathmtu); + sctp_frag_point(asoc, params->spp_pathmtu); } else { sp->pathmtu = params->spp_pathmtu; } @@ -2880,15 +2880,10 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, int optl val -= sizeof(struct sctphdr) + sizeof(struct sctp_data_chunk); } - - asoc->frag_point = val; + asoc->user_frag = val; + asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); } else { sp->user_frag = val; - - /* Update the frag_point of the existing associations. */ - list_for_each_entry(asoc, &(sp->ep->asocs), asocs) { - asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu); - } } return 0; |