Bug #15057
closedRouter Advertisement daemon does not prioritize IPv6 GUA over ULA
Added by Mathis Cavalli 12 months ago. Updated 10 months ago.
0%
Description
When saving or reloading radvd service, the conf file is regenerated
If the interface has a public track interface and a private ULA address, the private address may be mistakenly chosen as the track interface IPv6
Updated by Marcos M 12 months ago
- Status changed from New to Feedback
Try this patch (apply with the system patches package): ShowHide
diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 9a3ae4c520..44203e3c8a 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -356,13 +356,13 @@ function services_radvd_configure($blacklist = array()) { continue; } - $ifcfgipv6 = get_interface_ipv6($if); - if (!is_ipaddrv6($ifcfgipv6)) { + $ifcfgipv6 = get_interface_addresses($realif); + if (!is_ipaddrv6($ifcfgipv6['ipaddr6'])) { $subnetv6 = "::"; $ifcfgsnv6 = "64"; } else { - $ifcfgsnv6 = get_interface_subnetv6($if); - $subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6); + $ifcfgsnv6 = $ifcfgipv6['subnetbits6']; + $subnetv6 = gen_subnetv6($ifcfgipv6['ipaddr6'], $ifcfgipv6['subnetbits6']); } $radvdifs[$realif] = $realif; @@ -403,7 +403,7 @@ function services_radvd_configure($blacklist = array()) { if ($dhcpv6ifconf['radvd-dns'] != 'disabled') { $dnslist = array(); if (config_path_enabled('dnsmasq') || config_path_enabled('unbound')) { - $dnslist[] = $ifcfgipv6; + $dnslist[] = $ifcfgipv6['ipaddr6']; } else { foreach (config_get_path('system/dnsserver', []) as $server) { if (is_ipaddrv6($server)) {
Updated by Mathis Cavalli 12 months ago
Marcos M wrote in #note-1:
Try this patch (apply with the system patches package): {{collapse
[...]
}}
Just tried it, didn't work
I made a patch on github which did the job
https://github.com/pfsense/pfsense/pull/4659
but thanks for your answer, appreciate that
Updated by Marcos M 11 months ago
I'm not able to replicate this on 23.09 (should be the same as 2.7.1 for this issue). Regardless of whether the ULA comes before or after the GUA, the function returns the GUA:
# ifconfig output vmx0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500 description: WAN options=4e100bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWFILTER,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG> ether 00:50:56:b2:23:2f inet 10.0.5.235 netmask 0xffffff00 broadcast 10.0.5.255 inet6 fe80::250:56ff:feb2:232f%vmx0 prefixlen 64 scopeid 0x1 inet6 fc00::250:56ff:feb2:232f prefixlen 128 inet6 2001:db8:db8:db8:db8:a85f:46ef:e240 prefixlen 128 pltime 4500 vltime 7200 media: Ethernet autoselect status: active nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL> # php function output var_dump(get_interface_track6ip('wan')); array(2) { [0]=> string(32) "2001:db8:db8:db8:db8:a85f:46ef:e240" [1]=> string(3) "128" }
What pfSense version are you running, and what is the output for the above (test under Diagnostics > Command Prompt)?
Updated by Mathis Cavalli 11 months ago
I rolled back my change to get_interface_track6ip to show you what it returns with the original code
# ifconfig output bridge0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500 description: LAN options=0 ether 58:9c:fc:10:97:0f inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255 inet6 fe80::5a9c:fcff:fe10:970f%bridge0 prefixlen 64 scopeid 0x13 inet6 fe80::1:1%bridge0 prefixlen 64 scopeid 0x13 inet6 fc00:: prefixlen 64 inet6 2a01:cb08:e53:1300:5a9c:fcff:fe10:970f prefixlen 64 inet6 fd00:: prefixlen 64 id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15 maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200 root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0 member: ix3 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 8 priority 128 path cost 200000 member: igc3 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 4 priority 128 path cost 55 member: igc2 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 3 priority 128 path cost 2000000 member: igc1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 2 priority 128 path cost 55 member: igc0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 1 priority 128 path cost 55 member: ix1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 6 priority 128 path cost 2000 member: ix2 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP> ifmaxaddr 0 port 7 priority 128 path cost 2000 groups: bridge nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> # php output (wan has no ipv6 assigned, only lan has) var_dump(get_interface_track6ip('lan')); array(2) { [0]=> string(6) "fc00::" [1]=> string(2) "64" }
I'm using 23.09 too, i set 2.7.1 as affected version but as you say it should be the same
Updated by Marcos M 11 months ago
- Subject changed from local private ipv6 is being used instead of public track interface IPv6 in radvd to radvd does not prioritize IPv6 GUA over ULA
- Status changed from Incomplete to Pull Request Review
- Assignee set to Marcos M
- Target version set to 2.8.0
- Plus Target Version set to 24.03
Thanks! I was able to reproduce and confirm the issue. Please test the following patch: ShowHide
diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index b2416c8a02a15d953de2525d8cdcff2d3078958e..1aa012b267582ffb2af96d4ec48c2411751b9a73 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -6582,24 +6582,21 @@ function get_interface_linklocal($interface = "wan") { } } +/** + * Get the first IPv6 address that is not a VIP or Link-Local address. + * Prioritize IPv6 GUA over ULA. + * + * @param array $interface Interface to check + * @return array IP address and prefix length + * @return bool false If no match is found + */ function get_interface_track6ip($interface = "wan") { - $realif = get_real_interface($interface); - $vips = get_configured_vip_list('inet6'); - - foreach (pfSense_getall_interface_addresses($realif) as $ifaddr) { - list($ip, $bits) = explode("/", $ifaddr); - $ip = text_to_compressed_ip6($ip); - if (is_ipaddrv6($ip) && !is_linklocal($ip)) { - if (is_array($vips) && !empty($vips)) { - foreach ($vips as $vip) { - if ($ip == text_to_compressed_ip6($vip)) { - continue 2; - } - } - } - return array($ip, $bits); - } + $ifinfo = get_interface_addresses(get_real_interface($interface)); + + if (isset($ifinfo['ipaddr6']) && isset($ifinfo['subnetbits6'])) { + return [$ifinfo['ipaddr6'], $ifinfo['subnetbits6']]; } + return false; }
https://gitlab.netgate.com/pfSense/pfSense/-/merge_requests/1112
Updated by Mathis Cavalli 11 months ago
It works !
get_interface_track6ip now returns the GUA as expected, and radvd config file is correct
Thank you
Updated by Jim Pingle 10 months ago
- Subject changed from radvd does not prioritize IPv6 GUA over ULA to Router Advertisement daemon does not prioritize IPv6 GUA over ULA