Mark CHILD_SAs used for trap policies to uninstall them properly.
authorTobias Brunner <tobias@strongswan.org>
Mon, 4 Jun 2012 15:43:38 +0000 (17:43 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 4 Jun 2012 16:04:48 +0000 (18:04 +0200)
If the installation failed the state is not CHILD_ROUTED which means the
wrong priority is used to uninstall the policies.  This is a problem for
kernel interfaces that keep track of installed policies as now the proper
policy is not found (if the priority is considered).

src/libcharon/sa/child_sa.c

index d86578f..76cccee 100644 (file)
@@ -124,6 +124,11 @@ struct private_child_sa_t {
        child_sa_state_t state;
 
        /**
+        * TRUE if this CHILD_SA is used to install trap policies
+        */
+       bool trap;
+
+       /**
         * Specifies if UDP encapsulation is enabled (NAT traversal)
         */
        bool encap;
@@ -767,8 +772,11 @@ METHOD(child_sa_t, add_policies, status_t,
                        other_sa.ah.spi = this->other_spi;
                }
 
-               priority = this->state == CHILD_CREATED ? POLICY_PRIORITY_ROUTED
-                                                                                               : POLICY_PRIORITY_DEFAULT;
+               /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
+                * entry) we install a trap policy */
+               this->trap = this->state == CHILD_CREATED;
+               priority = this->trap ? POLICY_PRIORITY_ROUTED
+                                                         : POLICY_PRIORITY_DEFAULT;
 
                /* enumerate pairs of traffic selectors */
                enumerator = create_policy_enumerator(this);
@@ -797,8 +805,8 @@ METHOD(child_sa_t, add_policies, status_t,
                enumerator->destroy(enumerator);
        }
 
-       if (status == SUCCESS && this->state == CHILD_CREATED)
-       {       /* switch to routed state if no SAD entry set up */
+       if (status == SUCCESS && this->trap)
+       {
                set_state(this, CHILD_ROUTED);
        }
        return status;
@@ -970,8 +978,7 @@ METHOD(child_sa_t, destroy, void,
        traffic_selector_t *my_ts, *other_ts;
        policy_priority_t priority;
 
-       priority = this->state == CHILD_ROUTED ? POLICY_PRIORITY_ROUTED
-                                                                                  : POLICY_PRIORITY_DEFAULT;
+       priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
 
        set_state(this, CHILD_DESTROYING);