summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/kernel_libipsec
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/kernel_libipsec')
-rw-r--r--src/libcharon/plugins/kernel_libipsec/Makefile.in5
-rw-r--r--src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c20
-rw-r--r--src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c110
3 files changed, 71 insertions, 64 deletions
diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in
index c961c0bd8..6b6c95688 100644
--- a/src/libcharon/plugins/kernel_libipsec/Makefile.in
+++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in
@@ -231,6 +231,7 @@ DLLIB = @DLLIB@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
+EASY_INSTALL = @EASY_INSTALL@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
@@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
PTHREADLIB = @PTHREADLIB@
PYTHON = @PYTHON@
+PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
+PY_TEST = @PY_TEST@
RANLIB = @RANLIB@
RTLIB = @RTLIB@
RUBY = @RUBY@
@@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@
json_LIBS = @json_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
+libiptc_CFLAGS = @libiptc_CFLAGS@
+libiptc_LIBS = @libiptc_LIBS@
linux_headers = @linux_headers@
localedir = @localedir@
localstatedir = @localstatedir@
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
index bd07a67a2..6246dc505 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
@@ -222,10 +222,10 @@ static inline bool policy_entry_equals(policy_entry_t *a,
/**
* Expiration callback
*/
-static void expire(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, bool hard)
+static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
{
- hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol,
- spi, hard);
+ hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
+ spi, dst, hard);
}
METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
@@ -236,14 +236,14 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
METHOD(kernel_ipsec_t, get_spi, status_t,
private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
- u_int8_t protocol, u_int32_t reqid, u_int32_t *spi)
+ u_int8_t protocol, u_int32_t *spi)
{
- return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, reqid, spi);
+ return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, spi);
}
METHOD(kernel_ipsec_t, get_cpi, status_t,
private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst,
- u_int32_t reqid, u_int16_t *cpi)
+ u_int16_t *cpi)
{
return NOT_SUPPORTED;
}
@@ -254,13 +254,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window,
- bool initiator, bool encap, bool esn, bool inbound,
- traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+ bool initiator, bool encap, bool esn, bool inbound, bool update,
+ linked_list_t *src_ts, linked_list_t *dst_ts)
{
return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark,
tfc, lifetime, enc_alg, enc_key, int_alg, int_key,
- mode, ipcomp, cpi, initiator, encap, esn, inbound,
- src_ts, dst_ts);
+ mode, ipcomp, cpi, initiator, encap, esn,
+ inbound, update);
}
METHOD(kernel_ipsec_t, update_sa, status_t,
diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
index 6ce1d4eb0..830954e11 100644
--- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
+++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
@@ -131,35 +131,6 @@ static void deliver_plain(private_kernel_libipsec_router_t *this,
}
/**
- * Create an FD set covering all TUN devices and the read end of the notify pipe
- */
-static int collect_fds(private_kernel_libipsec_router_t *this, fd_set *fds)
-{
- enumerator_t *enumerator;
- tun_entry_t *entry;
- int maxfd;
-
- FD_ZERO(fds);
- FD_SET(this->notify[0], fds);
- maxfd = this->notify[0];
-
- FD_SET(this->tun.fd, fds);
- maxfd = max(maxfd, this->tun.fd);
-
- this->lock->read_lock(this->lock);
- enumerator = this->tuns->create_enumerator(this->tuns);
- while (enumerator->enumerate(enumerator, NULL, &entry))
- {
- FD_SET(entry->fd, fds);
- maxfd = max(maxfd, entry->fd);
- }
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
-
- return maxfd + 1;
-}
-
-/**
* Read and process outbound plaintext packet for the given TUN device
*/
static void process_plain(tun_device_t *tun)
@@ -183,29 +154,20 @@ static void process_plain(tun_device_t *tun)
}
/**
- * Handle waiting data for any TUN device
+ * Find flagged revents in a pollfd set by fd
*/
-static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds)
+static int find_revents(struct pollfd *pfd, int count, int fd)
{
- enumerator_t *enumerator;
- tun_entry_t *entry;
+ int i;
- if (FD_ISSET(this->tun.fd, fds))
+ for (i = 0; i < count; i++)
{
- process_plain(this->tun.tun);
- }
-
- this->lock->read_lock(this->lock);
- enumerator = this->tuns->create_enumerator(this->tuns);
- while (enumerator->enumerate(enumerator, NULL, &entry))
- {
- if (FD_ISSET(entry->fd, fds))
+ if (pfd[i].fd == fd)
{
- process_plain(entry->tun);
+ return pfd[i].revents;
}
}
- enumerator->destroy(enumerator);
- this->lock->unlock(this->lock);
+ return 0;
}
/**
@@ -213,28 +175,68 @@ static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds)
*/
static job_requeue_t handle_plain(private_kernel_libipsec_router_t *this)
{
+ enumerator_t *enumerator;
+ tun_entry_t *entry;
bool oldstate;
- fd_set fds;
- int maxfd;
+ int count = 0;
+ char buf[1];
+ struct pollfd *pfd;
+
+ this->lock->read_lock(this->lock);
- maxfd = collect_fds(this, &fds);
+ pfd = alloca(sizeof(*pfd) * (this->tuns->get_count(this->tuns) + 2));
+ pfd[count].fd = this->notify[0];
+ pfd[count].events = POLLIN;
+ count++;
+ pfd[count].fd = this->tun.fd;
+ pfd[count].events = POLLIN;
+ count++;
+
+ enumerator = this->tuns->create_enumerator(this->tuns);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ pfd[count].fd = entry->fd;
+ pfd[count].events = POLLIN;
+ count++;
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
oldstate = thread_cancelability(TRUE);
- if (select(maxfd, &fds, NULL, NULL, NULL) <= 0)
+ if (poll(pfd, count, -1) <= 0)
{
thread_cancelability(oldstate);
return JOB_REQUEUE_FAIR;
}
thread_cancelability(oldstate);
- if (FD_ISSET(this->notify[0], &fds))
- { /* list of TUN devices changed, read notification data, rebuild FDs */
- char buf[1];
- while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf));
+ if (pfd[0].revents & POLLIN)
+ {
+ /* list of TUN devices changed, read notification data, rebuild FDs */
+ while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf))
+ {
+ /* nop */
+ }
return JOB_REQUEUE_DIRECT;
}
- handle_tuns(this, &fds);
+ if (pfd[1].revents & POLLIN)
+ {
+ process_plain(this->tun.tun);
+ }
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->tuns->create_enumerator(this->tuns);
+ while (enumerator->enumerate(enumerator, NULL, &entry))
+ {
+ if (find_revents(pfd, count, entry->fd) & POLLIN)
+ {
+ process_plain(entry->tun);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->lock->unlock(this->lock);
+
return JOB_REQUEUE_DIRECT;
}