Hello *,

I required to make the SPI-range used by charon configureable. I've
appended the patch required to this mail. To achieve this I had to
introduce a new getter for the settings library in charon for an
unsigned int value (using strtoul). I took the liberty and added quite a
bunch of these getters for different sizes/signendness. I also migrated
settings_t to the new INIT/METHOD macros.
Feel free to apply the patches.

Kind regards,

Thomas

>From 3b3f08bac7f8d371dd66971a3e17eb7039f158ff Mon Sep 17 00:00:00 2001
From: Thomas Egerer <[email protected]>
Date: Thu, 18 Mar 2010 15:42:15 +0100
Subject: [PATCH 1/3] getter for int types differing in size/signedness

---
 src/libstrongswan/settings.c |  196 ++++++++++++++++++++++++++++++++++++++++++
 src/libstrongswan/settings.h |   84 ++++++++++++++++++-
 2 files changed, 279 insertions(+), 1 deletions(-)

diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
index def1d28..cbfe16d 100644
--- a/src/libstrongswan/settings.c
+++ b/src/libstrongswan/settings.c
@@ -200,6 +200,102 @@ static char* get_str(private_settings_t *this, char *key, char *def, ...)
 }
 
 /**
+ * Implementation of get_int8
+ */
+static int8_t get_int8(private_settings_t *this, char *key, int8_t def, ...)
+{
+	char *value;
+	int intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtol(value, NULL, 10);
+		if (errno == 0 && intval >= SCHAR_MIN && intval <= SCHAR_MAX)
+		{
+			return (int8_t)intval;
+		}
+	}
+	return def;
+}
+
+/**
+ * Implementation of get_uint8
+ */
+static u_int8_t get_uint8(private_settings_t *this, char *key, u_int8_t def, ...)
+{
+	char *value;
+	int intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtoul(value, NULL, 10);
+		if (errno == 0 && intval <= UCHAR_MAX)
+		{
+			return (u_int8_t)intval;
+		}
+	}
+	return def;
+}
+
+/**
+ * Implementation of get_int16
+ */
+static int16_t get_int16(private_settings_t *this, char *key, int16_t def, ...)
+{
+	char *value;
+	int intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtol(value, NULL, 10);
+		if (errno == 0 && intval >= SHRT_MIN && intval <= SHRT_MAX)
+		{
+			return (int16_t)intval;
+		}
+	}
+	return def;
+}
+
+/**
+ * Implementation of get_uint16
+ */
+static u_int16_t get_uint16(private_settings_t *this, char *key, u_int16_t def, ...)
+{
+	char *value;
+	int intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtoul(value, NULL, 10);
+		if (errno == 0 && intval <= USHRT_MAX)
+		{
+			return (u_int16_t)intval;
+		}
+	}
+	return def;
+}
+
+/**
  * Implementation of settings_t.get_bool.
  */
 static bool get_bool(private_settings_t *this, char *key, bool def, ...)
@@ -255,6 +351,96 @@ static int get_int(private_settings_t *this, char *key, int def, ...)
 }
 
 /**
+ * Implementation of get_uint
+ */
+static u_int32_t get_uint(private_settings_t *this, char *key, u_int32_t def, ...)
+{
+	char *value;
+	u_int32_t intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtoul(value, NULL, 10);
+		if (errno == 0)
+		{
+			return intval;
+		}
+	}
+	return def;
+}
+
+/**
+ * Implementation of get_int64
+ */
+static int64_t get_int64(private_settings_t *this, char *key, int64_t def, ...)
+{
+	char *value;
+	int64_t intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtoll(value, NULL, 10);
+		if (errno == 0)
+		{
+			return intval;
+		}
+	}
+	return def;
+}
+
+/**
+ * Implementation of get_uint64
+ */
+static u_int64_t get_uint64(private_settings_t *this, char *key, u_int64_t def, ...)
+{
+	char *value;
+	u_int64_t intval;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		errno = 0;
+		intval = strtoull(value, NULL, 10);
+		if (errno == 0)
+		{
+			return intval;
+		}
+	}
+	return def;
+}
+
+/**
+ * Implementation of get_char
+ */
+static char get_char(private_settings_t *this, char *key, char def, ...)
+{
+	char *value;
+	va_list args;
+
+	va_start(args, def);
+	value = find_value(this->top, key, args);
+	va_end(args);
+	if (value)
+	{
+		return value[0];
+	}
+	return def;
+}
+
+/**
  * Implementation of settings_t.get_double.
  */
 static double get_double(private_settings_t *this, char *key, double def, ...)
