[Openswan Users] disconnect causes failure

Paul Wouters paul at xelerance.com
Mon Sep 20 12:23:04 EDT 2010


On Mon, 20 Sep 2010, Bob Miller wrote:

> I am wondering if any progress has been made on this issue yet?  I saw a
> mail by Rick Olson recently with a workaround, looks better than the
> attempts I made at something similar, but I am wondering if there is
> anything more official...

Try the attached patch. It will be part of openswan 2.6.29 that should be
released shortly.

Paul
-------------- next part --------------
commit 20a8ae4a7a50d3cc100334d5a0851043c71e2c25
Author: Paul Wouters <paul at xelerance.com>
Date:   Tue Sep 14 23:51:50 2010 -0400

    NETKEY: Fix for spurious kernel acquires landing us wrongly into
            opportunistic code. [paul/dhr]
    
    NETKEY is sending bogus aquire messages sometimes when used with
    transport mode and L2TP (protoport 17/1701). These seem mostly triggered
    by Windows and OSX clients. The acquire is notify of a %hold message in
    the kernel. pluto then failed to match the acquire to a connection (there
    was no matching on-demand tunnel or opportunistic connection) and would
    install a "failsafe" %pass eroute. Unfortunately, the transport_proto
    argument (17) was not set in this replacement eroute, and so we would
    end up with a (bogus) %pass eroute, and a non-deleted netlink-aquire
    %hold invisible to pluto.
    
    In cannot_oppo() where we detect this failure, we now properly call
    replace_bare_shunt() with the "delete" argument for the %hold.
    
    A similar transport_proto mismatch in clear_narrow_holds() is fixed too.

diff --git a/programs/pluto/initiate.c b/programs/pluto/initiate.c
index f323576..5db0116 100644
--- a/programs/pluto/initiate.c
+++ b/programs/pluto/initiate.c
@@ -302,7 +302,7 @@ restart_connections_by_peer(struct connection *c)
 }
 
 /* (Possibly) Opportunistic Initiation:
- * Knowing clients (single IP addresses), try to build an tunnel.
+ * Knowing clients (single IP addresses), try to build a tunnel.
  * This may involve discovering a gateway and instantiating an
  * Opportunistic connection.  Called when a packet is caught by
  * a %trap, or when whack --oppohere --oppothere is used.
@@ -401,10 +401,10 @@ cannot_oppo(struct connection *c
 	struct state *st;
 
 	passert(c->kind == CK_TEMPLATE);
-	passert(c->policy_next->kind == CK_PERMANENT);
+	passert(nc->kind == CK_PERMANENT);
 
 	DBG(DBG_OPPO, DBG_log("OE failed for %s to %s, but %s overrides shunt"
-			      , ocb, pcb, c->policy_next->name));
+			      , ocb, pcb, nc->name));
 
 	/*
 	 * okay, here we need add to the "next" policy, which is ought
@@ -469,25 +469,23 @@ cannot_oppo(struct connection *c
 	return;
     }
 
-#ifdef KLIPS
+#ifdef KLIPS /* This should really be 'if opportunistic is supported' - netlink has acquires too */
     if (b->held)
     {
 	int failure_shunt = b->failure_shunt;
 
 	/* Replace HOLD with b->failure_shunt.
-	 * If no b->failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE.
+	 * If no failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE.
 	 */
-	if (b->failure_shunt == 0)
+	if (failure_shunt == 0)
 	{
-	    DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; installing %%pass"
+	    DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; removing spurious hold shunt"
 				  , ocb, pcb));
-	    failure_shunt = SPI_PASS;
 	}
-
 	(void) replace_bare_shunt(&b->our_client, &b->peer_client
 	    , b->policy_prio
 	    , failure_shunt
-	    , failure_shunt == SPI_PASS
+	    , failure_shunt != 0
 	    , b->transport_proto
 	    , ughmsg);
     }
@@ -753,10 +751,10 @@ initiate_ondemand_body(struct find_oppo_bundle *b
 	cannot_oppo(NULL, b, "impossible IP address");
 	work = 0;
     }
-    else if ((c = find_connection_for_clients(&sr
+    else if (!(c = find_connection_for_clients(&sr
 					      , &b->our_client
 					      , &b->peer_client
-					      , b->transport_proto)) == NULL)
+					      , b->transport_proto)))
     {
 	/* No connection explicitly handles the clients and there
 	 * are no Opportunistic connections -- whine and give up.
diff --git a/programs/pluto/kernel.c b/programs/pluto/kernel.c
index 8ee503c..d76adfe 100644
--- a/programs/pluto/kernel.c
+++ b/programs/pluto/kernel.c
@@ -118,7 +118,7 @@ DBG_bare_shunt_log(const char *op, const struct bare_shunt *bs)
             subnettot(&(bs)->his, 0, hist, sizeof(hist));
             satot(&(bs)->said, 0, sat, sizeof(sat));
             fmt_policy_prio(bs->policy_prio, prio);
-            DBG_log("%s bare shunt %p %s:%d -%d-> %s:%d => %s %s    %s"
+            DBG_log("%s bare shunt %p %s:%d --%d--> %s:%d => %s %s    %s"
                 , op, (const void *)(bs), ourst, ourport, (bs)->transport_proto, hist, hisport
                 , sat, prio, (bs)->why);
         });
@@ -133,7 +133,7 @@ record_and_initiate_opportunistic(const ip_subnet *ours
 {
     passert(samesubnettype(ours, his));
 
-    /* Add to bare shunt list.
+    /* Add the kernel shunt to the pluto bare shunt list.
      * We need to do this because the shunt was installed by KLIPS
      * which can't do this itself.
      */
@@ -967,7 +967,7 @@ clear_narrow_holds(
 	    (void) replace_bare_shunt(&p->ours.addr, &p->his.addr
 		    , BOTTOM_PRIO
 		    , SPI_PASS	/* not used */
-		    , FALSE, 0
+		    , FALSE, transport_proto
 		    , "removing clashing narrow holds");
 
 	    /* restart from beginning as we just removed and entry */
@@ -1033,7 +1033,7 @@ replace_bare_shunt(const ip_address *src, const ip_address *dst
                                 
                                 bs->ours = this_broad_client;
                                 bs->his =  that_broad_client;
-                                bs->transport_proto = 0;
+                                bs->transport_proto = transport_proto;
                                 bs->said.proto = SA_INT;
                                 bs->why = clone_str(why, "bare shunt story");
                                 bs->policy_prio = policy_prio;
@@ -1083,9 +1083,12 @@ replace_bare_shunt(const ip_address *src, const ip_address *dst
                 struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client
                                                            , &that_client, 0);
                 
+		passert(bs_pp != NULL);
                 if (repl)
                     {
-                        /* change over to new bare eroute */
+                        /* change over to new bare eroute
+			 * ours, his, transport_proto are the same.
+			 */
                         struct bare_shunt *bs = *bs_pp;
                         
                         pfree(bs->why);
diff --git a/programs/pluto/kernel_netlink.c b/programs/pluto/kernel_netlink.c
index 4a4456d..b44d705 100644
--- a/programs/pluto/kernel_netlink.c
+++ b/programs/pluto/kernel_netlink.c
@@ -457,7 +457,7 @@ netlink_raw_eroute(const ip_address *this_host
 		   , const ip_subnet *that_client
 		   , ipsec_spi_t spi
 		   , unsigned int proto
-		   , unsigned int transport_proto UNUSED
+		   , unsigned int transport_proto
 		   , enum eroute_type esatype
 		   , const struct pfkey_proto_info *proto_info
 		   , time_t use_lifetime UNUSED


More information about the Users mailing list