Hello Martin,

Martin Willi schrobtete:
> Hi Thomas,
> 
>> a child_sa for IPv6 addresses has the encap flag set, the kernel
>> rejects the insertion of the state with error code 22 (invalid
>> argument). This is due to the fact that IPv6 does not support NAT
>> (yet?).
> 
> Yes.
> 
>> Please consider the little patch for upstream inclusion.
> 
>> +    if (this->encap && src->get_family(src) != AF_INET6)
>> +    {
>> +            encap = TRUE;
>> +    }
> 
> I'm a little skeptic about just disabling the encapsulation flag. The
> flag gets set for specific reasons (i.e. NAT has been detected), and
> just disabling it does not help. Even worse, the SA gets established
> without error, but your traffic won't flow over the NAT device. 
I've given this some thought and must admit you're right.

> In my opinion, it makes more sense to throw this error and let the
> negotiation fail. Unless the kernel gains IPv6 NAT support (if ever),
> the patch won't help in situations where encapsulation is required.
This is true, but wouldn't telling the user that his/her setup is certain
to fail be way better?

> Or is there a specific scenario where encap is set, but the tunnel would
> work without?
There is indeed. But this would be merely a misconfiguration: Since at
loading time of a forced_encap config it is not tested whether or not
the configured peers are IPv6 hosts such a config will be loaded and not
be discarded.
At the time charon realizes the misconfiguration it might ignore the
force_encap flag or not. This is just a matter of taste.

I amended my first patch and added a second one to address the issue of
the misconfigured SAs.

Regards
Thomas
>From b58661729836b72d5db2929c3a1e89638f9208a8 Mon Sep 17 00:00:00 2001
From: Thomas Egerer <[email protected]>
Date: Thu, 8 Jul 2010 10:44:51 +0200
Subject: [PATCH 1/2] Ignore encapsulation flag for IPv6 CHILD_SAs

---
 src/libcharon/sa/child_sa.c |   22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index bd41cba..97ed1f2 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -605,7 +605,7 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
 	lifetime_cfg_t *lifetime;
 	host_t *src, *dst;
 	status_t status;
-	bool update = FALSE;
+	bool encap, update = FALSE;
 
 	/* now we have to decide which spi to use. Use self allocated, if "in",
 	 * or the one in the proposal, if not "in" (others). Additionally,
@@ -629,6 +629,24 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
 		this->other_cpi = cpi;
 	}
 
+	if (this->encap && src->get_family(src) == AF_INET6)
+	{
+		if (!lib->settings->get_bool(lib->settings, "charon.ignore_ipv6_nat", 0))
+		{
+			encap = TRUE;
+			DBG1(DBG_CHD, "NATted IPv6 connections are certain to fail, "
+					"trying it anyways");
+		}
+		else
+		{
+			DBG2(DBG_CHD, "ignoring NAT-condition detected on child sa");
+		}
+	}
+	else
+	{
+		encap = this->encap;
+	}
+
 	DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
 		 protocol_id_names, this->protocol);
 
@@ -678,7 +696,7 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
 				src, dst, spi, this->protocol, this->reqid,
 				inbound ? this->mark_in : this->mark_out,
 				lifetime, enc_alg, encr, int_alg, integ, this->mode,
-				this->ipcomp, cpi, this->encap, update, src_ts, dst_ts);
+				this->ipcomp, cpi, encap, update, src_ts, dst_ts);
 
 	free(lifetime);
 
-- 
1.7.1

>From 4f763480b20167d134d1b1b552f31e65887603aa Mon Sep 17 00:00:00 2001
From: Thomas Egerer <[email protected]>
Date: Thu, 8 Jul 2010 10:46:38 +0200
Subject: [PATCH 2/2] Inhibit forced NAT encapsulation for IPv6 connections

---
 src/libcharon/sa/ike_sa.c |   13 +++++++++++--
 1 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index 7536662..4a4466a 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -525,8 +525,17 @@ METHOD(ike_sa_t, set_condition, void,
 					this->conditions |= COND_NAT_ANY;
 					break;
 				case COND_NAT_FAKE:
-					DBG1(DBG_IKE, "faking NAT situation to enforce UDP encapsulation");
-					this->conditions |= COND_NAT_ANY;
+					if (this->my_host->get_family(this->my_host) == AF_INET6 &&
+						lib->settings->get_bool(lib->settings, "charon.no_forcedencaps_ipv6", 0))
+					{
+						DBG1(DBG_IKE, "not allowing IPv6 connection to use "
+								"faked NAT encapsulation");
+					}
+					else
+					{
+						DBG1(DBG_IKE, "faking NAT situation to enforce UDP encapsulation");
+						this->conditions |= COND_NAT_ANY;
+					}
 					break;
 				default:
 					break;
-- 
1.7.1

_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev

Reply via email to