From 119d6e981be3e2e89bac98b8eb958b335a28e7a0 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Tue, 8 Feb 2022 10:12:52 +0100 Subject: [PATCH] interfaces: clean up GRE same as GIF #5540 The IP alias implementation differs between GIF and GRE with GRE being worse off since 'if' can be the IP alias and we have no quick way of looking up the VIP. Will address later... --- src/etc/inc/interfaces.inc | 61 ++++++++++++++------------------- src/www/interfaces_gre.php | 26 ++++---------- src/www/interfaces_gre_edit.php | 22 +++++++----- 3 files changed, 45 insertions(+), 64 deletions(-) diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 4b9421ade..37bd6de14 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -651,10 +651,6 @@ function interfaces_gre_configure($verbose = false, $checkparent = 0, $realif = } foreach ($config['gres']['gre'] as $i => $gre) { - if (empty($gre['greif'])) { - $gre['greif'] = "gre{$i}"; - } - if (!empty($realif)) { if ($realif != $gre['greif']) { continue; @@ -662,9 +658,11 @@ function interfaces_gre_configure($verbose = false, $checkparent = 0, $realif = log_error(sprintf('Executing inline configuration of GRE tunnel %s', $realif)); } - if ($checkparent == 1 && strstr($gre['if'], '_vip')) { + $is_vip = strpos($gre['if'], '_vip') !== false || is_ipaddr($gre['if']); + + if ($checkparent == 1 && $is_vip) { continue; - } elseif ($checkparent == 2 && !strstr($gre['if'], '_vip')) { + } elseif ($checkparent == 2 && !$is_vip) { continue; } @@ -676,59 +674,45 @@ function interfaces_gre_configure($verbose = false, $checkparent = 0, $realif = } } -function interface_gre_configure(&$gre) +function interface_gre_configure($gre) { - if (!is_array($gre)) { - return -1; - } + /* XXX we miss a reference here for IP alias since 'if' is the alias address only, look up in VIPs? */ + interfaces_bring_up(get_real_interface(explode('_vip', $gre['if'])[0])); /* XXX overreach? */ - $realif = get_real_interface($gre['if']); - - interfaces_bring_up($realif); - - if (file_exists("/var/run/booting") || !empty($gre['greif'])) { - legacy_interface_destroy($gre['greif']); - legacy_interface_create($gre['greif']); - $greif = $gre['greif']; - } else { - $greif = legacy_interface_create('gre'); - } + /* XXX avoid destroy/create to make routes sticky */ + legacy_interface_destroy($gre['greif']); + legacy_interface_create($gre['greif']); /* Do not change the order here for more see gre(4) NOTES section. */ if (is_ipaddrv6($gre['remote-addr'])) { - $realifip = is_ipaddr($gre['if']) ? $gre['if'] : get_interface_ipv6($gre['if']); - mwexecf('/sbin/ifconfig %s inet6 tunnel %s %s', array($greif, $realifip, $gre['remote-addr'])); + mwexecf('/sbin/ifconfig %s inet6 tunnel %s %s', [ $gre['greif'], get_interface_ipv6($gre['if']), $gre['remote-addr']]); } else { - $realifip = is_ipaddr($gre['if']) ? $gre['if'] : get_interface_ip($gre['if']); - mwexecf('/sbin/ifconfig %s tunnel %s %s', array($greif, $realifip, $gre['remote-addr'])); + mwexecf('/sbin/ifconfig %s tunnel %s %s', [$gre['greif'], get_interface_ip($gre['if']), $gre['remote-addr']]); } if ((is_ipaddrv6($gre['tunnel-local-addr'])) || (is_ipaddrv6($gre['tunnel-remote-addr']))) { - mwexec("/sbin/ifconfig {$greif} inet6 " . escapeshellarg($gre['tunnel-local-addr']) . " " . escapeshellarg($gre['tunnel-remote-addr']) . " prefixlen 128"); + mwexec("/sbin/ifconfig {$gre['greif']} inet6 " . escapeshellarg($gre['tunnel-local-addr']) . " " . escapeshellarg($gre['tunnel-remote-addr']) . " prefixlen 128"); } else { - mwexec("/sbin/ifconfig {$greif} " . escapeshellarg($gre['tunnel-local-addr']) . " " . escapeshellarg($gre['tunnel-remote-addr']) . " netmask " . gen_subnet_mask($gre['tunnel-remote-net'])); + mwexec("/sbin/ifconfig {$gre['greif']} " . escapeshellarg($gre['tunnel-local-addr']) . " " . escapeshellarg($gre['tunnel-remote-addr']) . " netmask " . gen_subnet_mask($gre['tunnel-remote-net'])); } - interfaces_bring_up($greif); + interfaces_bring_up($gre['greif']); if (is_ipaddrv4($gre['tunnel-remote-addr'])) { - file_put_contents("/tmp/{$greif}_router", "${gre['tunnel-remote-addr']}\n"); - } - if (is_ipaddrv6($gre['tunnel-remote-addr'])) { - file_put_contents("/tmp/{$greif}_routerv6", "{$gre['tunnel-remote-addr']}\n"); + file_put_contents("/tmp/{$gre['greif']}_router", "${gre['tunnel-remote-addr']}\n"); + } elseif (is_ipaddrv6($gre['tunnel-remote-addr'])) { + file_put_contents("/tmp/{$gre['greif']}_routerv6", "{$gre['tunnel-remote-addr']}\n"); } $gateways = new \OPNsense\Routing\Gateways(legacy_interfaces_details()); foreach (array_keys(get_configured_interface_with_descr()) as $ifname) { - if ($config['interfaces'][$ifname]['if'] == $greif) { + if ($config['interfaces'][$ifname]['if'] == $gre['greif']) { if ($gateways->getInterfaceGateway($ifname, 'inet') || $gateways->getInterfaceGateway($ifname, 'inet6')) { system_routing_configure(false, $ifname); break; } } } - - return $greif; } function interfaces_gif_configure($verbose = false, $checkparent = 0, $realif = '') @@ -3797,7 +3781,12 @@ function link_interface_to_gre($interface) if (isset($config['gres']['gre'])) { foreach ($config['gres']['gre'] as $gre) { - if ($gre['if'] == $interface) { + $parent = explode('_vip', $gre['if'])[0]; + if (is_ipaddr($parent)) { + /* XXX requires a proper runtime setup or VIP lookup */ + $parent = convert_real_interface_to_friendly_interface_name(guess_interface_from_ip($parent)); + } + if ($parent == $interface) { $result[] = $gre; } } diff --git a/src/www/interfaces_gre.php b/src/www/interfaces_gre.php index 200286082..a1f8895f1 100644 --- a/src/www/interfaces_gre.php +++ b/src/www/interfaces_gre.php @@ -30,20 +30,10 @@ require_once("guiconfig.inc"); require_once("interfaces.inc"); -function gre_inuse($gre_intf) -{ - foreach (legacy_config_get_interfaces() as $if => $intf) { - if ($intf['if'] == $gre_intf) { - return true; - } - } - return false; -} - $a_gres = &config_read_array('gres', 'gre') ; if ($_SERVER['REQUEST_METHOD'] === 'POST') { - $input_errors = array(); + $input_errors = []; if (!empty($a_gres[$_POST['id']])) { $id = $_POST['id']; } @@ -127,14 +117,12 @@ legacy_html_escape_form_data($a_gres); foreach ($a_gres as $gre): ?> - - [] - - - + + + + + + diff --git a/src/www/interfaces_gre_edit.php b/src/www/interfaces_gre_edit.php index 6d7f1cee3..cfed77c7b 100644 --- a/src/www/interfaces_gre_edit.php +++ b/src/www/interfaces_gre_edit.php @@ -39,9 +39,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (!empty($a_gres[$_GET['id']])) { $id = $_GET['id']; } - $pconfig = array(); + $pconfig = []; // copy fields - $copy_fields = array('if', 'greif', 'remote-addr', 'tunnel-remote-net', 'tunnel-local-addr', 'tunnel-remote-addr', 'descr'); + $copy_fields = ['if', 'greif', 'remote-addr', 'tunnel-remote-net', 'tunnel-local-addr', 'tunnel-remote-addr', 'descr']; foreach ($copy_fields as $fieldname) { $pconfig[$fieldname] = isset($a_gres[$id][$fieldname]) ? $a_gres[$id][$fieldname] : null; } @@ -51,12 +51,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $id = $_POST['id']; } - $input_errors = array(); + $input_errors = []; $pconfig = $_POST; /* input validation */ $reqdfields = explode(" ", "if tunnel-remote-addr tunnel-remote-net tunnel-local-addr"); - $reqdfieldsn = array(gettext("Parent interface"),gettext("Local address"),gettext("Remote tunnel address"),gettext("Remote tunnel network"), gettext("Local tunnel address")); + $reqdfieldsn = [gettext('Parent interface'),gettext('Local address'),gettext('Remote tunnel address'),gettext('Remote tunnel network'), gettext('Local tunnel address')]; do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); @@ -75,15 +75,17 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } if (count($input_errors) == 0) { - $gre = array(); - $copy_fields = array('if', 'greif', 'remote-addr', 'tunnel-remote-net', 'tunnel-local-addr', 'tunnel-remote-addr', 'descr'); + $gre = []; + $copy_fields = ['if', 'greif', 'remote-addr', 'tunnel-remote-net', 'tunnel-local-addr', 'tunnel-remote-addr', 'descr']; foreach ($copy_fields as $fieldname) { $gre[$fieldname] = isset($pconfig[$fieldname]) ? $pconfig[$fieldname] : null; } - $gre['greif'] = interface_gre_configure($gre); - ifgroup_setup(); - if ($gre['greif'] == "" || !stristr($gre['greif'], "gre")) { + if (empty($gre['greif'])) { + $gre['greif'] = legacy_interface_create('gre'); /* XXX find another strategy */ + } + + if (empty($gre['greif']) || strpos($gre['greif'], 'gre') !== 0) { $input_errors[] = gettext("Error occurred creating interface, please retry."); } else { if (isset($id)) { @@ -92,6 +94,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $a_gres[] = $gre; } write_config(); + interface_gre_configure($gre); + ifgroup_setup(); $confif = convert_real_interface_to_friendly_interface_name($gre['greif']); if ($confif != '') { interface_configure(false, $confif);