How to properly permanent enable ip forwarding in Linux with systemd?

I try to enable ip forwarding (between enp0s3 and tun0 interfaces) and write net.ipv4.ip_forward = 1 in /etc/sysctl.conf. After restart I have

$ cat /proc/sys/net/ipv4/ip_forward
1

But forwarding still not working. I try to add net.ipv4.conf.default.forwarding=1 in /etc/sysctl.conf. Now after restart I have

$ cat /proc/sys/net/ipv4/ip_forward
1
$ cat /proc/sys/net/ipv4/conf/default/forwarding
1
$ cat /proc/sys/net/ipv4/conf/all/forwarding
1
$ cat /proc/sys/net/ipv4/conf/enp0s3/forwarding
0
$ cat /proc/sys/net/ipv4/conf/tun0/forwarding
0

I can not enable /proc/sys/net/ipv4/conf/enp0s3/forwarding and /proc/sys/net/ipv4/conf/tun0/forwarding in sysctl.conf because these files do not exists at such early boot time:

systemd-sysctl[85]: Couldn't write '1' to 'net/ipv4/conf/enp0s3/forwarding', ignoring: No such file or directory
systemd-sysctl[85]: Couldn't write '1' to 'net/ipv4/conf/tun0/forwarding', ignoring: No such file or directory)

, more over tun0 is dynamic interface (can be added and removed at any time).

If I manually enable forwarding for enp0s3 and tun0 then forwarding works as expected.

So, how to properly enable forwarding for interfaces?

PS: Gentoo with kernel 4.1.15 and systemd 226

PPS: if my memory serves me some time ago net.ipv4.ip_forward = 1 was enough.


Solution 1:

I finally resolve problem. I use systemd (with networkd) and new feature about ip forwarding has been introduced in systemd-221: "IPForwarding=" - see https://github.com/systemd/systemd/blob/a2088fd025deb90839c909829e27eece40f7fce4/NEWS

From man systemd.network:

[NETWORK] SECTION OPTIONS

...

IPForward=

Configures IP forwarding for the network interface. If enabled incoming packets on the network interface will be forwarded to other interfaces according to the routing table. Takes either a boolean argument, or the values "ipv4" or "ipv6", which only enables IP forwarding for the specified address family, or "kernel", which preserves existing sysctl settings. This controls the net.ipv4.conf..forwarding and net.ipv6.conf..forwarding sysctl options of the network interface (see ip-sysctl.txt[1] for details about sysctl options). Defaults to "no".

Note: unless this option is turned on, or set to "kernel", no IP forwarding is done on this interface, even if this is globally turned on in the kernel, with the net.ipv4.ip_forward, net.ipv4.conf.all.forwarding, and net.ipv6.conf.all.forwarding sysctl options.

So now I use network file like following to enable ip forwarding (per interface):

# cat /etc/systemd/network/tun0.network
[Match]
Name=tun0

[Network]
IPForward=ipv4