You are not logged in.

#1 2024-10-10 19:35:58

SunBlade
Member
From: at home
Registered: 2023-02-18
Posts: 26

[WORKAROUND] networkd overwrites disable_ipv6

Hi, most of the time i use IPv4 only, but occasionally i enable IPv6 to test things. To quickly enable/disable IPv6 i added net.ipv6.conf.all.disable_ipv6=1 to /etc/sysctl.d/. This has been working well for over a year now.


Today i wanted to test some things (time to rummaged through my routers config again), but the obligatory ip a (before enabling IPv6 on my machine) surprised me with this:

#> ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether d8:bb:c1:6f:bb:bb brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether d8:bb:c1:6f:bb:ba brd ff:ff:ff:ff:ff:ff
4: lan@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:ac:3b:00 brd ff:ff:ff:ff:ff:ff
    inet 192.168.109.11/24 metric 1024 brd 192.168.109.255 scope global dynamic lan
       valid_lft 397sec preferred_lft 397sec
    inet6 2001:16b8:a40e:27f0:c8dc:8361:8c97:bd3b/64 scope global temporary dynamic
       valid_lft 6847sec preferred_lft 3247sec
    inet6 2001:16b8:a40e:27f0:5054:ff:feac:3b00/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 6847sec preferred_lft 3247sec
    inet6 2001:16b8:a433:75f0:5054:ff:feac:3b00/64 scope global deprecated dynamic mngtmpaddr noprefixroute
       valid_lft 6847sec preferred_lft 0sec
    inet6 fe80::9025:3b06:f89e:6fae/64 scope link stable-privacy proto kernel_ll
       valid_lft forever preferred_lft forever

Did i accidentally delete my config? no.

#> cat /etc/sysctl.d/99-Custom.conf
net.ipv6.conf.all.disable_ipv6=1

Was my config loaded? yes and no.

#> sysctl net.ipv6.conf | grep -F "disable_ipv6"
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.eth1.disable_ipv6 = 1
net.ipv6.conf.lan.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 1

restart -> the exact same result
shutdown, wait, turn on -> the exact same result
what is going on here? some race condition? is my network config suddenly broken due to a systemd upgrade? is that a bug? can someone please explain.



Even if i explicitly add all interfaces to my config, lan will still enable IPv6 on boot.

$> cat /etc/sysctl.d/99-Custom.conf
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.eth0.disable_ipv6=1
net.ipv6.conf.eth1.disable_ipv6=1
net.ipv6.conf.lan.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
#> sysctl net.ipv6.conf | grep -F "disable_ipv6"
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1
net.ipv6.conf.eth1.disable_ipv6 = 1
net.ipv6.conf.lan.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 1

As a workaround i created a service which runs sysctl after network init.

$> cat /etc/systemd/system/disable_ipv6.service
[Unit]
Description=disable_ipv6.service

[Service]
Type=oneshot
ExecStart=-/usr/bin/sysctl -w net.ipv6.conf.all.disable_ipv6=1

[Install]
WantedBy=network-online.target

To clarify lan is a MACVLAN interface. In my opinion that is the best way if you want to integrate virtual machines into your network and host.
And here is my systemd-networkd config:

#> cat /etc/systemd/network/10-eth0.link
[Match]
PermanentMACAddress=d8:bb:c1:6f:bb:bb

[Link]
NamePolicy=
Name=eth0
#> cat /etc/systemd/network/10-eth1.link
[Match]
PermanentMACAddress=d8:bb:c1:6f:bb:ba

[Link]
NamePolicy=
Name=eth1
#> cat /etc/systemd/network/10-lan.netdev
[NetDev]
Name=lan
Kind=macvlan

[MACVLAN]
Mode=bridge
#> cat /etc/systemd/network/10-eth0.network
[Match]
Name=eth0

[Link]
RequiredForOnline=no

[Network]
MACVLAN=lan
#DHCP=yes
#DNSOverTLS=no
# why is v4 off by default but v6 on!?!
IPv6LinkLocalAddressGenerationMode=none
#> cat /etc/systemd/network/10-lan.network
[Match]
Name=lan

