Commit cec6880d authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sctp-plpmtud-fixes'



Xin Long says:

====================
sctp: a couple of fixes for PLPMTUD

Four fixes included in this patchset:

  - fix the packet sending in Error state.
  - fix the timer stop when transport update dst.
  - fix the outer header len calculation.
  - fix the return value for toobig processing.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 411a44c2 75cf662c
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -626,7 +626,8 @@ static inline __u32 sctp_min_frag_point(struct sctp_sock *sp, __u16 datasize)

static inline int sctp_transport_pl_hlen(struct sctp_transport *t)
{
	return __sctp_mtu_payload(sctp_sk(t->asoc->base.sk), t, 0, 0);
	return __sctp_mtu_payload(sctp_sk(t->asoc->base.sk), t, 0, 0) -
	       sizeof(struct sctphdr);
}

static inline void sctp_transport_pl_reset(struct sctp_transport *t)
@@ -653,12 +654,10 @@ static inline void sctp_transport_pl_update(struct sctp_transport *t)
	if (t->pl.state == SCTP_PL_DISABLED)
		return;

	if (del_timer(&t->probe_timer))
		sctp_transport_put(t);

	t->pl.state = SCTP_PL_BASE;
	t->pl.pmtu = SCTP_BASE_PLPMTU;
	t->pl.probe_size = SCTP_BASE_PLPMTU;
	sctp_transport_reset_probe_timer(t);
}

static inline bool sctp_transport_pl_enabled(struct sctp_transport *t)
+8 −5
Original line number Diff line number Diff line
@@ -581,14 +581,17 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
	chunk = list_entry(packet->chunk_list.next, struct sctp_chunk, list);
	sk = chunk->skb->sk;

	/* check gso */
	if (packet->size > tp->pathmtu && !packet->ipfragok && !chunk->pmtu_probe) {
		if (!sk_can_gso(sk)) {
		if (tp->pl.state == SCTP_PL_ERROR) { /* do IP fragmentation if in Error state */
			packet->ipfragok = 1;
		} else {
			if (!sk_can_gso(sk)) { /* check gso */
				pr_err_once("Trying to GSO but underlying device doesn't support it.");
				goto out;
			}
			gso = 1;
		}
	}

	/* alloc head skb */
	head = alloc_skb((gso ? packet->overhead : packet->size) +
+6 −5
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ bool sctp_transport_pl_send(struct sctp_transport *t)
		if (t->pl.probe_size == SCTP_BASE_PLPMTU) { /* BASE_PLPMTU Confirmation Failed */
			t->pl.state = SCTP_PL_ERROR; /* Base -> Error */

			t->pl.pmtu = SCTP_MIN_PLPMTU;
			t->pl.pmtu = SCTP_BASE_PLPMTU;
			t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
			sctp_assoc_sync_pmtu(t->asoc);
		}
@@ -366,8 +366,9 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu)
		if (pmtu >= SCTP_MIN_PLPMTU && pmtu < SCTP_BASE_PLPMTU) {
			t->pl.state = SCTP_PL_ERROR; /* Base -> Error */

			t->pl.pmtu = SCTP_MIN_PLPMTU;
			t->pl.pmtu = SCTP_BASE_PLPMTU;
			t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
			return true;
		}
	} else if (t->pl.state == SCTP_PL_SEARCH) {
		if (pmtu >= SCTP_BASE_PLPMTU && pmtu < t->pl.pmtu) {
@@ -378,11 +379,10 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu)
			t->pl.probe_high = 0;
			t->pl.pmtu = SCTP_BASE_PLPMTU;
			t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
			return true;
		} else if (pmtu > t->pl.pmtu && pmtu < t->pl.probe_size) {
			t->pl.probe_size = pmtu;
			t->pl.probe_count = 0;

			return false;
		}
	} else if (t->pl.state == SCTP_PL_COMPLETE) {
		if (pmtu >= SCTP_BASE_PLPMTU && pmtu < t->pl.pmtu) {
@@ -393,10 +393,11 @@ static bool sctp_transport_pl_toobig(struct sctp_transport *t, u32 pmtu)
			t->pl.probe_high = 0;
			t->pl.pmtu = SCTP_BASE_PLPMTU;
			t->pathmtu = t->pl.pmtu + sctp_transport_pl_hlen(t);
			return true;
		}
	}

	return true;
	return false;
}

bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)