kernel-interface: Pass the same data to del_policy() that was passed to add_policy()
authorTobias Brunner <tobias@strongswan.org>
Wed, 16 Sep 2015 14:44:09 +0000 (16:44 +0200)
committerTobias Brunner <tobias@strongswan.org>
Tue, 10 Nov 2015 15:42:52 +0000 (16:42 +0100)
The additional data can be helpful to identify the exact policy to
delete.

12 files changed:
src/charon-tkm/src/tkm/tkm_kernel_ipsec.c
src/frontends/android/jni/libandroidbridge/kernel/android_ipsec.c
src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
src/libcharon/plugins/load_tester/load_tester_ipsec.c
src/libcharon/sa/child_sa.c
src/libcharon/sa/shunt_manager.c
src/libhydra/kernel/kernel_interface.c
src/libhydra/kernel/kernel_interface.h
src/libhydra/kernel/kernel_ipsec.h
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c

index 7a0672a..2d22fbd 100644 (file)
@@ -281,9 +281,10 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_tkm_kernel_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
-       mark_t mark, policy_priority_t prio)
+       private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
+       mark_t mark, policy_priority_t priority)
 {
        return SUCCESS;
 }
index 29099d4..2eef49f 100644 (file)
@@ -126,12 +126,13 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_kernel_android_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_kernel_android_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t priority)
 {
        return ipsec->policies->del_policy(ipsec->policies, src_ts, dst_ts,
-                                                                          direction, reqid, mark, priority);
+                                                                          direction, sa->reqid, mark, priority);
 }
 
 METHOD(kernel_ipsec_t, flush_policies, status_t,
index 6246dc5..d738e6d 100644 (file)
@@ -563,15 +563,16 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_kernel_libipsec_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t priority)
 {
        policy_entry_t *policy, *found = NULL;
        status_t status;
 
        status = ipsec->policies->del_policy(ipsec->policies, src_ts, dst_ts,
-                                                                                direction, reqid, mark, priority);
+                                                                                direction, sa->reqid, mark, priority);
 
        policy = create_policy_entry(src_ts, dst_ts, direction);
 
index b38ded8..95f79f1 100644 (file)
@@ -2456,15 +2456,16 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_kernel_wfp_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t priority)
 {
        if (direction == POLICY_OUT && priority == POLICY_PRIORITY_ROUTED)
        {
-               if (remove_trap(this, reqid, FALSE, src_ts, dst_ts))
+               if (remove_trap(this, sa->reqid, FALSE, src_ts, dst_ts))
                {
-                       remove_trap(this, reqid, TRUE, src_ts, dst_ts);
+                       remove_trap(this, sa->reqid, TRUE, src_ts, dst_ts);
                        return SUCCESS;
                }
                return NOT_FOUND;
index 62d43e3..6a86bb8 100644 (file)
@@ -103,8 +103,9 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_load_tester_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_load_tester_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t priority)
 {
        return SUCCESS;
index 73f2ec9..b0f163c 100644 (file)
@@ -413,8 +413,14 @@ METHOD(enumerator_t, policy_enumerate, bool,
                {       /* protocol mismatch */
                        continue;
                }
-               *my_out = this->ts;
-               *other_out = other_ts;
+               if (my_out)
+               {
+                       *my_out = this->ts;
+               }
+               if (other_out)
+               {
+                       *other_out = other_ts;
+               }
                return TRUE;
        }
        return FALSE;
@@ -775,6 +781,50 @@ static bool require_policy_update()
 }
 
 /**
+ * Prepare SA config to install/delete policies
+ */
+static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa,
+                                                  ipsec_sa_cfg_t *other_sa)
+{
+       enumerator_t *enumerator;
+
+       *my_sa = (ipsec_sa_cfg_t){
+               .mode = this->mode,
+               .reqid = this->reqid,
+               .ipcomp = {
+                       .transform = this->ipcomp,
+               },
+       };
+       *other_sa = *my_sa;
+
+       my_sa->ipcomp.cpi = this->my_cpi;
+       other_sa->ipcomp.cpi = this->other_cpi;
+
+       if (this->protocol == PROTO_ESP)
+       {
+               my_sa->esp.use = TRUE;
+               my_sa->esp.spi = this->my_spi;
+               other_sa->esp.use = TRUE;
+               other_sa->esp.spi = this->other_spi;
+       }
+       else
+       {
+               my_sa->ah.use = TRUE;
+               my_sa->ah.spi = this->my_spi;
+               other_sa->ah.use = TRUE;
+               other_sa->ah.spi = this->other_spi;
+       }
+
+       enumerator = create_policy_enumerator(this);
+       while (enumerator->enumerate(enumerator, NULL, NULL))
+       {
+               my_sa->policy_count++;
+               other_sa->policy_count++;
+       }
+       enumerator->destroy(enumerator);
+}
+
+/**
  * Install 3 policies: out, in and forward
  */
 static status_t install_policies_internal(private_child_sa_t *this,
@@ -806,20 +856,22 @@ static status_t install_policies_internal(private_child_sa_t *this,
  * Delete 3 policies: out, in and forward
  */
 static void del_policies_internal(private_child_sa_t *this,
-               traffic_selector_t *my_ts, traffic_selector_t *other_ts,
-               policy_priority_t priority)
+       host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
+       traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
+       ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority)
 {
+
        hydra->kernel_interface->del_policy(hydra->kernel_interface,
-                                               my_ts, other_ts, POLICY_OUT, this->reqid,
-                                               this->mark_out, priority);
+                                               my_addr, other_addr, my_ts, other_ts, POLICY_OUT, type,
+                                               other_sa, this->mark_out, priority);
        hydra->kernel_interface->del_policy(hydra->kernel_interface,
-                                               other_ts, my_ts,  POLICY_IN, this->reqid,
-                                               this->mark_in, priority);
+                                               other_addr, my_addr, other_ts, my_ts, POLICY_IN,
+                                               type, my_sa, this->mark_in, priority);
        if (this->mode != MODE_TRANSPORT)
        {
                hydra->kernel_interface->del_policy(hydra->kernel_interface,
-                                               other_ts, my_ts, POLICY_FWD, this->reqid,
-                                               this->mark_in, priority);
+                                               other_addr, my_addr, other_ts, my_ts, POLICY_FWD,
+                                               type, my_sa, this->mark_in, priority);
        }
 }
 
