Commit e9726925 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Paolo Abeni
Browse files

net: psp: update the TCP MSS to reflect PSP packet overhead



PSP eats 40B of header space. Adjust MSS appropriately.

We can either modify tcp_mtu_to_mss() / tcp_mss_to_mtu()
or reuse icsk_ext_hdr_len. The former option is more TCP
specific and has runtime overhead. The latter is a bit
of a hack as PSP is not an ext_hdr. If one squints hard
enough, UDP encap is just a more practical version of
IPv6 exthdr, so go with the latter. Happy to change.

Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarDaniel Zahka <daniel.zahka@gmail.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250917000954.859376-10-daniel.zahka@gmail.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 6b46ca26
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#include <linux/skbuff.h>
#include <linux/rcupdate.h>
#include <linux/udp.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <net/psp/types.h>
@@ -143,6 +144,14 @@ static inline struct psp_assoc *psp_skb_get_assoc_rcu(struct sk_buff *skb)

	return psp_sk_get_assoc_rcu(skb->sk);
}

static inline unsigned int psp_sk_overhead(const struct sock *sk)
{
	int psp_encap = sizeof(struct udphdr) + PSP_HDR_SIZE + PSP_TRL_SIZE;
	bool has_psp = rcu_access_pointer(sk->psp_assoc);

	return has_psp ? psp_encap : 0;
}
#else
static inline void psp_sk_assoc_free(struct sock *sk) { }
static inline void
@@ -182,6 +191,11 @@ static inline struct psp_assoc *psp_skb_get_assoc_rcu(struct sk_buff *skb)
{
	return NULL;
}

static inline unsigned int psp_sk_overhead(const struct sock *sk)
{
	return 0;
}
#endif

static inline unsigned long
+3 −0
Original line number Diff line number Diff line
@@ -93,6 +93,9 @@ struct psp_dev_caps {

#define PSP_MAX_KEY	32

#define PSP_HDR_SIZE	16	/* We don't support optional fields, yet */
#define PSP_TRL_SIZE	16	/* AES-GCM/GMAC trailer size */

struct psp_skb_ext {
	__be32 spi;
	u16 dev_id;
+2 −2
Original line number Diff line number Diff line
@@ -294,9 +294,9 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
	inet->inet_dport = usin->sin_port;
	sk_daddr_set(sk, daddr);

	inet_csk(sk)->icsk_ext_hdr_len = 0;
	inet_csk(sk)->icsk_ext_hdr_len = psp_sk_overhead(sk);
	if (inet_opt)
		inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
		inet_csk(sk)->icsk_ext_hdr_len += inet_opt->opt.optlen;

	tp->rx_opt.mss_clamp = TCP_MSS_DEFAULT;

+5 −1
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#include <net/xfrm.h>
#include <net/compat.h>
#include <net/seg6.h>
#include <net/psp.h>

#include <linux/uaccess.h>

@@ -107,7 +108,10 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
		    !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
		    inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) {
			struct inet_connection_sock *icsk = inet_csk(sk);
			icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;

			icsk->icsk_ext_hdr_len =
				psp_sk_overhead(sk) +
				opt->opt_flen + opt->opt_nflen;
			icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
		}
	}
+3 −3
Original line number Diff line number Diff line
@@ -302,9 +302,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
	sk->sk_gso_type = SKB_GSO_TCPV6;
	ip6_dst_store(sk, dst, NULL, NULL);

	icsk->icsk_ext_hdr_len = 0;
	icsk->icsk_ext_hdr_len = psp_sk_overhead(sk);
	if (opt)
		icsk->icsk_ext_hdr_len = opt->opt_flen +
		icsk->icsk_ext_hdr_len += opt->opt_flen +
					  opt->opt_nflen;

	tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
Loading