[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Tue, 1 Jan 2019 15:58:54 +0100
From: Ralf Jung <post@...fj.de>
To: netdev@...r.kernel.org
Cc: David Ahern <dsahern@...il.com>,
Ondrej Zajicek <santiago@...reenet.org>, jan.matejka@....cz
Subject: Cannot bind to IPv6 address in VRF
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@...E: <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
Powered by blists - more mailing lists