@@ -864,31 +916,9 @@ METHOD(child_sa_t, add_policies, status_t,
        if (this->config->install_policy(this->config))
        {
                policy_priority_t priority;
-               ipsec_sa_cfg_t my_sa = {
-                       .mode = this->mode,
-                       .reqid = this->reqid,
-                       .ipcomp = {
-                               .transform = this->ipcomp,
-                       },
-               }, other_sa = my_sa;
-
-               my_sa.ipcomp.cpi = this->my_cpi;
-               other_sa.ipcomp.cpi = this->other_cpi;
-
-               if (this->protocol == PROTO_ESP)
-               {
-                       my_sa.esp.use = TRUE;
-                       my_sa.esp.spi = this->my_spi;
-                       other_sa.esp.use = TRUE;
-                       other_sa.esp.spi = this->other_spi;
-               }
-               else
-               {
-                       my_sa.ah.use = TRUE;
-                       my_sa.ah.spi = this->my_spi;
-                       other_sa.ah.use = TRUE;
-                       other_sa.ah.spi = this->other_spi;
-               }
+               ipsec_sa_cfg_t my_sa, other_sa;
+
+               prepare_sa_cfg(this, &my_sa, &other_sa);
 
                /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
                 * entry) we install a trap policy */
@@ -896,14 +926,6 @@ METHOD(child_sa_t, add_policies, status_t,
                priority = this->trap ? POLICY_PRIORITY_ROUTED
                                                          : POLICY_PRIORITY_DEFAULT;
 
-               enumerator = create_policy_enumerator(this);
-               while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
-               {
-                       my_sa.policy_count++;
-                       other_sa.policy_count++;
-               }
-               enumerator->destroy(enumerator);
-
                /* enumerate pairs of traffic selectors */
                enumerator = create_policy_enumerator(this);
                while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
@@ -1006,47 +1028,24 @@ METHOD(child_sa_t, update, status_t,
 
        if (this->config->install_policy(this->config) && require_policy_update())
        {
-               ipsec_sa_cfg_t my_sa = {
-                       .mode = this->mode,
-                       .reqid = this->reqid,
-                       .ipcomp = {
-                               .transform = this->ipcomp,
-                       },
-               }, other_sa = my_sa;
-
-               my_sa.ipcomp.cpi = this->my_cpi;
-               other_sa.ipcomp.cpi = this->other_cpi;
-
-               if (this->protocol == PROTO_ESP)
-               {
-                       my_sa.esp.use = TRUE;
-                       my_sa.esp.spi = this->my_spi;
-                       other_sa.esp.use = TRUE;
-                       other_sa.esp.spi = this->other_spi;
-               }
-               else
-               {
-                       my_sa.ah.use = TRUE;
-                       my_sa.ah.spi = this->my_spi;
-                       other_sa.ah.use = TRUE;
-                       other_sa.ah.spi = this->other_spi;
-               }
-
-               /* update policies */
                if (!me->ip_equals(me, this->my_addr) ||
                        !other->ip_equals(other, this->other_addr))
                {
+                       ipsec_sa_cfg_t my_sa, other_sa;
                        enumerator_t *enumerator;
                        traffic_selector_t *my_ts, *other_ts;
 
+                       prepare_sa_cfg(this, &my_sa, &other_sa);
+
                        /* always use high priorities, as hosts getting updated are INSTALLED */
                        enumerator = create_policy_enumerator(this);
                        while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
                        {
                                traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
                                /* remove old policies first */
-                               del_policies_internal(this, my_ts, other_ts,
-                                                                         POLICY_PRIORITY_DEFAULT);
+                               del_policies_internal(this, this->my_addr, this->other_addr,
+                                                                         my_ts, other_ts, &my_sa, &other_sa,
+                                                                         POLICY_IPSEC, POLICY_PRIORITY_DEFAULT);
 
                                /* check if we have to update a "dynamic" traffic selector */
                                if (!me->ip_equals(me, this->my_addr) &&
@@ -1068,21 +1067,20 @@ METHOD(child_sa_t, update, status_t,
 
                                /* reinstall updated policies */
                                install_policies_internal(this, me, other, my_ts, other_ts,
-                                                               &my_sa, &other_sa, POLICY_IPSEC,
-                                                               POLICY_PRIORITY_DEFAULT);
+                                                                                 &my_sa, &other_sa, POLICY_IPSEC,
+                                                                                 POLICY_PRIORITY_DEFAULT);
 
                                /* update fallback policies after the new policy is in place */
-                               if (old_my_ts || old_other_ts)
-                               {
-                                       del_policies_internal(this, old_my_ts ?: my_ts,
-                                                                                 old_other_ts ?: other_ts,
+                               del_policies_internal(this, this->my_addr, this->other_addr,
+                                                                         old_my_ts ?: my_ts,
+                                                                         old_other_ts ?: other_ts,
+                                                                         &my_sa, &other_sa, POLICY_DROP,
+                                                                         POLICY_PRIORITY_FALLBACK);
+                               install_policies_internal(this, me, other, my_ts, other_ts,
+                                                                                 &my_sa, &other_sa, POLICY_DROP,
                                                                                  POLICY_PRIORITY_FALLBACK);
-                                       install_policies_internal(this, me, other, my_ts, other_ts,
-                                                               &my_sa, &other_sa, POLICY_DROP,
-                                                               POLICY_PRIORITY_FALLBACK);
-                                       DESTROY_IF(old_my_ts);
-                                       DESTROY_IF(old_other_ts);
-                               }
+                               DESTROY_IF(old_my_ts);
+                               DESTROY_IF(old_other_ts);
                        }
                        enumerator->destroy(enumerator);
                }
@@ -1122,15 +1120,21 @@ METHOD(child_sa_t, destroy, void,
 
        if (this->config->install_policy(this->config))
        {
+               ipsec_sa_cfg_t my_sa, other_sa;
+
+               prepare_sa_cfg(this, &my_sa, &other_sa);
+
                /* delete all policies in the kernel */
                enumerator = create_policy_enumerator(this);
                while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
                {
-                       del_policies_internal(this, my_ts, other_ts, priority);
+                       del_policies_internal(this, this->my_addr, this->other_addr,
+                                       my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC, priority);
                        if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
                        {
-                               del_policies_internal(this, my_ts, other_ts,
-                                                                         POLICY_PRIORITY_FALLBACK);
+                               del_policies_internal(this, this->my_addr, this->other_addr,
+                                                               my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP,
+                                                               POLICY_PRIORITY_FALLBACK);
                        }
                }
                enumerator->destroy(enumerator);
index 9702aba..5231994 100644 (file)
@@ -203,15 +203,19 @@ static void uninstall_shunt_policy(child_cfg_t *child)
        linked_list_t *my_ts_list, *other_ts_list, *hosts;
        traffic_selector_t *my_ts, *other_ts;
        host_t *host_any, *host_any6;
+       policy_type_t policy_type;
        policy_priority_t policy_prio;
        status_t status = SUCCESS;
+       ipsec_sa_cfg_t sa = { .mode = MODE_TRANSPORT };
 
        switch (child->get_mode(child))
        {
                case MODE_PASS:
+                       policy_type = POLICY_PASS;
                        policy_prio = POLICY_PRIORITY_PASS;
                        break;
                case MODE_DROP:
+                       policy_type = POLICY_DROP;
                        policy_prio = POLICY_PRIORITY_FALLBACK;
                        break;
                default:
@@ -220,15 +224,11 @@ static void uninstall_shunt_policy(child_cfg_t *child)
 
        host_any = host_create_any(AF_INET);
        host_any6 = host_create_any(AF_INET6);
-       hosts = linked_list_create_with_items(host_any, host_any6, NULL);
 
+       hosts = linked_list_create_with_items(host_any, host_any6, NULL);
        my_ts_list =    child->get_traffic_selectors(child, TRUE,  NULL, hosts);
        other_ts_list = child->get_traffic_selectors(child, FALSE, NULL, hosts);
-
        hosts->destroy(hosts);
-       host_any6->destroy(host_any6);
-       host_any->destroy(host_any);
-
 
        /* enumerate pairs of traffic selectors */
        e_my_ts = my_ts_list->create_enumerator(my_ts_list);
@@ -249,20 +249,23 @@ static void uninstall_shunt_policy(child_cfg_t *child)
                        }
                        /* uninstall out policy */
                        status |= hydra->kernel_interface->del_policy(
-                                                       hydra->kernel_interface, my_ts, other_ts,
-                                                       POLICY_OUT, 0, child->get_mark(child, FALSE),
+                                                       hydra->kernel_interface, host_any, host_any,
+                                                       my_ts, other_ts, POLICY_OUT, policy_type,
+                                                       &sa, child->get_mark(child, FALSE),
                                                        policy_prio);
 
                        /* uninstall in policy */
                        status |= hydra->kernel_interface->del_policy(
-                                                       hydra->kernel_interface, other_ts, my_ts,
-                                                       POLICY_IN, 0, child->get_mark(child, TRUE),
+                                                       hydra->kernel_interface, host_any, host_any,
+                                                       other_ts, my_ts, POLICY_IN, policy_type,
+                                                       &sa, child->get_mark(child, TRUE),
                                                        policy_prio);
 
                        /* uninstall forward policy */
                        status |= hydra->kernel_interface->del_policy(
-                                                       hydra->kernel_interface, other_ts, my_ts,
-                                                       POLICY_FWD, 0, child->get_mark(child, TRUE),
+                                                       hydra->kernel_interface, host_any, host_any,
+                                                       other_ts, my_ts, POLICY_FWD, policy_type,
+                                                       &sa, child->get_mark(child, TRUE),
                                                        policy_prio);
                }
                e_other_ts->destroy(e_other_ts);
@@ -273,6 +276,8 @@ static void uninstall_shunt_policy(child_cfg_t *child)
                                                           offsetof(traffic_selector_t, destroy));
        other_ts_list->destroy_offset(other_ts_list,
                                                           offsetof(traffic_selector_t, destroy));
+       host_any6->destroy(host_any6);
+       host_any->destroy(host_any);
 
        if (status != SUCCESS)
        {
index e443545..89e95ad 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2013 Tobias Brunner
+ * Copyright (C) 2008-2015 Tobias Brunner
  * Hochschule fuer Technik Rapperswil
  * Copyright (C) 2010 Martin Willi
  * Copyright (C) 2010 revosec AG
@@ -509,16 +509,17 @@ METHOD(kernel_interface_t, query_policy, status_t,
 }
 
 METHOD(kernel_interface_t, del_policy, status_t,
-       private_kernel_interface_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t priority)
 {
        if (!this->ipsec)
        {
                return NOT_SUPPORTED;
        }
-       return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts,
-                                                                  direction, reqid, mark, priority);
+       return this->ipsec->del_policy(this->ipsec, src, dst, src_ts, dst_ts,
+                                                                  direction, type, sa, mark, priority);
 }
 
 METHOD(kernel_interface_t, flush_policies, status_t,
index 58113e5..45efe89 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2013 Tobias Brunner
+ * Copyright (C) 2006-2015 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -265,9 +265,6 @@ struct kernel_interface_t {
        /**
         * Add a policy to the SPD.
         *
-        * A policy is always associated to an SA. Traffic which matches a
-        * policy is handled by the SA with the same reqid.
-        *
         * @param src                   source address of SA
         * @param dst                   dest address of SA
         * @param src_ts                traffic selector to match traffic source
@@ -309,24 +306,24 @@ struct kernel_interface_t {
        /**
         * Remove a policy from the SPD.
         *
-        * The kernel interface implements reference counting for policies.
-        * If the same policy is installed multiple times (in the case of rekeying),
-        * the reference counter is increased. del_policy() decreases the ref counter
-        * and removes the policy only when no more references are available.
-        *
+        * @param src                   source address of SA
+        * @param dst                   dest address of SA
         * @param src_ts                traffic selector to match traffic source
         * @param dst_ts                traffic selector to match traffic dest
         * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
-        * @param reqid                 unique ID of the associated SA
-        * @param mark                  optional mark
+        * @param type                  type of policy, POLICY_(IPSEC|PASS|DROP)
+        * @param sa                    details about the SA(s) tied to this policy
+        * @param mark                  mark for this policy
         * @param priority              priority of the policy
         * @return                              SUCCESS if operation completed
         */
        status_t (*del_policy) (kernel_interface_t *this,
+                                                       host_t *src, host_t *dst,
                                                        traffic_selector_t *src_ts,
                                                        traffic_selector_t *dst_ts,
-                                                       policy_dir_t direction, u_int32_t reqid,
-                                                       mark_t mark, policy_priority_t priority);
+                                                       policy_dir_t direction, policy_type_t type,
+                                                       ipsec_sa_cfg_t *sa, mark_t mark,
+                                                       policy_priority_t priority);
 
        /**
         * Flush all policies from the SPD.
index 19caaa4..2458db5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2012 Tobias Brunner
+ * Copyright (C) 2006-2015 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
  * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
@@ -186,9 +186,6 @@ struct kernel_ipsec_t {
        /**
         * Add a policy to the SPD.
         *
-        * A policy is always associated to an SA. Traffic which matches a
-        * policy is handled by the SA with the same reqid.
-        *
         * @param src                   source address of SA
         * @param dst                   dest address of SA
         * @param src_ts                traffic selector to match traffic source
@@ -231,24 +228,24 @@ struct kernel_ipsec_t {
        /**
         * Remove a policy from the SPD.
         *
-        * The kernel interface implements reference counting for policies.
-        * If the same policy is installed multiple times (in the case of rekeying),
-        * the reference counter is increased. del_policy() decreases the ref counter
-        * and removes the policy only when no more references are available.
-        *
+        * @param src                   source address of SA
+        * @param dst                   dest address of SA
         * @param src_ts                traffic selector to match traffic source
         * @param dst_ts                traffic selector to match traffic dest
         * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
-        * @param reqid                 unique ID of the associated SA
-        * @param mark                  optional mark
+        * @param type                  type of policy, POLICY_(IPSEC|PASS|DROP)
+        * @param sa                    details about the SA(s) tied to this policy
+        * @param mark                  mark for this policy
         * @param priority              priority of the policy
         * @return                              SUCCESS if operation completed
         */
        status_t (*del_policy) (kernel_ipsec_t *this,
+                                                       host_t *src, host_t *dst,
                                                        traffic_selector_t *src_ts,
                                                        traffic_selector_t *dst_ts,
-                                                       policy_dir_t direction, u_int32_t reqid,
-                                                       mark_t mark, policy_priority_t priority);
+                                                       policy_dir_t direction, policy_type_t type,
+                                                       ipsec_sa_cfg_t *sa, mark_t mark,
+                                                       policy_priority_t priority);
 
        /**
         * Flush all policies from the SPD.
index a7a6f46..db66de2 100644 (file)
@@ -2470,8 +2470,9 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t prio)
 {
        policy_entry_t *current, policy;
@@ -2496,7 +2497,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
        /* find the policy */
        this->mutex->lock(this->mutex);
        current = this->policies->get(this->policies, &policy);
-       if (!current || current->reqid != reqid)
+       if (!current || current->reqid != sa->reqid)
        {
                if (mark.value)
                {
index 0df6fb5..107ee6a 100644 (file)
@@ -2691,8 +2691,9 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
 }
 
 METHOD(kernel_ipsec_t, del_policy, status_t,
-       private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
-       traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid,
+       private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
        mark_t mark, policy_priority_t prio)
 {
        unsigned char request[PFKEY_BUFFER_SIZE];
@@ -2737,7 +2738,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
        enumerator = policy->used_by->create_enumerator(policy->used_by);
        while (enumerator->enumerate(enumerator, (void**)&mapping))
        {
-               if (reqid == mapping->sa->cfg.reqid && priority == mapping->priority)
+               if (sa->reqid == mapping->sa->cfg.reqid &&
+                       priority == mapping->priority)
                {
                        to_remove = mapping;
                        is_installed = first;