kernel: Make range of SPIs for IPsec SAs configurable
authorTobias Brunner <tobias@strongswan.org>
Tue, 21 Feb 2017 18:21:01 +0000 (19:21 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 2 Mar 2017 07:52:56 +0000 (08:52 +0100)
conf/options/charon.opt
src/libcharon/kernel/kernel_interface.h
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
src/libipsec/ipsec_sa_mgr.c

index 7c56fc1..493d73f 100644 (file)
@@ -350,6 +350,12 @@ charon.signature_authentication_constraints = yes
        certificate chain, are also used as constraints against the signature scheme
        used by peers during IKEv2.
 
+charon.spi_min = 0xc0000000
+       The lower limit for SPIs requested from the kernel for IPsec SAs.
+
+charon.spi_max = 0xcfffffff
+       The upper limit for SPIs requested from the kernel for IPsec SAs.
+
 charon.start-scripts {}
        Section containing a list of scripts (name = path) that are executed when
        the daemon is started.
index 96c9ffa..d601ebd 100644 (file)
@@ -57,6 +57,12 @@ typedef enum kernel_feature_t kernel_feature_t;
 #include <kernel/kernel_net.h>
 
 /**
+ * Default range for SPIs requested from kernels
+ */
+#define KERNEL_SPI_MIN 0xc0000000
+#define KERNEL_SPI_MAX 0xcfffffff
+
+/**
  * Bitfield of optional features a kernel backend supports.
  *
  * This feature-set is for both, kernel_ipsec_t and kernel_net_t. Each
index 0dd793f..becf6b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2016 Tobias Brunner
+ * Copyright (C) 2006-2017 Tobias Brunner
  * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2008-2016 Andreas Steffen
  * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
@@ -1211,8 +1211,15 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
        private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
        uint8_t protocol, uint32_t *spi)
 {
-       if (get_spi_internal(this, src, dst, protocol,
-                                                0xc0000000, 0xcFFFFFFF, spi) != SUCCESS)
+       uint32_t spi_min, spi_max;
+
+       spi_min = lib->settings->get_int(lib->settings, "%s.spi_min",
+                                                                        KERNEL_SPI_MIN, lib->ns);
+       spi_max = lib->settings->get_int(lib->settings, "%s.spi_max",
+                                                                        KERNEL_SPI_MAX, lib->ns);
+
+       if (get_spi_internal(this, src, dst, protocol, min(spi_min, spi_max),
+                                                max(spi_min, spi_max), spi) != SUCCESS)
        {
                DBG1(DBG_KNL, "unable to get SPI");
                return FAILED;
index c99fe67..1787814 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2016 Tobias Brunner
+ * Copyright (C) 2008-2017 Tobias Brunner
  * Copyright (C) 2008 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
@@ -1586,8 +1586,15 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
        private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
        uint8_t protocol, uint32_t *spi)
 {
-       if (get_spi_internal(this, src, dst, protocol,
-                                                0xc0000000, 0xcFFFFFFF, spi) != SUCCESS)
+       uint32_t spi_min, spi_max;
+
+       spi_min = lib->settings->get_int(lib->settings, "%s.spi_min",
+                                                                        KERNEL_SPI_MIN, lib->ns);
+       spi_max = lib->settings->get_int(lib->settings, "%s.spi_max",
+                                                                        KERNEL_SPI_MAX, lib->ns);
+
+       if (get_spi_internal(this, src, dst, protocol, min(spi_min, spi_max),
+                                                max(spi_min, spi_max), spi) != SUCCESS)
        {
                DBG1(DBG_KNL, "unable to get SPI");
                return FAILED;
index ec35c6e..031d599 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2017 Tobias Brunner
  * Copyright (C) 2012 Giuliano Grassi
  * Copyright (C) 2012 Ralf Sager
  * Hochschule fuer Technik Rapperswil
@@ -398,7 +398,18 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t,
        private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, uint8_t protocol,
        uint32_t *spi)
 {
-       uint32_t spi_new;
+       uint32_t spi_min, spi_max, spi_new;
+
+       spi_min = lib->settings->get_int(lib->settings, "%s.spi_min",
+                                                                        KERNEL_SPI_MIN, lib->ns);
+       spi_max = lib->settings->get_int(lib->settings, "%s.spi_max",
+                                                                        KERNEL_SPI_MAX, lib->ns);
+       if (spi_min > spi_max)
+       {
+               spi_new = spi_min;
+               spi_min = spi_max;
+               spi_max = spi_new;
+       }
 
        this->mutex->lock(this->mutex);
        if (!this->rng)
@@ -421,6 +432,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t,
                        DBG1(DBG_ESP, "failed to allocate SPI");
                        return FAILED;
                }
+               spi_new = spi_min + spi_new % (spi_max - spi_min + 1);
                /* make sure the SPI is valid (not in range 0-255) */
                spi_new |= 0x00000100;
                spi_new = htonl(spi_new);