diff options
author | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@corsac.net> | 2012-06-28 21:16:07 +0200 |
commit | b34738ed08c2227300d554b139e2495ca5da97d6 (patch) | |
tree | 62f33b52820f2e49f0e53c0f8c636312037c8054 /src/libhydra/kernel | |
parent | 0a9d51a49042a68daa15b0c74a2b7f152f52606b (diff) | |
download | vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.tar.gz vyos-strongswan-b34738ed08c2227300d554b139e2495ca5da97d6.zip |
Imported Upstream version 4.6.4
Diffstat (limited to 'src/libhydra/kernel')
-rw-r--r-- | src/libhydra/kernel/kernel_interface.c | 60 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_interface.h | 28 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_ipsec.c | 24 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_ipsec.h | 60 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_listener.h | 2 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_net.c | 37 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_net.h | 15 |
7 files changed, 203 insertions, 23 deletions
diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 4b5b41f2b..573557506 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2010 Tobias Brunner + * Copyright (C) 2008-2011 Tobias Brunner * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG @@ -34,6 +34,16 @@ struct private_kernel_interface_t { kernel_interface_t public; /** + * Registered IPsec constructor + */ + kernel_ipsec_constructor_t ipsec_constructor; + + /** + * Registered net constructor + */ + kernel_net_constructor_t net_constructor; + + /** * ipsec interface */ kernel_ipsec_t *ipsec; @@ -128,18 +138,28 @@ METHOD(kernel_interface_t, del_sa, status_t, return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark); } +METHOD(kernel_interface_t, flush_sas, status_t, + private_kernel_interface_t *this) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->flush_sas(this->ipsec); +} + METHOD(kernel_interface_t, add_policy, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, traffic_selector_t *src_ts, traffic_selector_t *dst_ts, policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa, - mark_t mark, bool routed) + mark_t mark, policy_priority_t priority) { if (!this->ipsec) { return NOT_SUPPORTED; } return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts, - direction, type, sa, mark, routed); + direction, type, sa, mark, priority); } METHOD(kernel_interface_t, query_policy, status_t, @@ -157,15 +177,25 @@ METHOD(kernel_interface_t, query_policy, status_t, METHOD(kernel_interface_t, del_policy, status_t, private_kernel_interface_t *this, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark, - bool unrouted) + traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t reqid, + mark_t mark, policy_priority_t priority) { if (!this->ipsec) { return NOT_SUPPORTED; } return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts, - direction, mark, unrouted); + direction, reqid, mark, priority); +} + +METHOD(kernel_interface_t, flush_policies, status_t, + private_kernel_interface_t *this) +{ + if (!this->ipsec) + { + return NOT_SUPPORTED; + } + return this->ipsec->flush_policies(this->ipsec); } METHOD(kernel_interface_t, get_source_addr, host_t*, @@ -310,7 +340,7 @@ METHOD(kernel_interface_t, get_address_by_ts, status_t, if (!found) { - DBG1(DBG_KNL, "no local address found in traffic selector %R", ts); + DBG2(DBG_KNL, "no local address found in traffic selector %R", ts); return FAILED; } @@ -324,6 +354,7 @@ METHOD(kernel_interface_t, add_ipsec_interface, void, { if (!this->ipsec) { + this->ipsec_constructor = constructor; this->ipsec = constructor(); } } @@ -331,7 +362,11 @@ METHOD(kernel_interface_t, add_ipsec_interface, void, METHOD(kernel_interface_t, remove_ipsec_interface, void, private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor) { - /* TODO: replace if interface currently in use */ + if (constructor == this->ipsec_constructor) + { + this->ipsec->destroy(this->ipsec); + this->ipsec = NULL; + } } METHOD(kernel_interface_t, add_net_interface, void, @@ -339,6 +374,7 @@ METHOD(kernel_interface_t, add_net_interface, void, { if (!this->net) { + this->net_constructor = constructor; this->net = constructor(); } } @@ -346,7 +382,11 @@ METHOD(kernel_interface_t, add_net_interface, void, METHOD(kernel_interface_t, remove_net_interface, void, private_kernel_interface_t *this, kernel_net_constructor_t constructor) { - /* TODO: replace if interface currently in use */ + if (constructor == this->net_constructor) + { + this->net->destroy(this->net); + this->net = NULL; + } } METHOD(kernel_interface_t, add_listener, void, @@ -485,9 +525,11 @@ kernel_interface_t *kernel_interface_create() .update_sa = _update_sa, .query_sa = _query_sa, .del_sa = _del_sa, + .flush_sas = _flush_sas, .add_policy = _add_policy, .query_policy = _query_policy, .del_policy = _del_policy, + .flush_policies = _flush_policies, .get_source_addr = _get_source_addr, .get_nexthop = _get_nexthop, .get_interface = _get_interface, diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index 471a1d5d3..991cfafd0 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 Tobias Brunner + * Copyright (C) 2006-2011 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -175,6 +175,13 @@ struct kernel_interface_t { mark_t mark); /** + * Flush all SAs from the SAD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_sas) (kernel_interface_t *this); + + /** * Add a policy to the SPD. * * A policy is always associated to an SA. Traffic which matches a @@ -188,7 +195,7 @@ struct kernel_interface_t { * @param type type of policy, POLICY_(IPSEC|PASS|DROP) * @param sa details about the SA(s) tied to this policy * @param mark mark for this policy - * @param routed TRUE, if this policy is routed in the kernel + * @param priority priority of this policy * @return SUCCESS if operation completed */ status_t (*add_policy) (kernel_interface_t *this, @@ -196,7 +203,8 @@ struct kernel_interface_t { traffic_selector_t *src_ts, traffic_selector_t *dst_ts, policy_dir_t direction, policy_type_t type, - ipsec_sa_cfg_t *sa, mark_t mark, bool routed); + ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); /** * Query the use time of a policy. @@ -228,15 +236,23 @@ struct kernel_interface_t { * @param src_ts traffic selector to match traffic source * @param dst_ts traffic selector to match traffic dest * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param reqid unique ID of the associated SA * @param mark optional mark - * @param unrouted TRUE, if this policy is unrouted from the kernel + * @param priority priority of the policy * @return SUCCESS if operation completed */ status_t (*del_policy) (kernel_interface_t *this, traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, mark_t mark, - bool unrouted); + policy_dir_t direction, u_int32_t reqid, + mark_t mark, policy_priority_t priority); + + /** + * Flush all policies from the SPD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_policies) (kernel_interface_t *this); /** * Get our outgoing source address for a destination. diff --git a/src/libhydra/kernel/kernel_ipsec.c b/src/libhydra/kernel/kernel_ipsec.c index 383685426..9b38297cc 100644 --- a/src/libhydra/kernel/kernel_ipsec.c +++ b/src/libhydra/kernel/kernel_ipsec.c @@ -15,10 +15,14 @@ #include "kernel_ipsec.h" -ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_BEET, +#include <hydra.h> + +ENUM(ipsec_mode_names, MODE_TRANSPORT, MODE_DROP, "TRANSPORT", "TUNNEL", "BEET", + "PASS", + "DROP" ); ENUM(policy_dir_names, POLICY_IN, POLICY_FWD, @@ -35,3 +39,21 @@ ENUM(ipcomp_transform_names, IPCOMP_NONE, IPCOMP_LZJH, "IPCOMP_LZJH" ); +/** + * See header + */ +bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + hydra->kernel_interface->add_ipsec_interface(hydra->kernel_interface, + (kernel_ipsec_constructor_t)data); + } + else + { + hydra->kernel_interface->remove_ipsec_interface(hydra->kernel_interface, + (kernel_ipsec_constructor_t)data); + } + return TRUE; +} diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h index ef36efd11..ddb63283c 100644 --- a/src/libhydra/kernel/kernel_ipsec.h +++ b/src/libhydra/kernel/kernel_ipsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2010 Tobias Brunner + * Copyright (C) 2006-2011 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -27,6 +27,7 @@ typedef enum ipsec_mode_t ipsec_mode_t; typedef enum policy_dir_t policy_dir_t; typedef enum policy_type_t policy_type_t; +typedef enum policy_priority_t policy_priority_t; typedef enum ipcomp_transform_t ipcomp_transform_t; typedef struct kernel_ipsec_t kernel_ipsec_t; typedef struct ipsec_sa_cfg_t ipsec_sa_cfg_t; @@ -36,6 +37,7 @@ typedef struct mark_t mark_t; #include <utils/host.h> #include <crypto/prf_plus.h> #include <selectors/traffic_selector.h> +#include <plugins/plugin.h> /** * Mode of an IPsec SA. @@ -47,6 +49,10 @@ enum ipsec_mode_t { MODE_TUNNEL, /** BEET mode, tunnel mode but fixed, bound inner addresses */ MODE_BEET, + /** passthrough policy for traffic without an IPsec SA */ + MODE_PASS, + /** drop policy discarding traffic */ + MODE_DROP }; /** @@ -86,6 +92,18 @@ enum policy_type_t { }; /** + * High-level priority of a policy. + */ +enum policy_priority_t { + /** Default priority */ + POLICY_PRIORITY_DEFAULT, + /** Priority for trap policies */ + POLICY_PRIORITY_ROUTED, + /** Priority for fallback drop policies */ + POLICY_PRIORITY_FALLBACK, +}; + +/** * IPComp transform IDs, as in RFC 4306 */ enum ipcomp_transform_t { @@ -288,6 +306,13 @@ struct kernel_ipsec_t { mark_t mark); /** + * Flush all SAs from the SAD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_sas) (kernel_ipsec_t *this); + + /** * Add a policy to the SPD. * * A policy is always associated to an SA. Traffic which matches a @@ -301,7 +326,7 @@ struct kernel_ipsec_t { * @param type type of policy, POLICY_(IPSEC|PASS|DROP) * @param sa details about the SA(s) tied to this policy * @param mark mark for this policy - * @param routed TRUE, if this policy is routed in the kernel + * @param priority priority of this policy * @return SUCCESS if operation completed */ status_t (*add_policy) (kernel_ipsec_t *this, @@ -309,7 +334,8 @@ struct kernel_ipsec_t { traffic_selector_t *src_ts, traffic_selector_t *dst_ts, policy_dir_t direction, policy_type_t type, - ipsec_sa_cfg_t *sa, mark_t mark, bool routed); + ipsec_sa_cfg_t *sa, mark_t mark, + policy_priority_t priority); /** * Query the use time of a policy. @@ -342,15 +368,23 @@ struct kernel_ipsec_t { * @param src_ts traffic selector to match traffic source * @param dst_ts traffic selector to match traffic dest * @param direction direction of traffic, POLICY_(IN|OUT|FWD) + * @param reqid unique ID of the associated SA * @param mark optional mark - * @param unrouted TRUE, if this policy is unrouted from the kernel + * @param priority priority of the policy * @return SUCCESS if operation completed */ status_t (*del_policy) (kernel_ipsec_t *this, traffic_selector_t *src_ts, traffic_selector_t *dst_ts, - policy_dir_t direction, mark_t mark, - bool unrouted); + policy_dir_t direction, u_int32_t reqid, + mark_t mark, policy_priority_t priority); + + /** + * Flush all policies from the SPD. + * + * @return SUCCESS if operation completed + */ + status_t (*flush_policies) (kernel_ipsec_t *this); /** * Install a bypass policy for the given socket. @@ -367,4 +401,18 @@ struct kernel_ipsec_t { void (*destroy) (kernel_ipsec_t *this); }; +/** + * Helper function to (un-)register IPsec kernel interfaces from plugin features. + * + * This function is a plugin_feature_callback_t and can be used with the + * PLUGIN_CALLBACK macro to register an IPsec kernel interface constructor. + * + * @param plugin plugin registering the kernel interface + * @param feature associated plugin feature + * @param reg TRUE to register, FALSE to unregister + * @param data data passed to callback, an kernel_ipsec_constructor_t + */ +bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + #endif /** KERNEL_IPSEC_H_ @}*/ diff --git a/src/libhydra/kernel/kernel_listener.h b/src/libhydra/kernel/kernel_listener.h index 6f2dbd23b..5db297b6f 100644 --- a/src/libhydra/kernel/kernel_listener.h +++ b/src/libhydra/kernel/kernel_listener.h @@ -84,7 +84,7 @@ struct kernel_listener_t { policy_dir_t direction, host_t *local, host_t *remote); /** - * Hook called if changes in the networking layer occured (interfaces + * Hook called if changes in the networking layer occurred (interfaces * up/down, routes added/deleted etc.). * * @param address TRUE if address list, FALSE if routing changed diff --git a/src/libhydra/kernel/kernel_net.c b/src/libhydra/kernel/kernel_net.c new file mode 100644 index 000000000..0841ed803 --- /dev/null +++ b/src/libhydra/kernel/kernel_net.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "kernel_net.h" + +#include <hydra.h> + +/** + * See header + */ +bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + hydra->kernel_interface->add_net_interface(hydra->kernel_interface, + (kernel_net_constructor_t)data); + } + else + { + hydra->kernel_interface->remove_net_interface(hydra->kernel_interface, + (kernel_net_constructor_t)data); + } + return TRUE; +} diff --git a/src/libhydra/kernel/kernel_net.h b/src/libhydra/kernel/kernel_net.h index 69e01f43f..a89e76804 100644 --- a/src/libhydra/kernel/kernel_net.h +++ b/src/libhydra/kernel/kernel_net.h @@ -26,6 +26,7 @@ typedef struct kernel_net_t kernel_net_t; #include <utils/enumerator.h> #include <utils/host.h> +#include <plugins/plugin.h> /** * Interface to the network subsystem of the kernel. @@ -142,4 +143,18 @@ struct kernel_net_t { void (*destroy) (kernel_net_t *this); }; +/** + * Helper function to (un-)register net kernel interfaces from plugin features. + * + * This function is a plugin_feature_callback_t and can be used with the + * PLUGIN_CALLBACK macro to register an net kernel interface constructor. + * + * @param plugin plugin registering the kernel interface + * @param feature associated plugin feature + * @param reg TRUE to register, FALSE to unregister + * @param data data passed to callback, an kernel_net_constructor_t + */ +bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + #endif /** KERNEL_NET_H_ @}*/ |