summaryrefslogtreecommitdiff
path: root/src/libhydra/kernel
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@corsac.net>2012-06-28 21:16:07 +0200
committerYves-Alexis Perez <corsac@corsac.net>2012-06-28 21:16:07 +0200
commitb34738ed08c2227300d554b139e2495ca5da97d6 (patch)
tree62f33b52820f2e49f0e53c0f8c636312037c8054 /src/libhydra/kernel
parent0a9d51a49042a68daa15b0c74a2b7f152f52606b (diff)
downloadvyos-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.c60
-rw-r--r--src/libhydra/kernel/kernel_interface.h28
-rw-r--r--src/libhydra/kernel/kernel_ipsec.c24
-rw-r--r--src/libhydra/kernel/kernel_ipsec.h60
-rw-r--r--src/libhydra/kernel/kernel_listener.h2
-rw-r--r--src/libhydra/kernel/kernel_net.c37
-rw-r--r--src/libhydra/kernel/kernel_net.h15
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_ @}*/