Search code examples
systemdbootu-boot

systemd boot: Apply IP address for eth0 from U-Boot environment?


I have a yocto-based embedded Linux system using systemd. U-Boot/coreboot is used as used to boot the system. There are IP-Addresses stored in the U-Boot environment ...

=> printenv ipaddr
ipaddr=192.168.0.100

... as well as in systemd's /lib/systemd/network/wired.network:

[Match]
Name=eth0

[Network]
Address=192.168.0.100/24

.

For testing multiple devices, I need to alter IP addresses, as multiple devices are connected to the network at the same time.

Changing the systemd network file each time is no option, as after an update (with a complete rootfs image, and so the systemd config) it would be reset to the default values. So my idea was to provide the U-Boot IP address to the Linux kernel via kernel command line, as I have seen working on other devices before. Unfortunately, I was unable find information on how to do this on systemd, all examples I found were on System V.

My approach is to enhance the original (NFS in this case) boot cmdline:

# cat /proc/cmdline
console=ttyS4,115200 rootwait rw loglevel=1 macaddress=02:00:00:FF:FF:FF root=/dev/nfs nfsroot=192.168.0.1:/srv/nfs/192.168.0.100,v3 ip=192.168.0.100:192.168.0.1:192.168.0.1:255.255.255.0::eth0:off

by appending something like systemd.setenv=ipaddr=192.168.0.100 or ipaddr=192.168.0.100, and referring to this in the systemd network configuration:

[Match]
Name=eth0

[Network]
Address=${ipaddr}/24

.

However, this does not show the desired result, all I achieved, was a system hanging on:

[  OK  ] Started System Logger Daemon.
[  OK  ] Started Network Service.
[  OK  ] Started Login Service.
[  OK  ] Started Resetting boot counter.
[  OK  ] Started Bluetooth service.
[  OK  ] Reached target Bluetooth.
[  OK  ] Started Usermode Init Manager for TI Shared Transport line discipline.
         **Starting Wait for Network to be Configured...**
[  OK  ] Started Thermal Daemon Service.
         Starting Hostname Service...

Systemd version is: systemd 234 -PAM -AUDIT -SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP -LIBCRYPTSETUP -GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN2 -IDN default-hierarchy=hybrid

Can anyone tell, if this is possible at all? And if, how to get thigs sorted? Any hint would be helpful.


Solution

  • Found the solution:

    as systemd-networkd(8) states:

    Any links not matched by one of the .network files will be ignored. [...] When systemd-networkd exits, it generally leaves existing network devices and configuration intact. This makes it possible to transition from the initramfs and to restart the service without breaking connectivity.

    As Xypron pointed out, the kernel uses the ip= command line parameter to configure the network interface, which I already provided. Which means, that it is simply enough to not re-configure the interface via systemd at all!

    Simply deleting the network configuration is all that is required. In case the ip= parameter is not provided (in a default U-Boot configuration, whilst booting from mmc) however, we should provide a default for the eth0 interface to come up. We can achieve this by not deleting the file, but rather setting the KernelCommandLine= condition:

    cat <<"EOF" > /lib/systemd/network/wired.network
    [Match]
    Name=eth0
    KernelCommandLine=!ip
    
    [Network]
    Address=192.168.0.100/24
    EOF
    

    That's all folks...