I run lxc on a Gentoo host and created a container (Alpine Linux) with the following network setup:
lxc.net.0.type = veth
lxc.net.0.veth.mode = router
lxc.net.0.link = vl291
lxc.net.0.veth.pair = vl291get
lxc.net.0.name = eth0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 02:b6:aa:9b:87:29
lxc.net.0.ipv4.address = 192.168.191.4/32
lxc.net.0.ipv4.gateway = auto
lxc.net.0.l2proxy = 1
The host is connected to two networks – ip -br a s up
(after container start):
lo UNKNOWN 127.0.0.1/8 ::1/128
vl191 UP xxx.yyy.zzz.3/24 fe80::6e2b:59ff:feb0:2534/64
vl291 UP 192.168.191.3/24 fe80::6e2b:59ff:feb0:2535/64
vl291get@if2 UP fe80::fc91:d2ff:fed6:1400/64
(xxx.yyy.zzz.3
is a public IP address). A static route is created, by LXC, to the container IP address (as expected), ip r
:
default via xxx.yyy.zzz.1 dev vl191 metric 2
xxx.yyy.zzz.0/24 dev vl191 proto kernel scope link src xxx.yyy.zzz.3
192.168.191.0/24 dev vl291 proto kernel scope link src 192.168.191.3
192.168.191.4 dev vl291get scope link
However, the static route is missing a src
to set the source address – and with my setup ip route get 192.168.191.4
(from host) outputs:
192.168.191.4 dev vl291get src xxx.yyy.zzz.3 uid 0
cache
So when the host communicates with the container it will use the IP address of the other interface (i.e. not the IP address of the interface set by lxc.net.0.link
).
In my case this makes the connection between host and container non functional – because I also use policy based routing with the following rules (ip rule
):
0: from all lookup local
32764: from 192.168.191.3 lookup vl291 realms vl291/vl291
32765: from xxx.yyy.zzz.3 lookup vl191 realms vl191/vl191
32766: from all lookup main
32767: from all lookup default
So, the result is that packets from the host to the container will enter into the wrong table, vl191
(instead of vl291
). To fix this I ran:
ip route change 192.168.191.4 dev vl291get scope link src 192.168.191.3
and now:
$ ip r g 192.168.191.4
192.168.191.4 dev vl291get src 192.168.191.3 uid 0
cache
To be complete, I also had to add a static route in table vl291
in order to get my setup working (similar to the solution in #7152). Before this change table vl291
looked like this:
$ ip route show table vl291
default via 192.168.191.1 dev vl291 metric 3
192.168.191.0/24 dev vl291 scope link src 192.168.191.3 metric 3
i,e, all packets would go to interface vl291
(including those to 192.168.191.4
) – which can also be verified by running:
$ ip r g 192.168.191.4 from 192.168.191.3
192.168.191.4 from 192.168.191.3 dev vl291 table vl291 realms vl291/vl291 uid 0
cache
To fix this I added the following static route in table vl291
:
ip route add table vl291 192.168.191.4 dev vl291get src 192.168.191.3
In order to permanently solve this issue I run the above two ip-route commands in lxc.hook.start-host
. There are probably several other, perhaps better, ways to solve it… – but, my main question is if the lack of src
address in the static route (added by LXC) is intentional? I would rather expect it to be set to the IP address of the interface defined by lxc.net.0.veth.link
.