Make it possible to build IP stack as a module

This is not pretty, but it works.
This commit is contained in:
Ole André Vadla Ravnås 2022-05-10 00:47:37 +02:00
parent 9dc4573cce
commit 77b228276c
26 changed files with 1494 additions and 25 deletions

View file

@ -234,7 +234,7 @@ static inline bool ip_is_fragment(const struct iphdr *iph)
return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
} }
#ifdef CONFIG_INET #if IS_ENABLED(CONFIG_INET)
#include <net/dst.h> #include <net/dst.h>
/* The function in 2.2 was invalid, producing wrong result for /* The function in 2.2 was invalid, producing wrong result for
@ -404,7 +404,7 @@ enum ip_defrag_users {
}; };
int ip_defrag(struct sk_buff *skb, u32 user); int ip_defrag(struct sk_buff *skb, u32 user);
#ifdef CONFIG_INET #if IS_ENABLED(CONFIG_INET)
struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user); struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user);
#else #else
static inline struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) static inline struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)

4
net/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
#
# Generated files
#
Module.symvers

View file

@ -51,7 +51,7 @@ source "net/xfrm/Kconfig"
source "net/iucv/Kconfig" source "net/iucv/Kconfig"
config INET config INET
bool "TCP/IP networking" tristate "TCP/IP networking"
select CRYPTO select CRYPTO
select CRYPTO_AES select CRYPTO_AES
---help--- ---help---

View file

@ -32,7 +32,7 @@ static void net_secret_init(void)
} }
#endif #endif
#ifdef CONFIG_INET #if IS_ENABLED(CONFIG_INET)
static u32 seq_scale(u32 seq) static u32 seq_scale(u32 seq)
{ {
/* /*

View file

@ -2,7 +2,9 @@
# Makefile for the Linux TCP/IP (INET) layer. # Makefile for the Linux TCP/IP (INET) layer.
# #
obj-y := route.o inetpeer.o protocol.o \ obj-$(CONFIG_INET) += ipv4.o
ipv4-y := route.o inetpeer.o protocol.o \
ip_input.o ip_fragment.o ip_forward.o ip_options.o \ ip_input.o ip_fragment.o ip_forward.o ip_options.o \
ip_output.o ip_sockglue.o inet_hashtables.o \ ip_output.o ip_sockglue.o inet_hashtables.o \
inet_timewait_sock.o inet_connection_sock.o \ inet_timewait_sock.o inet_connection_sock.o \
@ -13,17 +15,21 @@ obj-y := route.o inetpeer.o protocol.o \
fib_frontend.o fib_semantics.o fib_trie.o \ fib_frontend.o fib_semantics.o fib_trie.o \
inet_fragment.o ping.o inet_fragment.o ping.o
ifeq ($(CONFIG_INET),m)
ipv4-y += module_lib.o
endif
obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o ipv4-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
obj-$(CONFIG_SYSFS) += sysfs_net_ipv4.o ipv4-$(CONFIG_SYSFS) += sysfs_net_ipv4.o
obj-$(CONFIG_PROC_FS) += proc.o ipv4-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o ipv4-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o
obj-$(CONFIG_IP_MROUTE) += ipmr.o ipv4-$(CONFIG_IP_MROUTE) += ipmr.o
obj-$(CONFIG_NET_IPIP) += ipip.o obj-$(CONFIG_NET_IPIP) += ipip.o
obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o
obj-$(CONFIG_NET_IPGRE) += ip_gre.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o
obj-$(CONFIG_NET_IPVTI) += ip_vti.o obj-$(CONFIG_NET_IPVTI) += ip_vti.o
obj-$(CONFIG_SYN_COOKIES) += syncookies.o ipv4-$(CONFIG_SYN_COOKIES) += syncookies.o
obj-$(CONFIG_INET_AH) += ah4.o obj-$(CONFIG_INET_AH) += ah4.o
obj-$(CONFIG_INET_ESP) += esp4.o obj-$(CONFIG_INET_ESP) += esp4.o
obj-$(CONFIG_INET_IPCOMP) += ipcomp.o obj-$(CONFIG_INET_IPCOMP) += ipcomp.o
@ -33,8 +39,8 @@ obj-$(CONFIG_INET_LRO) += inet_lro.o
obj-$(CONFIG_INET_TUNNEL) += tunnel4.o obj-$(CONFIG_INET_TUNNEL) += tunnel4.o
obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
obj-$(CONFIG_IP_PNP) += ipconfig.o ipv4-$(CONFIG_IP_PNP) += ipconfig.o
obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/ ipv4-$(CONFIG_NETFILTER) += netfilter.o netfilter/
obj-$(CONFIG_INET_DIAG) += inet_diag.o obj-$(CONFIG_INET_DIAG) += inet_diag.o
obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o obj-$(CONFIG_INET_UDP_DIAG) += udp_diag.o
@ -51,8 +57,8 @@ obj-$(CONFIG_TCP_CONG_SCALABLE) += tcp_scalable.o
obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
obj-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o ipv4-$(CONFIG_MEMCG_KMEM) += tcp_memcontrol.o
obj-$(CONFIG_NETLABEL) += cipso_ipv4.o ipv4-$(CONFIG_NETLABEL) += cipso_ipv4.o
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ ipv4-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
xfrm4_output.o xfrm4_output.o

View file

@ -119,6 +119,10 @@
#include <linux/mroute.h> #include <linux/mroute.h>
#endif #endif
MODULE_AUTHOR("Cast of dozens");
MODULE_DESCRIPTION("IPv4 protocol stack for Linux");
MODULE_LICENSE("GPL");
#ifdef CONFIG_ANDROID_PARANOID_NETWORK #ifdef CONFIG_ANDROID_PARANOID_NETWORK
#include <linux/android_aid.h> #include <linux/android_aid.h>
@ -1702,13 +1706,23 @@ static int __init ipv4_offload_init(void)
return 0; return 0;
} }
#ifndef CONFIG_INET_MODULE
fs_initcall(ipv4_offload_init); fs_initcall(ipv4_offload_init);
#endif
static struct packet_type ip_packet_type __read_mostly = { static struct packet_type ip_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_IP), .type = cpu_to_be16(ETH_P_IP),
.func = ip_rcv, .func = ip_rcv,
}; };
#ifdef CONFIG_INET_MODULE
int tcp_congestion_init(void);
int tcp_fastopen_init(void);
int sysctl_ipv4_init(void);
int sysfs_ipv4_init(void);
int tcp_memcontrol_init(void);
#endif
static int __init inet_init(void) static int __init inet_init(void)
{ {
struct inet_protosw *q; struct inet_protosw *q;
@ -1717,6 +1731,12 @@ static int __init inet_init(void)
BUILD_BUG_ON(sizeof(struct inet_skb_parm) > FIELD_SIZEOF(struct sk_buff, cb)); BUILD_BUG_ON(sizeof(struct inet_skb_parm) > FIELD_SIZEOF(struct sk_buff, cb));
#ifdef CONFIG_INET_MODULE
tcp_congestion_init();
tcp_fastopen_init();
ipv4_offload_init();
#endif
sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL); sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL);
if (!sysctl_local_reserved_ports) if (!sysctl_local_reserved_ports)
goto out; goto out;
@ -1823,6 +1843,21 @@ static int __init inet_init(void)
dev_add_pack(&ip_packet_type); dev_add_pack(&ip_packet_type);
#ifdef CONFIG_INET_MODULE
#ifdef CONFIG_SYSCTL
sysctl_ipv4_init();
#endif
#ifdef CONFIG_SYSFS
sysfs_ipv4_init();
#endif
#ifdef CONFIG_MEMCG_KMEM
tcp_memcontrol_init();
#endif
/* TODO: Implement unload logic */
try_module_get(THIS_MODULE);
#endif
rc = 0; rc = 0;
out: out:
return rc; return rc;

