在内核编译时启用 IP 转发

Jul*_*Nut 2 compiling ip kernel linux-kernel forwarding

我正在为路由器编译内核。我知道一种在现有 Linux 系统中启用 IP 转发的方法。在编译时,CONFIG_IP_FORWARD据说做同样的任务。

我正在使用基于 GTK 的内核配置工具 ( gconfig)配置 vanilla 内核的 3.12.14 版。但是,我在任何地方都看不到此选项。最近的内核中是否有备用配置选项,还是我遗漏了什么?

Tho*_*man 5

CONFIG_IP_FORWARDING2.0.x 内核系列开始,Linux 内核源就没有这个选项了。据我所知,已经没有编译时选项可以默认为内置内核启用 IP 转发。

从 2.1.x 系列开始,为 IPv4 启用 IP 转发的正确方法一直是选项。net.ipv4.ip_forward sysctl

sysctl.conf将以下行添加到(或 中的文件/etc/sysctl.d):

net.ipv4.ip_forward = 1
Run Code Online (Sandbox Code Playgroud)

然后,sysctl重新加载配置:

sysctl -p /etc/sysctl.conf
Run Code Online (Sandbox Code Playgroud)

也就是说,如果由于某种原因您需要配置内核以便/proc在启动时不需要设置 sysctl 选项(或等效选项),您可以sysctl直接在内核源代码树中更改该选项的默认值*。

sysctl表条目/proc/sys/net/ipv4/ip_forward是从以下定义的静态结构初始化的net/ipv4/devinet.c

static struct ctl_table ctl_forward_entry[] = {
        {
                .procname       = "ip_forward",
                .data           = &ipv4_devconf.data[
                                        IPV4_DEVCONF_FORWARDING - 1],
                .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = devinet_sysctl_forward,
                .extra1         = &ipv4_devconf,
                .extra2         = &init_net,
        },
        { },
};
Run Code Online (Sandbox Code Playgroud)

data字段被初始化为指向整数数组中的一个条目,该数组data是静态ipv4_devconf结构中的一个字段。该条目由 中IPV4_DEVCONF_FORWARDING定义的枚举值标识include/uapi/linux/ip.hdata结构中包含的数组只是部分初始化,省略了IPV4_DEVCONF_FORWARDING条目。由于结构具有静态存储,所有整型成员都初始化为零。因此,要为ip_forward sysctl表条目设置数据字段,以及记录的默认值,我们需要ipv4_devconf.data[IPV4_DEVCONF_FORWARD - 1]ipv4_devconf_dflt结构中的相应字段初始化为1。这可以通过以下补丁来实现:

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index bdbf68b..91fe073 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -69,6 +69,7 @@

 static struct ipv4_devconf ipv4_devconf = {
        .data = {
+               [IPV4_DEVCONF_FORWARDING - 1] = 1,
                [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
                [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
                [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
@@ -80,6 +81,7 @@ static struct ipv4_devconf ipv4_devconf = {

 static struct ipv4_devconf ipv4_devconf_dflt = {
        .data = {
+               [IPV4_DEVCONF_FORWARDING - 1] = 1,
                [IPV4_DEVCONF_ACCEPT_REDIRECTS - 1] = 1,
                [IPV4_DEVCONF_SEND_REDIRECTS - 1] = 1,
                [IPV4_DEVCONF_SECURE_REDIRECTS - 1] = 1,
Run Code Online (Sandbox Code Playgroud)

*免责声明:我不是 Linux 网络内部的专家,因此这里描述的方法完全有可能错过了通常由devinet_sysctl_forward()转发通常通过 启用时执行的一些初始化sysctl,因此请谨慎操作。上述补丁似乎适用于内核版本 3.14,/proc/sys/net/ipv4/ip_forward确实表明默认情况下启用转发,无需通过sysctl. 据我所知,3.12.14 在sysctl条目初始化方面似乎没有什么不同。我包含了补丁,希望它有用,但没有任何保证。