@@ -548,7 +734,17 @@ settings_t *settings_create(char *file)
 
 	this = malloc_thing(private_settings_t);
 	this->public.get_str = (char*(*)(settings_t*, char *key, char* def, ...))get_str;
+	this->public.get_char = (char(*)(settings_t*, char *key, char def, ...))get_char;
+	this->public.get_int8 = (int8_t(*)(settings_t*, char *key, int8_t def, ...))get_int8;
+	this->public.get_uint8 = (u_int8_t(*)(settings_t*, char *key, u_int8_t def, ...))get_uint8;
+	this->public.get_int16 = (int16_t(*)(settings_t*, char *key, int16_t def, ...))get_int16;
+	this->public.get_uint16 = (u_int16_t(*)(settings_t*, char *key, u_int16_t def, ...))get_uint16;
+	this->public.get_int32 = (int(*)(settings_t*, char *key, int def, ...))get_int;
 	this->public.get_int = (int(*)(settings_t*, char *key, int def, ...))get_int;
+	this->public.get_uint32 = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_uint;
+	this->public.get_uint = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_uint;
+	this->public.get_int64 = (int64_t(*)(settings_t*, char *key, int64_t def, ...))get_int64;
+	this->public.get_uint64 = (u_int64_t(*)(settings_t*, char *key, u_int64_t def, ...))get_uint64;
 	this->public.get_double = (double(*)(settings_t*, char *key, double def, ...))get_double;
 	this->public.get_time = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_time;
 	this->public.get_bool = (bool(*)(settings_t*, char *key, bool def, ...))get_bool;
