]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
child-sa: Configure UDP encapsulation for per-CPU SAs
authorTobias Brunner <tobias@strongswan.org>
Tue, 15 Jun 2021 09:11:14 +0000 (11:11 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 28 May 2025 14:35:27 +0000 (16:35 +0200)
As the kernel does not support processing UDP-encapsulated and plain ESP
for the same SA, we require forcing UDP encapsulation if there is no NAT.

src/libcharon/sa/child_sa.c

index d5c09c1dae7bd0aeff074f19767e372034532a99..2c0ef08ed12b9cd39df290725cdcc0f09687edd2 100644 (file)
@@ -988,6 +988,14 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
                this->my_cpi = cpi;
                dst_ts = my_ts;
                src_ts = other_ts;
+
+               if (this->per_cpu && this->encap)
+               {
+                       src = src->clone(src);
+                       /* accept inbound traffic from any port as we don't know if the
+                        * peer uses random ports or not */
+                       src->set_port(src, 0);
+               }
        }
        else
        {
@@ -1002,6 +1010,14 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
                {
                        tfc = this->config->get_tfc(this->config);
                }
+               if (this->per_cpu && this->encap &&
+                       this->config->has_option(this->config, OPT_PER_CPU_SAS_ENCAP))
+               {
+                       src = src->clone(src);
+                       /* use a random source port between 49152 and 65535. doesn't matter
+                        * if it's free or not as we don't receive traffic on it */
+                       src->set_port(src, 0xc000 | (random() & 0xffff));
+               }
        }
 
        DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
@@ -1106,6 +1122,10 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
 
        status = charon->kernel->add_sa(charon->kernel, &id, &sa);
 
+       if (src != this->my_addr && src != this->other_addr)
+       {
+               src->destroy(src);
+       }
        my_ts->destroy(my_ts);
        other_ts->destroy(other_ts);
        free(lifetime);