diff options
author | Martin Willi <martin@revosec.ch> | 2010-02-23 16:28:23 +0000 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2010-02-26 11:44:33 +0100 |
commit | 54f818590e1482eb271b01e9f462c58ec1299242 (patch) | |
tree | 4154d6fe798855f9a360e2a1f95dac44c74a128e /src/charon/plugins/kernel_netlink/kernel_netlink_ipsec.c | |
parent | 3e631491a0ecb922284198bf3a2cf82470f9a28a (diff) | |
download | strongswan-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.c | 103 |
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); |