Skip to content

Commit 3822a5f

Browse files
marceloleitnerdavem330
authored andcommitted
sctp: align MTU to a word
SCTP is a protocol that is aligned to a word (4 bytes). Thus using bare MTU can sometimes return values that are not aligned, like for loopback, which is 65536 but ipv4_mtu() limits that to 65535. This mis-alignment will cause the last non-aligned bytes to never be used and can cause issues with congestion control. So it's better to just consider a lower MTU and keep congestion control calcs saner as they are based on PMTU. Same applies to icmp frag needed messages, which is also fixed by this patch. One other effect of this is the inability to send MTU-sized packet without queueing or fragmentation and without hitting Nagle. As the check performed at sctp_packet_can_append_data(): if (chunk->skb->len + q->out_qlen >= transport->pathmtu - packet->overhead) /* Enough data queued to fill a packet */ return SCTP_XMIT_OK; with the above example of MTU, if there are no other messages queued, one cannot send a packet that just fits one packet (65532 bytes) and without causing DATA chunk fragmentation or a delay. v2: - Added WORD_TRUNC macro Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 31b055e commit 3822a5f

File tree

4 files changed

+11
-7
lines changed

4 files changed

+11
-7
lines changed

include/net/sctp/sctp.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@
8282
#define SCTP_PROTOSW_FLAG INET_PROTOSW_PERMANENT
8383
#endif
8484

85+
/* Round an int up to the next multiple of 4. */
86+
#define WORD_ROUND(s) (((s)+3)&~3)
87+
/* Truncate to the previous multiple of 4. */
88+
#define WORD_TRUNC(s) ((s)&~3)
89+
8590
/*
8691
* Function declarations.
8792
*/
@@ -475,9 +480,6 @@ for (pos = chunk->subh.fwdtsn_hdr->skip;\
475480
(void *)pos <= (void *)chunk->subh.fwdtsn_hdr->skip + end - sizeof(struct sctp_fwdtsn_skip);\
476481
pos++)
477482

478-
/* Round an int up to the next multiple of 4. */
479-
#define WORD_ROUND(s) (((s)+3)&~3)
480-
481483
/* External references. */
482484

483485
extern struct proto sctp_prot;

net/sctp/associola.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,8 @@ void sctp_assoc_sync_pmtu(struct sock *sk, struct sctp_association *asoc)
14061406
list_for_each_entry(t, &asoc->peer.transport_addr_list,
14071407
transports) {
14081408
if (t->pmtu_pending && t->dst) {
1409-
sctp_transport_update_pmtu(sk, t, dst_mtu(t->dst));
1409+
sctp_transport_update_pmtu(sk, t,
1410+
WORD_TRUNC(dst_mtu(t->dst)));
14101411
t->pmtu_pending = 0;
14111412
}
14121413
if (!pmtu || (t->pathmtu < pmtu))

net/sctp/input.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,8 @@ void sctp_v4_err(struct sk_buff *skb, __u32 info)
606606

607607
/* PMTU discovery (RFC1191) */
608608
if (ICMP_FRAG_NEEDED == code) {
609-
sctp_icmp_frag_needed(sk, asoc, transport, info);
609+
sctp_icmp_frag_needed(sk, asoc, transport,
610+
WORD_TRUNC(info));
610611
goto out_unlock;
611612
} else {
612613
if (ICMP_PROT_UNREACH == code) {

net/sctp/transport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
226226
}
227227

228228
if (transport->dst) {
229-
transport->pathmtu = dst_mtu(transport->dst);
229+
transport->pathmtu = WORD_TRUNC(dst_mtu(transport->dst));
230230
} else
231231
transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
232232
}
@@ -280,7 +280,7 @@ void sctp_transport_route(struct sctp_transport *transport,
280280
return;
281281
}
282282
if (transport->dst) {
283-
transport->pathmtu = dst_mtu(transport->dst);
283+
transport->pathmtu = WORD_TRUNC(dst_mtu(transport->dst));
284284

285285
/* Initialize sk->sk_rcv_saddr, if the transport is the
286286
* association's active path for getsockname().

0 commit comments

Comments
 (0)