diff --git a/src/etc/inc/gwlb.inc b/src/etc/inc/gwlb.inc index e31092aa86..6a5378e57d 100644 --- a/src/etc/inc/gwlb.inc +++ b/src/etc/inc/gwlb.inc @@ -223,12 +223,11 @@ function setup_gateways_monitor() { */ if (is_ipaddrv4($gateway['gateway']) && $gateway['monitor'] != $gateway['gateway']) { log_error(sprintf(gettext('Removing static route for monitor %1$s and adding a new route through %2$s'), $gateway['monitor'], $gateway['gateway'])); + $route_to = "-host {$gateway['monitor']}"; if (interface_isppp_type($gateway['friendlyiface'])) { - mwexec("/sbin/route change -host " . escapeshellarg($gateway['monitor']) . - " -iface " . escapeshellarg($gateway['interface']), true); + route_add_or_change("{$route_to} -iface {$gateway['interface']}"); } else { - mwexec("/sbin/route change -host " . escapeshellarg($gateway['monitor']) . - " " . escapeshellarg($gateway['gateway']), true); + route_add_or_change("{$route_to} {$gateway['gateway']}"); } pfSense_kill_states("0.0.0.0/0", $gateway['monitor'], $gateway['interface'], "icmp"); @@ -265,12 +264,11 @@ function setup_gateways_monitor() { */ if ($gateway['gateway'] != $gateway['monitor']) { log_error(sprintf(gettext('Removing static route for monitor %1$s and adding a new route through %2$s'), $gateway['monitor'], $gateway['gateway'])); + $route_to = "-host -inet6 {$gateway['monitor']}"; if (interface_isppp_type($gateway['friendlyiface'])) { - mwexec("/sbin/route change -host -inet6 " . escapeshellarg($gateway['monitor']) . - " -iface " . escapeshellarg($gateway['interface']), true); + route_add_or_change("{$route_to} -iface {$gateway['interface']}"); } else { - mwexec("/sbin/route change -host -inet6 " . escapeshellarg($gateway['monitor']) . - " " . escapeshellarg($gateway['gateway']), true); + route_add_or_change("{$route_to} {$gateway['gateway']}"); } pfSense_kill_states("::0.0.0.0/0", $gateway['monitor'], $gateway['interface'], "icmpv6"); @@ -842,7 +840,7 @@ function fixup_default_gateway($ipprotocol, $gateways_status, $gateways_arr) { } else { $inetfamily = "-inet"; } - mwexec("/sbin/route change {$inetfamily} default {$gateways_arr[$upgw]['gateway']}"); + route_add_or_change("{$inetfamily} default {$gateways_arr[$upgw]['gateway']}"); } } else if (!empty($dfltgwname)) { $defaultgw = trim(exec("/sbin/route -n get -{$ipprotocol} default | /usr/bin/awk '/gateway:/ {print $2}'"), " \n"); @@ -861,7 +859,7 @@ function fixup_default_gateway($ipprotocol, $gateways_status, $gateways_arr) { } } if ($defaultgw != $gateways_arr[$dfltgwname]['gateway']) { - mwexec("/sbin/route change -{$ipprotocol} default {$gateways_arr[$dfltgwname]['gateway']}"); + route_add_or_change("-{$ipprotocol} default {$gateways_arr[$dfltgwname]['gateway']}"); } } } diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 2ae27876b1..1e0be5d20e 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -1006,10 +1006,10 @@ function interface_gif_configure(&$gif, $gifkey = "") { } if (is_ipaddrv4($realifgw)) { - mwexec("/sbin/route change -host " . escapeshellarg($gif['remote-addr']) . " {$realifgw}"); + route_add_or_change("-host {$gif['remote-addr']} {$realifgw}"); } if (is_ipaddrv6($realifgw)) { - mwexec("/sbin/route change -host -inet6 " . escapeshellarg($gif['remote-addr']) . " {$realifgw}"); + route_add_or_change("-host -inet6 {$gif['remote-addr']} {$realifgw}"); } interfaces_bring_up($gifif); @@ -3738,7 +3738,7 @@ function interface_6rd_configure($interface = "wan", $wancfg) { $ip4gateway = get_interface_gateway($interface); if (is_ipaddrv4($ip4gateway)) { - mwexec("/sbin/route change -host " . escapeshellarg($wancfg['gateway-6rd']) . " {$ip4gateway}"); + route_add_or_change("-host {$wancfg['gateway-6rd']} {$ip4gateway}"); } /* configure dependent interfaces */ @@ -3845,7 +3845,7 @@ function interface_6to4_configure($interface = "wan", $wancfg) { $ip4gateway = get_interface_gateway($interface); if (is_ipaddrv4($ip4gateway)) { - mwexec("/sbin/route change -host 192.88.99.1 {$ip4gateway}"); + route_add_or_change("-host 192.88.99.1 {$ip4gateway}"); } if (!platform_booting()) { diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index e9ecd968ce..8d4f406719 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -213,17 +213,14 @@ function system_resolvconf_generate($dynupdate = false) { $dnsserver = $syscfg['dnsserver'][$dnscounter - 1]; if (is_ipaddr($gatewayip)) { - $cmd = 'change'; + route_add_or_change("-host {$inet6}{$dnsserver} {$gatewayip}"); } else { /* Remove old route when disable gw */ - $cmd = 'delete'; - $gatewayip = ''; - } - - mwexec("/sbin/route {$cmd} -host {$inet6}{$dnsserver} {$gatewayip}"); - if (isset($config['system']['route-debug'])) { - $mt = microtime(); - log_error("ROUTING debug: $mt - route {$cmd} -host {$inet6}{$dnsserver} {$gatewayip}"); + mwexec("/sbin/route delete -host {$inet6}{$dnsserver}"); + if (isset($config['system']['route-debug'])) { + $mt = microtime(); + log_error("ROUTING debug: $mt - route delete -host {$inet6}{$dnsserver}"); + } } } } @@ -593,12 +590,8 @@ function system_routing_configure($interface = "") { $srinterfacegw = $gateway['interface']; if (is_ipaddr($srgatewayip) && !empty($srinterfacegw)) { $inet = (!is_ipaddrv4($srgatewayip) ? "-inet6" : "-inet"); - $cmd = "/sbin/route change {$inet} " . escapeshellarg($srgatewayip) . " "; - mwexec($cmd . "-iface " . escapeshellarg($srinterfacegw)); - if (isset($config['system']['route-debug'])) { - $mt = microtime(); - log_error("ROUTING debug: $mt - $cmd -iface $srinterfacegw "); - } + route_add_or_change("{$inet} {$srgatewayip} " . + "-iface {$srinterfacegw}"); } } } @@ -608,7 +601,7 @@ function system_routing_configure($interface = "") { ; } else if (is_ipaddrv4($gatewayip)) { log_error(sprintf(gettext("ROUTING: setting default route to %s"), $gatewayip)); - mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip)); + route_add_or_change("-inet default {$gatewayip}"); } if (!empty($interface) && $interface != $interfacegwv6) { @@ -619,7 +612,7 @@ function system_routing_configure($interface = "") { $ifscope = "%{$defaultifv6}"; } log_error(sprintf(gettext("ROUTING: setting IPv6 default route to %s"), $gatewayipv6 . $ifscope)); - mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}")); + route_add_or_change("-inet6 default {$gatewayipv6}{$ifscope}"); } } @@ -710,7 +703,7 @@ function system_staticroutes_configure($interface = "", $update_dns = false) { $inet = (is_subnetv6($ip) ? "-inet6" : "-inet"); - $cmd = "/sbin/route change {$inet} {$blackhole} " . escapeshellarg($ip) . " "; + $cmd = "{$inet} {$blackhole} {$ip} "; if (is_subnet($ip)) { if (is_ipaddr($gatewayip)) { @@ -718,17 +711,9 @@ function system_staticroutes_configure($interface = "", $update_dns = false) { // add interface scope for link local v6 routes $gatewayip .= "%$interfacegw"; } - mwexec($cmd . escapeshellarg($gatewayip)); - if (isset($config['system']['route-debug'])) { - $mt = microtime(); - log_error("ROUTING debug: $mt - $cmd $gatewayip"); - } + route_add_or_change($cmd . $gatewayip); } else if (!empty($interfacegw)) { - mwexec($cmd . "-iface " . escapeshellarg($interfacegw)); - if (isset($config['system']['route-debug'])) { - $mt = microtime(); - log_error("ROUTING debug: $mt - $cmd -iface $interfacegw "); - } + route_add_or_change($cmd . "-iface {$interfacegw}"); } } } diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 1736a896fc..584b99ac71 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -2298,6 +2298,36 @@ function explode_assoc($delimiter, $string) { return $result; } +/* Try to change a static route, if it doesn't exist, add it */ +function route_add_or_change($args) { + global $config; + + if (empty($args)) { + return false; + } + + /* First, try to add it */ + $_gb = exec(escapeshellcmd("/sbin/route add " . $args), $output, $rc); + + if (isset($config['system']['route-debug'])) { + $mt = microtime(); + log_error("ROUTING debug: $mt - ADD RC={$rc} - $args"); + } + + if ($rc != 0) { + /* If it fails, try to change it */ + $_gb = exec(escapeshellcmd("/sbin/route change " . $args), + $output, $rc); + + if (isset($config['system']['route-debug'])) { + $mt = microtime(); + log_error("ROUTING debug: $mt - CHG RC={$rc} - $args"); + } + } + + return ($rc == 0); +} + function get_staticroutes($returnsubnetsonly = false, $returnhostnames = false) { global $config, $aliastable; diff --git a/src/etc/inc/vpn.inc b/src/etc/inc/vpn.inc index 9217cc2165..bd08234450 100644 --- a/src/etc/inc/vpn.inc +++ b/src/etc/inc/vpn.inc @@ -880,7 +880,7 @@ EOD; if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) { if (is_ipaddrv4($gatewayip)) { // log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}"); - mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true); + route_add_or_change("-host {$sourcehost} {$gatewayip}"); } } } @@ -907,7 +907,7 @@ EOD; if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) { if (is_ipaddrv6($gatewayip)) { // log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}"); - mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true); + route_add_or_change("-inet6 -host {$sourcehost} {$gatewayip}"); } } } diff --git a/src/usr/local/sbin/ppp-linkup b/src/usr/local/sbin/ppp-linkup index 035de7234e..7b41e0a293 100755 --- a/src/usr/local/sbin/ppp-linkup +++ b/src/usr/local/sbin/ppp-linkup @@ -50,12 +50,14 @@ if [ "${PROTOCOL}" == "inet" ]; then if echo "${DNS1_RAW}" | grep -q dns1; then DNS1=`echo "${DNS1_RAW}" | awk '{print $2}'` echo "${DNS1}" >> /var/etc/nameserver_${IF} - route change "${DNS1}" ${REMOTE_IP} + route change "${DNS1}" ${REMOTE_IP} \ + || route add "${DNS1}" ${REMOTE_IP} fi if echo "${DNS2_RAW}" | grep -q dns2; then DNS2=`echo "${DNS2_RAW}" | awk '{print $2}'` echo "${DNS2}" >> /var/etc/nameserver_${IF} - route change "${DNS2}" ${REMOTE_IP} + route change "${DNS2}" ${REMOTE_IP} \ + || route add "${DNS2}" ${REMOTE_IP} fi pfSctl -c 'service reload dns' sleep 1 @@ -75,12 +77,14 @@ elif [ "${PROTOCOL}" == "inet6" ]; then if echo "${DNS1_RAW}" | grep -q dns1; then DNS1=`echo "${DNS1_RAW}" | awk '{print $2}'` echo "${DNS1}" >> /var/etc/nameserver_v6${IF} - route change -inet6 "${DNS1}" ${REMOTE_IP} + route change -inet6 "${DNS1}" ${REMOTE_IP} \ + || route add -inet6 "${DNS1}" ${REMOTE_IP} fi if echo "${DNS2_RAW}" | grep -q dns2; then DNS2=`echo "${DNS2_RAW}" | awk '{print $2}'` echo "${DNS2}" >> /var/etc/nameserver_v6${IF} - route change -inet6 "${DNS2}" ${REMOTE_IP} + route change -inet6 "${DNS2}" ${REMOTE_IP} \ + || route add -inet6 "${DNS2}" ${REMOTE_IP} fi pfSctl -c 'service reload dns' sleep 1 diff --git a/src/usr/local/sbin/prefixes.php b/src/usr/local/sbin/prefixes.php index 29cbbf909c..746de8694a 100644 --- a/src/usr/local/sbin/prefixes.php +++ b/src/usr/local/sbin/prefixes.php @@ -98,7 +98,8 @@ foreach ($duid_arr as $entry) { // echo "add routes\n"; if (count($routes) > 0) { foreach ($routes as $address => $prefix) { - echo "/sbin/route change -inet6 {$prefix} {$address}\n"; + echo "/sbin/route change -inet6 {$prefix} {$address} " . + "|| /sbin/route add -inet6 {$prefix} {$address}\n"; } }