View file

@ -582,6 +582,7 @@ out:
return ret; return ret;
} }
} }
EXPORT_SYMBOL(__inet_hash_connect);
/* /*
* Bind a port for a connect operation and hash it. * Bind a port for a connect operation and hash it.

View file

@ -65,6 +65,7 @@ int inet_twsk_bind_unhash(struct inet_timewait_sock *tw,
*/ */
return 1; return 1;
} }
EXPORT_SYMBOL(inet_twsk_unhash);
/* Must be called with locally disabled BHs. */ /* Must be called with locally disabled BHs. */
static void __inet_twsk_kill(struct inet_timewait_sock *tw, static void __inet_twsk_kill(struct inet_timewait_sock *tw,

1370
net/ipv4/module_lib.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -59,7 +59,9 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
sockets = proto_sockets_allocated_sum_positive(&tcp_prot); sockets = proto_sockets_allocated_sum_positive(&tcp_prot);
local_bh_enable(); local_bh_enable();
#ifndef CONFIG_INET_MODULE
socket_seq_show(seq); socket_seq_show(seq);
#endif
seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n", seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
sock_prot_inuse_get(net, &tcp_prot), orphans, sock_prot_inuse_get(net, &tcp_prot), orphans,
tcp_death_row.tw_count, sockets, tcp_death_row.tw_count, sockets,

View file

@ -958,7 +958,11 @@ static __net_initdata struct pernet_operations ipv4_sysctl_ops = {
.exit = ipv4_sysctl_exit_net, .exit = ipv4_sysctl_exit_net,
}; };
#ifdef CONFIG_INET_MODULE
int sysctl_ipv4_init(void)
#else
static __init int sysctl_ipv4_init(void) static __init int sysctl_ipv4_init(void)
#endif
{ {
struct ctl_table_header *hdr; struct ctl_table_header *hdr;
struct ctl_table *i; struct ctl_table *i;
@ -984,4 +988,6 @@ static __init int sysctl_ipv4_init(void)
return 0; return 0;
} }
#ifndef CONFIG_INET_MODULE
__initcall(sysctl_ipv4_init); __initcall(sysctl_ipv4_init);
#endif

View file

@ -67,7 +67,11 @@ static struct attribute_group ipv4_attr_group = {
.attrs = ipv4_attrs, .attrs = ipv4_attrs,
}; };
#ifdef CONFIG_INET_MODULE
int sysfs_ipv4_init(void)
#else
static __init int sysfs_ipv4_init(void) static __init int sysfs_ipv4_init(void)
#endif
{ {
struct kobject *ipv4_kobject; struct kobject *ipv4_kobject;
int ret; int ret;
@ -85,4 +89,6 @@ static __init int sysfs_ipv4_init(void)
return 0; return 0;
} }
#ifndef CONFIG_INET_MODULE
subsys_initcall(sysfs_ipv4_init); subsys_initcall(sysfs_ipv4_init);
#endif

