[systemd-devel] systemd-networkd, IPv6PrivacyExtensions=kernel, sysctl and devicenames

Andrei Borzenkov arvidjaar at gmail.com
Sat May 23 06:40:10 UTC 2020


22.05.2020 22:17, Ede Wolf пишет:
> Am 22.05.20 um 17:58 schrieb Andrei Borzenkov:
>>>
>>> The problem is, that sysctl.conf is being executed before the interfaces
>>> get their eventual names.
>>>
>>
>> That sounds like actual bug. What systemd version do you use?
> 
> At least it is, what the journal suggest, as seen below. However,
> generally it sounds like a good idea to read sysctl.conf as early as
> possible
> 
> 
> As for my version:
> 
> $  pacman -Qs systemd
> local/systemd 245.5-2
>     system and service manager
> local/systemd-libs 245.5-2
>     systemd client libraries
> local/systemd-sysvcompat 245.5-2
>     sysvinit compat for systemd
> 
> $ uname -a
> Linux willy 5.6.13-arch1-1 #1 SMP PREEMPT Thu, 14 May 2020 06:52:53
> +0000 x86_64 GNU/Linux
> 
> Same issues with the arch lts-kernel, this behaviour is consistent and
> easily reproducable.
> 
> 
>>>>> And the logs read:
>>>>>
>>>>> journalctl -b0 | grep -E 'sysctl|ens3|eth0'
>>>>> 08:56:46 systemd[263]: systemd-sysctl.service: Executing:
>>>>> /usr/lib/systemd/systemd-sysctl
>>>>> 08:56:46 systemd-sysctl[263]: Couldn't write '2' to
>>>>> 'net/ipv6/conf/ens3/addr_gen_mode', ignoring: No such file or
>>>>> directory
>>>>> 08:56:46 systemd-sysctl[263]: Couldn't write '2' to
>>>>> 'net/ipv6/conf/ens3/use_tempaddr', ignoring: No such file or directory

Sorry, I did not pay attention. Errors come from systemd-syctl service
which indeed runs concurrently with udev and races with interface
renaming. But udev also applies settings individually to each interface,
see below.

>>>>> 08:56:47 kernel: virtio_net virtio0 ens3: renamed from eth0
>>>>> 08:56:47 systemd[1]: sys-subsystem-net-devices-ens3.device: Changed
>>>>> dead
>>>>> -> plugged
>>>>> 08:56:47 systemd[1]:
>>>>> sys-devices-pci0000:00-0000:00:03.0-virtio0-net-ens3.device: Changed
>>>>> dead -> plugged
>>>>> 08:56:51 systemd-networkd[459]: ens3: Interface name change detected,
>>>>> ens3 has been renamed to eth0.
>>
>> I wonder where this comes from.
>>
>>>>> 08:56:51 systemd-networkd[459]: eth0: Interface name change detected,
>>>>> eth0 has been renamed to ens3.
>>>>> 08:56:51 systemd-networkd[459]: ens3: IPv6 successfully enabled
>>>>> 08:56:51 systemd-networkd[459]: ens3: Link UP
>>>>> 08:56:51 systemd-networkd[459]: ens3: Gained carrier
>>>>> ...
> 
> Same wonders here, but, despite the mysterial double renaming,
> systemd-sysctl is still being called before even the first rename. A
> good second here. So I have no chance to set any values for ens3 at all.
> 

Given lack of errors after interface rename, settings were most probably
applied correctly.

> 
>>
>> udev applies sysctl just once - when interface first appears. 
> 
> Any deeper insight on this? I was under the impression, sysctl is read
> by systemd-sysctl only and not by udev at all? But admittedly, I am not
> very knowledgable here. So I'd like to improve.
> 

udev invokes systemd-sysctl for specific interface as part of event
processing, normally in 99-systemd.rules but of course could be
anywhere. Just search for systemd-sysctl in rules files.

> 
>> using final name (that can be different from initial kernel name). So if
>> device appeared under eth0 and got name ens3 during event procesing,
>> udev applies sysctl to ens3 and never to eth0. If udev applied settings
>> to eth0 before rename, these settings would be preserved after rename.
> 
> That does at least not correspond to my observation.
> 
> It seems, the kernel creates
> 
> net/ipv6/conf/eth0/use_tempaddr
> 
> upon detection and after renaming,
> 
> net/ipv6/conf/ens3/use_tempaddr
> 
> does not keep the values.
> 

tw:~ # systemctl stop NetworkManager.service
tw:~ # ip l set dev enp0s5 down
tw:~ # cat /proc/sys/net/ipv6/conf/enp0s5/use_tempaddr
1
tw:~ # cat /proc/sys/net/ipv6/conf/enp0s5/addr_gen_mode
1
tw:~ # echo 3 > /proc/sys/net/ipv6/conf/enp0s5/addr_gen_mode
tw:~ # echo 2 > /proc/sys/net/ipv6/conf/enp0s5/use_tempaddr
tw:~ # cat /proc/sys/net/ipv6/conf/enp0s5/use_tempaddr
2
tw:~ # cat /proc/sys/net/ipv6/conf/enp0s5/addr_gen_mode
3
tw:~ # ip l set dev enp0s5 name ififif
tw:~ # ip l set dev ififif up
tw:~ # cat /proc/sys/net/ipv6/conf/ififif/use_tempaddr
2
tw:~ # cat /proc/sys/net/ipv6/conf/ififif/addr_gen_mode
3


What likely happens in your case is something else changes settings
after they had been applied by udev. Notice I had to stop NetworkManager
to avoid interfering as soon as link comes up.

> Is there a way to make systemd-sysctl a bit more verbose, so we can see
> wether the eth0 setting are actually being applied?
> 

Sure, you can simply set SYSTEMD_LOG_LEVEL=debug on kernel command line
and it will apply to all systemd components or you can set this variable
for specific service. But as mentioned earlier, errors that you see are
red herring - they are literally expected if you attempt to set sysctl
values for individual interface globally. Or you must make sure
interface gets final name before systemd-sysctl.service runs, e.g. in
initrd.

> So far we only see the error from ens3, but no positives from the eth0
> settings.
> 
> Nonetheless, this would still impose a problem. As the eth* names are
> not reliable, faking a setting intended for ens3 to eth0 in sysctl.conf
> is a bit risky and most likely not the idea behind the whole renaming
> thingy.
> 
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel



More information about the systemd-devel mailing list