diff options
author | Tobias Brunner <tobias@strongswan.org> | 2012-02-24 11:07:34 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2012-08-08 15:12:24 +0200 |
commit | e49abcede093ded4d11de88a6d0c25f003c9771e (patch) | |
tree | a34d5a92882578ecb0b4820df0ff5f9af5f94807 /src | |
parent | 08b2ce7aa7070674d756fefd365a96b600f3ebcb (diff) | |
download | strongswan-e49abcede093ded4d11de88a6d0c25f003c9771e.tar.bz2 strongswan-e49abcede093ded4d11de88a6d0c25f003c9771e.tar.xz |
Let kernel interfaces decide how to enable UDP decapsulation of ESP packets.
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/plugins/load_tester/load_tester_ipsec.c | 9 | ||||
-rw-r--r-- | src/libcharon/plugins/socket_default/socket_default_socket.c | 42 | ||||
-rw-r--r-- | src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c | 20 | ||||
-rw-r--r-- | src/libcharon/plugins/socket_raw/socket_raw_socket.c | 28 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_interface.c | 13 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_interface.h | 16 | ||||
-rw-r--r-- | src/libhydra/kernel/kernel_ipsec.h | 13 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c | 12 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c | 28 | ||||
-rw-r--r-- | src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 42 |
10 files changed, 133 insertions, 90 deletions
diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c index 440197260..ded6b2d20 100644 --- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c +++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c @@ -108,12 +108,6 @@ METHOD(kernel_ipsec_t, del_policy, status_t, return SUCCESS; } -METHOD(kernel_ipsec_t, bypass_socket, bool, - private_load_tester_ipsec_t *this, int fd, int family) -{ - return TRUE; -} - METHOD(kernel_ipsec_t, destroy, void, private_load_tester_ipsec_t *this) { @@ -141,7 +135,8 @@ load_tester_ipsec_t *load_tester_ipsec_create() .query_policy = _query_policy, .del_policy = _del_policy, .flush_policies = (void*)return_failed, - .bypass_socket = _bypass_socket, + .bypass_socket = (void*)return_true, + .enable_udp_decap = (void*)return_true, .destroy = _destroy, }, }, diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index eba7219b2..b035d575a 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -40,9 +40,6 @@ #include <netinet/ip.h> #include <netinet/udp.h> #include <net/if.h> -#ifdef __APPLE__ -#include <sys/sysctl.h> -#endif #include <hydra.h> #include <daemon.h> @@ -54,15 +51,6 @@ /* length of non-esp marker */ #define MARKER_LEN sizeof(u_int32_t) -/* from linux/udp.h */ -#ifndef UDP_ENCAP -#define UDP_ENCAP 100 -#endif /*UDP_ENCAP*/ - -#ifndef UDP_ENCAP_ESPINUDP -#define UDP_ENCAP_ESPINUDP 2 -#endif /*UDP_ENCAP_ESPINUDP*/ - /* these are not defined on some platforms */ #ifndef SOL_IP #define SOL_IP IPPROTO_IP @@ -70,9 +58,6 @@ #ifndef SOL_IPV6 #define SOL_IPV6 IPPROTO_IPV6 #endif -#ifndef SOL_UDP -#define SOL_UDP IPPROTO_UDP -#endif /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that * previously defined IPV6_PKTINFO */ @@ -513,17 +498,14 @@ static int open_socket(private_socket_default_socket_t *this, DBG1(DBG_NET, "installing IKE bypass policy failed"); } -#ifndef __APPLE__ + /* enable UDP decapsulation globally, only for one socket needed */ + if (family == AF_INET && port == CHARON_NATT_PORT && + !hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface, + skt, family, port)) { - /* enable UDP decapsulation globally, only for one socket needed */ - int type = UDP_ENCAP_ESPINUDP; - if (family == AF_INET && port == CHARON_NATT_PORT && - setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) - { - DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno)); - } + DBG1(DBG_NET, "enabling UDP decapsulation failed"); } -#endif + return skt; } @@ -568,18 +550,6 @@ socket_default_socket_t *socket_default_socket_create() "%s.max_packet", MAX_PACKET, charon->name), ); -#ifdef __APPLE__ - { - int natt_port = CHARON_NATT_PORT; - if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &natt_port, - sizeof(natt_port)) != 0) - { - DBG1(DBG_NET, "could not set net.inet.ipsec.esp_port to %d: %s", - natt_port, strerror(errno)); - } - } -#endif - this->ipv4 = open_socket(this, AF_INET, CHARON_UDP_PORT); if (this->ipv4 == 0) { diff --git a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c index ec61e61c9..787f6f444 100644 --- a/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c +++ b/src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c @@ -48,15 +48,6 @@ /* length of non-esp marker */ #define MARKER_LEN sizeof(u_int32_t) -/* from linux/udp.h */ -#ifndef UDP_ENCAP -#define UDP_ENCAP 100 -#endif /*UDP_ENCAP*/ - -#ifndef UDP_ENCAP_ESPINUDP -#define UDP_ENCAP_ESPINUDP 2 -#endif /*UDP_ENCAP_ESPINUDP*/ - /* these are not defined on some platforms */ #ifndef SOL_IP #define SOL_IP IPPROTO_IP @@ -64,9 +55,6 @@ #ifndef SOL_IPV6 #define SOL_IPV6 IPPROTO_IPV6 #endif -#ifndef SOL_UDP -#define SOL_UDP IPPROTO_UDP -#endif /* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that * previously defined IPV6_PKTINFO */ @@ -352,7 +340,7 @@ METHOD(socket_t, receiver, status_t, static int open_socket(private_socket_dynamic_socket_t *this, int family, u_int16_t port) { - int on = TRUE, type = UDP_ENCAP_ESPINUDP; + int on = TRUE; struct sockaddr_storage addr; socklen_t addrlen; u_int sol, pktinfo = 0; @@ -424,10 +412,12 @@ static int open_socket(private_socket_dynamic_socket_t *this, } /* enable UDP decapsulation on each socket */ - if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + if (!hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface, + fd, family, port)) { - DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno)); + DBG1(DBG_NET, "enabling UDP decapsulation failed"); } + return fd; } diff --git a/src/libcharon/plugins/socket_raw/socket_raw_socket.c b/src/libcharon/plugins/socket_raw/socket_raw_socket.c index 600f5453d..8d0b4226c 100644 --- a/src/libcharon/plugins/socket_raw/socket_raw_socket.c +++ b/src/libcharon/plugins/socket_raw/socket_raw_socket.c @@ -55,15 +55,6 @@ #define IKE_VERSION_OFFSET 17 #define IKE_LENGTH_OFFSET 24 -/* from linux/udp.h */ -#ifndef UDP_ENCAP -#define UDP_ENCAP 100 -#endif /*UDP_ENCAP*/ - -#ifndef UDP_ENCAP_ESPINUDP -#define UDP_ENCAP_ESPINUDP 2 -#endif /*UDP_ENCAP_ESPINUDP*/ - /* needed for older kernel headers */ #ifndef IPV6_2292PKTINFO #define IPV6_2292PKTINFO 2 @@ -412,7 +403,6 @@ static int open_send_socket(private_socket_raw_socket_t *this, int family, u_int16_t port) { int on = TRUE; - int type = UDP_ENCAP_ESPINUDP; struct sockaddr_storage addr; int skt; @@ -463,22 +453,20 @@ static int open_send_socket(private_socket_raw_socket_t *this, return 0; } - if (family == AF_INET) - { - /* enable UDP decapsulation globally, only for one socket needed */ - if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) - { - DBG1(DBG_NET, "unable to set UDP_ENCAP: %s; NAT-T may fail", - strerror(errno)); - } - } - if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface, skt, family)) { DBG1(DBG_NET, "installing bypass policy on send socket failed"); } + /* enable UDP decapsulation globally, only for one socket needed */ + if (family == AF_INET && port == CHARON_NATT_PORT && + !hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface, + skt, family, port)) + { + DBG1(DBG_NET, "enabling UDP decapsulation failed"); + } + return skt; } diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index b6bc5d92e..650cb1e9e 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG @@ -294,6 +294,16 @@ METHOD(kernel_interface_t, bypass_socket, bool, return this->ipsec->bypass_socket(this->ipsec, fd, family); } +METHOD(kernel_interface_t, enable_udp_decap, bool, + private_kernel_interface_t *this, int fd, int family, u_int16_t port) +{ + if (!this->ipsec) + { + return FALSE; + } + return this->ipsec->enable_udp_decap(this->ipsec, fd, family, port); +} + METHOD(kernel_interface_t, get_address_by_ts, status_t, private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip) { @@ -539,6 +549,7 @@ kernel_interface_t *kernel_interface_create() .add_route = _add_route, .del_route = _del_route, .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, .get_address_by_ts = _get_address_by_ts, .add_ipsec_interface = _add_ipsec_interface, diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index 991cfafd0..37b72f8bb 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2011 Tobias Brunner + * Copyright (C) 2006-2012 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -361,11 +361,23 @@ struct kernel_interface_t { * * @param fd socket file descriptor to setup policy for * @param family protocol family of the socket - * @return TRUE of policy set up successfully + * @return TRUE if policy set up successfully */ bool (*bypass_socket)(kernel_interface_t *this, int fd, int family); /** + * Enable decapsulation of ESP-in-UDP packets for the given port/socket. + * + * @param fd socket file descriptor + * @param family protocol family of the socket + * @param port the UDP port + * @return TRUE if UDP decapsulation was enabled successfully + */ + bool (*enable_udp_decap)(kernel_interface_t *this, int fd, int family, + u_int16_t port); + + + /** * manager methods */ diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h index 852f0560c..500a77cad 100644 --- a/src/libhydra/kernel/kernel_ipsec.h +++ b/src/libhydra/kernel/kernel_ipsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2011 Tobias Brunner + * Copyright (C) 2006-2012 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -403,6 +403,17 @@ struct kernel_ipsec_t { bool (*bypass_socket)(kernel_ipsec_t *this, int fd, int family); /** + * Enable decapsulation of ESP-in-UDP packets for the given port/socket. + * + * @param fd socket file descriptor + * @param family protocol family of the socket + * @param port the UDP port + * @return TRUE if UDP decapsulation was enabled successfully + */ + bool (*enable_udp_decap)(kernel_ipsec_t *this, int fd, int family, + u_int16_t port); + + /** * Destroy the implementation. */ void (*destroy) (kernel_ipsec_t *this); diff --git a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c index 7e58cf30b..5f077b234 100644 --- a/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c +++ b/src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c @@ -2537,13 +2537,6 @@ static status_t register_pfkey_socket(private_kernel_klips_ipsec_t *this, u_int8 return SUCCESS; } -METHOD(kernel_ipsec_t, bypass_socket, bool, - private_kernel_klips_ipsec_t *this, int fd, int family) -{ - /* KLIPS does not need a bypass policy for IKE */ - return TRUE; -} - METHOD(kernel_ipsec_t, destroy, void, private_kernel_klips_ipsec_t *this) { @@ -2585,7 +2578,10 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create() .query_policy = _query_policy, .del_policy = _del_policy, .flush_policies = (void*)return_failed, - .bypass_socket = _bypass_socket, + /* KLIPS does not need a bypass policy for IKE */ + .bypass_socket = (void*)return_true, + /* KLIPS does not need enabling UDP decap explicitly */ + .enable_udp_decap = (void*)return_true, .destroy = _destroy, }, }, diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index b46450c38..73d290051 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -58,6 +58,20 @@ #define IPV6_XFRM_POLICY 34 #endif /*IPV6_XFRM_POLICY*/ +/* from linux/udp.h */ +#ifndef UDP_ENCAP +#define UDP_ENCAP 100 +#endif + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +/* this is not defined on some platforms */ +#ifndef SOL_UDP +#define SOL_UDP IPPROTO_UDP +#endif + /** Default priority of installed policies */ #define PRIO_BASE 512 @@ -2607,6 +2621,19 @@ METHOD(kernel_ipsec_t, bypass_socket, bool, return TRUE; } +METHOD(kernel_ipsec_t, enable_udp_decap, bool, + private_kernel_netlink_ipsec_t *this, int fd, int family, u_int16_t port) +{ + int type = UDP_ENCAP_ESPINUDP; + + if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + { + DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno)); + return FALSE; + } + return TRUE; +} + METHOD(kernel_ipsec_t, destroy, void, private_kernel_netlink_ipsec_t *this) { @@ -2654,6 +2681,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() .del_policy = _del_policy, .flush_policies = _flush_policies, .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, .destroy = _destroy, }, }, diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index dfe10f93f..13422670a 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -51,6 +51,9 @@ #include <unistd.h> #include <time.h> #include <errno.h> +#ifdef __APPLE__ +#include <sys/sysctl.h> +#endif #include "kernel_pfkey_ipsec.h" @@ -99,6 +102,20 @@ #define IPV6_IPSEC_POLICY 34 #endif +/* from linux/udp.h */ +#ifndef UDP_ENCAP +#define UDP_ENCAP 100 +#endif + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +/* this is not defined on some platforms */ +#ifndef SOL_UDP +#define SOL_UDP IPPROTO_UDP +#endif + /** default priority of installed policies */ #define PRIO_BASE 512 @@ -2488,6 +2505,30 @@ METHOD(kernel_ipsec_t, bypass_socket, bool, return TRUE; } +METHOD(kernel_ipsec_t, enable_udp_decap, bool, + private_kernel_pfkey_ipsec_t *this, int fd, int family, u_int16_t port) +{ +#ifndef __APPLE__ + int type = UDP_ENCAP_ESPINUDP; + + if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) + { + DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno)); + return FALSE; + } +#else /* __APPLE__ */ + if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &port, + sizeof(port)) != 0) + { + DBG1(DBG_KNL, "could not set net.inet.ipsec.esp_port to %d: %s", + port, strerror(errno)); + return FALSE; + } +#endif /* __APPLE__ */ + + return TRUE; +} + METHOD(kernel_ipsec_t, destroy, void, private_kernel_pfkey_ipsec_t *this) { @@ -2532,6 +2573,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() .del_policy = _del_policy, .flush_policies = _flush_policies, .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, .destroy = _destroy, }, }, |