View file

@ -1245,8 +1245,10 @@ out:
out_nopush: out_nopush:
release_sock(sk); release_sock(sk);
#ifndef CONFIG_INET_MODULE
if (copied + copied_syn) if (copied + copied_syn)
uid_stat_tcp_snd(current_uid(), copied + copied_syn); uid_stat_tcp_snd(current_uid(), copied + copied_syn);
#endif
return copied + copied_syn; return copied + copied_syn;
do_fault: do_fault:
@ -1551,7 +1553,9 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
if (copied > 0) { if (copied > 0) {
tcp_recv_skb(sk, seq, &offset); tcp_recv_skb(sk, seq, &offset);
tcp_cleanup_rbuf(sk, copied); tcp_cleanup_rbuf(sk, copied);
#ifndef CONFIG_INET_MODULE
uid_stat_tcp_rcv(current_uid(), copied); uid_stat_tcp_rcv(current_uid(), copied);
#endif
} }
return copied; return copied;
} }
@ -1957,8 +1961,10 @@ skip_copy:
release_sock(sk); release_sock(sk);
#ifndef CONFIG_INET_MODULE
if (copied > 0) if (copied > 0)
uid_stat_tcp_rcv(current_uid(), copied); uid_stat_tcp_rcv(current_uid(), copied);
#endif
return copied; return copied;
out: out:
@ -1967,8 +1973,10 @@ out:
recv_urg: recv_urg:
err = tcp_recv_urg(sk, msg, len, flags); err = tcp_recv_urg(sk, msg, len, flags);
#ifndef CONFIG_INET_MODULE
if (err > 0) if (err > 0)
uid_stat_tcp_rcv(current_uid(), err); uid_stat_tcp_rcv(current_uid(), err);
#endif
goto out; goto out;
recv_sndq: recv_sndq:

