aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pluto/kernel.c95
-rw-r--r--src/pluto/kernel.h1
-rw-r--r--src/pluto/plutomain.c1
-rw-r--r--src/pluto/server.c27
4 files changed, 86 insertions, 38 deletions
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
index 690f28a2d..164e42833 100644
--- a/src/pluto/kernel.c
+++ b/src/pluto/kernel.c
@@ -38,6 +38,7 @@
#include <library.h>
#include <hydra.h>
#include <crypto/rngs/rng.h>
+#include <kernel/kernel_listener.h>
#ifdef KLIPS
#include <signal.h>
@@ -66,6 +67,7 @@
#include "nat_traversal.h"
#include "alg_info.h"
#include "kernel_alg.h"
+#include "pluto.h"
bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */
@@ -182,6 +184,22 @@ static traffic_selector_t *traffic_selector_from_subnet(const ip_subnet *client,
return ts;
}
+/**
+ * Helper function that converts a traffic_selector_t to an ip_subnet.
+ */
+static ip_subnet subnet_from_traffic_selector(traffic_selector_t *ts)
+{
+ ip_subnet subnet;
+ host_t *net;
+ u_int8_t mask;
+ ts->to_subnet(ts, &net, &mask);
+ subnet.addr = *(ip_address*)net->get_sockaddr(net);
+ subnet.maskbits = mask;
+ net->destroy(net);
+ return subnet;
+}
+
+
void record_and_initiate_opportunistic(const ip_subnet *ours,
const ip_subnet *his,
int transport_proto, const char *why)
@@ -1773,17 +1791,63 @@ failed:
const struct kernel_ops *kernel_ops;
-#endif /* KLIPS */
+/**
+ * Data for acquire events
+ */
+typedef struct {
+ /** Subnets */
+ ip_subnet src, dst;
+ /** Transport protocol */
+ int proto;
+} acquire_data_t;
-void init_kernel(void)
+/**
+ * Callback for acquire events (called by main thread)
+ */
+void handle_acquire(acquire_data_t *this)
{
-#ifdef KLIPS
+ record_and_initiate_opportunistic(&this->src, &this->dst, this->proto,
+ "%acquire");
+}
+
+/**
+ * Handler for kernel events (called by thread-pool thread)
+ */
+kernel_listener_t *kernel_handler;
- if (no_klips)
+METHOD(kernel_listener_t, acquire, bool,
+ kernel_listener_t *this, u_int32_t reqid,
+ traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+{
+ if (src_ts && dst_ts)
{
- kernel_ops = &noklips_kernel_ops;
- return;
+ acquire_data_t *data;
+ DBG(DBG_CONTROL,
+ DBG_log("creating acquire event for policy %R === %R "
+ "with reqid {%u}", src_ts, dst_ts, reqid));
+ INIT(data,
+ .src = subnet_from_traffic_selector(src_ts),
+ .dst = subnet_from_traffic_selector(dst_ts),
+ .proto = src_ts->get_protocol(src_ts),
+ );
+ pluto->events->queue(pluto->events, (void*)handle_acquire, data, free);
}
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("ignoring acquire without traffic selectors for policy "
+ "with reqid {%u}", reqid));
+ }
+ DESTROY_IF(src_ts);
+ DESTROY_IF(dst_ts);
+ return TRUE;
+}
+
+#endif /* KLIPS */
+
+void init_kernel(void)
+{
+#ifdef KLIPS
init_pfkey();
@@ -1807,14 +1871,23 @@ void init_kernel(void)
}
#endif
- if (kernel_ops->init)
- {
- kernel_ops->init();
- }
-
/* register SA types that we can negotiate */
can_do_IPcomp = FALSE; /* until we get a response from KLIPS */
kernel_ops->pfkey_register();
+
+ INIT(kernel_handler,
+ .acquire = _acquire,
+ );
+ hydra->kernel_interface->add_listener(hydra->kernel_interface,
+ kernel_handler);
+#endif
+}
+
+void kernel_finalize()
+{
+#ifdef KLIPS
+ hydra->kernel_interface->remove_listener(hydra->kernel_interface,
+ kernel_handler);
#endif
}
diff --git a/src/pluto/kernel.h b/src/pluto/kernel.h
index 26efd0013..9b1d57a88 100644
--- a/src/pluto/kernel.h
+++ b/src/pluto/kernel.h
@@ -151,6 +151,7 @@ extern void record_and_initiate_opportunistic(const ip_subnet *
, const char *why);
extern void init_kernel(void);
+extern void kernel_finalize(void);
extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c);
diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c
index c172e8f3a..ecb4aa50e 100644
--- a/src/pluto/plutomain.c
+++ b/src/pluto/plutomain.c
@@ -786,6 +786,7 @@ void exit_pluto(int status)
free_remembered_public_keys();
delete_every_connection();
whack_attribute_finalize(); /* free in-memory pools */
+ kernel_finalize();
fetch_finalize(); /* stop fetching thread */
free_crl_fetch(); /* free chain of crl fetch requests */
free_ocsp_fetch(); /* free chain of ocsp fetch requests */
diff --git a/src/pluto/server.c b/src/pluto/server.c
index 6ad49640d..1f90039a8 100644
--- a/src/pluto/server.c
+++ b/src/pluto/server.c
@@ -859,20 +859,6 @@ call_server(void)
maxfd = events_fd;
FD_SET(events_fd, &readfds);
-#ifdef KLIPS
- if (!no_klips)
- {
- int fd = *kernel_ops->async_fdp;
-
- if (kernel_ops->process_queue)
- kernel_ops->process_queue();
- if (maxfd < fd)
- maxfd = fd;
- passert(!FD_ISSET(fd, &readfds));
- FD_SET(fd, &readfds);
- }
-#endif
-
if (listening)
{
for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
@@ -964,19 +950,6 @@ call_server(void)
ndes--;
}
-#ifdef KLIPS
- if (!no_klips && FD_ISSET(*kernel_ops->async_fdp, &readfds))
- {
- passert(ndes > 0);
- DBG(DBG_CONTROL,
- DBG_log(BLANK_FORMAT);
- DBG_log("*received kernel message"));
- kernel_ops->process_msg();
- passert(GLOBALS_ARE_RESET());
- ndes--;
- }
-#endif
-
for (ifp = interfaces; ifp != NULL; ifp = ifp->next)
{
if (FD_ISSET(ifp->fd, &readfds))