Revert "tcp/udp: Make early_demux back namespacified."

This reverts commit 7162f05f1f which is
commit 11052589cf5c0bab3b4884d423d5f60c38fcf25d upstream.

It is breaks the abi and is not needed in Android systems, so revert it.

Bug: 161946584
Change-Id: I357d52cd6a635050f305127246f95cb2302633be
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2022-11-12 14:05:44 +00:00
parent 9e134db9c7
commit c2ad6ebaaa
9 changed files with 106 additions and 47 deletions

View File

@ -39,6 +39,8 @@
/* This is used to register protocols. */
struct net_protocol {
int (*early_demux)(struct sk_buff *skb);
int (*early_demux_handler)(struct sk_buff *skb);
int (*handler)(struct sk_buff *skb);
void (*err_handler)(struct sk_buff *skb, u32 info);
unsigned int no_policy:1,
@ -52,6 +54,8 @@ struct net_protocol {
#if IS_ENABLED(CONFIG_IPV6)
struct inet6_protocol {
void (*early_demux)(struct sk_buff *skb);
void (*early_demux_handler)(struct sk_buff *skb);
int (*handler)(struct sk_buff *skb);
void (*err_handler)(struct sk_buff *skb,

View File

@ -901,8 +901,6 @@ static inline int tcp_v6_sdif(const struct sk_buff *skb)
#endif
return 0;
}
void tcp_v6_early_demux(struct sk_buff *skb);
#endif
static inline bool inet_exact_dif_match(struct net *net, struct sk_buff *skb)

View File

@ -173,7 +173,6 @@ typedef struct sock *(*udp_lookup_t)(struct sk_buff *skb, __be16 sport,
struct sk_buff *udp_gro_receive(struct list_head *head, struct sk_buff *skb,
struct udphdr *uh, udp_lookup_t lookup);
int udp_gro_complete(struct sk_buff *skb, int nhoff, udp_lookup_t lookup);
void udp_v6_early_demux(struct sk_buff *skb);
struct sk_buff *__udp_gso_segment(struct sk_buff *gso_skb,
netdev_features_t features);

View File

@ -1678,7 +1678,12 @@ static const struct net_protocol igmp_protocol = {
};
#endif
static const struct net_protocol tcp_protocol = {
/* thinking of making this const? Don't.
* early_demux can change based on sysctl.
*/
static struct net_protocol tcp_protocol = {
.early_demux = tcp_v4_early_demux,
.early_demux_handler = tcp_v4_early_demux,
.handler = tcp_v4_rcv,
.err_handler = tcp_v4_err,
.no_policy = 1,
@ -1686,7 +1691,12 @@ static const struct net_protocol tcp_protocol = {
.icmp_strict_tag_validation = 1,
};
static const struct net_protocol udp_protocol = {
/* thinking of making this const? Don't.
* early_demux can change based on sysctl.
*/
static struct net_protocol udp_protocol = {
.early_demux = udp_v4_early_demux,
.early_demux_handler = udp_v4_early_demux,
.handler = udp_rcv,
.err_handler = udp_err,
.no_policy = 1,

View File

@ -306,38 +306,28 @@ drop:
return true;
}
int udp_v4_early_demux(struct sk_buff *);
int tcp_v4_early_demux(struct sk_buff *);
static int ip_rcv_finish_core(struct net *net, struct sock *sk,
struct sk_buff *skb, struct net_device *dev)
{
const struct iphdr *iph = ip_hdr(skb);
int (*edemux)(struct sk_buff *skb);
struct rtable *rt;
int err;
if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
if (net->ipv4.sysctl_ip_early_demux &&
!skb_dst(skb) &&
!skb->sk &&
!ip_is_fragment(iph)) {
switch (iph->protocol) {
case IPPROTO_TCP:
if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux)) {
tcp_v4_early_demux(skb);
const struct net_protocol *ipprot;
int protocol = iph->protocol;
/* must reload iph, skb->head might have changed */
iph = ip_hdr(skb);
}
break;
case IPPROTO_UDP:
if (READ_ONCE(net->ipv4.sysctl_udp_early_demux)) {
err = udp_v4_early_demux(skb);
if (unlikely(err))
goto drop_error;
/* must reload iph, skb->head might have changed */
iph = ip_hdr(skb);
}
break;
ipprot = rcu_dereference(inet_protos[protocol]);
if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) {
err = edemux(skb);
if (unlikely(err))
goto drop_error;
/* must reload iph, skb->head might have changed */
iph = ip_hdr(skb);
}
}

View File

@ -332,6 +332,61 @@ bad_key:
return ret;
}
static void proc_configure_early_demux(int enabled, int protocol)
{
struct net_protocol *ipprot;
#if IS_ENABLED(CONFIG_IPV6)
struct inet6_protocol *ip6prot;
#endif
rcu_read_lock();
ipprot = rcu_dereference(inet_protos[protocol]);
if (ipprot)
ipprot->early_demux = enabled ? ipprot->early_demux_handler :
NULL;
#if IS_ENABLED(CONFIG_IPV6)
ip6prot = rcu_dereference(inet6_protos[protocol]);
if (ip6prot)
ip6prot->early_demux = enabled ? ip6prot->early_demux_handler :
NULL;
#endif
rcu_read_unlock();
}
static int proc_tcp_early_demux(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int ret = 0;
ret = proc_dointvec(table, write, buffer, lenp, ppos);
if (write && !ret) {
int enabled = init_net.ipv4.sysctl_tcp_early_demux;
proc_configure_early_demux(enabled, IPPROTO_TCP);
}
return ret;
}
static int proc_udp_early_demux(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int ret = 0;
ret = proc_dointvec(table, write, buffer, lenp, ppos);
if (write && !ret) {
int enabled = init_net.ipv4.sysctl_udp_early_demux;
proc_configure_early_demux(enabled, IPPROTO_UDP);
}
return ret;
}
static int proc_tfo_blackhole_detect_timeout(struct ctl_table *table,
int write,
void __user *buffer,
@ -583,14 +638,14 @@ static struct ctl_table ipv4_net_table[] = {
.data = &init_net.ipv4.sysctl_udp_early_demux,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_douintvec_minmax,
.proc_handler = proc_udp_early_demux
},
{
.procname = "tcp_early_demux",
.data = &init_net.ipv4.sysctl_tcp_early_demux,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_douintvec_minmax,
.proc_handler = proc_tcp_early_demux
},
{
.procname = "ip_default_ttl",

View File

@ -47,25 +47,18 @@
#include <net/inet_ecn.h>
#include <net/dst_metadata.h>
void udp_v6_early_demux(struct sk_buff *);
void tcp_v6_early_demux(struct sk_buff *);
static void ip6_rcv_finish_core(struct net *net, struct sock *sk,
struct sk_buff *skb)
{
if (READ_ONCE(net->ipv4.sysctl_ip_early_demux) &&
!skb_dst(skb) && !skb->sk) {
switch (ipv6_hdr(skb)->nexthdr) {
case IPPROTO_TCP:
if (READ_ONCE(net->ipv4.sysctl_tcp_early_demux))
tcp_v6_early_demux(skb);
break;
case IPPROTO_UDP:
if (READ_ONCE(net->ipv4.sysctl_udp_early_demux))
udp_v6_early_demux(skb);
break;
}
}
void (*edemux)(struct sk_buff *skb);
if (net->ipv4.sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {
const struct inet6_protocol *ipprot;
ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]);
if (ipprot && (edemux = READ_ONCE(ipprot->early_demux)))
edemux(skb);
}
if (!skb_valid_dst(skb))
ip6_route_input(skb);
}

View File

@ -1673,7 +1673,7 @@ do_time_wait:
goto discard_it;
}
void tcp_v6_early_demux(struct sk_buff *skb)
static void tcp_v6_early_demux(struct sk_buff *skb)
{
const struct ipv6hdr *hdr;
const struct tcphdr *th;
@ -2028,7 +2028,12 @@ struct proto tcpv6_prot = {
.diag_destroy = tcp_abort,
};
static const struct inet6_protocol tcpv6_protocol = {
/* thinking of making this const? Don't.
* early_demux can change based on sysctl.
*/
static struct inet6_protocol tcpv6_protocol = {
.early_demux = tcp_v6_early_demux,
.early_demux_handler = tcp_v6_early_demux,
.handler = tcp_v6_rcv,
.err_handler = tcp_v6_err,
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,

View File

@ -912,7 +912,7 @@ static struct sock *__udp6_lib_demux_lookup(struct net *net,
return NULL;
}
void udp_v6_early_demux(struct sk_buff *skb)
static void udp_v6_early_demux(struct sk_buff *skb)
{
struct net *net = dev_net(skb->dev);
const struct udphdr *uh;
@ -1533,7 +1533,12 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
}
#endif
static const struct inet6_protocol udpv6_protocol = {
/* thinking of making this const? Don't.
* early_demux can change based on sysctl.
*/
static struct inet6_protocol udpv6_protocol = {
.early_demux = udp_v6_early_demux,
.early_demux_handler = udp_v6_early_demux,
.handler = udpv6_rcv,
.err_handler = udpv6_err,
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,