View file

@ -137,12 +137,19 @@ int tcp_set_default_congestion_control(const char *name)
return ret; return ret;
} }
#ifdef CONFIG_INET_MODULE
int tcp_congestion_init(void)
#else
/* Set default value from kernel configuration at bootup */ /* Set default value from kernel configuration at bootup */
static int __init tcp_congestion_default(void) static int __init tcp_congestion_default(void)
#endif
{ {
return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG); return tcp_set_default_congestion_control(CONFIG_DEFAULT_TCP_CONG);
} }
#ifndef CONFIG_INET_MODULE
late_initcall(tcp_congestion_default); late_initcall(tcp_congestion_default);
#endif
/* Build string with list of available congestion control values */ /* Build string with list of available congestion control values */

View file

@ -80,7 +80,11 @@ void tcp_fastopen_cookie_gen(__be32 addr, struct tcp_fastopen_cookie *foc)
rcu_read_unlock(); rcu_read_unlock();
} }
#ifdef CONFIG_INET_MODULE
int tcp_fastopen_init(void)
#else
static int __init tcp_fastopen_init(void) static int __init tcp_fastopen_init(void)
#endif
{ {
__u8 key[TCP_FASTOPEN_KEY_LENGTH]; __u8 key[TCP_FASTOPEN_KEY_LENGTH];
@ -89,4 +93,6 @@ static int __init tcp_fastopen_init(void)
return 0; return 0;
} }
#ifndef CONFIG_INET_MODULE
late_initcall(tcp_fastopen_init); late_initcall(tcp_fastopen_init);
#endif

View file

@ -2891,7 +2891,7 @@ struct proto tcp_prot = {
.compat_setsockopt = compat_tcp_setsockopt, .compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt, .compat_getsockopt = compat_tcp_getsockopt,
#endif #endif
#ifdef CONFIG_MEMCG_KMEM #if defined(CONFIG_MEMCG_KMEM) && !defined(CONFIG_INET_MODULE)
.init_cgroup = tcp_init_cgroup, .init_cgroup = tcp_init_cgroup,
.destroy_cgroup = tcp_destroy_cgroup, .destroy_cgroup = tcp_destroy_cgroup,
.proto_cgroup = tcp_proto_cgroup, .proto_cgroup = tcp_proto_cgroup,

View file

@ -280,9 +280,15 @@ static struct cftype tcp_files[] = {
{ } /* terminate */ { } /* terminate */
}; };
#ifdef CONFIG_INET_MODULE
int tcp_memcontrol_init(void)
#else
static int __init tcp_memcontrol_init(void) static int __init tcp_memcontrol_init(void)
#endif
{ {
WARN_ON(cgroup_add_cftypes(&mem_cgroup_subsys, tcp_files)); WARN_ON(cgroup_add_cftypes(&mem_cgroup_subsys, tcp_files));
return 0; return 0;
} }
#ifndef CONFIG_INET_MODULE
__initcall(tcp_memcontrol_init); __initcall(tcp_memcontrol_init);
#endif

View file

@ -1413,7 +1413,9 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
is_udplite); is_udplite);
UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
kfree_skb(skb); kfree_skb(skb);
#ifndef CONFIG_INET_MODULE
trace_udp_fail_queue_rcv_skb(rc, sk); trace_udp_fail_queue_rcv_skb(rc, sk);
#endif
return -1; return -1;
} }

View file

@ -40,7 +40,14 @@ obj-$(CONFIG_IPV6_SIT) += sit.o
obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.o
obj-$(CONFIG_IPV6_GRE) += ip6_gre.o obj-$(CONFIG_IPV6_GRE) += ip6_gre.o
ifeq ($(CONFIG_INET),m)
ipv6-y += ip6_icmp.o
ipv6-y += output_core.o protocol.o $(ipv6-offload)
ipv6-y += inet6_hashtables.o
else
obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o obj-y += addrconf_core.o exthdrs_core.o ip6_checksum.o ip6_icmp.o
obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload) obj-$(CONFIG_INET) += output_core.o protocol.o $(ipv6-offload)
obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
endif

