mirror of
https://github.com/torvalds/linux.git
synced 2025-08-15 14:11:42 +02:00

DCCP was orphaned in 2021 by commit054c4610bd
("MAINTAINERS: dccp: move Gerrit Renker to CREDITS"), which noted that the last maintainer had been inactive for five years. In recent years, it has become a playground for syzbot, and most changes to DCCP have been odd bug fixes triggered by syzbot. Apart from that, the only changes have been driven by treewide or networking API updates or adjustments related to TCP. Thus, in 2023, we announced we would remove DCCP in 2025 via commitb144fcaf46
("dccp: Print deprecation notice."). Since then, only one individual has contacted the netdev mailing list. [0] There is ongoing research for Multipath DCCP. The repository is hosted on GitHub [1], and development is not taking place through the upstream community. While the repository is published under the GPLv2 license, the scheduling part remains proprietary, with a LICENSE file [2] stating: "This is not Open Source software." The researcher mentioned a plan to address the licensing issue, upstream the patches, and step up as a maintainer, but there has been no further communication since then. Maintaining DCCP for a decade without any real users has become a burden. Therefore, it's time to remove it. Removing DCCP will also provide significant benefits to TCP. It allows us to freely reorganize the layout of struct inet_connection_sock, which is currently shared with DCCP, and optimize it to reduce the number of cachelines accessed in the TCP fast path. Note that we keep DCCP netfilter modules as requested. [3] Link: https://lore.kernel.org/netdev/20230710182253.81446-1-kuniyu@amazon.com/T/#u #[0] Link: https://github.com/telekom/mp-dccp #[1] Link: https://github.com/telekom/mp-dccp/blob/mpdccp_v03_k5.10/net/dccp/non_gpl_scheduler/LICENSE #[2] Link: https://lore.kernel.org/netdev/Z_VQ0KlCRkqYWXa-@calendula/ #[3] Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Acked-by: Paul Moore <paul@paul-moore.com> (LSM and SELinux) Acked-by: Casey Schaufler <casey@schaufler-ca.com> Link: https://patch.msgid.link/20250410023921.11307-3-kuniyu@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
158 lines
4.1 KiB
C
158 lines
4.1 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/module.h>
|
|
#include <linux/cache.h>
|
|
#include <linux/random.h>
|
|
#include <linux/hrtimer.h>
|
|
#include <linux/ktime.h>
|
|
#include <linux/string.h>
|
|
#include <linux/net.h>
|
|
#include <linux/siphash.h>
|
|
#include <net/secure_seq.h>
|
|
|
|
#if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_INET)
|
|
#include <linux/in6.h>
|
|
#include <net/tcp.h>
|
|
|
|
static siphash_aligned_key_t net_secret;
|
|
static siphash_aligned_key_t ts_secret;
|
|
|
|
#define EPHEMERAL_PORT_SHUFFLE_PERIOD (10 * HZ)
|
|
|
|
static __always_inline void net_secret_init(void)
|
|
{
|
|
net_get_random_once(&net_secret, sizeof(net_secret));
|
|
}
|
|
|
|
static __always_inline void ts_secret_init(void)
|
|
{
|
|
net_get_random_once(&ts_secret, sizeof(ts_secret));
|
|
}
|
|
#endif
|
|
|
|
#ifdef CONFIG_INET
|
|
static u32 seq_scale(u32 seq)
|
|
{
|
|
/*
|
|
* As close as possible to RFC 793, which
|
|
* suggests using a 250 kHz clock.
|
|
* Further reading shows this assumes 2 Mb/s networks.
|
|
* For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
|
|
* For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
|
|
* we also need to limit the resolution so that the u32 seq
|
|
* overlaps less than one time per MSL (2 minutes).
|
|
* Choosing a clock of 64 ns period is OK. (period of 274 s)
|
|
*/
|
|
return seq + (ktime_get_real_ns() >> 6);
|
|
}
|
|
#endif
|
|
|
|
#if IS_ENABLED(CONFIG_IPV6)
|
|
u32 secure_tcpv6_ts_off(const struct net *net,
|
|
const __be32 *saddr, const __be32 *daddr)
|
|
{
|
|
const struct {
|
|
struct in6_addr saddr;
|
|
struct in6_addr daddr;
|
|
} __aligned(SIPHASH_ALIGNMENT) combined = {
|
|
.saddr = *(struct in6_addr *)saddr,
|
|
.daddr = *(struct in6_addr *)daddr,
|
|
};
|
|
|
|
if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
|
|
return 0;
|
|
|
|
ts_secret_init();
|
|
return siphash(&combined, offsetofend(typeof(combined), daddr),
|
|
&ts_secret);
|
|
}
|
|
EXPORT_IPV6_MOD(secure_tcpv6_ts_off);
|
|
|
|
u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
|
|
__be16 sport, __be16 dport)
|
|
{
|
|
const struct {
|
|
struct in6_addr saddr;
|
|
struct in6_addr daddr;
|
|
__be16 sport;
|
|
__be16 dport;
|
|
} __aligned(SIPHASH_ALIGNMENT) combined = {
|
|
.saddr = *(struct in6_addr *)saddr,
|
|
.daddr = *(struct in6_addr *)daddr,
|
|
.sport = sport,
|
|
.dport = dport
|
|
};
|
|
u32 hash;
|
|
|
|
net_secret_init();
|
|
hash = siphash(&combined, offsetofend(typeof(combined), dport),
|
|
&net_secret);
|
|
return seq_scale(hash);
|
|
}
|
|
EXPORT_SYMBOL(secure_tcpv6_seq);
|
|
|
|
u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
|
|
__be16 dport)
|
|
{
|
|
const struct {
|
|
struct in6_addr saddr;
|
|
struct in6_addr daddr;
|
|
unsigned int timeseed;
|
|
__be16 dport;
|
|
} __aligned(SIPHASH_ALIGNMENT) combined = {
|
|
.saddr = *(struct in6_addr *)saddr,
|
|
.daddr = *(struct in6_addr *)daddr,
|
|
.timeseed = jiffies / EPHEMERAL_PORT_SHUFFLE_PERIOD,
|
|
.dport = dport,
|
|
};
|
|
net_secret_init();
|
|
return siphash(&combined, offsetofend(typeof(combined), dport),
|
|
&net_secret);
|
|
}
|
|
EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
|
|
#endif
|
|
|
|
#ifdef CONFIG_INET
|
|
u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr)
|
|
{
|
|
if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1)
|
|
return 0;
|
|
|
|
ts_secret_init();
|
|
return siphash_2u32((__force u32)saddr, (__force u32)daddr,
|
|
&ts_secret);
|
|
}
|
|
|
|
/* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d),
|
|
* but fortunately, `sport' cannot be 0 in any circumstances. If this changes,
|
|
* it would be easy enough to have the former function use siphash_4u32, passing
|
|
* the arguments as separate u32.
|
|
*/
|
|
u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
|
|
__be16 sport, __be16 dport)
|
|
{
|
|
u32 hash;
|
|
|
|
net_secret_init();
|
|
hash = siphash_3u32((__force u32)saddr, (__force u32)daddr,
|
|
(__force u32)sport << 16 | (__force u32)dport,
|
|
&net_secret);
|
|
return seq_scale(hash);
|
|
}
|
|
EXPORT_SYMBOL_GPL(secure_tcp_seq);
|
|
|
|
u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
|
|
{
|
|
net_secret_init();
|
|
return siphash_4u32((__force u32)saddr, (__force u32)daddr,
|
|
(__force u16)dport,
|
|
jiffies / EPHEMERAL_PORT_SHUFFLE_PERIOD,
|
|
&net_secret);
|
|
}
|
|
EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
|
|
#endif
|