diff options
author | smos <seth.mos@dds.nl> | 2011-09-01 09:04:38 +0200 |
---|---|---|
committer | smos <seth.mos@dds.nl> | 2011-09-01 12:33:36 +0200 |
commit | 81a3b6f56faa862142ff9bf2195b5276a152e733 (patch) | |
tree | f091bbee07564753828b7e52657e80b7802c8d03 /etc | |
parent | d5bff5e4e7e1fa346e63291be32f8582828f84ae (diff) | |
download | pfsense-81a3b6f56faa862142ff9bf2195b5276a152e733.zip pfsense-81a3b6f56faa862142ff9bf2195b5276a152e733.tar.gz |
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.
Diffstat (limited to 'etc')
-rw-r--r-- | etc/inc/gwlb.inc | 9 | ||||
-rw-r--r-- | etc/inc/interfaces.inc | 40 |
2 files changed, 48 insertions, 1 deletions
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; |