From 81a3b6f56faa862142ff9bf2195b5276a152e733 Mon Sep 17 00:00:00 2001 From: smos Date: Thu, 1 Sep 2011 09:04:38 +0200 Subject: Add a find_interface_ipv6_ll() to find the link local address of a interface. Use this link local address for the apinger srcip otherwise we might try using the DHCP6 /128 address which will fail. We need to extend apinger or any replacement thereoff to understand the %{$realif} scope suffix for link local addresses so that these are always correct. This is important since link local gateway addresses are a normal thing and FreeBSD will complain otherwise. --- etc/inc/gwlb.inc | 9 ++++++++- etc/inc/interfaces.inc | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/etc/inc/gwlb.inc b/etc/inc/gwlb.inc index 03e308c..7697de0 100644 --- a/etc/inc/gwlb.inc +++ b/etc/inc/gwlb.inc @@ -152,7 +152,14 @@ EOD; $gwifip = find_interface_ip($gateway['interface'], true); } if (is_ipaddrv6($gateway['gateway'])) { - $gwifip = find_interface_ipv6($gateway['interface'], true); + /* link locals really need a different src ip */ + if(preg_match("/fe80::/i", $gateway['gateway'])) { + $linklocal = explode("%", find_interface_ipv6_ll($gateway['interface'], true)); + $gwifip = $linklocal[0]; + $ifscope = "%". $linklocal[1]; + } else { + $gwifip = find_interface_ipv6($gateway['interface'], true); + } } if (!is_ipaddr($gwifip)) continue; //Skip this target diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index 454f89e..70d08d7 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -3698,6 +3698,46 @@ function find_interface_ipv6($interface, $flush = false) return $interface_ipv6_arr_cache[$interface]; } +/* + * find_interface_ipv6_ll($interface): return the interface ipv6 link local (first found) + */ +function find_interface_ipv6_ll($interface, $flush = false) +{ + global $interface_ipv6_arr_cache; + global $interface_snv6_arr_cache; + global $config; + + $interface = str_replace("\n", "", $interface); + + if (!does_interface_exist($interface)) + return; + + /* Setup IP cache */ + if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) { + $ifinfo = pfSense_get_interface_addresses($interface); + // FIXME: Add IPv6 support to the pfSense module + exec("/sbin/ifconfig {$interface} inet6", $output); + foreach($output as $line) { + if(preg_match("/inet6/", $line)) { + $parts = explode(" ", $line); + if(preg_match("/fe80::/", $parts[1])) { + $ifinfo['ipaddrv6'] = $parts[1]; + if($parts[2] == "-->") { + $parts[5] = "126"; + $ifinfo['subnetbitsv6'] = $parts[5]; + } else { + $ifinfo['subnetbitsv6'] = $parts[3]; + } + } + } + } + $interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6']; + $interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6']; + } + + return $interface_ipv6_arr_cache[$interface]; +} + function find_interface_subnet($interface, $flush = false) { global $interface_sn_arr_cache; -- cgit v1.1