[Link]
MACAddress=52:54:00:AC:3B:00
RequiredForOnline=yes

[Network]
DHCP=ipv4
DNSOverTLS=no
IPv6LinkLocalAddressGenerationMode=random
IPv6PrivacyExtensions=yes

[DHCPv4]
SendHostname=true
# where is the easy to configure string option?!?
#ClientIdentifier=name
ClientIdentifier=mac
UseDNS=true
UseNTP=true
# you can not customise the client identifier?!?
#SendOption=61:string:\x00GMonster

Last edited by SunBlade (2024-10-19 08:04:59)


Live your life, you got only one.

Offline

#2 2024-10-11 11:26:12

-thc
Member
Registered: 2017-03-15
Posts: 685

Re: [WORKAROUND] networkd overwrites disable_ipv6

As long as I've used systemd-networkd the sysctl "IPv6 disable" options had no effect on the network setup whatsoever. They were ignored. I removed them.

The defaults of the relevant options in the systemd-networkd configuration files ("IPv6AcceptRA=yes", "LinkLocalAddressing=ipv6" and "IPv6LinkLocalAddressGenerationMode=eui64") allow interfaces to be configured via SLAAC - independent of the "DHCP=ipv4" setting.

If you want IPv4 only:

[Network]
DHCP=ipv4
IPv6AcceptRA=no
LinkLocalAddressing=no

Last edited by -thc (2024-10-11 14:23:53)

Offline

#3 2024-10-11 14:55:03

SunBlade
Member
From: at home
Registered: 2023-02-18
Posts: 26

Re: [WORKAROUND] networkd overwrites disable_ipv6

-thc wrote:

If you want IPv4 only:

No. As i already stated, i want a quick and easy way to temporarily enable IPv6. And

sudo sysctl -w net.ipv6.conf.all.disable_ipv6={0|1}

fits the bill exactly.



-thc wrote:

As long as I used systemd-networkd the sysctl "IPv6 disable" options had no effect on the network setup whatsoever. They were ignored. I removed them.

last time i did some IPv6 tests was in february. My sysctl config

#> cat /etc/sysctl.d/99-Custom.conf
net.ipv6.conf.all.disable_ipv6=1

was working as expected then. i was tinkering on my macvlan to get proper RA config from my router. That is when i learned that reboot is the most surefire method to update networkd config.
All interfaces did start without IPv6 then.
When my macvlan was properly configured i could start my test VMs. But every time my IPv6-only test VM could not connect to my host machine, i was painfully reminded that i did reboot recently and needed to enable IPv6 again.


Live your life, you got only one.

Offline

#4 2024-10-11 15:35:28

-thc
Member
Registered: 2017-03-15
Posts: 685

Re: [WORKAROUND] networkd overwrites disable_ipv6

