Hi all, I am experiencing trouble with using Bird over IPv6 inside a VRF, and reduced this down to a problem with IPv6 `bind`.
I have a VRF called "vrf_freifunk", with some GRE tunnel devices in it: > 3: vrf_freifunk: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP > group default qlen 1000 > link/ether 6e:6d:9f:5d:f3:f2 brd ff:ff:ff:ff:ff:ff > 12: tun-up-a_ak@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1280 qdisc noqueue > master vrf_freifunk state UNKNOWN group default qlen 1000 > link/gre 82.165.162.239 peer 185.66.195.0 > inet 100.64.3.21/31 scope global tun-up-a_ak > valid_lft forever preferred_lft forever > inet6 2a03:2260:0:194::2/64 scope global > valid_lft forever preferred_lft forever > inet6 fe80::200:5efe:52a5:a2ef/64 scope link > valid_lft forever preferred_lft forever Now I am running the following python script to reproduce the problem: > #!/usr/bin/python3 > > > import socket > > s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP) > s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b"vrf_freifunk") > s.bind(("100.64.3.21", 188)) > > s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM, socket.IPPROTO_TCP) > s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1) > s.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, b"vrf_freifunk") > s.bind(("2a03:2260:0:194::2", 188)) The IPv4 block completes successfully, but doing the same with IPv6 in the second block fails saying: > Traceback (most recent call last): > File "./test.py", line 11, in <module> > s.bind(("2a03:2260:0:194::2", 188)) > OSError: [Errno 99] Cannot assign requested address If instead, in the last line, I use the IPv6 address of eth0 (which is not inside this VRF), the `bind` call succeeds. On the other hand, when I try using the eth0 IPv4 address in the first block, `bind` fails as expected because the address is not inside `vrf_freifunk`. If I replace `vrf_freifunk` by `tun-up-a_ak` (which is more like what Bird does), the behavior remains the same. I think this is a kernel bug, it seems like setting `SO_BINDTODEVICE` on the IPv6 socket is just ignored entirely. This is using a Debian stable backports kernel: > $ uname -a > Linux gw1.saar.freifunk.net 4.18.0-0.bpo.3-amd64 #1 SMP Debian > 4.18.20-2~bpo9+1 (2018-12-08) x86_64 GNU/Linux Any help debugging this would be appreciated. Kind regards, Ralf