I have problem adding direct routes through systemd-networkd. What I'm trying to achieve is similar to:

ip a a 192.168.0.2/32 dev enp0s3
ip r a 192.168.0.1/32 dev enp0s3
ip r a default via 192.168.0.1

This is weird setup, I know, but I can't use usual ip a a 192.168.0.2/24 to reach gateway. For some reason whole /24 subnet is reachable through the gateway in this subnet. So this default route is not only for catch-all routes, but to reach subnet as well. So, I've created /etc/systemd/network/enp0s3.network:

[Match]
Name=enp0s3

[Address]
Address=192.168.0.2/32

[Route]
Destination=192.168.0.1/32

[Route]
Gateway=192.168.0.1

The problem with this setup is that second Route block is never executed. I did some debugging and here is the difference between what ip and systemd-networkd does for the first Route block.

# ip
192.168.0.1 dev enp0s3 scope link
# networkd
192.168.0.1 dev enp0s3 proto static

So systemd-networkd doesn't add scope link to the route. That's why an attempt to add default route via 192.168.0.1 fails with Network is unreachable error. This is fixable by

ip r c 192.168.0.1/32 dev enp0s3 # automatically adds `scope link`
ip r a default via 192.168.0.1   # added successfully

So my question is: should such behaviour be considered a systemd-networkd bug or am I using it wrong? I couldn't find any documentation regarding direct routes in networkd. For now I've disabled systemd-networkd and created service to run ip commands directly. But I'd like to use standard approach as this is CoreOS I'm trying to configure.

up vote 6 down vote accepted

So the solution here is a bit tricky: you need to add gateway as a pointopoint parameter with /32 mask. This works:

[Match]
Name=enp0s3

[Address]
Address=192.168.0.2
Peer=192.168.0.1/32

[Network]
Gateway=192.168.0.1
  • This solves a similar problem I had: if you have the DHCPServer enabled and there are multiple VLANs on the interface, the server will fail and the default route will not be set. Disabling the DHCPServer allows the default route to be set. Having a single VLAN allows it to be set. But with both the DHCPServer and multiple VLANs present the default route fails. This fixes the problem nicely so I am writing this here in the hopes that web crawlers pick this up. The documentation for "Peer" is woefully sparse. – rand'Chris Aug 16 at 21:20
  • I don't see a way to edit my comment above, but this doesn't actually solve my problem because this solution (using Peer) appears to break the broadcast address, which is necessary for DHCP. Question moved to: serverfault.com/questions/926853/… – rand'Chris Aug 17 at 14:20

What you want is to specify how the Gateway can be reached via the local scope. That is it in fact reachable on the same segment. You example is merely missing the line Scope=link.

[Match]
Name=enp0s3

[Address]
Address=192.168.0.2/32

[Route]
Destination=192.168.0.1/32
Scope=link

[Route]
Gateway=192.168.0.1

I have a similar setup for IPv6 (someone describing the case here: https://phyks.me/2014/11/getting-ipv6-to-work-with-a-kimsufi-server.html).

For your case it would translate as such:

[Math]
Name=enp0s3

[Network]
Address=192.168.0.2/32
Gateway=192.168.0.1

[Route]
Destination=192.168.0.1

It works OK (in my case at least), although I’ve recently noticed systemd-networkd outputing enp1s0f0: Could not set NDisc route or address: Invalid argument. But not sure of why and my system still works.

EDIT: This error seems unrelated. I’ve discovered that my provider has enabled RA, so I’m not even specifying a Gateway anymore (just an Address, no Route) and still have this error.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.