Project

General

Profile

Bug #3285

Virtual IPs on FreeBSD cannot set IPv6 addresses

Added by Chris Ryder almost 2 years ago. Updated 12 days ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Category:
freebsd
Start date:
03.12.2019
Due date:
Estimated time:
Affected version:
5.8.1
Resolution:

Description

Running StrongSwan 5.8.1 on a FreeBSD 12.1 machine, acting as a roaming VPN client it appears that StrongSwan is only able to assign IPv4 addresses to the tun interface. IPv4 traffic works fine, and I have other VPN clients (iOS and Mac OS X built-in clients) connect to the VPN server and get both IPv6 and IPv4 addresses assigned correctly. However, on the FreeBSD client, StrongSwan reports the following when it brings up the VPN:

.....
scheduling reauthentication in 86170s
maximum IKE_SA lifetime 86350s
installing new virtual IP 81.XX.XX.XX
created TUN device: tun0
installing new virtual IP 2001:XXX:XXXX:XXXX::XXXX
created TUN device: tun1
failed to add address on tun1: Invalid argument
installing virtual IP 2001:XXXX:XXXX:XXXX::XXXX failed
selected proposal: ESP:AES_CBC_256/HMAC_SHA1_96/NO_EXT_SEQ
CHILD_SA vpn{2} established with SPIs c740b4b1_i 65f904ab_o and TS 81.XX.XX.XX/32 === 81.XX.XX.YY/29 ZZ.ZZ.ZZ.ZZ/28
connection 'vpn' established successfully

Digging into the `failed to add address on tun1: Invalid argument` message, I think the problem is that in https://wiki.strongswan.org/projects/strongswan/repository/revisions/master/entry/src/libstrongswan/networking/tun_device.c#L168 the SIOCAIFADDR ioctl (and other friends) is being used, which I think only supports IPv4 address on FreeBSD/Darwin - for IPv6 I think SIOCAIFADDR_IN6 and friends are needed. I don't have any experience of that level of networking code though, but the source for the FreeBSD ifconfig tool https://github.com/freebsd/freebsd/tree/master/sbin/ifconfig shows a difference between inet and inet6 code paths: https://github.com/freebsd/freebsd/blob/master/sbin/ifconfig/af_inet.c https://github.com/freebsd/freebsd/blob/master/sbin/ifconfig/af_inet6.c

There is also a sample of how to set IPv6 addresses on Darwin which looks similar: https://gist.github.com/icpz/65476f8c1ae4c0451b2f67c3fccc2244

noroutes.ifconfig (1.95 KB) noroutes.ifconfig Dries Michiels, 23.09.2021 21:03
noroutes.netstat (2.01 KB) noroutes.netstat Dries Michiels, 23.09.2021 21:03
preconn.ifconfig (1.43 KB) preconn.ifconfig Dries Michiels, 23.09.2021 21:03
preconn.netstat (1.72 KB) preconn.netstat Dries Michiels, 23.09.2021 21:03
routes.ifconfig (1.97 KB) routes.ifconfig Dries Michiels, 23.09.2021 21:03
routes.netstat (2.25 KB) routes.netstat Dries Michiels, 23.09.2021 21:03
charon.log (256 KB) charon.log Dries Michiels, 27.09.2021 21:08

Related issues

Related to Issue #974: Charon crash on Mac OS with IPv6 Virtual IPNew

History

#1 Updated by Tobias Brunner almost 2 years ago

  • Status changed from New to Feedback

That's a known issue. See the (very old) commit in the tun-device-ipv6 branch. Since I had no IPv6 connectivity at the time (and nobody really seemed interested), I never tested it (don't know if it even is complete).

#2 Updated by Chris Ryder almost 2 years ago

Ah, I hadn't managed to find that branch - I'll see if I can get that code updated to work in my FreeBSD scenario, thanks!

#3 Updated by Tobias Brunner almost 2 years ago

  • Related to Issue #974: Charon crash on Mac OS with IPv6 Virtual IP added

#4 Updated by Dries Michiels about 2 months ago

Could we give this some priority? Would be cool for my FreeBSD client to support IPv6.
I am happy to test a branch if you have something ready to test.

#5 Updated by Dries Michiels about 2 months ago

Tobias, is this the commit in question I could test? Could you maybe rebase it so I can apply it cleanly?

https://wiki.strongswan.org/projects/strongswan/repository/revisions/0b236674069f004a9c4102e6ee8af2de9e9f4eb8/diff/src/libstrongswan/networking/tun_device.c?

#6 Updated by Tobias Brunner about 2 months ago

I've quickly rebased the branch. Only compile tested.

#7 Updated by Dries Michiels 25 days ago

Tobias Brunner wrote:

I've quickly rebased the branch. Only compile tested.

Hi Tobias,

Is it possible for you to rebase to the 5.9.3 tag source code. That's what's used in the FreeBSD port, that makes it easy for me to create a patch on top of the current port.
Hopefully this is not asking to much but this will make it much easier for me to get your changes regarding the ipv6 virtual ip in and compiled, and tested :)

