From 76f7d80e80c3217979e92548f7f93cdb96d9f6c5 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 21 Feb 2013 09:39:23 +0100 Subject: [PATCH 1/3] Introduce "features" for the kernel backends returning kernel capabilities --- src/libhydra/kernel/kernel_interface.c | 18 +++++++++++++++++- src/libhydra/kernel/kernel_interface.h | 19 +++++++++++++++++++ src/libhydra/kernel/kernel_ipsec.h | 8 ++++++++ src/libhydra/kernel/kernel_net.h | 8 ++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 8948e0561..b82fd6d3d 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -137,6 +137,22 @@ struct private_kernel_interface_t { bool ifaces_exclude; }; +METHOD(kernel_interface_t, get_features, kernel_feature_t, + private_kernel_interface_t *this) +{ + kernel_feature_t features = 0; + + if (this->ipsec && this->ipsec->get_features) + { + features |= this->ipsec->get_features(this->ipsec); + } + if (this->net && this->net->get_features) + { + features |= this->net->get_features(this->net); + } + return features; +} + METHOD(kernel_interface_t, get_spi, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) @@ -682,6 +698,7 @@ kernel_interface_t *kernel_interface_create() INIT(this, .public = { + .get_features = _get_features, .get_spi = _get_spi, .get_cpi = _get_cpi, .add_sa = _add_sa, @@ -757,4 +774,3 @@ kernel_interface_t *kernel_interface_create() return &this->public; } - diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index 8d8ef2e83..8d8d048d0 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -47,6 +47,7 @@ #define KERNEL_INTERFACE_H_ typedef struct kernel_interface_t kernel_interface_t; +typedef enum kernel_feature_t kernel_feature_t; #include #include @@ -55,6 +56,17 @@ typedef struct kernel_interface_t kernel_interface_t; #include #include +/** + * Bitfield of optional features a kernel backend supports. + * + * This feature-set is for both, kernel_ipsec_t and kernel_net_t. Each + * backend returns a subset of these features. + */ +enum kernel_feature_t { + /** IPsec can process ESPv3 (RFC 4303) TFC padded packets */ + KERNEL_ESP_V3_TFC = (1<<0), +}; + /** * Constructor function for ipsec kernel interface */ @@ -73,6 +85,13 @@ typedef kernel_net_t* (*kernel_net_constructor_t)(void); */ struct kernel_interface_t { + /** + * Get the feature set supported by the net and ipsec kernel backends. + * + * @return ORed feature-set of backends + */ + kernel_feature_t (*get_features)(kernel_interface_t *this); + /** * Get a SPI from the kernel. * diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h index 1da0805cb..c8afcaffd 100644 --- a/src/libhydra/kernel/kernel_ipsec.h +++ b/src/libhydra/kernel/kernel_ipsec.h @@ -30,6 +30,7 @@ typedef struct kernel_ipsec_t kernel_ipsec_t; #include #include #include +#include /** * Interface to the ipsec subsystem of the kernel. @@ -44,6 +45,13 @@ typedef struct kernel_ipsec_t kernel_ipsec_t; */ struct kernel_ipsec_t { + /** + * Get the feature set supported by this kernel backend. + * + * @return ORed feature-set of backend + */ + kernel_feature_t (*get_features)(kernel_ipsec_t *this); + /** * Get a SPI from the kernel. * diff --git a/src/libhydra/kernel/kernel_net.h b/src/libhydra/kernel/kernel_net.h index 6a3b2cee7..0d3417f1d 100644 --- a/src/libhydra/kernel/kernel_net.h +++ b/src/libhydra/kernel/kernel_net.h @@ -28,6 +28,7 @@ typedef enum kernel_address_type_t kernel_address_type_t; #include #include #include +#include /** * Type of addresses (e.g. when enumerating them) @@ -55,6 +56,13 @@ enum kernel_address_type_t { */ struct kernel_net_t { + /** + * Get the feature set supported by this kernel backend. + * + * @return ORed feature-set of backend + */ + kernel_feature_t (*get_features)(kernel_net_t *this); + /** * Get our outgoing source address for a destination. * From 53e62f5d0c32bbd63720846bcc65e4346975b965 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 21 Feb 2013 09:45:46 +0100 Subject: [PATCH 2/3] Indicate support for processing ESPv3 TFC padding in Netlink IPsec backend --- .../plugins/kernel_netlink/kernel_netlink_ipsec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index f9b2634a0..eebb5d978 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -1036,6 +1036,12 @@ static job_requeue_t receive_events(private_kernel_netlink_ipsec_t *this) return JOB_REQUEUE_DIRECT; } +METHOD(kernel_ipsec_t, get_features, kernel_feature_t, + private_kernel_netlink_ipsec_t *this) +{ + return KERNEL_ESP_V3_TFC; +} + /** * Get an SPI for a specific protocol from the kernel. */ @@ -2734,6 +2740,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() INIT(this, .public = { .interface = { + .get_features = _get_features, .get_spi = _get_spi, .get_cpi = _get_cpi, .add_sa = _add_sa, @@ -2822,4 +2829,3 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() return &this->public; } - From 5c55be49153a5f960769f66a67ecdafc77649115 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 21 Feb 2013 10:09:39 +0100 Subject: [PATCH 3/3] Send ESP_TFC_PADDING_NOT_SUPPORTED if the used kernel doesn't support it --- src/libcharon/sa/ikev2/tasks/child_create.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index eb3972c29..32c0e8c4a 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -18,6 +18,7 @@ #include "child_create.h" #include +#include #include #include #include @@ -615,6 +616,7 @@ static void build_payloads(private_child_create_t *this, message_t *message) nonce_payload_t *nonce_payload; ke_payload_t *ke_payload; ts_payload_t *ts_payload; + kernel_feature_t features; /* add SA payload */ if (this->initiator) @@ -661,6 +663,13 @@ static void build_payloads(private_child_create_t *this, message_t *message) default: break; } + + features = hydra->kernel_interface->get_features(hydra->kernel_interface); + if (!(features & KERNEL_ESP_V3_TFC)) + { + message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED, + chunk_empty); + } } /**