aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>2018-04-26 15:58:55 -0400
committerDavid S. Miller <davem@davemloft.net>2018-04-27 14:35:23 -0400
commit2f5e3c9df6938b823664869ec87af3da8df272f6 (patch)
tree22be567d684b1c89bc40f433099a2909fdbbfb2e
parentfeddd6c1af30ab11d73ce0e4e76b40dfc899dbda (diff)
sctp: introduce sctp_assoc_update_frag_point
and avoid the open-coded versions of it. Now sctp_datamsg_from_user can just re-use asoc->frag_point as it will always be updated. Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/sctp.h20
-rw-r--r--include/net/sctp/structs.h1
-rw-r--r--net/sctp/associola.c24
-rw-r--r--net/sctp/chunk.c12
-rw-r--r--net/sctp/socket.c2
5 files changed, 20 insertions, 39 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 0b98e4683f10..350c65620a4e 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -428,26 +428,6 @@ static inline int sctp_list_single_entry(struct list_head *head)
428 return (head->next != head) && (head->next == head->prev); 428 return (head->next != head) && (head->next == head->prev);
429} 429}
430 430
431/* Break down data chunks at this point. */
432static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
433{
434 struct sctp_sock *sp = sctp_sk(asoc->base.sk);
435 struct sctp_af *af = sp->pf->af;
436 int frag = pmtu;
437
438 frag -= af->ip_options_len(asoc->base.sk);
439 frag -= af->net_header_len;
440 frag -= sizeof(struct sctphdr) + sctp_datachk_len(&asoc->stream);
441
442 if (asoc->user_frag)
443 frag = min_t(int, frag, asoc->user_frag);
444
445 frag = SCTP_TRUNC4(min_t(int, frag, SCTP_MAX_CHUNK_LEN -
446 sctp_datachk_len(&asoc->stream)));
447
448 return frag;
449}
450
451static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc) 431static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
452{ 432{
453 sctp_assoc_sync_pmtu(asoc); 433 sctp_assoc_sync_pmtu(asoc);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index c5e244be8f1e..ebf809eed33a 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -2097,6 +2097,7 @@ int sctp_assoc_update(struct sctp_association *old,
2097 2097
2098__u32 sctp_association_get_next_tsn(struct sctp_association *); 2098__u32 sctp_association_get_next_tsn(struct sctp_association *);
2099 2099
2100void sctp_assoc_update_frag_point(struct sctp_association *asoc);
2100void sctp_assoc_set_pmtu(struct sctp_association *asoc, __u32 pmtu); 2101void sctp_assoc_set_pmtu(struct sctp_association *asoc, __u32 pmtu);
2101void sctp_assoc_sync_pmtu(struct sctp_association *asoc); 2102void sctp_assoc_sync_pmtu(struct sctp_association *asoc);
2102void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int); 2103void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 85b362324084..a29025418b96 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -666,8 +666,6 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
666 666
667 peer->pmtu_pending = 0; 667 peer->pmtu_pending = 0;
668 668
669 asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu);
670
671 /* The asoc->peer.port might not be meaningful yet, but 669 /* The asoc->peer.port might not be meaningful yet, but
672 * initialize the packet structure anyway. 670 * initialize the packet structure anyway.
673 */ 671 */
@@ -1370,10 +1368,26 @@ sctp_assoc_choose_alter_transport(struct sctp_association *asoc,
1370 } 1368 }
1371} 1369}
1372 1370
1371void sctp_assoc_update_frag_point(struct sctp_association *asoc)
1372{
1373 int frag = sctp_mtu_payload(sctp_sk(asoc->base.sk), asoc->pathmtu,
1374 sctp_datachk_len(&asoc->stream));
1375
1376 if (asoc->user_frag)
1377 frag = min_t(int, frag, asoc->user_frag);
1378
1379 frag = min_t(int, frag, SCTP_MAX_CHUNK_LEN -
1380 sctp_datachk_len(&asoc->stream));
1381
1382 asoc->frag_point = SCTP_TRUNC4(frag);
1383}
1384
1373void sctp_assoc_set_pmtu(struct sctp_association *asoc, __u32 pmtu) 1385void sctp_assoc_set_pmtu(struct sctp_association *asoc, __u32 pmtu)
1374{ 1386{
1375 if (asoc->pathmtu != pmtu) 1387 if (asoc->pathmtu != pmtu) {
1376 asoc->pathmtu = pmtu; 1388 asoc->pathmtu = pmtu;
1389 sctp_assoc_update_frag_point(asoc);
1390 }
1377 1391
1378 pr_debug("%s: asoc:%p, pmtu:%d, frag_point:%d\n", __func__, asoc, 1392 pr_debug("%s: asoc:%p, pmtu:%d, frag_point:%d\n", __func__, asoc,
1379 asoc->pathmtu, asoc->frag_point); 1393 asoc->pathmtu, asoc->frag_point);
@@ -1403,10 +1417,6 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
1403 } 1417 }
1404 1418
1405 sctp_assoc_set_pmtu(asoc, pmtu); 1419 sctp_assoc_set_pmtu(asoc, pmtu);
1406 asoc->frag_point = sctp_frag_point(asoc, pmtu);
1407
1408 pr_debug("%s: asoc:%p, pmtu:%d, frag_point:%d\n", __func__, asoc,
1409 asoc->pathmtu, asoc->frag_point);
1410} 1420}
1411 1421
1412/* Should we send a SACK to update our peer? */ 1422/* Should we send a SACK to update our peer? */
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index be296d633e95..79daa98208c3 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -172,8 +172,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
172 struct list_head *pos, *temp; 172 struct list_head *pos, *temp;
173 struct sctp_chunk *chunk; 173 struct sctp_chunk *chunk;
174 struct sctp_datamsg *msg; 174 struct sctp_datamsg *msg;
175 struct sctp_sock *sp;
176 struct sctp_af *af;
177 int err; 175 int err;
178 176
179 msg = sctp_datamsg_new(GFP_KERNEL); 177 msg = sctp_datamsg_new(GFP_KERNEL);
@@ -192,12 +190,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
192 /* This is the biggest possible DATA chunk that can fit into 190 /* This is the biggest possible DATA chunk that can fit into
193 * the packet 191 * the packet
194 */ 192 */
195 sp = sctp_sk(asoc->base.sk); 193 max_data = asoc->frag_point;
196 af = sp->pf->af;
197 max_data = asoc->pathmtu - af->net_header_len -
198 sizeof(struct sctphdr) - sctp_datachk_len(&asoc->stream) -
199 af->ip_options_len(asoc->base.sk);
200 max_data = SCTP_TRUNC4(max_data);
201 194
202 /* If the the peer requested that we authenticate DATA chunks 195 /* If the the peer requested that we authenticate DATA chunks
203 * we need to account for bundling of the AUTH chunks along with 196 * we need to account for bundling of the AUTH chunks along with
@@ -222,9 +215,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
222 } 215 }
223 } 216 }
224 217
225 /* Check what's our max considering the above */
226 max_data = min_t(size_t, max_data, asoc->frag_point);
227
228 /* Set first_len and then account for possible bundles on first frag */ 218 /* Set first_len and then account for possible bundles on first frag */
229 first_len = max_data; 219 first_len = max_data;
230 220
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b9d14f57146b..21bf457be3ea 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3251,7 +3251,7 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
3251 sctp_datachk_len(&asoc->stream); 3251 sctp_datachk_len(&asoc->stream);
3252 } 3252 }
3253 asoc->user_frag = val; 3253 asoc->user_frag = val;
3254 asoc->frag_point = sctp_frag_point(asoc, asoc->pathmtu); 3254 sctp_assoc_update_frag_point(asoc);
3255 } else { 3255 } else {
3256 if (params.assoc_id && sctp_style(sk, UDP)) 3256 if (params.assoc_id && sctp_style(sk, UDP))
3257 return -EINVAL; 3257 return -EINVAL;