From 2618c2b91b23d3a1ece2c8f269260dabfbd4cc49 Mon Sep 17 00:00:00 2001 From: Franco Fichtner Date: Tue, 7 Feb 2023 15:21:03 +0100 Subject: [PATCH] system: prevent spurious far gateway detect Reported for DHCP in #5493 consider that all connectivity modes that create a router file to be eligable for this only. VIPs do overcomplicate this but that is also where the gateway has to be explicit instead of being provided at a later time, which makes the validations fail which is why we end up here. Also move the current route check to avoid some work. The check is not 100% when flipping the far behaviour but doing less work and keeping the current behaviour is fine. --- src/etc/inc/system.inc | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 6afb5149f..69ffc9fe5 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -538,20 +538,7 @@ function system_default_route($gateway, $family, $interface, $far = false) return; } - if ($family == 'inet') { - if (!$far) { - list (, $network) = interfaces_primary_address($interface); - if (ip_in_subnet($gateway, $network)) { - $realif = null; - } else { - log_msg("ROUTING: treating '{$gateway}' as far gateway for '{$network}'"); - } - } - } else { - /* IPv6 does not support far gateway notion */ - $realif = null; - } - + /* XXX while this does prevent unnecessary work it cannot detect a flip of far gateway setting */ $tmpcmd = "/sbin/route -n get -{$family} default 2>/dev/null | /usr/bin/awk '/gateway:/ {print $2}'"; $current = trim(exec($tmpcmd), " \n"); if ($current == $gateway) { @@ -559,6 +546,30 @@ function system_default_route($gateway, $family, $interface, $far = false) return; } + if ($family == 'inet') { + $dynamicgw = trim(@file_get_contents("/tmp/${realif}_router") ?? ''); + if (!empty($dynamicgw) && $gateway === $dynamicgw) { + /* special case tries to turn on far gateway when required for dynamic gateway */ + list (, $network) = interfaces_primary_address($interface); + if (empty($network) || ip_in_subnet($gateway, $network)) { + /* + * If we fail a primary network detection or the local address + * is in the same network as the gateway address do nothing. + */ + $realif = null; + } else { + log_msg("ROUTING: treating '{$gateway}' as far gateway for '{$network}'"); + } + } elseif (!$far) { + /* standard case disables host routes when not set in a static gateway */ + $realif = null; + } + } else { + /* IPv6 does not support far gateway notion */ + $realif = null; + } + + mwexecf('/sbin/route delete -%s default', [$family], true); if (!empty($realif)) { mwexecf('/sbin/route delete -%s %s -interface %s', [$family, $gateway, $realif], true);