If you take a look at the Wiki (https://wiki.archlinux.org/title/IPv6#Disable_IPv6) the sysctl settings imply they would work after a restart - but they don't - because it's too early:

Oct 11 17:22:00 vArch systemd-sysctl[227]: Couldn't write '1' to 'net/ipv6/conf/enp0s3/disable_ipv6'. ignoring: No such file or directory

Your workaround is probably the best compromise.

Offline

#5 2024-10-11 17:03:23

SunBlade
Member
From: at home
Registered: 2023-02-18
Posts: 26

Re: [WORKAROUND] networkd overwrites disable_ipv6

-thc wrote:

If you take a look at the Wiki (https://wiki.archlinux.org/title/IPv6#Disable_IPv6) the sysctl settings imply they would work after a restart - but they don't - because it's too early:

Thanks for the reminder. I did forget to check the journal for those errors:

#> journalctl --no-hostname --no-pager -ab|grep -F "ipv6"
Okt 10 20:15:01 systemd-sysctl[556]: Couldn't write '1' to 'net/ipv6/conf/eth0/disable_ipv6', ignoring: No such file or directory
Okt 10 20:15:01 systemd-sysctl[556]: Couldn't write '1' to 'net/ipv6/conf/eth1/disable_ipv6', ignoring: No such file or directory
Okt 10 20:15:01 systemd-sysctl[556]: Couldn't write '1' to 'net/ipv6/conf/lan/disable_ipv6', ignoring: No such file or directory
Okt 10 20:15:05 systemd[1]: Starting disable_ipv6.service...
Okt 10 20:15:05 sysctl[1123]: net.ipv6.conf.all.disable_ipv6 = 1
Okt 10 20:15:05 systemd[1]: disable_ipv6.service: Deactivated successfully.
Okt 10 20:15:05 systemd[1]: Finished disable_ipv6.service.

This now begs the question: is this a bug or is the wiki outdated?


Live your life, you got only one.

Offline

#6 2024-10-12 06:57:02

-thc
Member
Registered: 2017-03-15
Posts: 685

Re: [WORKAROUND] networkd overwrites disable_ipv6

I don't know who's to blame here - and maybe no one in particular.

The sysctl settings regarding disabling IPv6 should only be applied when all interfaces are present. But if the systemd-sysctl unit waits for the target "network.target" it leads to a non-resolvable mess: systemd-resolved wants to be started after systemd-sysctl but before "network.target".

IMHO the current state of the systemd units prevents applying those settings at boot time due to non-trivial timing issues. Maybe the Wiki should mention this.

Your workaround is IMHO still the best compromise.

Offline

#7 2024-10-15 19:03:33

SunBlade
Member
From: at home
Registered: 2023-02-18
Posts: 26

Re: [WORKAROUND] networkd overwrites disable_ipv6

after reading the man pages of sysctl and networkd (yes i have that much time), i am still not sure if this is a bug or intended behaviour.

currently it looks like networkd ignores sysctl net.ipv6.conf.default.disable_ipv6={0|1} when configuring interfaces.
an interfaces disable_ipv6 is reset to 0 by networkd unless IPv6LinkLocalAddressGenerationMode=none is specified, which is counterproductive because that completely disables IPv6 on the interface.

so, upstream i made a bug report / request for clarification:
https://github.com/systemd/systemd/issues/34782


-thc wrote:

Maybe the Wiki should mention this.

Yea... after i get a confirmation what exactly the intended behaviour is, maybe i'll work on the wiki page.


Live your life, you got only one.

Offline

#8 2024-10-19 09:32:32

SunBlade
Member
From: at home
Registered: 2023-02-18
Posts: 26

Re: [WORKAROUND] networkd overwrites disable_ipv6

as it currently stands, ignoring the default config of disable_ipv6 and setting the value depending on whether the user has completely disabled IPv6 on that interface or not, is the intended behaviour of networkd.
since the kernel properly spins up and shuts down the IPv6 stack when this value changes, i assumed this to be a user-only configured value. but i guess i was wrong about that.

enabling the stack on an interface which has no LinkLocalAddress is a waste of resources. and keeping the stack disabled when the user specifies an IPv6 config, probably results in a bug report. so, i can understand why networkd wants to enable/disable the IPv6 stack depending on the configuration.

for people who want a quick and easy way to enable/disable IPv6 via sysctl, this unit enforces the configured default state of the IPv6 stack on all interfaces each time after networkd has configured them:

#> cat /etc/systemd/system/enforce_disable_ipv6.service
[Unit]
Description=enforce default disable_ipv6
AssertPathExists=/proc/sys/net/ipv6/conf/all/disable_ipv6
AssertPathExists=/proc/sys/net/ipv6/conf/default/disable_ipv6
After=systemd-networkd.service
PartOf=systemd-networkd.service

[Service]
Type=oneshot
ExecStart=-/usr/bin/cp --no-preserve=all -T /proc/sys/net/ipv6/conf/default/disable_ipv6 /proc/sys/net/ipv6/conf/all/disable_ipv6

[Install]
WantedBy=systemd-networkd.service

#> systemctl enable --now enforce_disable_ipv6.service
Created symlink '/etc/systemd/system/systemd-networkd.service.wants/enforce_disable_ipv6.service' → '/etc/systemd/system/enforce_disable_ipv6.service'.

Live your life, you got only one.

Offline

Board footer

Powered by FluxBB