View file

@ -77,6 +77,8 @@ static inline int current_has_network(void)
} }
#endif #endif
#include "ip6_offload.h"
MODULE_AUTHOR("Cast of dozens"); MODULE_AUTHOR("Cast of dozens");
MODULE_DESCRIPTION("IPv6 protocol stack for Linux"); MODULE_DESCRIPTION("IPv6 protocol stack for Linux");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
@ -850,6 +852,8 @@ static int __init inet6_init(void)
BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > FIELD_SIZEOF(struct sk_buff, cb)); BUILD_BUG_ON(sizeof(struct inet6_skb_parm) > FIELD_SIZEOF(struct sk_buff, cb));
ipv6_offload_init();
/* Register the socket-side information for inet6_create. */ /* Register the socket-side information for inet6_create. */
for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) for (r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
INIT_LIST_HEAD(r); INIT_LIST_HEAD(r);

View file

@ -20,7 +20,7 @@ static const struct net_offload dstopt_offload = {
.flags = INET6_PROTO_GSO_EXTHDR, .flags = INET6_PROTO_GSO_EXTHDR,
}; };
int __init ipv6_exthdrs_offload_init(void) int ipv6_exthdrs_offload_init(void)
{ {
int ret; int ret;

View file

@ -264,7 +264,7 @@ static struct packet_offload ipv6_packet_offload __read_mostly = {
}, },
}; };
static int __init ipv6_offload_init(void) void ipv6_offload_init(void)
{ {
if (tcpv6_offload_init() < 0) if (tcpv6_offload_init() < 0)
@ -275,7 +275,4 @@ static int __init ipv6_offload_init(void)
pr_crit("%s: Cannot add EXTHDRS protocol offload\n", __func__); pr_crit("%s: Cannot add EXTHDRS protocol offload\n", __func__);
dev_add_offload(&ipv6_packet_offload); dev_add_offload(&ipv6_packet_offload);
return 0;
} }
fs_initcall(ipv6_offload_init);

View file

@ -11,6 +11,7 @@
#ifndef __ip6_offload_h #ifndef __ip6_offload_h
#define __ip6_offload_h #define __ip6_offload_h
void ipv6_offload_init(void);
int ipv6_exthdrs_offload_init(void); int ipv6_exthdrs_offload_init(void);
int udp_offload_init(void); int udp_offload_init(void);
int tcpv6_offload_init(void); int tcpv6_offload_init(void);

View file

@ -1945,7 +1945,7 @@ struct proto tcpv6_prot = {
.compat_setsockopt = compat_tcp_setsockopt, .compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt, .compat_getsockopt = compat_tcp_getsockopt,
#endif #endif
#ifdef CONFIG_MEMCG_KMEM #if defined(CONFIG_MEMCG_KMEM) && !defined(CONFIG_INET_MODULE)
.proto_cgroup = tcp_proto_cgroup, .proto_cgroup = tcp_proto_cgroup,
#endif #endif
.clear_sk = tcp_v6_clear_sk, .clear_sk = tcp_v6_clear_sk,

View file

@ -89,7 +89,7 @@ static const struct net_offload tcpv6_offload = {
}, },
}; };
int __init tcpv6_offload_init(void) int tcpv6_offload_init(void)
{ {
return inet6_add_offload(&tcpv6_offload, IPPROTO_TCP); return inet6_add_offload(&tcpv6_offload, IPPROTO_TCP);
} }

View file

@ -125,7 +125,7 @@ static const struct net_offload udpv6_offload = {
}, },
}; };
int __init udp_offload_init(void) int udp_offload_init(void)
{ {
return inet6_add_offload(&udpv6_offload, IPPROTO_UDP); return inet6_add_offload(&udpv6_offload, IPPROTO_UDP);
} }