From d2a14f7fba26dc154c74cda3d83dff2b8e1762fb Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Tue, 9 Apr 2019 18:41:53 +0200 Subject: [PATCH] gateways, reimplement into new class (https://github.com/opnsense/core/issues/2279) Its work in progress, but the basic idea is to make sure we can easily output a list of all gateways (ipv4+ipv6) in the system, which is always correctly ordered by priority. As soon as this works, we should be able to propogate ipprotocol to the gateway groups as well and easily iterate over the list to deterimine which gateways should be used at any time. When settings are available in gateways->gateway_item, they should logically precede the ones generated dynamically. --- .../app/library/OPNsense/Routing/Gateways.php | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 src/opnsense/mvc/app/library/OPNsense/Routing/Gateways.php diff --git a/src/opnsense/mvc/app/library/OPNsense/Routing/Gateways.php b/src/opnsense/mvc/app/library/OPNsense/Routing/Gateways.php new file mode 100644 index 000000000..f82e1808c --- /dev/null +++ b/src/opnsense/mvc/app/library/OPNsense/Routing/Gateways.php @@ -0,0 +1,154 @@ +configHandle = Config::getInstance()->object(); + } + + /** + * @param array $payload containing serialized ifconfig data + */ + public function setIfconfig($payload) + { + $this->ifconfig = $payload; + } + + /** + * return all non virtual interfaces + * @return array + */ + private function getDefinedInterfaces() + { + $result = array(); + if (!empty($this->configHandle->interfaces)) { + foreach ($this->configHandle->interfaces->children() as $ifname => $iface) { + if (!isset($iface->virtual) || $iface->virtual != "1") { + $result[$ifname] = array(); + foreach ($iface as $key => $value) { + $result[$ifname][(string)$key] = (string)$value; + } + } + } + } + return $result; + } + + /** + * return all defined gateways + * @return array + */ + public function getGateways() + { + $result = array(); + $definedIntf = $this->getDefinedInterfaces(); + $dynamic_gw = array(); + $gatewaySeq = 1; + // iterate configured gateways + if (!empty($this->configHandle->gateways)) { + foreach ($this->configHandle->gateways->children() as $tag => $gateway) { + $gw_arr = array(); + foreach ($gateway as $key => $value) { + $gw_arr[(string)$key] = (string)$value; + } + $gw_arr['priority'] = 1; // XXX define in gateway + if ($tag == "gateway_item") { + $gw_arr["if"] = $definedIntf[$gw_arr["interface"]]['if']; + if (Util::isIpAddress($gateway->gateway)) { + $gwkey = sprintf("%d%010d", $gw_arr['priority'], $gatewaySeq); + $result[$gwkey] = $gw_arr; + } else { + // dynamic gateways might have settings, temporary store + if (empty($dynamic_gw[(string)$gateway->interface])) { + $dynamic_gw[(string)$gateway->interface] = array(); + } + $dynamic_gw[(string)$gateway->interface][] = $gw_arr; + } + } + $gatewaySeq++; + } + } + // add dynamic gateways + foreach ($definedIntf as $ifname => $ifcfg) { + foreach (["inet", "inet6"] as $ipproto) { + // filename suffix and interface type as defined in the interface + $fsuffix = $ipproto == "inet6" ? "v6" : ""; + $ctype = $ipproto == "inet" ? $ifcfg['ipaddr'] : $ifcfg['ipaddrv6']; + // default configuration, when not set in gateway_item + $thisconf = [ + "priority" => 1, + "interface" => $ifname, + "weight" => 1, + "ipprotocol" => $ipproto, + "name" => strtoupper("{$ifname}_{$ctype}"), + "descr" => "Interface " . strtoupper("{$ifname}_{$ctype}") . " Gateway", + "if" => $ifcfg['if'], + "defaultgw" => file_exists("/tmp/{$ifcfg['if']}_defaultgw".$fsuffix) + ]; + // locate interface gateway settings + if (!empty($dynamic_gw[$ifname])) { + foreach ($dynamic_gw[$ifname] as $gw_arr) { + if ($gw_arr['ipprotocol'] == $ipproto) { + // dynamic gateway for this ip protocol found, use config + $thisconf = $gw_arr; + break; + } + } + } + // dynamic gateways dump their addres in /tmp/[IF]_router[FSUFFIX] + if (file_exists("/tmp/{$ifcfg['if']}_router".$fsuffix)) { + $thisconf['gateway'] = trim(@file_get_contents("/tmp/{$ifcfg['if']}_router".$fsuffix)); + $gwkey = sprintf("%d%010d", $gw_arr['priority'], $gatewaySeq); + $result[$gwkey] = $thisconf; + $gatewaySeq++; + } + } + } + // sort by priority + ksort($result); + return $result; + } + +}