--- filter.inc.bak 2018-06-06 11:38:15.442508000 +1000 +++ filter.inc 2018-06-07 10:58:42.179627000 +1000 @@ -218,14 +218,74 @@ } $gwstatus =& $a_gateways[$gateway['monitor']]; if (strstr($gwstatus['status'], "down")) { - $any_gateway_down = true; - break; + if (!empty($gateway['interface'])) + $gwiface = $gateway['interface']; + else + $gwiface = get_real_interface($gateway['friendlyiface']); + + log_error("Removing states for interface {$gwiface}"); + $nat_states = exec_command("/sbin/pfctl -i {$gwiface} -ss"); + + $cleared_states = array(); + foreach (explode("\n", $nat_states) as $nat_state) { + + $ipv4_num_matches = preg_match_all('/([\d\.]+):[\d]+[\s-><)]+/i', $nat_state, $ipv4_matches, PREG_SET_ORDER); + + if ($ipv4_num_matches == 3) { + + $natsrc = $ipv4_matches[1][1]; + $dst = $ipv4_matches[2][1]; + + if (!(empty($natsrc) || empty($dst) || in_array("{$natsrc},{$dst}", $cleared_states))) { + + $cleared_states[] = "{$natsrc},{$dst}"; + pfSense_kill_states($natsrc, $dst); + + } + + $src = $ipv4_matches[0][1]; + $dst = $ipv4_matches[2][1]; + + if (!(empty($src) || empty($dst) || in_array("{$src},{$dst}", $cleared_states))) { + + $cleared_states[] = "{$src},{$dst}"; + pfSense_kill_states($src, $dst); + + } + + } elseif ($ipv4_num_matches == 2) { + + $src = $ipv4_matches[0][1]; + $dst = $ipv4_matches[1][1]; + + if (!(empty($src) || empty($dst) || in_array("{$src},{$dst}", $cleared_states))) { + + $cleared_states[] = "{$src},{$dst}"; + pfSense_kill_states($src, $dst); + + } + } + + $ipv6_num_matches = preg_match_all('/([\da-f:]+)\[[\d]+\]+[\s-><]+/i', $nat_state, $ipv6_matches, PREG_SET_ORDER); + + if ($ipv6_num_matches == 2) { + + $src = $ipv6_matches[0][1]; + $dst = $ipv6_matches[1][1]; + + if (!(empty($src) || empty($dst) || in_array("{$src},{$dst}", $cleared_states))) { + + $cleared_states[] = "{$src},{$dst}"; + pfSense_kill_states($src, $dst); + + } + + } + } + mwexec("/sbin/pfctl -i {$gwiface} -Fs", true); } } } - if ($any_gateway_down == true) { - mwexec("/sbin/pfctl -Fs"); - } } /* reload filter sync */