From 71afb77560bc8653c0c67cc48719413fed600ceb Mon Sep 17 00:00:00 2001 From: Chris Buechler Date: Wed, 14 Oct 2015 02:06:32 -0500 Subject: This is necessary for dhcrelay to function. Revert "remove the destination server's interface(s) from dhcrelay" This reverts commit 97613114b5b74c334609d7fcd79c94741b111793. --- etc/inc/services.inc | 138 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 132 insertions(+), 6 deletions(-) diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 108ddcb..d115994 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -1518,6 +1518,73 @@ function services_dhcrelay_configure() { $dhcrelayifs[] = get_real_interface($dhcrelayif); } + /* + * In order for the relay to work, it needs to be active + * on the interface in which the destination server sits. + */ + $srvips = explode(",", $dhcrelaycfg['server']); + foreach ($srvips as $srcidx => $srvip) { + unset($destif); + foreach ($iflist as $ifname) { + $subnet = get_interface_ip($ifname); + if (!is_ipaddr($subnet)) + continue; + $subnet .= "/" . get_interface_subnet($ifname); + if (ip_in_subnet($srvip, $subnet)) { + $destif = get_real_interface($ifname); + break; + } + } + if (!isset($destif)) { + foreach (get_staticroutes() as $rtent) { + if (ip_in_subnet($srvip, $rtent['network'])) { + $a_gateways = return_gateways_array(true); + $destif = $a_gateways[$rtent['gateway']]['interface']; + break; + } + } + } + + if (!isset($destif)) { + /* Create a array from the existing route table */ + exec("/usr/bin/netstat -rnWf inet", $route_str); + array_shift($route_str); + array_shift($route_str); + array_shift($route_str); + array_shift($route_str); + $route_arr = array(); + foreach($route_str as $routeline) { + $items = preg_split("/[ ]+/i", $routeline); + if (is_subnetv4($items[0])) { + $subnet = $items[0]; + } elseif (is_ipaddrv4($items[0])) { + $subnet = "{$items[0]}/32"; + } else { + // Not a subnet or IP address, skip to the next line. + continue; + } + if (ip_in_subnet($srvip, $subnet)) { + $destif = trim($items[6]); + break; + } + } + } + + if (!isset($destif)) { + if (is_array($config['gateways']['gateway_item'])) { + foreach ($config['gateways']['gateway_item'] as $gateway) { + if (isset($gateway['defaultgw'])) { + $destif = get_real_interface($gateway['interface']); + break; + } + } + } else + $destif = get_real_interface("wan"); + } + + if (!empty($destif)) + $dhcrelayifs[] = $destif; + } $dhcrelayifs = array_unique($dhcrelayifs); /* fire up dhcrelay */ @@ -1531,11 +1598,6 @@ function services_dhcrelay_configure() { if (isset($dhcrelaycfg['agentoption'])) $cmd .= " -a -m replace"; - $srvips = explode(",", $dhcrelaycfg['server']); - if (!is_array($srvips)) { - log_error("No DHCP relay destination IP has been configured!"); - return; - } $cmd .= " " . implode(" ", $srvips); mwexec($cmd); unset($cmd); @@ -1578,12 +1640,76 @@ function services_dhcrelay6_configure() { $dhcrelayifs[] = get_real_interface($dhcrelayif); } $dhcrelayifs = array_unique($dhcrelayifs); + + /* + * In order for the relay to work, it needs to be active + * on the interface in which the destination server sits. + */ $srvips = explode(",", $dhcrelaycfg['server']); if (!is_array($srvips)) { - log_error("No destination IP has been configured!"); + log_error("No destination ip has been configured!"); return; } + $srvifaces = array(); + foreach ($srvips as $srcidx => $srvip) { + unset($destif); + foreach ($iflist as $ifname) { + $subnet = get_interface_ipv6($ifname); + if (!is_ipaddrv6($subnet)) + continue; + $subnet .= "/" . get_interface_subnetv6($ifname); + if (ip_in_subnet($srvip, $subnet)) { + $destif = get_real_interface($ifname); + break; + } + } + if (!isset($destif)) { + if (is_array($config['staticroutes']['route'])) { + foreach ($config['staticroutes']['route'] as $rtent) { + if (ip_in_subnet($srvip, $rtent['network'])) { + $a_gateways = return_gateways_array(true); + $destif = $a_gateways[$rtent['gateway']]['interface']; + break; + } + } + } + } + + if (!isset($destif)) { + /* Create a array from the existing route table */ + exec("/usr/bin/netstat -rnWf inet6", $route_str); + array_shift($route_str); + array_shift($route_str); + array_shift($route_str); + array_shift($route_str); + $route_arr = array(); + foreach($route_str as $routeline) { + $items = preg_split("/[ ]+/i", $routeline); + if (ip_in_subnet($srvip, $items[0])) { + $destif = trim($items[6]); + break; + } + } + } + + if (!isset($destif)) { + if (is_array($config['gateways']['gateway_item'])) { + foreach ($config['gateways']['gateway_item'] as $gateway) { + if (isset($gateway['defaultgw'])) { + $destif = get_real_interface($gateway['interface']); + break; + } + } + } else + $destif = get_real_interface("wan"); + } + + if (!empty($destif)) { + $srvifaces[] = "{$srvip}%{$destif}"; + } + } + /* fire up dhcrelay */ if (empty($dhcrelayifs) || empty($srvifaces) ) { log_error("No suitable interface found for running dhcrelay -6!"); -- cgit v1.1