child-sa: Install "outbound" FWD policy with lower priority
authorTobias Brunner <tobias@strongswan.org>
Mon, 2 May 2016 12:21:30 +0000 (14:21 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 6 May 2016 18:27:18 +0000 (20:27 +0200)
This provides a fix if symmetrically overlapping policies are
installed as e.g. the case in the ikev2/ip-two-pools-db scenario:

  carol 10.3.0.1/32 ----- 10.3.0.0/16, 10.4.0.0/16 moon
  alice 10.4.0.1/32 ----- 10.3.0.0/16, 10.4.0.0/16 moon

Among others, the following FWD policies are installed on moon:

  src 10.3.0.1/32 dst 10.4.0.0/16
    ...
    tmpl ...

  src 10.4.0.0/16 dst 10.3.0.1/32
    ...

  src 10.4.0.1/32 dst 10.3.0.0/16
    ...
    tmpl ...

  src 10.3.0.0/16 dst 10.4.0.1/32
    ...

Because the network prefixes are the same for all of these they all have the
same priority.  Due to that it depends on the install order which policy gets
used.  For instance, a packet from 10.3.0.1 to 10.4.0.1 will match the
first as well as the last policy.  However, when handling the inbound
packet we have to use the first one as the packet will otherwise be
dropped due to a template mismatch.  And we can't install templates with
the "outbound" FWD policies as that would prevent using different
IPsec modes or e.g. IPComp on only one of multiple SAs.

Instead we install the "outbound" FWD policies with a lower priority
than the "inbound" FWD policies so the latter are preferred.  But we use
a higher priority than default drop policies would use (in case they'd
be defined with the same subnets).

src/libcharon/sa/child_sa.c

index babfb01..e75e399 100644 (file)
@@ -927,9 +927,16 @@ static status_t install_policies_internal(private_child_sa_t *this,
                 * matching outbound forwarded traffic, to allow another tunnel to use
                 * the reversed subnets and do the same we don't set a reqid (this also
                 * allows the kernel backend to distinguish between the two types of
-                * FWD policies) */
+                * FWD policies). To avoid problems with symmetrically overlapping
+                * policies of two SAs we install them with reduced priority.  As they
+                * basically act as bypass policies for drop policies we use a higher
+                * priority than is used for them. */
                out_id.dir = POLICY_FWD;
                other_sa->reqid = 0;
+               if (priority == POLICY_PRIORITY_DEFAULT)
+               {
+                       out_policy.prio = POLICY_PRIORITY_ROUTED;
+               }
                status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy);
                /* reset the reqid for any other further policies */
                other_sa->reqid = this->reqid;
@@ -983,6 +990,10 @@ static void del_policies_internal(private_child_sa_t *this,
 
                out_id.dir = POLICY_FWD;
                other_sa->reqid = 0;
+               if (priority == POLICY_PRIORITY_DEFAULT)
+               {
+                       out_policy.prio = POLICY_PRIORITY_ROUTED;
+               }
                charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
                other_sa->reqid = this->reqid;
        }