[PATCH mptcp-next v4 05/10] ipv6: extract and export ip6_sock_set_tclass helpers
Geliang Tang <[email protected]> Thu, 30 Jul 2026 10:53:58 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <38818ad1f4e454278de4542ea9a88cb4d2ec8c0a.1785378180.git.tanggeliang@kylinos.cn> |
From: Geliang Tang <[email protected]> The IPV6_TCLASS case in do_ipv6_setsockopt() inlined the same ECN mask handling and inet6_sk(sk)->tclass write that callers need to do when propagating a tclass value onto a freshly created socket. Pull this into small helpers exported via <net/ipv6.h>, so external modules (e.g. nvme-tcp, nvmet-tcp) can apply IPV6_TCLASS without duplicating the ECN handling. Signed-off-by: Geliang Tang <[email protected]> --- include/net/ipv6.h | 3 +++ net/ipv6/ipv6_sockglue.c | 31 +++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 3de07e738538..82e57b34ba57 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -1252,6 +1252,9 @@ static inline void ip6_sock_set_recverr(struct sock *sk) inet6_set_bit(RECVERR6, sk); } +void __ip6_sock_set_tclass(struct sock *sk, int val); +void ip6_sock_set_tclass(struct sock *sk, int val); + #define IPV6_PREFER_SRC_MASK (IPV6_PREFER_SRC_TMP | IPV6_PREFER_SRC_PUBLIC | \ IPV6_PREFER_SRC_COA) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index b4c977434c2e..c59f25fbb336 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -373,6 +373,28 @@ static int ipv6_set_opt_hdr(struct sock *sk, int optname, sockptr_t optval, return err; } +void __ip6_sock_set_tclass(struct sock *sk, int val) +{ + u8 old_tclass = inet6_sk(sk)->tclass; + + if (sk->sk_type == SOCK_STREAM) { + val &= ~INET_ECN_MASK; + val |= old_tclass & INET_ECN_MASK; + } + if (old_tclass != val) { + WRITE_ONCE(inet6_sk(sk)->tclass, val); + sk_dst_reset(sk); + } +} + +void ip6_sock_set_tclass(struct sock *sk, int val) +{ + sockopt_lock_sock(sk); + __ip6_sock_set_tclass(sk, val); + sockopt_release_sock(sk); +} +EXPORT_SYMBOL(ip6_sock_set_tclass); + int do_ipv6_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen) { @@ -713,14 +735,7 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname, /* RFC 3542, 6.5: default traffic class of 0x0 */ if (val == -1) val = 0; - if (sk->sk_type == SOCK_STREAM) { - val &= ~INET_ECN_MASK; - val |= np->tclass & INET_ECN_MASK; - } - if (np->tclass != val) { - np->tclass = val; - sk_dst_reset(sk); - } + __ip6_sock_set_tclass(sk, val); retv = 0; break; -- 2.53.0