ike: Force NAT-T/UDP encapsulation if kernel interface requires it
authorTobias Brunner <tobias@strongswan.org>
Mon, 17 Jun 2013 08:23:04 +0000 (10:23 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 21 Jun 2013 15:03:21 +0000 (17:03 +0200)
src/libcharon/sa/ikev1/tasks/isakmp_natd.c
src/libcharon/sa/ikev2/tasks/ike_natd.c

index 5a779ff..fc6ac07 100644 (file)
@@ -97,6 +97,20 @@ struct private_isakmp_natd_t {
 };
 
 /**
+ * Check if UDP encapsulation has to be forced either by config or required
+ * by the kernel interface
+ */
+static bool force_encap(ike_cfg_t *ike_cfg)
+{
+       if (!ike_cfg->force_encap(ike_cfg))
+       {
+               return hydra->kernel_interface->get_features(hydra->kernel_interface) &
+                                       KERNEL_REQUIRE_UDP_ENCAPSULATION;
+       }
+       return TRUE;
+}
+
+/**
  * Get NAT-D payload type (RFC 3947 or RFC 3947 drafts).
  */
 static payload_type_t get_nat_d_payload_type(ike_sa_t *ike_sa)
@@ -183,7 +197,7 @@ static hash_payload_t *build_natd_payload(private_isakmp_natd_t *this, bool src,
        chunk_t hash;
 
        config = this->ike_sa->get_ike_cfg(this->ike_sa);
-       if (src && config->force_encap(config))
+       if (src && force_encap(config))
        {
                hash = generate_natd_hash_faked(this);
        }
@@ -297,7 +311,7 @@ static void process_payloads(private_isakmp_natd_t *this, message_t *message)
                                                                        !this->src_matched);
                config = this->ike_sa->get_ike_cfg(this->ike_sa);
                if (this->dst_matched && this->src_matched &&
-                       config->force_encap(config))
+                       force_encap(config))
                {
                        this->ike_sa->set_condition(this->ike_sa, COND_NAT_FAKE, TRUE);
                }
index 0a93db9..4fc968f 100644 (file)
@@ -78,6 +78,19 @@ struct private_ike_natd_t {
        bool mapping_changed;
 };
 
+/**
+ * Check if UDP encapsulation has to be forced either by config or required
+ * by the kernel interface
+ */
+static bool force_encap(ike_cfg_t *ike_cfg)
+{
+       if (!ike_cfg->force_encap(ike_cfg))
+       {
+               return hydra->kernel_interface->get_features(hydra->kernel_interface) &
+                                       KERNEL_REQUIRE_UDP_ENCAPSULATION;
+       }
+       return TRUE;
+}
 
 /**
  * Build NAT detection hash for a host
@@ -147,7 +160,7 @@ static notify_payload_t *build_natd_payload(private_ike_natd_t *this,
 
        ike_sa_id = this->ike_sa->get_id(this->ike_sa);
        config = this->ike_sa->get_ike_cfg(this->ike_sa);
-       if (config->force_encap(config) && type == NAT_DETECTION_SOURCE_IP)
+       if (force_encap(config) && type == NAT_DETECTION_SOURCE_IP)
        {
                hash = generate_natd_hash_faked(this);
        }
@@ -256,7 +269,7 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
                                                                        !this->src_matched);
                config = this->ike_sa->get_ike_cfg(this->ike_sa);
                if (this->dst_matched && this->src_matched &&
-                       config->force_encap(config))
+                       force_encap(config))
                {
                        this->ike_sa->set_condition(this->ike_sa, COND_NAT_FAKE, TRUE);
                }
@@ -316,7 +329,7 @@ METHOD(task_t, build_i, status_t,
         * 3. Include all possbile addresses
         */
        host = message->get_source(message);
-       if (!host->is_anyaddr(host) || ike_cfg->force_encap(ike_cfg))
+       if (!host->is_anyaddr(host) || force_encap(ike_cfg))
        {       /* 1. or if we force UDP encap, as it doesn't matter if it's %any */
                notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, host);
                if (notify)