git: 301bff9bdd62 - stable/13 - ppp: improve MSS clamping
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 02 Feb 2023 00:04:15 UTC
The branch stable/13 has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=301bff9bdd628f27af7d0a6cda440b9525fde336 commit 301bff9bdd628f27af7d0a6cda440b9525fde336 Author: Michael Tuexen <tuexen@FreeBSD.org> AuthorDate: 2022-12-08 08:48:29 +0000 Commit: Michael Tuexen <tuexen@FreeBSD.org> CommitDate: 2023-02-02 00:03:50 +0000 ppp: improve MSS clamping ppp supports MSS clamping for TCP/IPv4. This patch * improves MSS clamping for TCP/IPv4 by using the MSS as specified in RFC 6691. * adds support for MSS clamping for TCP/IPv6. Reported by: Timo Voelker Reviewed by: thj Differential Revision: https://reviews.freebsd.org/D37624 (cherry picked from commit cef3c4e0bab8bd5e84ab8cfa2fa48a1e3dca5876) --- usr.sbin/ppp/tcpmss.c | 76 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/usr.sbin/ppp/tcpmss.c b/usr.sbin/ppp/tcpmss.c index 765668e9d137..cbf85dbf2a09 100644 --- a/usr.sbin/ppp/tcpmss.c +++ b/usr.sbin/ppp/tcpmss.c @@ -35,6 +35,9 @@ #include <netinet/in_systm.h> #include <netinet/in.h> #include <netinet/ip.h> +#ifndef NOINET6 +#include <netinet/ip6.h> +#endif #include <netinet/tcp.h> #include <sys/un.h> @@ -69,10 +72,12 @@ /*- - * We are in a liberal position about MSS - * (RFC 879, section 7). + * Compute the MSS as described in RFC 6691. */ -#define MAXMSS(mtu) ((mtu) - sizeof(struct ip) - sizeof(struct tcphdr) - 12) +#define MAXMSS4(mtu) ((mtu) - sizeof(struct ip) - sizeof(struct tcphdr)) +#ifndef NOINET6 +#define MAXMSS6(mtu) ((mtu) - sizeof(struct ip6_hdr) - sizeof(struct tcphdr)) +#endif /*- @@ -146,6 +151,10 @@ static struct mbuf * tcpmss_Check(struct bundle *bundle, struct mbuf *bp) { struct ip *pip; +#ifndef NOINET6 + struct ip6_hdr *pip6; + struct ip6_frag *pfrag; +#endif size_t hlen, plen; if (!Enabled(bundle, OPT_TCPMSSFIXUP)) @@ -153,19 +162,58 @@ tcpmss_Check(struct bundle *bundle, struct mbuf *bp) bp = m_pullup(bp); plen = m_length(bp); + if (plen < sizeof(struct ip)) + return bp; pip = (struct ip *)MBUF_CTOP(bp); - hlen = pip->ip_hl << 2; - - /* - * Check for MSS option only for TCP packets with zero fragment offsets - * and correct total and header lengths. - */ - if (pip->ip_p == IPPROTO_TCP && (ntohs(pip->ip_off) & IP_OFFMASK) == 0 && - ntohs(pip->ip_len) == plen && hlen <= plen && - plen >= sizeof(struct tcphdr) + hlen) - MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen, - MAXMSS(bundle->iface->mtu)); + switch (pip->ip_v) { + case IPVERSION: + /* + * Check for MSS option only for TCP packets with zero fragment offsets + * and correct total and header lengths. + */ + hlen = pip->ip_hl << 2; + if (pip->ip_p == IPPROTO_TCP && (ntohs(pip->ip_off) & IP_OFFMASK) == 0 && + ntohs(pip->ip_len) == plen && hlen <= plen && + plen >= sizeof(struct tcphdr) + hlen) + MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen, + MAXMSS4(bundle->iface->mtu)); + break; +#ifndef NOINET6 + case IPV6_VERSION >> 4: + /* + * Check for MSS option only for TCP packets with no extension headers + * or a single extension header which is a fragmentation header with + * offset 0. Furthermore require that the length field is correct. + */ + if (plen < sizeof(struct ip6_hdr)) + break; + pip6 = (struct ip6_hdr *)MBUF_CTOP(bp); + if (ntohs(pip6->ip6_plen) + sizeof(struct ip6_hdr) != plen) + break; + hlen = 0; + switch (pip6->ip6_nxt) { + case IPPROTO_TCP: + hlen = sizeof(struct ip6_hdr); + break; + case IPPROTO_FRAGMENT: + if (plen >= sizeof(struct ip6_frag) + sizeof(struct ip6_hdr)) { + pfrag = (struct ip6_frag *)(MBUF_CTOP(bp) + sizeof(struct ip6_hdr)); + if (pfrag->ip6f_nxt == IPPROTO_TCP && + ntohs(pfrag->ip6f_offlg & IP6F_OFF_MASK) == 0) + hlen = sizeof(struct ip6_hdr)+ sizeof(struct ip6_frag); + } + break; + } + if (hlen > 0 && plen >= sizeof(struct tcphdr) + hlen) + MSSFixup((struct tcphdr *)(MBUF_CTOP(bp) + hlen), plen - hlen, + MAXMSS6(bundle->iface->mtu)); + break; +#endif + default: + log_Printf(LogDEBUG, "tcpmss_Check: Unknown IP family %u\n", pip->ip_v); + break; + } return bp; }