aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-02-24 11:07:34 +0100
committerTobias Brunner <tobias@strongswan.org>2012-08-08 15:12:24 +0200
commite49abcede093ded4d11de88a6d0c25f003c9771e (patch)
treea34d5a92882578ecb0b4820df0ff5f9af5f94807 /src
parent08b2ce7aa7070674d756fefd365a96b600f3ebcb (diff)
downloadstrongswan-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.c9
-rw-r--r--src/libcharon/plugins/socket_default/socket_default_socket.c42
-rw-r--r--src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c20
-rw-r--r--src/libcharon/plugins/socket_raw/socket_raw_socket.c28
-rw-r--r--src/libhydra/kernel/kernel_interface.c13
-rw-r--r--src/libhydra/kernel/kernel_interface.h16
-rw-r--r--src/libhydra/kernel/kernel_ipsec.h13
-rw-r--r--src/libhydra/plugins/kernel_klips/kernel_klips_ipsec.c12
-rw-r--r--src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c28
-rw-r--r--src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c42
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,
},
},