Weird behavior when restarting networkd

Hi,

I’m following Stefan’s instructions from this answer:

I have this wired.network in /usr/lib/systemd/network :

[Match]
Name=eth0

[Network]
Address=192.168.102.1/24

Immediately after boot this works fine:

# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:14:2D:4A:4B:CF
          inet addr:192.168.102.1  Bcast:192.168.102.255  Mask:255.255.255.0

However, if I modify the IP address e.g. 192.168.102.2 and issue a systemctl restart systemd-networkd the ifconfig output does not change (as it should, as far as I can understand). However, this is the output from networkctl status:

# networkctl status
●      State: routable
     Address: 192.168.102.1 on eth0
              192.168.102.2 on eth0
              192.168.11.1 on usb0
              fe80::214:2dff:fe4a:4bcf on eth0

And if I change the IP address to end with 3 and restart the service another record is added to this list. The device will now answer pings on all 3 IP addresses. ifconfig output is still unchanged from the listing above, i.e. it report the IP address the device booted with, not the “latest” one.

This seems like a bug to me but could of course be some feature that I don’t understand. Could you please look into this?

This is currently a known limitation of systemd-networkd. The behavior has been intended at first, to allow the user to manually configuring IP addresses besides the running networkd service. With the release of systemd 228 this behavior has been changed and the network addresses will be removed (see also systemd issue #780). However, even our next release will likely not contain that fix yet (our next release will build upon Angstrom 2015.12, which uses systemd 225 or 226).

As a work around you can either just reboot the whole system or extend the systemd-networkd.service file with an additional commit

ExecStartPre=/sbin/ip addr flush dev eth0

By restarting the service, the new network settings should get applied:

systemctl restart systemd-networkd

Thank you Stefan, this does indeed work.

However, systemd-networkd (at least at its current version of 219) seems like it has some maturing to do. I did not use a capital N for “Name” in my configuration file (the config file I posted above apparently did not make it intact to my system). Instead of just refusing to load networking due to a config syntax error my rule now matched all interfaces and caused an interface named “sit0” (the ipv6 bridging interface) to be started as well with the same IP address as eth0. This had the odd consequence that any address on the network answered pings. I did some scratching of the head over that until I tried

journalctl -u systemd-networkd

which hinted at the core issue. For anyone reading this considering to go down this route there appears to be a lot of movement in networkd at the moment. I had intended to use the DHCPServer feature I found documented somewhere but apparently it was only added in September 2015, i.e. 227 which then probably will show up in the June-2016 version of Angstrom:

https://github.com/systemd/systemd/blame/master/src/network/networkd-network-gperf.gperf

Yeah there is indeed quite some movement in networkd development, especially in supplementary function such as DHCP. We use the DHCP functionality for the RNDIS interface (to provide an IP to the host) and discovered some oddity there too.

However, some features just works very nicely already today, e.g. we also used the bridging feature, which is really nice to configure through networkd.

One thing: the ip command is located in /sbin . Also, I had some trouble doing this via reload so I’m just restarting the service instead, can’t see any downsides to that. To summarize, this is what I added to /lib/systemd/system/systemd-networkd.service undir the [Service] section:

ExecStartPre=/sbin/ip addr flush dev eth0

And to load new network settings I just:

systemctl restart systemd-networkd

Thanks for the update! That makes sense, I will update my answer accordingly.