diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 6b3ca804f7..c8402a8885 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -48,17 +48,10 @@ function services_rtadvd_configure() { echo "services_rtadvd_configure() being called $mt\n"; } - if($g['services_dhcp_server_enable'] == false) - return; - if(is_process_running("rtadvd")) { mwexec("killall -9 rtadvd", true); } - /* DHCP enabled on any interfaces? */ - if (!is_dhcp_server_enabled()) - return 0; - if (!is_array($config['dhcpdv6'])) $config['dhcpdv6'] = array(); @@ -92,7 +85,11 @@ EOD; /* Currently for DHCP interfaces only, openvpn? */ $rtadvdnum = 0; foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + if($dhcpv6ifconf['mode'] == "disabled") + continue; + $rtadvdnum++; + /* It appears we can not advertise the gateway IP (carp) * rtadvd[44205]: IPV6_JOIN_GROUP(link) on vip1: Can't assign requested address if($dhcpv6ifconf['gateway'] <> "") { @@ -139,31 +136,8 @@ EOD; function services_dhcpd_configure() { global $config, $g; - - if($g['services_dhcp_server_enable'] == false) - return; - if(isset($config['system']['developerspew'])) { - $mt = microtime(); - echo "services_dhcpd_configure($if) being called $mt\n"; - } - - /* kill any running dhcpd */ - if(is_process_running("dhcpd")) { - mwexec("killall dhcpd", true); - } - - /* DHCP enabled on any interfaces? */ - if (!is_dhcp_server_enabled()) - return 0; - - /* if OLSRD is enabled, allow WAN to house DHCP. */ - if($config['installedpackages']['olsrd']) - foreach($config['installedpackages']['olsrd']['config'] as $olsrd) - if($olsrd['enable']) - $is_olsr_enabled = true; - - /* configure DHCPD chroot */ + /* configure DHCPD chroot once */ $fd = fopen("{$g['tmp_path']}/dhcpd.sh","w"); $status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`; fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n"); @@ -184,6 +158,38 @@ function services_dhcpd_configure() { fclose($fd); mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh"); + services_dhcpdv4_configure(); + services_dhcpdv6_configure(); + services_rtadvd_configure(); + return; + +} +function services_dhcpdv4_configure() { + global $config, $g; + + if($g['services_dhcp_server_enable'] == false) + return; + + if(isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "services_dhcpdv4_configure($if) being called $mt\n"; + } + + /* kill any running dhcpd */ + if(is_process_running("dhcpd")) { + killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid/dhcpd.pid"); + } + + /* DHCP enabled on any interfaces? */ + if (!is_dhcp_server_enabled()) + return 0; + + /* if OLSRD is enabled, allow WAN to house DHCP. */ + if($config['installedpackages']['olsrd']) + foreach($config['installedpackages']['olsrd']['config'] as $olsrd) + if($olsrd['enable']) + $is_olsr_enabled = true; + if ($g['booting']) { if ($g['platform'] != "pfSense") { /* restore the leases, if we have them */ @@ -196,25 +202,13 @@ function services_dhcpd_configure() { log_error("DHCP leases restore failed exited with $dhcpreturn, the error is: $dhcprestore\n"); } } - if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) { - $dhcprestore = ""; - $dhcpreturn = ""; - exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn); - $dhcprestore = implode(" ", $dhcprestore); - if($dhcpreturn <> 0) { - log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n"); - } - } } } $syscfg = $config['system']; if (!is_array($config['dhcpd'])) $config['dhcpd'] = array(); - if (!is_array($config['dhcpdv6'])) - $config['dhcpdv6'] = array(); $dhcpdcfg = $config['dhcpd']; - $dhcpdv6cfg = $config['dhcpdv6']; $Iflist = get_configured_interface_list(); if ($g['booting']) @@ -224,9 +218,8 @@ function services_dhcpd_configure() { /* write dhcpd.conf */ $fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w"); - $fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w"); - if ((!$fd) || (! $fdv6)) { - printf("Error: cannot open dhcpd.conf or dhcpdv6.conf in services_dhcpd_configure().\n"); + if (!$fd) { + printf("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().\n"); return 1; } @@ -242,14 +235,6 @@ function services_dhcpd_configure() { } } } - $custoptionsv6 = ""; - foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { - if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) { - foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) { - $custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n"; - } - } - } $dhcpdconf = << $dhcpv6ifconf) { - - interfaces_staticarp_configure($dhcpv6if); - - if (!isset($dhcpv6ifconf['enable'])) - continue; - - if($dhcpv6ifconf['failover_peerip'] <> "") { - $intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']); - $intipv6 = find_interface_ipv6($intv6); - $real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if); - /* - * yep, failover peer is defined. - * does it match up to a defined vip? - */ - $skew = 110; - $a_vip = &$config['virtualip']['vip']; - if(is_array($a_vip)) { - foreach ($a_vip as $vipent) { - if($intv6 == $real_dhcpv6if) { - /* this is the interface! */ - if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20")) - $skew = 0; - } - } - } else { - log_error("Warning! DHCPv6 Failover setup and no CARP virtual IPv6's defined!"); - } - if($skew > 10) { - $typev6 = "secondary"; - $dhcpdv6conf_pri = "mclt 600;\n"; - $my_portv6 = "520"; - $peer_portv6 = "519"; - } else { - $my_portv6 = "519"; - $peer_portv6 = "520"; - $typev6 = "primary"; - $dhcpdv6conf_pri = "split 128;\n"; - $dhcpdv6conf_pri .= " mclt 600;\n"; - } - $dhcpdv6conf .= << 0) { + mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " . + join(" ", $dhcpdifs)); + } + + if ($g['booting']) { + print "done.\n"; + } + + return 0; +} + +function services_dhcpdv6_configure() { + global $config, $g; + + if($g['services_dhcp_server_enable'] == false) + return; + + if(isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "services_dhcpd_configure($if) being called $mt\n"; + } + + /* kill any running dhcpd */ + if(is_process_running("dhcpd")) { + killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid"); + } + + /* DHCP enabled on any interfaces? */ + if (!is_dhcp_server_enabled()) + return 0; + + /* if OLSRD is enabled, allow WAN to house DHCP. */ + if($config['installedpackages']['olsrd']) + foreach($config['installedpackages']['olsrd']['config'] as $olsrd) + if($olsrd['enable']) + $is_olsr_enabled = true; + + if ($g['booting']) { + if ($g['platform'] != "pfSense") { + /* restore the leases, if we have them */ + if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) { + $dhcprestore = ""; + $dhcpreturn = ""; + exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn); + $dhcprestore = implode(" ", $dhcprestore); + if($dhcpreturn <> 0) { + log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n"); + } + } + } + } + + $syscfg = $config['system']; + if (!is_array($config['dhcpdv6'])) + $config['dhcpdv6'] = array(); + $dhcpdv6cfg = $config['dhcpdv6']; + $Iflist = get_configured_interface_list(); + + if ($g['booting']) + echo "Starting DHCPv6 service..."; + else + sleep(1); + + /* write dhcpdv6.conf */ + $fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w"); + if (! $fdv6) { + printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n"); + return 1; + } + + $custoptionsv6 = ""; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) { + foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) { + $custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n"; + } + } + } + + $dhcpdv6conf = << $dhcpv6ifconf) { + + interfaces_staticarp_configure($dhcpv6if); + + if (!isset($dhcpv6ifconf['enable'])) + continue; + + if($dhcpv6ifconf['failover_peerip'] <> "") { + $intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']); + $intipv6 = find_interface_ipv6($intv6); + $real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if); + /* + * yep, failover peer is defined. + * does it match up to a defined vip? + */ + $skew = 110; + $a_vip = &$config['virtualip']['vip']; + if(is_array($a_vip)) { + foreach ($a_vip as $vipent) { + if($intv6 == $real_dhcpv6if) { + /* this is the interface! */ + if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20")) + $skew = 0; + } + } + } else { + log_error("Warning! DHCPv6 Failover setup and no CARP virtual IPv6's defined!"); + } + if($skew > 10) { + $typev6 = "secondary"; + $dhcpdv6conf_pri = "mclt 600;\n"; + $my_portv6 = "520"; + $peer_portv6 = "519"; + } else { + $my_portv6 = "519"; + $peer_portv6 = "520"; + $typev6 = "primary"; + $dhcpdv6conf_pri = "split 128;\n"; + $dhcpdv6conf_pri .= " mclt 600;\n"; + } + $dhcpdv6conf .= << $dhcpv6ifconf) { @@ -702,20 +782,18 @@ EOD; EOD; /* add static mappings */ - /* Does not work for IPv6 - /* You can not use a hardware parameter for DHCPv6 hosts - /* Needs to be figured out + /* Needs to use DUID */ if (is_array($dhcpv6ifconf['staticmap'])) { $i = 0; foreach ($dhcpv6ifconf['staticmap'] as $sm) { $dhcpdv6conf .= << "unmanaged") { $realif = escapeshellcmd(get_real_interface($dhcpv6if)); @@ -743,34 +820,19 @@ EOD; } } - fwrite($fd, $dhcpdconf); - fclose($fd); fwrite($fdv6, $dhcpdv6conf); fclose($fdv6); - - /* create an empty leases database */ - touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"); - touch("{$g['varrun_path']}/dhcpd.pid"); /* create an empty leases v6 database */ touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases"); - touch("{$g['varrun_path']}/dhcpdv6.pid"); + print_r(dhcpdv6ifs); /* fire up dhcpd in a chroot */ - if(count($dhcpdifs) > 0) { - mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf " . - join(" ", $dhcpdifs)); - } - if(count($dhcpdv6ifs) > 0) { - mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf " . + mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf -pf {$g['varrun_path']}/dhcpdv6.pid " . join(" ", $dhcpdv6ifs)); - mwexec("/usr/sbin/rtadvd " . join(" ", $dhcpdv6ifs)); } - /* start ipv6 route advertising if required */ - services_rtadvd_configure(); - if ($g['booting']) { print "done.\n"; } diff --git a/usr/local/www/services_dhcpv6.php b/usr/local/www/services_dhcpv6.php index ee03adb4d5..d05839d591 100644 --- a/usr/local/www/services_dhcpv6.php +++ b/usr/local/www/services_dhcpv6.php @@ -56,52 +56,6 @@ if(!$g['services_dhcp_server_enable']) { */ ini_set("memory_limit","64M"); -/* This function will remove entries from dhcpd.leases that would otherwise - * overlap with static DHCP reservations. If we don't clean these out, - * then DHCP will print a warning in the logs about a duplicate lease - */ -function dhcp_clean_leases() { - global $g, $config; - $leasesfile = "{$g['dhcpd_chroot_path']}/var/db/dhcpdv6.leases"; - if (!file_exists($leasesfile)) - return; - /* Build list of static MACs */ - $staticmacs = array(); - foreach($config['interfaces'] as $ifname => $ifarr) - if (is_array($config['dhcpdv6'][$ifname]['staticmap'])) - foreach($config['dhcpdv6'][$ifname]['staticmap'] as $static) - $staticmacs[] = $static['mac']; - /* Read existing leases */ - $leases_contents = explode("\n", file_get_contents($leasesfile)); - $newleases_contents = array(); - $i=0; - while ($i < count($leases_contents)) { - /* Find a lease definition */ - if (substr($leases_contents[$i], 0, 6) == "lease ") { - $templease = array(); - $thismac = ""; - /* Read to the end of the lease declaration */ - do { - if (substr($leases_contents[$i], 0, 20) == " hardware ethernet ") - $thismac = substr($leases_contents[$i], 20, 17); - $templease[] = $leases_contents[$i]; - $i++; - } while ($leases_contents[$i-1] != "}"); - /* Check for a matching MAC address and if not present, keep it. */ - if (! in_array($thismac, $staticmacs)) - $newleases_contents = array_merge($newleases_contents, $templease); - } else { - /* It's a line we want to keep, copy it over. */ - $newleases_contents[] = $leases_contents[$i]; - $i++; - } - } - /* Write out the new leases file */ - $fd = fopen($leasesfile, 'w'); - fwrite($fd, implode("\n", $newleases_contents)); - fclose($fd); -} - $if = $_GET['if']; if ($_POST['if']) $if = $_POST['if']; @@ -148,7 +102,6 @@ if (is_array($config['dhcpdv6'][$if])){ list($pconfig['dns1'],$pconfig['dns2']) = $config['dhcpdv6'][$if]['dnsserver']; $pconfig['enable'] = isset($config['dhcpdv6'][$if]['enable']); $pconfig['denyunknown'] = isset($config['dhcpdv6'][$if]['denyunknown']); - $pconfig['staticarp'] = isset($config['dhcpdv6'][$if]['staticarp']); $pconfig['ddnsdomain'] = $config['dhcpdv6'][$if]['ddnsdomain']; $pconfig['ddnsupdate'] = isset($config['dhcpdv6'][$if]['ddnsupdate']); list($pconfig['ntp1'],$pconfig['ntp2']) = $config['dhcpdv6'][$if]['ntpserver']; @@ -193,7 +146,7 @@ function is_inrange($test, $start, $end) { return false; } -$modes = array("unmanaged" => "Unmanaged", "managed" => "Managed", "assist" => "Assisted"); +$advertise_modes = array("disabled" => "Disabled", "unmanaged" => "Unmanaged", "managed" => "Managed", "assist" => "Assisted"); if ($_POST) { @@ -263,9 +216,6 @@ if ($_POST) { foreach ($a_maps as $map) if (empty($map['ipaddrv6'])) $noip = true; - if ($_POST['staticarp'] && $noip) - $input_errors[] = "Cannot enable static ARP when you have static map entries without IP addresses. Ensure all static maps have IPv6 addresses and try again."; - if (!$input_errors) { /* make sure the range lies within the current subnet */ /* FIXME change for ipv6 subnet */ @@ -334,7 +284,6 @@ if ($_POST) { $config['dhcpdv6'][$if]['domainsearchlist'] = $_POST['domainsearchlist']; $config['dhcpdv6'][$if]['denyunknown'] = ($_POST['denyunknown']) ? true : false; $config['dhcpdv6'][$if]['enable'] = ($_POST['enable']) ? true : false; - $config['dhcpdv6'][$if]['staticarp'] = ($_POST['staticarp']) ? true : false; $config['dhcpdv6'][$if]['ddnsdomain'] = $_POST['ddnsdomain']; $config['dhcpdv6'][$if]['ddnsupdate'] = ($_POST['ddnsupdate']) ? true : false; @@ -363,8 +312,8 @@ if ($_POST) { $retvaldhcp = 0; $retvaldns = 0; /* Stop DHCPv6 so we can cleanup leases */ - killbyname("dhcpdv6"); - dhcp_clean_leases(); + killbyname("dhcpd -6"); + // dhcp_clean_leases(); /* dnsmasq_configure calls dhcpd_configure */ /* no need to restart dhcpd twice */ if (isset($config['dnsmasq']['regdhcpstatic'])) { @@ -399,7 +348,7 @@ if ($_GET['act'] == "del") { } $pgtitle = array(gettext("Services"),gettext("DHCPv6 server")); -$statusurl = "status_dhcp_leases.php"; +$statusurl = "status_dhcpv6_leases.php"; $logurl = "diag_logs_dhcp.php"; include("head.inc"); @@ -419,30 +368,30 @@ include("head.inc");