#8 Updated by Tobias Brunner 25 days ago

The patch should apply cleanly to 5.9.3 as there have not been any changes to tun_device.c.

#9 Updated by Dries Michiels 25 days ago

Tobias Brunner wrote:

The patch should apply cleanly to 5.9.3 as there have not been any changes to tun_device.c.

You are right :), so I briefly tested and the virtual IPv6 address is installed correctly.
I still have to search why I lost IPv6 connectivity (couldnt ping6 after initiating the conn)

I did a test with install_routes = no (noroutes), and install_routes = yes (routes), and my default config without any tunnel (preconn).

The only error I got was with the install_routes = yes config as you see bellow.

"[KNL] installing route failed: 0.0.0.0/0 via fe80::a236:9fff:fecd:7de7 src 10.0.1.1 dev tun0"

[IKE] maximum IKE_SA lifetime 14978s
[IKE] installing DNS server 10.0.0.1 via resolvconf
[IKE] installing new virtual IP 10.0.1.1
[LIB] created TUN device: tun0
[IKE] installing new virtual IP 2a02:1811:251a:d210::1
[LIB] created TUN device: tun1
[IKE] received ESP_TFC_PADDING_NOT_SUPPORTED, not using ESPv3 TFC padding
[CFG] selected proposal: ESP:AES_GCM_16_128
[KNL] adding PF_ROUTE route failed: Invalid argument
[KNL] installing route failed: 0.0.0.0/0 via fe80::a236:9fff:fecd:7de7 src 10.0.1.1 dev tun0
[IKE] CHILD_SA home{1} established with SPIs c6c78156_i cec4c700_o and TS 10.0.1.1/32 2a02:1811:251a:d210::1/128 === 0.0.0.0/0 ::/0

#10 Updated by Dries Michiels 25 days ago

TLDR: Code works fine for installing the IPv6 virtual IP. SHIP IT! :D

#11 Updated by Tobias Brunner 25 days ago

I still have to search why I lost IPv6 connectivity (couldnt ping6 after initiating the conn)

Through the tunnel? Or in the LAN?

"[KNL] installing route failed: 0.0.0.0/0 via fe80::a236:9fff:fecd:7de7 src 10.0.1.1 dev tun0"

Hm, that's a very weird combination (IPv4 subnet and source address but IPv6 link-local address as next hop).

Could you try this again with the log level for knl increased to 2?

But even if the next hop is IPv6, da565d9832 should prevent that address from getting set on the route, so not sure why the installation still fails (unless it's related to this recent FreeBSD kernel issue).

#12 Updated by Dries Michiels 22 days ago

Could you try this again with the log level for knl increased to 2?

Is this equivalent to "swanctl --initiate --debug=2 --child=home"

#13 Updated by Tobias Brunner 22 days ago

Could you try this again with the log level for knl increased to 2?

Is this equivalent to "swanctl --initiate --debug=2 --child=home"

Not exactly. First, --debug only sets the log level for messages generated by swanctl itself. To change the log level for messages generated by the daemon while initiating, the option would be --loglevel. However, that logs messages from all subsystems on level 2 (including some that produce a lot of unnecessary output like enc and asn). And it only logs messages related to the initiation, i.e. it stops after the CHILD_SA has been installed (that should be OK in this case, though).

#14 Updated by Dries Michiels 21 days ago

Ok, I put the default log level at 2 in charon-logging.conf. Hopefully it is not to much clutter.

#15 Updated by Tobias Brunner 21 days ago

  • Category set to freebsd

Ok, I put the default log level at 2 in charon-logging.conf. Hopefully it is not to much clutter.

Would have been better to only increase the level for knl, but it's OK. So since the IKE traffic is sent over IPv6 the next hop selection kinda makes sense, I guess:

Sep 27 21:06:03 DRIES-NB charon[72932]: 04[KNL] using fe80::a236:9fff:fecd:7de7 as nexthop to reach 2a02:1811:251a:d200:4ecc:6aff:fe28:3ea3

As mentioned earlier, the value is then ignored when installing the route as the address family doesn't match, so the question is why this installation fails:

Sep 27 21:06:03 DRIES-NB charon[72932]: 04[KNL] installing route: 0.0.0.0/0 via fe80::a236:9fff:fecd:7de7 src 10.0.1.1 dev tun0
Sep 27 21:06:03 DRIES-NB charon[72932]: 04[KNL] adding PF_ROUTE route failed: Invalid argument

One possibility might actually be the missing RTAX_GATEWAY attribute. But I'm pretty sure this worked when I added the commit linked above four years ago. So maybe it's something that changed in the FreeBSD kernel. We could maybe configure an AF_LINK address as RTAX_GATEWAY, set to the interface we have for the route. Could you try the patch I pushed to the tun-device-ipv6 branch?

#16 Updated by Tobias Brunner 12 days ago

Any feedback on the "route via interface" patch?

Also available in: Atom PDF