diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc
index f7cd290db0..c86ecd367d 100644
--- a/etc/inc/vpn.inc
+++ b/etc/inc/vpn.inc
@@ -1734,6 +1734,57 @@ function vpn_ipsec_refresh_policies() {
}
}
+/* remove SPD polices */
+function remove_tunnel_spd_policy($phase1,$phase2) {
+ global $config;
+ global $g;
+
+ $spdconf = "";
+ if($phase1 && $phase2) {
+ $ep = ipsec_get_phase1_src($phase1);
+ $gw = trim($phase1['remote-gateway']);
+ $sad_arr = ipsec_dump_sad();
+ $remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
+
+ if (!empty($phase2['natlocalid']))
+ $local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid']);
+ else
+ $local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
+
+ if ($phase2['mode'] == "tunnel6")
+ $family = "-6";
+ else
+ $family = "-4";
+
+ $spdconf .= "spddelete {$family} {$local_subnet} " .
+ "{$remote_subnet} any -P out ipsec " .
+ "{$phase2['protocol']}/tunnel/{$ep}-" .
+ "{$gw}/unique;\n";
+
+ $spdconf .= "spddelete {$family} {$remote_subnet} " .
+ "{$local_subnet} any -P in ipsec " .
+ "{$phase2['protocol']}/tunnel/{$gw}-" .
+ "{$ep}/unique;\n";
+
+ /* zap any existing SA entries */
+ foreach($sad_arr as $sad) {
+ if(($sad['dst'] == $ep) && ($sad['src'] == $gw))
+ $spdconf .= "delete {$family} {$ep} {$gw} {$phase2['protocol']} 0x{$sad['spi']};\n";
+ if(($sad['src'] == $ep) && ($sad['dst'] == $_gw))
+ $spdconf .= "delete {$family} {$gw} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
+ }
+ }
+
+ log_error(sprintf(gettext("Removing SPDs from tunnel gw '%1\$s'. Local Subnet '%2\$s' and Remote Subnet '%3\$s'. Reloading policy"),$phase1['remote-gateway'],$local_subnet,$remote_subnet));
+
+ $now = time();
+ $spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
+ /* generate temporary spd.conf */
+ @file_put_contents($spdfile, $spdconf);
+ unset($spdconf);
+ return true;
+}
+
/* reloads the tunnel configuration for a tunnel item
* Will remove and add SPD polices */
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
diff --git a/usr/local/www/vpn_ipsec.php b/usr/local/www/vpn_ipsec.php
index 55b601cf1b..4f154b70cd 100755
--- a/usr/local/www/vpn_ipsec.php
+++ b/usr/local/www/vpn_ipsec.php
@@ -88,8 +88,13 @@ if ($_GET['act'] == "delph1")
/* remove all phase2 entries that match the ikeid */
$ikeid = $a_phase1[$_GET['p1index']]['ikeid'];
foreach ($a_phase2 as $p2index => $ph2tmp)
- if ($ph2tmp['ikeid'] == $ikeid)
+ if ($ph2tmp['ikeid'] == $ikeid) {
+ remove_tunnel_spd_policy($a_phase1[$_GET['p1index']],$a_phase2[$p2index]);
unset($a_phase2[$p2index]);
+ }
+
+ /* needs to guarantee that SPDs will be removed before phase 1 */
+ vpn_ipsec_refresh_policies();
/* remove the phase1 entry */
unset($a_phase1[$_GET['p1index']]);
@@ -104,7 +109,8 @@ if ($_GET['act'] == "delph1")
if ($_GET['act'] == "delph2")
{
- if ($a_phase2[$_GET['p2index']]) {
+ if ($a_phase1[$_GET['p1index']] && $a_phase2[$_GET['p2index']]) {
+ remove_tunnel_spd_policy($a_phase1[$_GET['p1index']],$a_phase2[$_GET['p2index']]);
/* remove the phase2 entry */
unset($a_phase2[$_GET['p2index']]);
vpn_ipsec_refresh_policies();
@@ -382,7 +388,7 @@ include("head.inc");
" width="17" height="17" border="0">
- ')">
+ ')">
" width="17" height="17" border="0">