diff options
author | smos <seth.mos@dds.nl> | 2012-10-12 12:20:43 +0200 |
---|---|---|
committer | smos <seth.mos@dds.nl> | 2012-10-12 12:20:43 +0200 |
commit | 651018775c78e38045966825b920b641a0302b43 (patch) | |
tree | d30b1896abf6342e5588fa8ad4514408b42fe261 /etc | |
parent | b00dc86644b06d63874cbf64142a6a0c4eff8bfc (diff) | |
download | pfsense-651018775c78e38045966825b920b641a0302b43.zip pfsense-651018775c78e38045966825b920b641a0302b43.tar.gz |
Merge changes required for using the ISC dhclient in pfSense with prefix delegation. This should hopefully be a bit more reliable in the long run.
The dhclient6-script could be merged with dhclient-script in the future.
Still need to cleanup old adresses and prefixes, as well as LAN prefixes when a old prefix dissapears. This needs some thought and clue to strap together.
Diffstat (limited to 'etc')
-rw-r--r-- | etc/inc/interfaces.inc | 121 | ||||
-rw-r--r-- | etc/inc/system.inc | 20 | ||||
-rwxr-xr-x | etc/rc.newwanipv6 | 42 |
3 files changed, 72 insertions, 111 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index 9a23e20..5d831fd 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -37,7 +37,7 @@ pfSense_BUILDER_BINARIES: /sbin/dhclient /bin/sh /usr/bin/grep /usr/bin/xargs /usr/bin/awk /usr/local/sbin/choparp pfSense_BUILDER_BINARIES: /sbin/ifconfig /sbin/route /usr/sbin/ngctl /usr/sbin/arp /bin/kill /usr/local/sbin/mpd5 - pfSense_BUILDER_BINARIES: /usr/local/sbin/dhcp6c + pfSense_BUILDER_BINARIES: /usr/local/sbin/dhclient pfSense_MODULE: interfaces */ @@ -2642,7 +2642,7 @@ function find_dhclient_process($interface) { function find_dhcp6c_process($interface) { if ($interface) - $pid = `/bin/ps auxw|grep "[d]hcp6c" |grep "{$interface}"|awk '{print $2}'`; + $pid = `/bin/ps auxww|grep "[d]hclient[ ]-6" |grep "{$interface}"|awk '{print $2}'`; else return(false); @@ -3078,10 +3078,21 @@ function interface_track6_dhcp6_configure($interface = "lan") { if (empty($wancfg)) $wancfg = array(); + $realwanif = get_real_interface($wanif); + if(is_readable("{$g['vardb_path']}/{$realwanif}_pd_ipv6")) { + $ifcfgipv6pfx = file_get_contents("{$g['vardb_path']}/{$realwanif}_pd_ipv6"); + } else { + log_error("No DHCP-PD delegated prefix found, exiting"); + return false; + } + + log_error("Delegated IPv6 prefix is {$ifcfgipv6pfx}"); + $ifcfgipv6pfxarr = explode("/", $ifcfgipv6pfx); + $ifcfgipv6 = $ifcfgipv6pfxarr[0]; - $ifcfgipv6 = find_interface_ipv6($lanif); if(is_ipaddrv6($ifcfgipv6)) { $dhcp6lanarr = explode(":", Net_IPv6::uncompress($ifcfgipv6)); + /* we need to fold the $lancfg['track6-prefix-id'] into this address */ $dhcp6lanarr[4] = 0; $dhcp6lanarr[5] = 0; $dhcp6lanarr[6] = 0; @@ -3089,6 +3100,8 @@ function interface_track6_dhcp6_configure($interface = "lan") { $dhcp6lan = Net_IPv6::compress(implode(":", $dhcp6lanarr)); log_error("dhcp6 {$interface} with ipv6 address {$dhcp6lan} based on {$lancfg['track6-interface']}"); mwexec("/sbin/ifconfig {$lanif} inet6 {$dhcp6lan} prefixlen 64"); + } else { + log_error("The DHCP-PD interface {$interface} address {$ifcfgipv6} is not a valid IPv6 address"); } return 0; } @@ -3287,105 +3300,49 @@ function interface_dhcpv6_configure($interface = "wan") { $wanif = get_real_interface($interface); - /* Add ISC IPv6 dhclient here, only wide-dhcp6c works for now. */ + /* Add ISC IPv6 dhclient here */ $fd = fopen("{$g['varetc_path']}/dhcp6c_{$interface}.conf", "w"); if (!$fd) { printf("Error: cannot open dhcp6c_{$interface}.conf in interface_dhcpv6_configure() for writing.\n"); return 1; } - $dhcp6cconf = ""; - $dhcp6cconf .= "interface {$wanif} {\n"; + $dhcp6cconf = "interface \"{$wanif}\" {\n"; + $dhcp6cconf .= "script \"/sbin/dhclient6-script\";\n"; + $dhcp6cconf .= "}\n"; - /* for SLAAC interfaces we do fire off a dhcp6 client for just our name servers */ - if($wancfg['ipaddrv6'] == "slaac") { - $dhcp6cconf .= " information-only;\n"; - $dhcp6cconf .= " request domain-name-servers;\n"; - $dhcp6cconf .= " request domain-name;\n"; - $dhcp6cconf .= " script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n"; - $dhcp6cconf .= "};\n"; - } else { - - $dhcp6cconf .= " send ia-na 0; # request stateful address\n"; - if(is_numeric($wancfg['dhcp6-ia-pd-len'])) { - $dhcp6cconf .= " send ia-pd 0; # request prefix delegation\n"; - } - $dhcp6cconf .= "request domain-name-servers;\n"; - $dhcp6cconf .= "request domain-name;\n"; - $dhcp6cconf .= "script \"{$g['varetc_path']}/dhcp6c_{$interface}_script.sh\"; # we'd like some nameservers please\n"; - - $dhcp6cconf .= "};\n"; - $dhcp6cconf .= "id-assoc na 0 { };\n"; - if(is_numeric($wancfg['dhcp6-ia-pd-len'])) { - /* Setup the prefix delegation */ - $dhcp6cconf .= "id-assoc pd 0 {\n"; - foreach($iflist as $friendly => $ifdescr) { - if($config['interfaces'][$friendly]['track6-interface'] != $interface) - continue; - if(is_numeric($config['interfaces'][$friendly]['track6-prefix-id'])) { - log_error("setting up $friendly - {$config['interfaces'][$friendly]['track6-prefix-id']}"); - $realif = get_real_interface($friendly); - $dhcp6cconf .= " prefix-interface {$realif} {\n"; - $dhcp6cconf .= " sla-id {$config['interfaces'][$friendly]['track6-prefix-id']};\n"; - $dhcp6cconf .= " sla-len {$wancfg['dhcp6-ia-pd-len']};\n"; - $dhcp6cconf .= " };\n"; - } - } - $dhcp6cconf .= "};\n"; - } - } fwrite($fd, $dhcp6cconf); fclose($fd); - /* Add wide-dhcp6c shell script here. Because we can not pass a argument to it. */ - $fds = fopen("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", "w"); - if (!$fds) { - printf("Error: cannot open dhcp6c_{$interface}_script.sh in interface_dhcpv6_configure() for writing.\n"); - return 1; - } - $dhcp6cscript = "#!/bin/sh\n"; - $dhcp6cscript .= "# This shell script launches /etc/rc.newwanipv6 with a interface argument.\n"; - $dhcp6cscript .= "/etc/rc.newwanipv6 $interface \n"; - - fwrite($fds, $dhcp6cscript); - fclose($fds); - chmod("{$g['varetc_path']}/dhcp6c_{$interface}_script.sh", 0755); - - /* accept router advertisements for this interface */ mwexec("/sbin/sysctl -w net.inet6.ip6.accept_rtadv=1"); log_error("Accept router advertisements on interface {$wanif} "); mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv"); /* run a filter configure so that the filter rules allow traffic before we launch the client */ - filter_configure(); + filter_configure_sync(); sleep(3); - /* fire up dhcp6c for IPv6 first, this backgrounds immediately */ - mwexec("/usr/local/sbin/dhcp6c -d -c {$g['varetc_path']}/dhcp6c_{$interface}.conf {$wanif}"); - sleep(1); - exec("/sbin/rtsol -d {$wanif} 2>&1", $out, $ret); - if(!empty($out)) { - foreach($out as $line) { - if((stristr($line, "received")) && (!stristr($line, "unexpected"))) { - $parts = explode(" ", $line); - if(is_ipaddrv6($parts[3])) { - log_error("Found IPv6 default gateway '{$parts[3]}' by RA."); - file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$parts[3]}\n"); - file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$parts[3]}\n"); - break; - } - } - } + /* dhclient -6 + * -T temprorary address + * -S information only + * -P Prefix + * -N request address with temporary or prefix + */ + + $dhcp6c_options = ""; + if($wancfg['ipaddrv6'] == "slaac") { + $dhcp6c_options .= "-S "; } - /* worst case is that the rc.newwanipv6 handles setting up the track6 interface */ - if($wancfg['ippaddrv6'] != "slaac") { - /* configure dependent interfaces */ - foreach($iflist as $if => $ifname) { - if($config['interfaces'][$if]['track6-interface'] == $interface) - interface_track6_configure($if); - } + if($wancfg['ipaddrv6'] == "dhcp6") { + $dhcp6c_options .= "-N "; + } + if(is_numeric($wancfg['dhcp6-ia-pd-len'])) { + $dhcp6c_options .= "-P "; } + /* fire up dhcp6c for IPv6 first, this backgrounds immediately */ + mwexec("/usr/local/sbin/dhclient -6 {$dhcp6c_options} -cf {$g['varetc_path']}/dhcp6c_{$interface}.conf -lf {$g['varetc_path']}/dhcp6c_{$interface}.leases -pf {$g['varrun_path']}/dhcp6c_{$interface}.pid {$wanif}"); + sleep(5); return 0; } diff --git a/etc/inc/system.inc b/etc/inc/system.inc index 2e3b44f..76f2c39 100644 --- a/etc/inc/system.inc +++ b/etc/inc/system.inc @@ -1672,4 +1672,24 @@ function get_possible_listen_ips() { return $listenips; } +/* Pick up IPv6 router advertisements on the interface */ +function pickup_ipv6_router_advertisement($interface) { + global $g; + $realif = get_real_interface($interface); + exec("/sbin/rtsol -d {$realif} 2>&1", $out, $ret); + if(!empty($out)) { + foreach($out as $line) { + if((stristr($line, "received")) && (!stristr($line, "unexpected"))) { + $parts = explode(" ", $line); + if(is_ipaddrv6($parts[3])) { + log_error("Found IPv6 default gateway '{$parts[3]}' on interface {$realif} by RA."); + file_put_contents("{$g['tmp_path']}/{$realif}_routerv6", "{$parts[3]}\n"); + file_put_contents("{$g['tmp_path']}/{$realif}_defaultgwv6", "{$parts[3]}\n"); + break; + } + } + } + } +} + ?> diff --git a/etc/rc.newwanipv6 b/etc/rc.newwanipv6 index e09b4c7..cc1927e 100755 --- a/etc/rc.newwanipv6 +++ b/etc/rc.newwanipv6 @@ -49,15 +49,6 @@ if($g['booting']) exit; -// echo print_r($_ENV, true); -/*Array -( - [REASON] => NBI - [new_domain_name_servers] => 2001:470:20::2 - [new_domain_name] => domain.nl. -) -*/ - function restart_packages() { global $oldip, $curwanipv6, $g; @@ -70,24 +61,16 @@ function restart_packages() { log_error("rc.newwanipv6: Informational is starting."); -/* FIXME: how can we find out about the correct interface name? */ -/* switch to ISC dhcp6 client? */ -$curwanipv6 = get_interface_ipv6(); -$interface = "wan"; -$interface_real = get_real_interface(); - -$name_servers = explode(" ", $_ENV['new_domain_name_servers']); -$valid_ns = array(); -foreach($name_servers as $ns) { - if(is_ipaddrv6(trim($ns))) - $valid_ns[] = trim($ns); -} -if(count($valid_ns > 0)) - file_put_contents("{$g['varetc_path']}/nameserver_v6{$interface}", implode("\n", $valid_ns)); +/* Interface IP address has changed */ +$argument = str_replace("\n", "", $argv[1]); -if(!empty($_ENV['new_domain_name'])) { - file_put_contents("{$g['varetc_path']}/searchdomain_v6{$interface}", $_ENV['new_domain_name']); -} +if($argument != "") + $interface = convert_real_interface_to_friendly_interface_name($argument); +else + $interface = "wan"; + +$interface_real = get_real_interface($interface); +$curwanipv6 = get_interface_ipv6($interface_real); log_error("rc.newwanipv6: on (IP address: {$curwanipv6}) (interface: {$interface}) (real interface: {$interface_real})."); @@ -117,6 +100,10 @@ system_resolvconf_generate(true); /* write current WAN IPv6 to file */ file_put_contents("{$g['vardb_path']}/{$interface}_ipv6", $curwanipv6); +/* pickup ipv6 router advertisements */ +pickup_ipv6_router_advertisement($interface_real); +sleep(3); + /* check native IPv6 interface tracking */ switch($config['interfaces'][$interface]['ipaddrv6']) { case "dhcp6": @@ -158,9 +145,6 @@ services_dnsupdate_process($interface); /* signal dyndns update */ services_dyndns_configure($interface); -/* wait for the dhcp6c process to configure the LAN interface */ -sleep(5); - /* reconfigure IPsec tunnels */ vpn_ipsec_force_reload(); |