Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit feddd6c1 authored by Marcelo Ricardo Leitner's avatar Marcelo Ricardo Leitner Committed by David S. Miller
Browse files

sctp: introduce sctp_mtu_payload



When given a MTU, this function calculates how much payload we can carry
on it. Without a MTU, it calculates the amount of header overhead we
have.

So that when we have extra overhead, like the one added for IP options
on SELinux patches, it is easier to handle it.

Signed-off-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c4b2893d
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -607,6 +607,25 @@ static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *
	return t->dst;
}

/* Calculate max payload size given a MTU, or the total overhead if
 * given MTU is zero
 */
static inline __u32 sctp_mtu_payload(const struct sctp_sock *sp,
				     __u32 mtu, __u32 extra)
{
	__u32 overhead = sizeof(struct sctphdr) + extra;

	if (sp)
		overhead += sp->pf->af->net_header_len;
	else
		overhead += sizeof(struct ipv6hdr);

	if (WARN_ON_ONCE(mtu && mtu <= overhead))
		mtu = overhead;

	return mtu ? mtu - overhead : overhead;
}

static inline bool sctp_transport_pmtu_check(struct sctp_transport *t)
{
	__u32 pmtu = max_t(size_t, SCTP_TRUNC4(dst_mtu(t->dst)),
+10 −15
Original line number Diff line number Diff line
@@ -90,8 +90,8 @@ void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,
{
	struct sctp_transport *tp = packet->transport;
	struct sctp_association *asoc = tp->asoc;
	struct sctp_sock *sp = NULL;
	struct sock *sk;
	size_t overhead = sizeof(struct ipv6hdr) + sizeof(struct sctphdr);

	pr_debug("%s: packet:%p vtag:0x%x\n", __func__, packet, vtag);
	packet->vtag = vtag;
@@ -102,25 +102,20 @@ void sctp_packet_config(struct sctp_packet *packet, __u32 vtag,

	/* set packet max_size with pathmtu, then calculate overhead */
	packet->max_size = tp->pathmtu;

	if (asoc) {
		struct sctp_sock *sp = sctp_sk(asoc->base.sk);
		struct sctp_af *af = sp->pf->af;

		overhead = af->net_header_len +
			   af->ip_options_len(asoc->base.sk);
		overhead += sizeof(struct sctphdr);
		packet->overhead = overhead;
		packet->size = overhead;
	} else {
		packet->overhead = overhead;
		packet->size = overhead;
		return;
		sk = asoc->base.sk;
		sp = sctp_sk(sk);
	}
	packet->overhead = sctp_mtu_payload(sp, 0, 0);
	packet->size = packet->overhead;

	if (!asoc)
		return;

	/* update dst or transport pathmtu if in need */
	sk = asoc->base.sk;
	if (!sctp_transport_dst_check(tp)) {
		sctp_transport_route(tp, NULL, sctp_sk(sk));
		sctp_transport_route(tp, NULL, sp);
		if (asoc->param_flags & SPP_PMTUD_ENABLE)
			sctp_assoc_sync_pmtu(asoc);
	} else if (!sctp_transport_pmtu_check(tp)) {
+2 −5
Original line number Diff line number Diff line
@@ -3234,11 +3234,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
	if (val) {
		int min_len, max_len;

		min_len = SCTP_DEFAULT_MINSEGMENT - af->net_header_len;
		min_len -= af->ip_options_len(sk);
		min_len -= sizeof(struct sctphdr) +
			   sizeof(struct sctp_data_chunk);

		min_len = sctp_mtu_payload(sp, SCTP_DEFAULT_MINSEGMENT,
					   sizeof(struct sctp_data_chunk));
		max_len = SCTP_MAX_CHUNK_LEN - sizeof(struct sctp_data_chunk);

		if (val < min_len || val > max_len)