aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-02-23 16:28:23 +0000
committerMartin Willi <martin@revosec.ch>2010-02-26 11:44:33 +0100
commit54f818590e1482eb271b01e9f462c58ec1299242 (patch)
tree4154d6fe798855f9a360e2a1f95dac44c74a128e /src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
parent3e631491a0ecb922284198bf3a2cf82470f9a28a (diff)
downloadstrongswan-54f818590e1482eb271b01e9f462c58ec1299242.tar.bz2
strongswan-54f818590e1482eb271b01e9f462c58ec1299242.tar.xz
Pass sockets to bypass to kernel interface, allowing us to register them dynamically
Diffstat (limited to 'src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c')
-rw-r--r--src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c103
1 files changed, 42 insertions, 61 deletions
diff --git a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
index e5f7ac130..c8bcfd6ff 100644
--- a/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
+++ b/src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c
@@ -1892,6 +1892,47 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
return SUCCESS;
}
+METHOD(kernel_ipsec_t, bypass_socket, bool,
+ private_kernel_netlink_ipsec_t *this, int fd, int family)
+{
+ struct xfrm_userpolicy_info policy;
+ u_int sol, ipsec_policy;
+
+ switch (family)
+ {
+ case AF_INET:
+ sol = SOL_IP;
+ ipsec_policy = IP_XFRM_POLICY;
+ break;
+ case AF_INET6:
+ sol = SOL_IPV6;
+ ipsec_policy = IPV6_XFRM_POLICY;
+ break;
+ default:
+ return FALSE;
+ }
+
+ memset(&policy, 0, sizeof(policy));
+ policy.action = XFRM_POLICY_ALLOW;
+ policy.sel.family = family;
+
+ policy.dir = XFRM_POLICY_OUT;
+ if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+ {
+ DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
+ strerror(errno));
+ return FALSE;
+ }
+ policy.dir = XFRM_POLICY_IN;
+ if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+ {
+ DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
+ strerror(errno));
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(kernel_ipsec_t, destroy, void,
private_kernel_netlink_ipsec_t *this)
{
@@ -1912,60 +1953,6 @@ METHOD(kernel_ipsec_t, destroy, void,
free(this);
}
-/**
- * Add bypass policies for IKE on the sockets used by charon
- */
-static bool add_bypass_policies()
-{
- int fd, family, port;
- enumerator_t *sockets;
- bool status = TRUE;
-
- sockets = charon->socket->create_enumerator(charon->socket);
- while (sockets->enumerate(sockets, &fd, &family, &port))
- {
- struct xfrm_userpolicy_info policy;
- u_int sol, ipsec_policy;
-
- switch (family)
- {
- case AF_INET:
- sol = SOL_IP;
- ipsec_policy = IP_XFRM_POLICY;
- break;
- case AF_INET6:
- sol = SOL_IPV6;
- ipsec_policy = IPV6_XFRM_POLICY;
- break;
- default:
- continue;
- }
-
- memset(&policy, 0, sizeof(policy));
- policy.action = XFRM_POLICY_ALLOW;
- policy.sel.family = family;
-
- policy.dir = XFRM_POLICY_OUT;
- if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- status = FALSE;
- break;
- }
- policy.dir = XFRM_POLICY_IN;
- if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
- strerror(errno));
- status = FALSE;
- break;
- }
- }
- sockets->destroy(sockets);
- return status;
-}
-
/*
* Described in header.
*/
@@ -1986,6 +1973,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
.add_policy = _add_policy,
.query_policy = _query_policy,
.del_policy = _del_policy,
+ .bypass_socket = _bypass_socket,
.destroy = _destroy,
},
.policies = hashtable_create((hashtable_hash_t)policy_hash,
@@ -2020,13 +2008,6 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
{
charon->kill(charon, "unable to bind XFRM event socket");
}
-
- /* add bypass policies on the sockets used by charon */
- if (!add_bypass_policies())
- {
- charon->kill(charon, "unable to add bypass policies on sockets");
- }
-
this->job = callback_job_create((callback_job_cb_t)receive_events,
this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job);