diff --git a/src/libstrongswan/settings.h b/src/libstrongswan/settings.h
index f274fb3..bb716e3 100644
--- a/src/libstrongswan/settings.h
+++ b/src/libstrongswan/settings.h
@@ -75,16 +75,98 @@ struct settings_t {
 	bool (*get_bool)(settings_t *this, char *key, bool def, ...);
 
 	/**
-	 * Get an integer value.
+	 * Get a character value.
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of  key
+	 */
+	char (*get_char)(settings_t *this, char *key, char def, ...);
+
+	/**
+	 * Get an 8 bit integer value.
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of the key
+	 */
+	int8_t (*get_int8)(settings_t *this, char *key, int8_t def, ...);
+
+	/**
+	 * Get an 8 bit unsigned integer value.
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of the key
+	 */
+	u_int8_t (*get_uint8)(settings_t *this, char *key, u_int8_t def, ...);
+
+	/**
+	 * Get an 16 bit integer value.
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of the key
+	 */
+	int16_t (*get_int16)(settings_t *this, char *key, int16_t def, ...);
+
+	/**
+	 * Get an 16 bit unsigned integer value.
 	 *
 	 * @param key		key including sections, printf style format
 	 * @param def		value returned if key not found
 	 * @param ...		argument list for key
 	 * @return			value of the key
 	 */
+	u_int16_t (*get_uint16)(settings_t *this, char *key, u_int16_t def, ...);
+
+	/**
+	 * Get an integer value (32 bit).
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of the key
+	 */
+	int (*get_int32)(settings_t *this, char *key, int def, ...);
 	int (*get_int)(settings_t *this, char *key, int def, ...);
 
 	/**
+	 * Get an unsigned integer value (32 bit).
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of  key
+	 */
+	u_int32_t (*get_uint32)(settings_t *this, char *key, u_int32_t def, ...);
+	u_int32_t (*get_uint)(settings_t *this, char *key, u_int32_t def, ...);
+
+	/**
+	 * Get a 64 bit integer value.
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of  key
+	 */
+	int64_t (*get_int64)(settings_t *this, char *key, int64_t def, ...);
+
+	/**
+	 * Get a 64 bit unsigned integer value.
+	 *
+	 * @param key		key including sections, printf style format
+	 * @param def		value returned if key not found
+	 * @param ...		argument list for key
+	 * @return			value of  key
+	 */
+	u_int64_t (*get_uint64)(settings_t *this, char *key, u_int64_t def, ...);
+
+	/**
 	 * Get an double value.
 	 *
 	 * @param key		key including sections, printf style format
-- 
1.6.3.3


>From 7d6bf9ed579b315fd4e7f78285ff294175d583e9 Mon Sep 17 00:00:00 2001
From: Thomas Egerer <[email protected]>
Date: Thu, 18 Mar 2010 16:06:27 +0100
Subject: [PATCH 2/3] Migrated settings_t to METHOD/INIT macros

---
 src/libstrongswan/settings.c |  142 ++++++++++++++++--------------------------
 1 files changed, 54 insertions(+), 88 deletions(-)

diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c
index cbfe16d..de5163c 100644
--- a/src/libstrongswan/settings.c
+++ b/src/libstrongswan/settings.c
@@ -181,10 +181,8 @@ static char *find_value(section_t *section, char *key, va_list args)
 	return value;
 }
 
-/**
- * Implementation of settings_t.get.
- */
-static char* get_str(private_settings_t *this, char *key, char *def, ...)
+METHOD(settings_t, get_str, char*, private_settings_t *this, char *key,
+		char *def, ...)
 {
 	char *value;
 	va_list args;
@@ -199,10 +197,8 @@ static char* get_str(private_settings_t *this, char *key, char *def, ...)
 	return def;
 }
 
-/**
- * Implementation of get_int8
- */
-static int8_t get_int8(private_settings_t *this, char *key, int8_t def, ...)
+METHOD(settings_t, get_int8, int8_t, private_settings_t *this, char *key,
+		int8_t def, ...)
 {
 	char *value;
 	int intval;
@@ -223,10 +219,8 @@ static int8_t get_int8(private_settings_t *this, char *key, int8_t def, ...)
 	return def;
 }
 
-/**
- * Implementation of get_uint8
- */
-static u_int8_t get_uint8(private_settings_t *this, char *key, u_int8_t def, ...)
+METHOD(settings_t, get_uint8, u_int8_t, private_settings_t *this, char *key,
+		u_int8_t def, ...)
 {
 	char *value;
 	int intval;
@@ -247,10 +241,8 @@ static u_int8_t get_uint8(private_settings_t *this, char *key, u_int8_t def, ...
 	return def;
 }
 
-/**
- * Implementation of get_int16
- */
-static int16_t get_int16(private_settings_t *this, char *key, int16_t def, ...)
+METHOD(settings_t, get_int16, int16_t, private_settings_t *this, char *key,
+		int16_t def, ...)
 {
 	char *value;
 	int intval;
@@ -271,10 +263,8 @@ static int16_t get_int16(private_settings_t *this, char *key, int16_t def, ...)
 	return def;
 }
 
-/**
- * Implementation of get_uint16
- */
-static u_int16_t get_uint16(private_settings_t *this, char *key, u_int16_t def, ...)
+METHOD(settings_t, get_uint16, u_int16_t, private_settings_t *this, char *key,
+		u_int16_t def, ...)
 {
 	char *value;
 	int intval;
@@ -295,10 +285,8 @@ static u_int16_t get_uint16(private_settings_t *this, char *key, u_int16_t def,
 	return def;
 }
 
-/**
- * Implementation of settings_t.get_bool.
- */
-static bool get_bool(private_settings_t *this, char *key, bool def, ...)
+METHOD(settings_t, get_bool, bool, private_settings_t *this, char *key,
+		bool def, ...)
 {
 	char *value;
 	va_list args;
@@ -326,10 +314,7 @@ static bool get_bool(private_settings_t *this, char *key, bool def, ...)
 	return def;
 }
 
-/**
- * Implementation of settings_t.get_int.
- */
-static int get_int(private_settings_t *this, char *key, int def, ...)
+METHOD(settings_t, get_int, int, private_settings_t *this, char *key, int def, ...)
 {
 	char *value;
 	int intval;
@@ -350,10 +335,8 @@ static int get_int(private_settings_t *this, char *key, int def, ...)
 	return def;
 }
 
-/**
- * Implementation of get_uint
- */
-static u_int32_t get_uint(private_settings_t *this, char *key, u_int32_t def, ...)
+METHOD(settings_t, get_uint, u_int32_t, private_settings_t *this, char *key,
+		u_int32_t def, ...)
 {
 	char *value;
 	u_int32_t intval;
@@ -374,10 +357,8 @@ static u_int32_t get_uint(private_settings_t *this, char *key, u_int32_t def, ..
 	return def;
 }
 
-/**
- * Implementation of get_int64
- */
-static int64_t get_int64(private_settings_t *this, char *key, int64_t def, ...)
+METHOD(settings_t, get_int64, int64_t, private_settings_t *this, char *key,
+		int64_t def, ...)
 {
 	char *value;
 	int64_t intval;
@@ -398,10 +379,8 @@ static int64_t get_int64(private_settings_t *this, char *key, int64_t def, ...)
 	return def;
 }
 
-/**
- * Implementation of get_uint64
- */
-static u_int64_t get_uint64(private_settings_t *this, char *key, u_int64_t def, ...)
+METHOD(settings_t, get_uint64, u_int64_t, private_settings_t *this, char *key,
+		u_int64_t def, ...)
 {
 	char *value;
 	u_int64_t intval;
@@ -422,10 +401,8 @@ static u_int64_t get_uint64(private_settings_t *this, char *key, u_int64_t def,
 	return def;
 }
 
-/**
- * Implementation of get_char
- */
-static char get_char(private_settings_t *this, char *key, char def, ...)
+METHOD(settings_t, get_char, char, private_settings_t *this, char *key,
+		char def, ...)
 {
 	char *value;
 	va_list args;
@@ -440,10 +417,8 @@ static char get_char(private_settings_t *this, char *key, char def, ...)
 	return def;
 }
 
-/**
- * Implementation of settings_t.get_double.
- */
-static double get_double(private_settings_t *this, char *key, double def, ...)
+METHOD(settings_t, get_double, double, private_settings_t *this, char *key,
+		double def, ...)
 {
 	char *value;
 	double dval;
@@ -464,10 +439,8 @@ static double get_double(private_settings_t *this, char *key, double def, ...)
 	return def;
 }
 
-/**
- * Implementation of settings_t.get_time.
- */
-static u_int32_t get_time(private_settings_t *this, char *key, u_int32_t def, ...)
+METHOD(settings_t, get_time, u_int32_t, private_settings_t *this, char *key,
+		u_int32_t def, ...)
 {
 	char *value, *endptr;
 	u_int32_t timeval;
@@ -512,11 +485,8 @@ static bool section_filter(void *null, section_t **in, char **out)
 	return TRUE;
 }
 
-/**
- * Implementation of settings_t.create_section_enumerator
- */
-static enumerator_t* create_section_enumerator(private_settings_t *this,
-											   char *key, ...)
+METHOD(settings_t, create_section_enumerator, enumerator_t*,
+		private_settings_t *this, char *key, ...)
 {
 	section_t *section;
 	va_list args;
@@ -545,11 +515,8 @@ static bool kv_filter(void *null, kv_t **in, char **key,
 	return TRUE;
 }
 
-/**
- * Implementation of settings_t.create_key_value_enumerator
- */
-static enumerator_t* create_key_value_enumerator(private_settings_t *this,
-												 char *key, ...)
+METHOD(settings_t, create_key_value_enumerator, enumerator_t*,
+		private_settings_t *this, char *key, ...)
 {
 	section_t *section;
 	va_list args;
@@ -709,10 +676,7 @@ static section_t* parse_section(char **text, char *name)
 	return section;
 }
 
-/**
- * Implementation of settings_t.destroy
- */
-static void destroy(private_settings_t *this)
+METHOD(settings_t, destroy, void, private_settings_t *this)
 {
 	if (this->top)
 	{
@@ -732,28 +696,30 @@ settings_t *settings_create(char *file)
 	FILE *fd;
 	int len;
 
-	this = malloc_thing(private_settings_t);
-	this->public.get_str = (char*(*)(settings_t*, char *key, char* def, ...))get_str;
-	this->public.get_char = (char(*)(settings_t*, char *key, char def, ...))get_char;
-	this->public.get_int8 = (int8_t(*)(settings_t*, char *key, int8_t def, ...))get_int8;
-	this->public.get_uint8 = (u_int8_t(*)(settings_t*, char *key, u_int8_t def, ...))get_uint8;
-	this->public.get_int16 = (int16_t(*)(settings_t*, char *key, int16_t def, ...))get_int16;
-	this->public.get_uint16 = (u_int16_t(*)(settings_t*, char *key, u_int16_t def, ...))get_uint16;
-	this->public.get_int32 = (int(*)(settings_t*, char *key, int def, ...))get_int;
-	this->public.get_int = (int(*)(settings_t*, char *key, int def, ...))get_int;
-	this->public.get_uint32 = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_uint;
-	this->public.get_uint = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_uint;
-	this->public.get_int64 = (int64_t(*)(settings_t*, char *key, int64_t def, ...))get_int64;
-	this->public.get_uint64 = (u_int64_t(*)(settings_t*, char *key, u_int64_t def, ...))get_uint64;
-	this->public.get_double = (double(*)(settings_t*, char *key, double def, ...))get_double;
-	this->public.get_time = (u_int32_t(*)(settings_t*, char *key, u_int32_t def, ...))get_time;
-	this->public.get_bool = (bool(*)(settings_t*, char *key, bool def, ...))get_bool;
-	this->public.create_section_enumerator = (enumerator_t*(*)(settings_t*,char *section, ...))create_section_enumerator;
-	this->public.create_key_value_enumerator = (enumerator_t*(*)(settings_t*, char *key, ...))create_key_value_enumerator;
-	this->public.destroy = (void(*)(settings_t*))destroy;
-
-	this->top = NULL;
-	this->text = NULL;
+	INIT(this,
+		.public = {
+			.get_str = _get_str,
+			.get_char = _get_char,
+			.get_int8 = _get_int8,
+			.get_uint8 = _get_uint8,
+			.get_int16 = _get_int16,
+			.get_uint16 = _get_uint16,
+			.get_int32 = _get_int,
+			.get_int = _get_int,
+			.get_uint32 = _get_uint,
+			.get_uint = _get_uint,
+			.get_int64 = _get_int64,
+			.get_uint64 = _get_uint64,
+			.get_double = _get_double,
+			.get_time = _get_time,
+			.get_bool = _get_bool,
+			.create_section_enumerator = _create_section_enumerator,
+			.create_key_value_enumerator = _create_key_value_enumerator,
+			.destroy = _destroy,
+		},
+		.top = NULL,
+		.text = NULL,
+	);
 
 	if (file == NULL)
 	{
-- 
1.6.3.3


>From 7debd6125bae5991d38abf377bdd83574d63957e Mon Sep 17 00:00:00 2001
From: Thomas Egerer <[email protected]>
Date: Thu, 21 Jan 2010 10:59:52 +0100
Subject: [PATCH 3/3] allow spi-range configuration from userspace

---
 src/charon/kernel/kernel_interface.h               |    3 +++
 .../plugins/kernel_klips/kernel_klips_ipsec.c      |   16 +++++++++++++++-
 .../plugins/kernel_netlink/kernel_netlink_ipsec.c  |   17 ++++++++++++++++-
 .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c      |   18 ++++++++++++++++--
 4 files changed, 50 insertions(+), 4 deletions(-)

diff --git a/src/charon/kernel/kernel_interface.h b/src/charon/kernel/kernel_interface.h
index 4a62e76..d4d7091 100644
--- a/src/charon/kernel/kernel_interface.h
+++ b/src/charon/kernel/kernel_interface.h
@@ -33,6 +33,9 @@ typedef struct kernel_interface_t kernel_interface_t;
 #include <kernel/kernel_ipsec.h>
 #include <kernel/kernel_net.h>
 
+#define KERNEL_MIN_SPI 0xc0000000
+#define KERNEL_MAX_SPI 0xcFFFFFFF
+
 /**
  * Constructor function for ipsec kernel interface
  */
diff --git a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
index 01df4f7..e1e1b53 100644
--- a/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
+++ b/src/charon/plugins/kernel_klips/kernel_klips_ipsec.c
@@ -1542,6 +1542,20 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 	 */
 	rng_t *rng;
 	u_int32_t spi_gen;
+	u_int32_t min_spi, max_spi;
+
+	min_spi = lib->settings->get_int(lib->settings, "charon.kernel.min_spi",
+			KERNEL_MIN_SPI);
+	max_spi = lib->settings->get_int(lib->settings, "charon.kernel.max_spi",
+			KERNEL_MAX_SPI);
+
+	if (max_spi < min_spi)
+	{
+		min_spi = KERNEL_MIN_SPI;
+		max_spi = KERNEL_MAX_SPI;
+		DBG1(DBG_KNL, "maximum SPI value greater than minimum, using defaults "
+				"[%.x-%.x]", min_spi, max_spi);
+	}
 
 	rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
 	if (!rng)
@@ -1553,7 +1567,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 	rng->destroy(rng);
 
 	/* charon's SPIs lie within the range from 0xc0000000 to 0xcFFFFFFF */
-	spi_gen = 0xc0000000 | (spi_gen & 0x0FFFFFFF);
+	spi_gen = min_spi | (spi_gen & (max_spi ^ min_spi));
 
 	DBG2(DBG_KNL, "allocated SPI %.8x for %N SA between %#H..%#H",
 			spi_gen, protocol_id_names, protocol, src, dst);
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index 1b8c1b8..8ca9e1d 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -879,10 +879,25 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 	private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
 	protocol_id_t protocol, u_int32_t reqid, u_int32_t *spi)
 {
+	u_int32_t min_spi, max_spi;
+
+	min_spi = lib->settings->get_int(lib->settings, "charon.kernel.min_spi",
+			KERNEL_MIN_SPI);
+	max_spi = lib->settings->get_int(lib->settings, "charon.kernel.max_spi",
+			KERNEL_MAX_SPI);
+
+	if (max_spi < min_spi)
+	{
+		min_spi = KERNEL_MIN_SPI;
+		max_spi = KERNEL_MAX_SPI;
+		DBG1(DBG_KNL, "maximum SPI value greater than minimum, using defaults "
+				"[%.x-%.x]", min_spi, max_spi);
+	}
+
 	DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid);
 
 	if (get_spi_internal(this, src, dst, proto_ike2kernel(protocol),
-			0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS)
+			min_spi, max_spi, reqid, spi) != SUCCESS)
 	{
 		DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid);
 		return FAILED;
diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
index 8a7883c..3f9039a 100644
--- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
+++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c
@@ -1160,6 +1160,20 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 	pfkey_msg_t response;
 	u_int32_t received_spi = 0;
 	size_t len;
+	u_int32_t min_spi, max_spi;
+
+	min_spi = lib->settings->get_int(lib->settings, "charon.kernel.min_spi",
+			KERNEL_MIN_SPI);
+	max_spi = lib->settings->get_int(lib->settings, "charon.kernel.max_spi",
+			KERNEL_MAX_SPI);
+
+	if (max_spi < min_spi)
+	{
+		min_spi = KERNEL_MIN_SPI;
+		max_spi = KERNEL_MAX_SPI;
+		DBG1(DBG_KNL, "maximum SPI value greater than minimum, using defaults "
+				"[%.x-%.x]", min_spi, max_spi);
+	}
 
 	memset(&request, 0, sizeof(request));
 
@@ -1181,8 +1195,8 @@ METHOD(kernel_ipsec_t, get_spi, status_t,
 	range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg);
 	range->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
 	range->sadb_spirange_len = PFKEY_LEN(sizeof(struct sadb_spirange));
-	range->sadb_spirange_min = 0xc0000000;
-	range->sadb_spirange_max = 0xcFFFFFFF;
+	range->sadb_spirange_min = min_spi;
+	range->sadb_spirange_max = max_spi;
 	PFKEY_EXT_ADD(msg, range);
 
 	if (pfkey_send(this, msg, &out, &len) == SUCCESS)
-- 
1.6.3.3


Attachment: signature.asc
Description: OpenPGP digital signature

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

Reply via email to