0

I am currently trying to simulate a network using network namespaces under Linux. I have already set up the nodes and connected them, and they can ping each other, one hop at a time. But I am really struggling trying to enable IP forwarding.

I am using Ubuntu Server 21.04 and networking on my system is controlled by systemd-networkd. systemd's version is 247.3-3ubuntu3.4. net.ipv6.conf.all.forwarding and net.ipv4.ip_forward are already enabled. Because networkd is used, forwarding has to be enabled in configuration files additionally. For one of my namespaces, this looks as follows:

/etc/systemd/network/router1i.network:

[Match]
Name=router1i

[Network]
IPForward=yes

and /etc/systemd/network/router1i2.network:

[Match]
Name=router1i2

[Network]
IPForward=yes

Those (router1i and router1i2) are both veth interfaces and the only 2 interfaces in the namespace.

If I use the command ip -6 route get to fe80::1:0:200 iif router1i2 in the namespace, I get the correct answer fe80::1:0:200 from :: dev router1i2 proto kernel metric 256 iif router1i2 pref medium, because the route doesn't involve forwarding. If I use the similar command ip -6 route get to fe80::1:0:200 iif router1i, that starts from the other interface, the answer suddenly is RNETLINK answers: Network is unreachable. So apparently, forwarding isn't enabled.

I already tried to get networkd to update by using networkctl reconfigure router1i from within the namespace, but it says Failed to reconfigure network interface router1i: No such device or address. This is strange, because when I use networkctl status router1i, it lists all the information correctly. A full reload using networkctl reload was also already tried and doesn't change anything.

I'm honestly pretty much at my wit's end. I don't even necessarily need to get it to work with networkd. Any idea or workaround would be very much appreciated.

Edit:

I have now exchanged the link-local addresses with Unique Local Addresses, as dirkt suggested. The routes are now selected correctly judging from the output of ip -6 route get. But I still can't ping other network interfaces. I'll add the details below, because I honestly can't find the error.

Configuration of the interfaces:

ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip addr show
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
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
6: router1i@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether be:fc:8e:30:e4:18 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fd00:0:0:1000::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::bcfc:8eff:fe30:e418/64 scope link
       valid_lft forever preferred_lft forever
8: router1i2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d6:3f:e9:9a:93:f3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fd00:0:0:1001::1/63 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::d43f:e9ff:fe9a:93f3/64 scope link
       valid_lft forever preferred_lft forever

IPv6 Routing Table:

ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip -6 route
fd00:0:0:1000::/64 dev router1i proto kernel metric 256 pref medium
fd00:0:0:1000::/63 dev router1i2 proto kernel metric 256 pref medium
fe80::/64 dev router1i proto kernel metric 256 pref medium
fe80::/64 dev router1i2 proto kernel metric 256 pref medium
default via fd00:0:0:1001::2 dev router1i2 metric 1024 pref medium

Output of ip netconf:

ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip netconf
inet lo forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet router1i forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet router1i2 forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet all forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet default forwarding on rp_filter loose mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 lo forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 router1i forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 router1i2 forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 all forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off
inet6 default forwarding on mc_forwarding off proxy_neigh off ignore_routes_with_linkdown off

This now works correctly:

ubuntu@ubuntu:~$ sudo ip netns exec Router1 ip -6 route get to fd00:0:0:1001::2 iif router1i
fd00:0:0:1001::2 from :: dev router1i2 proto kernel metric 256 iif router1i pref medium

But when I try to actually ping that address from router1i, it says:

ubuntu@ubuntu:~$ sudo ip netns exec Router1 ping6 fd00:0:0:1001::2 -I router1i
ping6: connect: Network is unreachable

Forwarding is on and the correct route is selected, so why does it still not work?

Edit2:

I got it to work! Thanks to everyone who tried to help.

Apparently I misjudged what the ping with -I option does. This got me confused and my inexperience didn't help... In the end, I found out that the last piece missing was a wrong route in one of the outer namespaces that hindered it from answering the pings. I should have found that way sooner, but I got too obsessed with the forwarding issue...

So anyway, thanks again, and have a nice day!

4
  • 2
    fe80::/10 are link-local addresses though?
    – Tom Yan
    Aug 1 at 17:00
  • You are right about the link-local addresses, those were part of the problem. I exchanged them for Unique Local Addresses, as dirkt suggested. But even though the right route is now shown using "ip -6 route get", I still can't ping an interface from another interface on the same machine... "ip netconf" says "forwarding on" for every interface, but I still think, it may not be properly activated in the namespace.
    – ObiBabobi
    Aug 2 at 4:13
  • Does the destination have proper return routes for their reply though?
    – Tom Yan
    Aug 2 at 5:30
  • You are correct, this was the main issue... Thanks for the help!
    – ObiBabobi
    Aug 2 at 6:11
2

fe80::/10 are link local addresses. I think these are unroutable (though there may be some tricks to make them routable, I never tried).

If you want to play around with IPv6 routing, don't use these; instead, assign Unique Local Addresses (ULAs, range fc00::/7) in addition to the link-local addresses (which are usually autoconfigured) to your interfaces.

And you can also use ip -6 route get from ... to ... for debugging.

Set up routes as usual with ip route add ... while you are playing around.

Remember routes need to be set on all nodes (or in your case, namespaces) along the path of the packet, not only on the "forwarding" nodes (it's a typical beginner's mistake to forget that).


It's easier to make this work if you don't make your life difficult by trying to ping "from interfaces to interfaces" (I assume with -I).

Set up three namespaces A, B, C. Connect A and B with a veth pair, and connect B and C with a veth pair. Place ULA addresses (with correct subnets, one subnet for A/B, one subnet for B/C) on all four network interfaces. Set default routes on A and C (via the resp. B interface). Enable forwarding in B. Then, in A, try to ping the address on the near interface in B, then the address on the "far" interface in B, then C. Just use plain ping <addr>. See where it stops working (if it doesn't work right out of the box).

To debug, run tcpdump in four terminals on all four interfaces. Run an xterm (or multiple ones) in the network namespace, that makes debugging and set up a lot easier.

If it still doesn't work, make a new question, include all commands you made the above setup, include the pings that work, and for the pings that don't work, include the tcpdump output. (Remote debugging per Q&A is a PITA).

2
  • You are right, link-local addresses are not suited for what I want to do. Thank you very much, i did not know this! But still, even though the routes are now correctly shown using "ip -6 route get", pinging an interface from another interface still doesn't work...
    – ObiBabobi
    Aug 2 at 4:07
  • 1
    Sorry for me being so inexperienced. I made a bunch of new terminal windows (though with screen, not xterm) and ran tcpdump on them. First, I noticed, that the forwarding was actually working. But on router1i2 I had a bunch of Neigbor Solicitation messages, that requested an address that was not directly connected. I had forgotten to add a necessary next-hop... Now it works! I have apparently misjudged what ping with the -I option can and can't do. Sorry again for wasting your time, now it all seems so obvious. But please know that you have helped me out a lot, and that I have learned a lot!
    – ObiBabobi
    Aug 2 at 6:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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