Merge branch 'libhydra-bye-bye'
authorTobias Brunner <tobias@strongswan.org>
Thu, 3 Mar 2016 16:39:27 +0000 (17:39 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 3 Mar 2016 16:39:58 +0000 (17:39 +0100)
Moves kernel plugins to libcharon and removes the unused libhydra.  The
kernel interface is now accessible under charon->kernel.

229 files changed:
Android.mk
configure.ac
packages/maemo-strongswan/debian/strongswan.install
packages/strongswan/debian/libstrongswan.install
src/Makefile.am
src/charon-cmd/Makefile.am
src/charon-cmd/charon-cmd.c
src/charon-nm/Makefile.am
src/charon-nm/charon-nm.c
src/charon-svc/Makefile.am
src/charon-svc/charon-svc.c
src/charon-systemd/Makefile.am
src/charon-systemd/charon-systemd.c
src/charon-tkm/Makefile.am
src/charon-tkm/src/charon-tkm.c
src/charon-tkm/src/ees/ees_callbacks.c
src/charon-tkm/tests/keymat_tests.c
src/charon-tkm/tests/tests.c
src/charon/Android.mk
src/charon/Makefile.am
src/charon/charon.c
src/checksum/Makefile.am
src/checksum/checksum_builder.c
src/conftest/Makefile.am
src/conftest/conftest.c
src/conftest/conftest.h
src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java
src/frontends/android/app/src/main/jni/Android.mk
src/frontends/android/app/src/main/jni/libandroidbridge/Android.mk
src/frontends/android/app/src/main/jni/libandroidbridge/android_jni.c
src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_attr.c
src/frontends/android/app/src/main/jni/libandroidbridge/backend/android_dns_proxy.c
src/frontends/android/app/src/main/jni/libandroidbridge/charonservice.c
src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_ipsec.c
src/frontends/android/app/src/main/jni/libandroidbridge/kernel/android_net.c
src/frontends/osx/charon-xpc/charon-xpc.c
src/frontends/osx/strongSwan.xcodeproj/project.pbxproj
src/libcharon/Android.mk
src/libcharon/Makefile.am
src/libcharon/attributes/mem_pool.c
src/libcharon/daemon.c
src/libcharon/daemon.h
src/libcharon/kernel/kernel_handler.c
src/libcharon/kernel/kernel_handler.h
src/libcharon/kernel/kernel_interface.c [new file with mode: 0644]
src/libcharon/kernel/kernel_interface.h [new file with mode: 0644]
src/libcharon/kernel/kernel_ipsec.c [new file with mode: 0644]
src/libcharon/kernel/kernel_ipsec.h [new file with mode: 0644]
src/libcharon/kernel/kernel_listener.h [new file with mode: 0644]
src/libcharon/kernel/kernel_net.c [new file with mode: 0644]
src/libcharon/kernel/kernel_net.h [new file with mode: 0644]
src/libcharon/network/receiver.c
src/libcharon/plugins/addrblock/Makefile.am
src/libcharon/plugins/android_dns/Makefile.am
src/libcharon/plugins/android_log/Makefile.am
src/libcharon/plugins/attr/Makefile.am
src/libcharon/plugins/attr_sql/Makefile.am
src/libcharon/plugins/certexpire/Makefile.am
src/libcharon/plugins/connmark/Makefile.am
src/libcharon/plugins/coupling/Makefile.am
src/libcharon/plugins/dhcp/Makefile.am
src/libcharon/plugins/dhcp/dhcp_socket.c
src/libcharon/plugins/dnscert/Makefile.am
src/libcharon/plugins/duplicheck/Makefile.am
src/libcharon/plugins/eap_aka/Makefile.am
src/libcharon/plugins/eap_aka_3gpp2/Makefile.am
src/libcharon/plugins/eap_dynamic/Makefile.am
src/libcharon/plugins/eap_gtc/Makefile.am
src/libcharon/plugins/eap_identity/Makefile.am
src/libcharon/plugins/eap_md5/Makefile.am
src/libcharon/plugins/eap_mschapv2/Makefile.am
src/libcharon/plugins/eap_peap/Makefile.am
src/libcharon/plugins/eap_radius/Makefile.am
src/libcharon/plugins/eap_sim/Makefile.am
src/libcharon/plugins/eap_sim_file/Makefile.am
src/libcharon/plugins/eap_sim_pcsc/Makefile.am
src/libcharon/plugins/eap_simaka_pseudonym/Makefile.am
src/libcharon/plugins/eap_simaka_reauth/Makefile.am
src/libcharon/plugins/eap_simaka_sql/Makefile.am
src/libcharon/plugins/eap_tls/Makefile.am
src/libcharon/plugins/eap_tnc/Makefile.am
src/libcharon/plugins/eap_ttls/Makefile.am
src/libcharon/plugins/error_notify/Makefile.am
src/libcharon/plugins/ext_auth/Makefile.am
src/libcharon/plugins/farp/Makefile.am
src/libcharon/plugins/forecast/Makefile.am
src/libcharon/plugins/forecast/forecast_forwarder.c
src/libcharon/plugins/ha/Makefile.am
src/libcharon/plugins/ipseckey/Makefile.am
src/libcharon/plugins/kernel_iph/Makefile.am
src/libcharon/plugins/kernel_iph/kernel_iph_net.c
src/libcharon/plugins/kernel_iph/kernel_iph_plugin.c
src/libcharon/plugins/kernel_libipsec/Makefile.am
src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c
src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c
src/libcharon/plugins/kernel_netlink/.gitignore [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/Makefile.am [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.h [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_net.h [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.h [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.h [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/suites/test_socket.c [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/tests.c [new file with mode: 0644]
src/libcharon/plugins/kernel_netlink/tests.h [new file with mode: 0644]
src/libcharon/plugins/kernel_pfkey/Makefile.am [new file with mode: 0644]
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c [new file with mode: 0644]
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.h [new file with mode: 0644]
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.c [new file with mode: 0644]
src/libcharon/plugins/kernel_pfkey/kernel_pfkey_plugin.h [new file with mode: 0644]
src/libcharon/plugins/kernel_pfroute/Makefile.am [new file with mode: 0644]
src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c [new file with mode: 0644]
src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.h [new file with mode: 0644]
src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.c [new file with mode: 0644]
src/libcharon/plugins/kernel_pfroute/kernel_pfroute_plugin.h [new file with mode: 0644]
src/libcharon/plugins/kernel_wfp/Makefile.am
src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c
src/libcharon/plugins/led/Makefile.am
src/libcharon/plugins/load_tester/Makefile.am
src/libcharon/plugins/load_tester/load_tester_config.c
src/libcharon/plugins/load_tester/load_tester_plugin.c
src/libcharon/plugins/lookip/Makefile.am
src/libcharon/plugins/maemo/Makefile.am
src/libcharon/plugins/medcli/Makefile.am
src/libcharon/plugins/medsrv/Makefile.am
src/libcharon/plugins/osx_attr/Makefile.am
src/libcharon/plugins/radattr/Makefile.am
src/libcharon/plugins/resolve/Makefile.am
src/libcharon/plugins/resolve/resolve_handler.c
src/libcharon/plugins/smp/Makefile.am
src/libcharon/plugins/socket_default/Makefile.am
src/libcharon/plugins/socket_default/socket_default_socket.c
src/libcharon/plugins/socket_dynamic/Makefile.am
src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
src/libcharon/plugins/socket_win/Makefile.am
src/libcharon/plugins/socket_win/socket_win_socket.c
src/libcharon/plugins/sql/Makefile.am
src/libcharon/plugins/stroke/Makefile.am
src/libcharon/plugins/stroke/stroke_config.c
src/libcharon/plugins/stroke/stroke_control.c
src/libcharon/plugins/stroke/stroke_list.c
src/libcharon/plugins/systime_fix/Makefile.am
src/libcharon/plugins/tnc_ifmap/Makefile.am
src/libcharon/plugins/tnc_ifmap/tnc_ifmap_listener.c
src/libcharon/plugins/tnc_pdp/Makefile.am
src/libcharon/plugins/uci/Makefile.am
src/libcharon/plugins/unity/Makefile.am
src/libcharon/plugins/updown/Makefile.am
src/libcharon/plugins/updown/updown_listener.c
src/libcharon/plugins/vici/Makefile.am
src/libcharon/plugins/vici/vici_tests.c
src/libcharon/plugins/whitelist/Makefile.am
src/libcharon/plugins/xauth_eap/Makefile.am
src/libcharon/plugins/xauth_generic/Makefile.am
src/libcharon/plugins/xauth_noauth/Makefile.am
src/libcharon/plugins/xauth_pam/Makefile.am
src/libcharon/processing/jobs/adopt_children_job.c
src/libcharon/sa/child_sa.c
src/libcharon/sa/ike_sa.c
src/libcharon/sa/ikev1/tasks/isakmp_natd.c
src/libcharon/sa/ikev1/tasks/xauth.c
src/libcharon/sa/ikev2/tasks/child_create.c
src/libcharon/sa/ikev2/tasks/ike_me.c
src/libcharon/sa/ikev2/tasks/ike_mobike.c
src/libcharon/sa/ikev2/tasks/ike_natd.c
src/libcharon/sa/shunt_manager.c
src/libcharon/sa/trap_manager.c
src/libcharon/tests/Makefile.am
src/libcharon/tests/libcharon_tests.c
src/libhydra/Android.mk [deleted file]
src/libhydra/Makefile.am [deleted file]
src/libhydra/hydra.c [deleted file]
src/libhydra/hydra.h [deleted file]
src/libhydra/kernel/kernel_interface.c [deleted file]
src/libhydra/kernel/kernel_interface.h [deleted file]
src/libhydra/kernel/kernel_ipsec.c [deleted file]
src/libhydra/kernel/kernel_ipsec.h [deleted file]
src/libhydra/kernel/kernel_listener.h [deleted file]
src/libhydra/kernel/kernel_net.c [deleted file]
src/libhydra/kernel/kernel_net.h [deleted file]
src/libhydra/plugins/kernel_netlink/.gitignore [deleted file]
src/libhydra/plugins/kernel_netlink/Makefile.am [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.h [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_net.h [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.c [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_plugin.h [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c [deleted file]
src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h [deleted file]
src/libhydra/plugins/kernel_netlink/suites/test_socket.c [deleted file]
src/libhydra/plugins/kernel_netlink/tests.c [deleted file]
src/libhydra/plugins/kernel_netlink/tests.h [deleted file]
src/libhydra/plugins/kernel_pfkey/Makefile.am [deleted file]
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c [deleted file]
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.h [deleted file]
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c [deleted file]
src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.h [deleted file]
src/libhydra/plugins/kernel_pfroute/Makefile.am [deleted file]
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c [deleted file]
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.h [deleted file]
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.c [deleted file]
src/libhydra/plugins/kernel_pfroute/kernel_pfroute_plugin.h [deleted file]
src/libhydra/tests/.gitignore [deleted file]
src/libhydra/tests/Makefile.am [deleted file]
src/libhydra/tests/hydra_tests.c [deleted file]
src/libhydra/tests/hydra_tests.h [deleted file]
src/libsimaka/Makefile.am
src/libstrongswan/utils/compat/windows.c
src/pool/Makefile.am
src/scepclient/Makefile.am
src/starter/Android.mk
src/starter/Makefile.am
src/starter/netkey.c
src/starter/starter.c
testing/tests/ikev1/ip-pool-db/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/ip-pool-db/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/ip-split-pools-db/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/ip-two-pools-db/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/ip-two-pools-mixed/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/ip-two-pools-v4v6-db/hosts/moon/etc/strongswan.conf
testing/tests/sql/ip-pool-db-expired/hosts/moon/etc/strongswan.conf
testing/tests/sql/ip-pool-db-restart/hosts/moon/etc/strongswan.conf
testing/tests/sql/ip-pool-db/hosts/moon/etc/strongswan.conf
testing/tests/sql/ip-split-pools-db-restart/hosts/moon/etc/strongswan.conf
testing/tests/sql/ip-split-pools-db/hosts/moon/etc/strongswan.conf

index 7b8bc8f..f17289e 100644 (file)
@@ -97,7 +97,6 @@ strongswan_CFLAGS += \
 strongswan_BUILD := \
        charon \
        libcharon \
-       libhydra \
        libstrongswan \
        libtncif \
        libtnccs \
index 6278076..5f22808 100644 (file)
@@ -1280,9 +1280,8 @@ cmd_plugins=
 aikgen_plugins=
 
 # location specific lists for checksumming,
-# for src/libcharon, src/libhydra, src/libstrongswan and src/libtnccs
+# for src/libcharon, src/libstrongswan and src/libtnccs
 c_plugins=
-h_plugins=
 s_plugins=
 t_plugins=
 
@@ -1347,9 +1346,9 @@ ADD_PLUGIN([load-tester],          [c charon])
 ADD_PLUGIN([kernel-libipsec],      [c charon cmd])
 ADD_PLUGIN([kernel-wfp],           [c charon])
 ADD_PLUGIN([kernel-iph],           [c charon])
-ADD_PLUGIN([kernel-pfkey],         [h charon starter nm cmd])
-ADD_PLUGIN([kernel-pfroute],       [h charon starter nm cmd])
-ADD_PLUGIN([kernel-netlink],       [h charon starter nm cmd])
+ADD_PLUGIN([kernel-pfkey],         [c charon starter nm cmd])
+ADD_PLUGIN([kernel-pfroute],       [c charon starter nm cmd])
+ADD_PLUGIN([kernel-netlink],       [c charon starter nm cmd])
 ADD_PLUGIN([resolve],              [c charon cmd])
 ADD_PLUGIN([socket-default],       [c charon nm cmd])
 ADD_PLUGIN([socket-dynamic],       [c charon cmd])
@@ -1511,6 +1510,9 @@ AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
 AM_CONDITIONAL(USE_DHCP, test x$dhcp = xtrue)
 AM_CONDITIONAL(USE_LOAD_TESTER, test x$load_tester = xtrue)
 AM_CONDITIONAL(USE_HA, test x$ha = xtrue)
+AM_CONDITIONAL(USE_KERNEL_NETLINK, test x$kernel_netlink = xtrue)
+AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue)
+AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue)
 AM_CONDITIONAL(USE_KERNEL_LIBIPSEC, test x$kernel_libipsec = xtrue)
 AM_CONDITIONAL(USE_KERNEL_WFP, test x$kernel_wfp = xtrue)
 AM_CONDITIONAL(USE_KERNEL_IPH, test x$kernel_iph = xtrue)
@@ -1578,12 +1580,6 @@ AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue)
 AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue)
 AM_CONDITIONAL(USE_ATTR_SQL, test x$attr_sql = xtrue)
 
-#  hydra plugins
-# ---------------
-AM_CONDITIONAL(USE_KERNEL_NETLINK, test x$kernel_netlink = xtrue)
-AM_CONDITIONAL(USE_KERNEL_PFKEY, test x$kernel_pfkey = xtrue)
-AM_CONDITIONAL(USE_KERNEL_PFROUTE, test x$kernel_pfroute = xtrue)
-
 #  other options
 # ---------------
 AM_CONDITIONAL(USE_LEAK_DETECTIVE, test x$leak_detective = xtrue)
@@ -1605,7 +1601,6 @@ AM_CONDITIONAL(USE_SCEPCLIENT, test x$scepclient = xtrue)
 AM_CONDITIONAL(USE_SCRIPTS, test x$scripts = xtrue)
 AM_CONDITIONAL(USE_CONFTEST, test x$conftest = xtrue)
 AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$pki = xtrue -o x$scepclient = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$tls = xtrue -o x$tnc_tnccs = xtrue -o x$aikgen = xtrue -o x$svc = xtrue -o x$systemd = xtrue)
-AM_CONDITIONAL(USE_LIBHYDRA, test x$charon = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue)
 AM_CONDITIONAL(USE_LIBCHARON, test x$charon = xtrue -o x$conftest = xtrue -o x$nm = xtrue -o x$tkm = xtrue -o x$cmd = xtrue -o x$svc = xtrue -o x$systemd = xtrue)
 AM_CONDITIONAL(USE_LIBIPSEC, test x$libipsec = xtrue)
 AM_CONDITIONAL(USE_LIBTNCIF, test x$tnc_tnccs = xtrue -o x$imcv = xtrue)
@@ -1748,11 +1743,6 @@ AC_CONFIG_FILES([
        src/libstrongswan/plugins/bliss/tests/Makefile
        src/libstrongswan/plugins/test_vectors/Makefile
        src/libstrongswan/tests/Makefile
-       src/libhydra/Makefile
-       src/libhydra/plugins/kernel_netlink/Makefile
-       src/libhydra/plugins/kernel_pfkey/Makefile
-       src/libhydra/plugins/kernel_pfroute/Makefile
-       src/libhydra/tests/Makefile
        src/libipsec/Makefile
        src/libipsec/tests/Makefile
        src/libsimaka/Makefile
@@ -1828,6 +1818,9 @@ AC_CONFIG_FILES([
        src/libcharon/plugins/unity/Makefile
        src/libcharon/plugins/uci/Makefile
        src/libcharon/plugins/ha/Makefile
+       src/libcharon/plugins/kernel_netlink/Makefile
+       src/libcharon/plugins/kernel_pfkey/Makefile
+       src/libcharon/plugins/kernel_pfroute/Makefile
        src/libcharon/plugins/kernel_libipsec/Makefile
        src/libcharon/plugins/kernel_wfp/Makefile
        src/libcharon/plugins/kernel_iph/Makefile
@@ -1922,6 +1915,5 @@ AC_MSG_RESULT([-----------------------------------------------------])
 
 AC_MSG_RESULT([libstrongswan:$s_plugins])
 AC_MSG_RESULT([libcharon:    $c_plugins])
-AC_MSG_RESULT([libhydra:     $h_plugins])
 AC_MSG_RESULT([libtnccs:     $t_plugins])
 AC_MSG_RESULT([])
index 71b46e3..ff3d627 100644 (file)
@@ -2,7 +2,6 @@
 etc
 # libraries
 usr/lib/ipsec/libstrongswan.so*
-usr/lib/ipsec/libhydra.so*
 usr/lib/ipsec/libcharon.so*
 # starter etc.
 usr/sbin/ipsec
index d384cf3..1d3fe0c 100644 (file)
@@ -2,7 +2,6 @@ etc/strongswan.conf                                                                                             etc/
 usr/lib/strongswan/libstrongswan.so*                                                   usr/lib/strongswan/
 usr/lib/strongswan/libcharon.so*                                                               usr/lib/strongswan/
 usr/lib/strongswan/libtls.so*                                                                  usr/lib/strongswan/
-usr/lib/strongswan/libhydra.so*                                                                        usr/lib/strongswan/
 usr/lib/strongswan/plugins/libstrongswan-x509.so*                              usr/lib/strongswan/plugins/
 usr/lib/strongswan/plugins/libstrongswan-pubkey.so*                            usr/lib/strongswan/plugins/
 usr/lib/strongswan/plugins/libstrongswan-xcbc.so*                              usr/lib/strongswan/plugins/
index 9608a3a..a9df10c 100644 (file)
@@ -4,10 +4,6 @@ if USE_LIBSTRONGSWAN
   SUBDIRS += libstrongswan
 endif
 
-if USE_LIBHYDRA
-  SUBDIRS += libhydra
-endif
-
 if USE_LIBIPSEC
   SUBDIRS += libipsec
 endif
index 73df450..1f4033a 100644 (file)
@@ -12,7 +12,6 @@ charon-cmd.o :        $(top_builddir)/config.status
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_DIR=\"${ipsecdir}\" \
        -DIPSEC_PIDDIR=\"${piddir}\" \
@@ -20,6 +19,5 @@ AM_CPPFLAGS = \
 
 charon_cmd_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la \
        -lm $(PTHREADLIB) $(DLLIB)
index d3b31cc..f350198 100644 (file)
@@ -26,7 +26,6 @@
 #include <errno.h>
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 #include <utils/backtrace.h>
 #include <threading/thread.h>
@@ -330,11 +329,6 @@ int main(int argc, char *argv[])
                        exit(SS_RC_DAEMON_INTEGRITY);
                }
        }
-       atexit(libhydra_deinit);
-       if (!libhydra_init())
-       {
-               exit(SS_RC_INITIALIZATION_FAILED);
-       }
        atexit(libcharon_deinit);
        if (!libcharon_init())
        {
index d3630ff..b6f0c8b 100644 (file)
@@ -9,7 +9,6 @@ charon_nm_SOURCES = \
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_DIR=\"${ipsecdir}\" \
        -DIPSEC_PIDDIR=\"${piddir}\" \
@@ -21,6 +20,5 @@ AM_CFLAGS = \
 
 charon_nm_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la \
        -lm $(PTHREADLIB) $(DLLIB) ${nm_LIBS}
index fb090e5..cbbed7a 100644 (file)
@@ -20,7 +20,6 @@
 #include <unistd.h>
 #include <errno.h>
 
-#include <hydra.h>
 #include <daemon.h>
 
 #include <library.h>
@@ -177,14 +176,6 @@ int main(int argc, char *argv[])
                exit(SS_RC_DAEMON_INTEGRITY);
        }
 
-       if (!libhydra_init())
-       {
-               dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm");
-               libhydra_deinit();
-               library_deinit();
-               exit(SS_RC_INITIALIZATION_FAILED);
-       }
-
        if (!libcharon_init())
        {
                dbg_syslog(DBG_DMN, 1, "initialization failed - aborting charon-nm");
@@ -212,7 +203,6 @@ int main(int argc, char *argv[])
        {
                DBG1(DBG_DMN, "integrity tests enabled:");
                DBG1(DBG_DMN, "lib    'libstrongswan': passed file and segment integrity tests");
-               DBG1(DBG_DMN, "lib    'libhydra': passed file and segment integrity tests");
                DBG1(DBG_DMN, "lib    'libcharon': passed file and segment integrity tests");
                DBG1(DBG_DMN, "daemon 'charon-nm': passed file integrity test");
        }
@@ -260,7 +250,6 @@ int main(int argc, char *argv[])
 
 deinit:
        libcharon_deinit();
-       libhydra_deinit();
        library_deinit();
        return status;
 }
index ecccf02..c91ad08 100644 (file)
@@ -6,11 +6,9 @@ charon-svc.o : $(top_builddir)/config.status
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DPLUGINS=\""${charon_plugins}\""
 
 charon_svc_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la
index 03cbdb8..522cd12 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 
 #include <utils/backtrace.h>
@@ -210,28 +209,22 @@ static void init_and_run(DWORD dwArgc, LPTSTR *lpszArgv, int (*wait)())
                if (library_init(NULL, SERVICE_NAME))
                {
                        update_status(SERVICE_START_PENDING);
-                       if (libhydra_init())
+                       if (libcharon_init())
                        {
+                               charon->load_loggers(charon, levels, TRUE);
+                               print_version();
                                update_status(SERVICE_START_PENDING);
-                               if (libcharon_init())
+                               if (charon->initialize(charon, PLUGINS))
                                {
-                                       charon->load_loggers(charon, levels, TRUE);
-                                       print_version();
                                        update_status(SERVICE_START_PENDING);
-                                       if (charon->initialize(charon, PLUGINS))
-                                       {
-                                               update_status(SERVICE_START_PENDING);
-                                               lib->plugins->status(lib->plugins, LEVEL_CTRL);
+                                       lib->plugins->status(lib->plugins, LEVEL_CTRL);
 
-                                               charon->start(charon);
+                                       charon->start(charon);
 
-                                               status.dwWin32ExitCode = wait();
-                                       }
-                                       update_status(SERVICE_STOP_PENDING);
-                                       libcharon_deinit();
+                                       status.dwWin32ExitCode = wait();
                                }
                                update_status(SERVICE_STOP_PENDING);
-                               libhydra_deinit();
+                               libcharon_deinit();
                        }
                        update_status(SERVICE_STOP_PENDING);
                        library_deinit();
index ee85d43..9942a36 100644 (file)
@@ -7,13 +7,11 @@ charon-systemd.o :    $(top_builddir)/config.status
 
 charon_systemd_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        $(systemd_CFLAGS) $(systemd_daemon_CFLAGS) $(systemd_journal_CFLAGS) \
        -DPLUGINS=\""${charon_plugins}\""
 
 charon_systemd_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la \
        $(systemd_LIBS) $(systemd_daemon_LIBS) $(systemd_journal_LIBS) -lm $(PTHREADLIB) $(DLLIB)
index 4286cde..a83db5a 100644 (file)
@@ -31,7 +31,6 @@
 #include <systemd/sd-daemon.h>
 #include <systemd/sd-journal.h>
 
-#include <hydra.h>
 #include <daemon.h>
 
 #include <library.h>
@@ -355,12 +354,6 @@ int main(int argc, char *argv[])
                sd_notifyf(0, "STATUS=integrity check of charon-systemd failed");
                return SS_RC_INITIALIZATION_FAILED;
        }
-       atexit(libhydra_deinit);
-       if (!libhydra_init())
-       {
-               sd_notifyf(0, "STATUS=libhydra initialization failed");
-               return SS_RC_INITIALIZATION_FAILED;
-       }
        atexit(libcharon_deinit);
        if (!libcharon_init())
        {
index d2b81a3..ad54eaf 100644 (file)
@@ -4,15 +4,13 @@ OBJ = $(abs_top_builddir)/src
 AM_CPPFLAGS = \
        -include $(abs_top_builddir)/config.h \
        -I$(SRC)/libstrongswan \
-       -I$(SRC)/libhydra \
        -I$(SRC)/libcharon
 
 LIBLD = \
        -L$(OBJ)/libstrongswan/.libs \
-       -L$(OBJ)/libhydra/.libs \
        -L$(OBJ)/libcharon/.libs
-LIBPT = $(OBJ)/libstrongswan/.libs:$(OBJ)/libhydra/.libs:$(OBJ)/libcharon/.libs
-LIBFL = -lstrongswan -lhydra -lcharon
+LIBPT = $(OBJ)/libstrongswan/.libs:$(OBJ)/libcharon/.libs
+LIBFL = -lstrongswan -lcharon
 
 DEFS += -DPLUGINS=\""$(PLUGINS)\"" -DIPSEC_PIDDIR=\"${piddir}\"
 
index 3923c8a..13352e5 100644 (file)
@@ -26,7 +26,6 @@
 #include <libgen.h>
 #include <errno.h>
 
-#include <hydra.h>
 #include <daemon.h>
 #include <library.h>
 #include <utils/backtrace.h>
@@ -256,14 +255,6 @@ int main(int argc, char *argv[])
                exit(status);
        }
 
-       if (!libhydra_init())
-       {
-               dbg_syslog(DBG_DMN, 1, "initialization failed - aborting %s", dmn_name);
-               libhydra_deinit();
-               library_deinit();
-               exit(status);
-       }
-
        if (!libcharon_init())
        {
                dbg_syslog(DBG_DMN, 1, "initialization failed - aborting %s", dmn_name);
@@ -391,7 +382,6 @@ int main(int argc, char *argv[])
 deinit:
        destroy_dh_mapping();
        libcharon_deinit();
-       libhydra_deinit();
        library_deinit();
        tkm_deinit();
        return status;
index 74c0d36..f4107d9 100644 (file)
@@ -14,7 +14,7 @@
  * for more details.
  */
 
-#include <hydra.h>
+#include <daemon.h>
 #include <utils/debug.h>
 #include <tkm/constants.h>
 #include <tkm/types.h>
@@ -25,8 +25,7 @@
 void charon_esa_acquire(result_type *res, const sp_id_type sp_id)
 {
        DBG1(DBG_KNL, "ees: acquire received for reqid %u", sp_id);
-       hydra->kernel_interface->acquire(hydra->kernel_interface, sp_id, NULL,
-                                                                        NULL);
+       charon->kernel->acquire(charon->kernel, sp_id, NULL, NULL);
        *res = TKM_OK;
 }
 
@@ -47,6 +46,5 @@ void charon_esa_expire(result_type *res, const sp_id_type sp_id,
 
        DBG1(DBG_KNL, "ees: expire received for reqid %u, spi %x, dst %H", sp_id,
                 ntohl(spi_rem), dst);
-       hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
-                                                                       spi_rem, dst, hard != 0);
+       charon->kernel->expire(charon->kernel, protocol, spi_rem, dst, hard != 0);
 }
index d087bee..8bba1f9 100644 (file)
@@ -17,7 +17,6 @@
 #include <tests/test_suite.h>
 
 #include <daemon.h>
-#include <hydra.h>
 #include <config/proposal.h>
 #include <encoding/payloads/ike_header.h>
 #include <tkm/client.h>
index ac152b6..e3cd2d9 100644 (file)
@@ -18,7 +18,6 @@
 #include <tests/test_runner.h>
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 
 #include "tkm.h"
@@ -50,7 +49,6 @@ static bool test_runner_init(bool init)
 
        if (init)
        {
-               libhydra_init();
                libcharon_init();
                lib->settings->set_int(lib->settings,
                                                           "test-runner.filelog.stdout.default", 0);
@@ -74,8 +72,6 @@ static bool test_runner_init(bool init)
 
                plugin_loader_add_plugindirs(BUILDDIR "/src/libstrongswan/plugins",
                                                                         PLUGINS);
-               plugin_loader_add_plugindirs(BUILDDIR "/src/libhydra/plugins",
-                                                                        PLUGINS);
                plugin_loader_add_plugindirs(BUILDDIR "/src/libcharon/plugins",
                                                                         PLUGINS);
                if (charon->initialize(charon, PLUGINS))
@@ -95,7 +91,6 @@ static bool test_runner_init(bool init)
 
        destroy_dh_mapping();
        libcharon_deinit();
-       libhydra_deinit();
        return result;
 }
 
index 852d73c..92a0270 100644 (file)
@@ -8,7 +8,6 @@ charon.c
 # build charon -----------------------------------------------------------------
 
 LOCAL_C_INCLUDES += \
-       $(strongswan_PATH)/src/libhydra \
        $(strongswan_PATH)/src/libcharon \
        $(strongswan_PATH)/src/libstrongswan
 
@@ -23,7 +22,7 @@ LOCAL_ARM_MODE := arm
 
 LOCAL_PRELINK_MODULE := false
 
-LOCAL_SHARED_LIBRARIES += libstrongswan libhydra libcharon
+LOCAL_SHARED_LIBRARIES += libstrongswan libcharon
 
 include $(BUILD_EXECUTABLE)
 
index 6c5b88e..c6a6f40 100644 (file)
@@ -7,7 +7,6 @@ charon.o :      $(top_builddir)/config.status
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_DIR=\"${ipsecdir}\" \
        -DIPSEC_PIDDIR=\"${piddir}\" \
@@ -15,7 +14,6 @@ AM_CPPFLAGS = \
 
 charon_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la \
        -lm $(PTHREADLIB) $(DLLIB)
 
index 4c2a9a4..116ce7e 100644 (file)
@@ -27,7 +27,6 @@
 #include <fcntl.h>
 #include <errno.h>
 
-#include <hydra.h>
 #include <daemon.h>
 
 #include <library.h>
@@ -309,14 +308,6 @@ int main(int argc, char *argv[])
                exit(SS_RC_DAEMON_INTEGRITY);
        }
 
-       if (!libhydra_init())
-       {
-               dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon");
-               libhydra_deinit();
-               library_deinit();
-               exit(SS_RC_INITIALIZATION_FAILED);
-       }
-
        if (!libcharon_init())
        {
                dbg_stderr(DBG_DMN, 1, "initialization failed - aborting charon");
@@ -403,7 +394,6 @@ int main(int argc, char *argv[])
        {
                DBG1(DBG_DMN, "integrity tests enabled:");
                DBG1(DBG_DMN, "lib    'libstrongswan': passed file and segment integrity tests");
-               DBG1(DBG_DMN, "lib    'libhydra': passed file and segment integrity tests");
                DBG1(DBG_DMN, "lib    'libcharon': passed file and segment integrity tests");
                DBG1(DBG_DMN, "daemon 'charon': passed file integrity test");
        }
@@ -457,7 +447,6 @@ int main(int argc, char *argv[])
 
 deinit:
        libcharon_deinit();
-       libhydra_deinit();
        library_deinit();
        return status;
 }
index b358699..9cc5fb6 100644 (file)
@@ -8,7 +8,6 @@ EXTRA_PROGRAMS = checksum_builder
 checksum_builder_SOURCES = checksum_builder.c
 checksum_builder_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la \
        $(DLLIB)
 checksum_builder_LDFLAGS = -rpath '$(DESTDIR)$(ipseclibdir)'
@@ -17,7 +16,6 @@ CLEANFILES = checksum.c $(EXTRA_PROGRAMS)
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DPLUGINDIR=\"${DESTDIR}${plugindir}\"
 
@@ -35,14 +33,6 @@ if !MONOLITHIC
   AM_CPPFLAGS += -DS_PLUGINS=\""${s_plugins}\""
 endif
 
-if USE_LIBHYDRA
-  deps += $(top_builddir)/src/libhydra/libhydra.la
-  libs += $(DESTDIR)$(ipseclibdir)/libhydra.so
-if !MONOLITHIC
-  AM_CPPFLAGS += -DH_PLUGINS=\""${h_plugins}\""
-endif
-endif
-
 if USE_LIBIPSEC
   deps += $(top_builddir)/src/libipsec/libipsec.la
   libs += $(DESTDIR)$(ipseclibdir)/libipsec.so
index cc8185e..65399f5 100644 (file)
@@ -19,7 +19,6 @@
 #include <dlfcn.h>
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 #include <collections/enumerator.h>
 
@@ -128,9 +127,8 @@ int main(int argc, char* argv[])
 {
        int i;
 
-       /* forces link against libhydra/libcharon, imports symbols needed to
+       /* forces link against libcharon, imports symbols needed to
         * dlopen plugins */
-       hydra = NULL;
        charon = NULL;
 
        /* avoid confusing leak reports in build process */
@@ -159,9 +157,6 @@ int main(int argc, char* argv[])
 #ifdef S_PLUGINS
        build_plugin_checksums(S_PLUGINS);
 #endif
-#ifdef H_PLUGINS
-       build_plugin_checksums(H_PLUGINS);
-#endif
 #ifdef T_PLUGINS
        build_plugin_checksums(T_PLUGINS);
 #endif
index eeb26f2..2d4e439 100644 (file)
@@ -2,7 +2,6 @@ ipsec_PROGRAMS = conftest
 
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DPLUGINS=\""${charon_plugins}\""
 
@@ -20,7 +19,6 @@ conftest_SOURCES = conftest.c conftest.h config.c config.h actions.c actions.h \
 
 conftest_LDADD = \
        $(top_builddir)/src/libstrongswan/libstrongswan.la \
-       $(top_builddir)/src/libhydra/libhydra.la \
        $(top_builddir)/src/libcharon/libcharon.la \
        -lm $(PTHREADLIB) $(DLLIB)
 
index edfe0ca..d10f3c7 100644 (file)
@@ -356,7 +356,6 @@ static void cleanup()
        free(conftest->suite_dir);
        free(conftest);
        libcharon_deinit();
-       libhydra_deinit();
        library_deinit();
 }
 
@@ -442,16 +441,9 @@ int main(int argc, char *argv[])
                library_deinit();
                return SS_RC_LIBSTRONGSWAN_INTEGRITY;
        }
-       if (!libhydra_init())
-       {
-               libhydra_deinit();
-               library_deinit();
-               return SS_RC_INITIALIZATION_FAILED;
-       }
        if (!libcharon_init())
        {
                libcharon_deinit();
-               libhydra_deinit();
                library_deinit();
                return SS_RC_INITIALIZATION_FAILED;
        }
index 6bbdabd..2d03204 100644 (file)
@@ -21,7 +21,6 @@
 #define CONFTEST_H_
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 #include <credentials/sets/mem_cred.h>
 
index e5241d5..84c44c1 100644 (file)
@@ -848,7 +848,6 @@ public class CharonVpnService extends VpnService implements Runnable
                                System.loadLibrary("imcv");
                        }
 
-                       System.loadLibrary("hydra");
                        System.loadLibrary("charon");
                        System.loadLibrary("ipsec");
                }
index d2c6480..b295320 100644 (file)
@@ -71,7 +71,6 @@ strongswan_BUILD := \
        libandroidbridge \
        strongswan/src/libipsec \
        strongswan/src/libcharon \
-       strongswan/src/libhydra \
        strongswan/src/libstrongswan
 
 ifneq ($(strongswan_USE_BYOD),)
index c56b8d5..31eb27f 100644 (file)
@@ -25,7 +25,6 @@ endif
 
 LOCAL_C_INCLUDES += \
        $(strongswan_PATH)/src/libipsec \
-       $(strongswan_PATH)/src/libhydra \
        $(strongswan_PATH)/src/libcharon \
        $(strongswan_PATH)/src/libstrongswan
 
@@ -54,7 +53,7 @@ LOCAL_PRELINK_MODULE := false
 
 LOCAL_LDLIBS := -llog
 
-LOCAL_SHARED_LIBRARIES := libstrongswan libhydra libipsec libcharon
+LOCAL_SHARED_LIBRARIES := libstrongswan libipsec libcharon
 
 ifneq ($(strongswan_USE_BYOD),)
 LOCAL_SHARED_LIBRARIES += libimcv libtncif libtnccs
index a6412bd..eaba85d 100644 (file)
@@ -37,7 +37,6 @@ static struct {
        { "libtnccs.so", NULL },
        { "libimcv.so", NULL },
 #endif
-       { "libhydra.so", NULL },
        { "libcharon.so", NULL },
        { "libipsec.so", NULL },
 };
index 908e372..7d71da2 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "android_dns_proxy.h"
 
-#include <hydra.h>
+#include <daemon.h>
 #include <threading/rwlock.h>
 #include <collections/hashtable.h>
 #include <processing/jobs/callback_job.h>
@@ -121,8 +121,7 @@ static int open_socket(int family)
                DBG1(DBG_NET, "could not open proxy socket: %s", strerror(errno));
                return -1;
        }
-       if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface,
-                                                                                               skt, family))
+       if (!charon->kernel->bypass_socket(charon->kernel, skt, family))
        {
                DBG1(DBG_NET, "installing bypass policy for proxy socket failed");
                close(skt);
index 2655f73..3bed6eb 100644 (file)
@@ -35,7 +35,6 @@
 #endif
 
 #include <daemon.h>
-#include <hydra.h>
 #include <ipsec.h>
 #include <library.h>
 #include <threading/thread.h>
@@ -606,17 +605,9 @@ JNI_METHOD(CharonVpnService, initializeCharon, jboolean,
        set_options(logfile);
        free(logfile);
 
-       if (!libhydra_init())
-       {
-               libhydra_deinit();
-               library_deinit();
-               return FALSE;
-       }
-
        if (!libipsec_init())
        {
                libipsec_deinit();
-               libhydra_deinit();
                library_deinit();
                return FALSE;
        }
@@ -625,7 +616,6 @@ JNI_METHOD(CharonVpnService, initializeCharon, jboolean,
        {
                libcharon_deinit();
                libipsec_deinit();
-               libhydra_deinit();
                library_deinit();
                return FALSE;
        }
@@ -657,7 +647,6 @@ JNI_METHOD(CharonVpnService, initializeCharon, jboolean,
                libcharon_deinit();
                charonservice_deinit(env);
                libipsec_deinit();
-               libhydra_deinit();
                library_deinit();
                return FALSE;
        }
@@ -687,7 +676,6 @@ JNI_METHOD(CharonVpnService, deinitializeCharon, void)
        libcharon_deinit();
        charonservice_deinit(env);
        libipsec_deinit();
-       libhydra_deinit();
        library_deinit();
 }
 
index 1eb6084..a740303 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <utils/debug.h>
 #include <library.h>
-#include <hydra.h>
+#include <daemon.h>
 #include <ipsec.h>
 
 typedef struct private_kernel_android_ipsec_t private_kernel_android_ipsec_t;
@@ -42,8 +42,7 @@ struct private_kernel_android_ipsec_t {
  */
 static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
 {
-       hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
-                                                                       spi, dst, hard);
+       charon->kernel->expire(charon->kernel, protocol, spi, dst, hard);
 }
 
 METHOD(kernel_ipsec_t, get_spi, status_t,
index 2ce1bdf..acc4b75 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "../android_jni.h"
 #include "../charonservice.h"
-#include <hydra.h>
+#include <daemon.h>
 #include <processing/jobs/callback_job.h>
 #include <threading/mutex.h>
 
@@ -75,7 +75,7 @@ static job_requeue_t roam_event()
 {
        /* this will fail if no connection is up */
        charonservice->bypass_socket(charonservice, -1, 0);
-       hydra->kernel_interface->roam(hydra->kernel_interface, TRUE);
+       charon->kernel->roam(charon->kernel, TRUE);
        return JOB_REQUEUE_NONE;
 }
 
index 0d8f0f4..14ce2e2 100644 (file)
@@ -22,7 +22,6 @@
 #include <errno.h>
 
 #include <library.h>
-#include <hydra.h>
 #include <daemon.h>
 #include <threading/thread.h>
 #include <utils/backtrace.h>
@@ -170,11 +169,6 @@ int main(int argc, char *argv[])
                        exit(SS_RC_DAEMON_INTEGRITY);
                }
        }
-       atexit(libhydra_deinit);
-       if (!libhydra_init())
-       {
-               exit(SS_RC_INITIALIZATION_FAILED);
-       }
        atexit(libcharon_deinit);
        if (!libcharon_init())
        {
index e5f2228..90e2335 100644 (file)
                                        /usr/include,
                                        ../../libstrongswan,
                                        ../../libcharon,
-                                       ../../libhydra,
                                );
                                INFOPLIST_FILE = "charon-xpc/charon-xpc-Info.plist";
                                INSTALL_PATH = /;
                                        /usr/lib,
                                        ../../libstrongswan/.libs,
                                        ../../libcharon/.libs,
-                                       ../../libhydra/.libs,
                                );
                                MACOSX_DEPLOYMENT_TARGET = 10.7;
                                OTHER_CFLAGS = (
                                        "-force_load",
                                        ../../libipsec/.libs/libipsec.a,
                                        "-force_load",
-                                       ../../libhydra/.libs/libhydra.a,
-                                       "-force_load",
                                        ../../libcharon/.libs/libcharon.a,
                                        "-sectcreate",
                                        __TEXT,
                                        /usr/include,
                                        ../../libstrongswan,
                                        ../../libcharon,
-                                       ../../libhydra,
                                );
                                INFOPLIST_FILE = "charon-xpc/charon-xpc-Info.plist";
                                INSTALL_PATH = /;
                                        /usr/lib,
                                        ../../libstrongswan/.libs,
                                        ../../libcharon/.libs,
-                                       ../../libhydra/.libs,
                                );
                                MACOSX_DEPLOYMENT_TARGET = 10.7;
                                OTHER_CFLAGS = (
                                        "-force_load",
                                        ../../libipsec/.libs/libipsec.a,
                                        "-force_load",
-                                       ../../libhydra/.libs/libhydra.a,
-                                       "-force_load",
                                        ../../libcharon/.libs/libcharon.a,
                                        "-sectcreate",
                                        __TEXT,
index 1008579..844bbfd 100644 (file)
@@ -47,7 +47,10 @@ encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \
 encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \
 encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \
 encoding/payloads/fragment_payload.c encoding/payloads/fragment_payload.h \
-kernel/kernel_handler.c kernel/kernel_handler.h \
+kernel/kernel_interface.c kernel/kernel_interface.h \
+kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
+kernel/kernel_net.c kernel/kernel_net.h \
+kernel/kernel_listener.h kernel/kernel_handler.c kernel/kernel_handler.h \
 network/receiver.c network/receiver.h network/sender.c network/sender.h \
 network/socket.c network/socket.h \
 network/socket_manager.c network/socket_manager.h \
@@ -216,6 +219,10 @@ endif
 
 LOCAL_SRC_FILES += $(call add_plugin, load-tester)
 
+LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey)
+
+LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink)
+
 LOCAL_SRC_FILES += $(call add_plugin, socket-default)
 
 LOCAL_SRC_FILES += $(call add_plugin, socket-dynamic)
@@ -228,7 +235,6 @@ endif
 # build libcharon --------------------------------------------------------------
 
 LOCAL_C_INCLUDES += \
-       $(strongswan_PATH)/src/libhydra \
        $(strongswan_PATH)/src/libstrongswan
 
 LOCAL_CFLAGS := $(strongswan_CFLAGS)
@@ -241,6 +247,6 @@ LOCAL_ARM_MODE := arm
 
 LOCAL_PRELINK_MODULE := false
 
-LOCAL_SHARED_LIBRARIES += libstrongswan libhydra
+LOCAL_SHARED_LIBRARIES += libstrongswan
 
 include $(BUILD_SHARED_LIBRARY)
index 66fce81..4de8faa 100644 (file)
@@ -46,7 +46,10 @@ encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \
 encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \
 encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \
 encoding/payloads/fragment_payload.c encoding/payloads/fragment_payload.h \
-kernel/kernel_handler.c kernel/kernel_handler.h \
+kernel/kernel_interface.c kernel/kernel_interface.h \
+kernel/kernel_ipsec.c kernel/kernel_ipsec.h \
+kernel/kernel_net.c kernel/kernel_net.h \
+kernel/kernel_listener.h kernel/kernel_handler.c kernel/kernel_handler.h \
 network/receiver.c network/receiver.h network/sender.c network/sender.h \
 network/socket.c network/socket.h \
 network/socket_manager.c network/socket_manager.h \
@@ -143,7 +146,6 @@ daemon.lo :         $(top_builddir)/config.status
 AM_CPPFLAGS = \
        -I${linux_headers} \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_DIR=\"${ipsecdir}\" \
        -DIPSEC_PIDDIR=\"${piddir}\"
@@ -153,7 +155,6 @@ AM_LDFLAGS = \
 
 libcharon_la_LIBADD = \
   $(top_builddir)/src/libstrongswan/libstrongswan.la \
-  $(top_builddir)/src/libhydra/libhydra.la \
   -lm $(PTHREADLIB) $(DLLIB) $(SOCKLIB)
 
 if USE_WINDOWS
@@ -512,6 +513,27 @@ if MONOLITHIC
 endif
 endif
 
+if USE_KERNEL_PFKEY
+  SUBDIRS += plugins/kernel_pfkey
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la
+endif
+endif
+
+if USE_KERNEL_PFROUTE
+  SUBDIRS += plugins/kernel_pfroute
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la
+endif
+endif
+
+if USE_KERNEL_NETLINK
+  SUBDIRS += plugins/kernel_netlink
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/kernel_netlink/libstrongswan-kernel-netlink.la
+endif
+endif
+
 if USE_KERNEL_LIBIPSEC
   SUBDIRS += plugins/kernel_libipsec
 if MONOLITHIC
index 2796682..833c3e9 100644 (file)
@@ -17,7 +17,6 @@
 #include "mem_pool.h"
 
 #include <library.h>
-#include <hydra.h>
 #include <utils/debug.h>
 #include <collections/hashtable.h>
 #include <collections/array.h>
index f861460..799c3f6 100644 (file)
@@ -685,6 +685,7 @@ static void destroy(private_daemon_t *this)
        DESTROY_IF(this->public.xauth);
        DESTROY_IF(this->public.backends);
        DESTROY_IF(this->public.socket);
+       DESTROY_IF(this->public.kernel);
 
        /* rehook library logging, shutdown logging */
        dbg = dbg_old;
@@ -862,6 +863,7 @@ private_daemon_t *daemon_create()
                .ref = 1,
        );
        charon = &this->public;
+       this->public.kernel = kernel_interface_create();
        this->public.attributes = attribute_manager_create();
        this->public.controller = controller_create();
        this->public.eap = eap_manager_create();
index 0b66ea3..654e22a 100644 (file)
@@ -63,7 +63,7 @@
  * @defgroup payloads payloads
  * @ingroup encoding
  *
- * @defgroup ckernel kernel
+ * @defgroup kernel kernel
  * @ingroup libcharon
  *
  * @defgroup network network
 typedef struct daemon_t daemon_t;
 
 #include <attributes/attribute_manager.h>
+#include <kernel/kernel_interface.h>
 #include <network/sender.h>
 #include <network/receiver.h>
 #include <network/socket_manager.h>
@@ -239,6 +240,11 @@ struct daemon_t {
        socket_manager_t *socket;
 
        /**
+        * Kernel interface to communicate with kernel
+        */
+       kernel_interface_t *kernel;
+
+       /**
         * A ike_sa_manager_t instance.
         */
        ike_sa_manager_t *ike_sa_manager;
index 9c0e260..be37d30 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "kernel_handler.h"
 
-#include <hydra.h>
 #include <daemon.h>
 #include <processing/jobs/acquire_job.h>
 #include <processing/jobs/delete_child_sa_job.h>
@@ -135,8 +134,7 @@ METHOD(kernel_listener_t, roam, bool,
 METHOD(kernel_handler_t, destroy, void,
        private_kernel_handler_t *this)
 {
-       hydra->kernel_interface->remove_listener(hydra->kernel_interface,
-                                                                                        &this->public.listener);
+       charon->kernel->remove_listener(charon->kernel, &this->public.listener);
        free(this);
 }
 
@@ -157,8 +155,7 @@ kernel_handler_t *kernel_handler_create()
                },
        );
 
-       hydra->kernel_interface->add_listener(hydra->kernel_interface,
-                                                                                 &this->public.listener);
+       charon->kernel->add_listener(charon->kernel, &this->public.listener);
 
        return &this->public;
 }
index 48ad688..f1fa0bd 100644 (file)
@@ -15,7 +15,7 @@
 
 /**
  * @defgroup kernel_handler kernel_handler
- * @{ @ingroup ckernel
+ * @{ @ingroup kernel
  */
 
 #ifndef KERNEL_HANDLER_H_
diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c
new file mode 100644 (file)
index 0000000..40c4ee5
--- /dev/null
@@ -0,0 +1,1085 @@
+/*
+ * Copyright (C) 2008-2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2010 Martin Willi
+ * Copyright (C) 2010 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/*
+ * Copyright (c) 2012 Nanoteq Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "kernel_interface.h"
+
+#include <utils/debug.h>
+#include <threading/mutex.h>
+#include <collections/linked_list.h>
+#include <collections/hashtable.h>
+#include <collections/array.h>
+
+typedef struct private_kernel_interface_t private_kernel_interface_t;
+
+typedef struct kernel_algorithm_t kernel_algorithm_t;
+
+/**
+ * Mapping of IKE algorithms to kernel-specific algorithm identifiers
+ */
+struct kernel_algorithm_t {
+
+       /**
+        * Transform type of the algorithm
+        */
+       transform_type_t type;
+
+       /**
+        * Identifier specified in IKE
+        */
+       u_int16_t ike;
+
+       /**
+        * Identifier as defined in pfkeyv2.h
+        */
+       u_int16_t kernel;
+
+       /**
+        * Name of the algorithm in linux crypto API
+        */
+       char *name;
+};
+
+/**
+ * Private data of a kernel_interface_t object.
+ */
+struct private_kernel_interface_t {
+
+       /**
+        * Public part of kernel_interface_t object.
+        */
+       kernel_interface_t public;
+
+       /**
+        * Registered IPsec constructor
+        */
+       kernel_ipsec_constructor_t ipsec_constructor;
+
+       /**
+        * Registered net constructor
+        */
+       kernel_net_constructor_t net_constructor;
+
+       /**
+        * ipsec interface
+        */
+       kernel_ipsec_t *ipsec;
+
+       /**
+        * network interface
+        */
+       kernel_net_t *net;
+
+       /**
+        * mutex for listeners
+        */
+       mutex_t *mutex;
+
+       /**
+        * list of registered listeners
+        */
+       linked_list_t *listeners;
+
+       /**
+        * Reqid entries indexed by reqids
+        */
+       hashtable_t *reqids;
+
+       /**
+        * Reqid entries indexed by traffic selectors
+        */
+       hashtable_t *reqids_by_ts;
+
+       /**
+        * mutex for algorithm mappings
+        */
+       mutex_t *mutex_algs;
+
+       /**
+        * List of algorithm mappings (kernel_algorithm_t*)
+        */
+       linked_list_t *algorithms;
+
+       /**
+        * List of interface names to include or exclude (char*), NULL if interfaces
+        * are not filtered
+        */
+       linked_list_t *ifaces_filter;
+
+       /**
+        * TRUE to exclude interfaces listed in ifaces_filter, FALSE to consider
+        * only those listed there
+        */
+       bool ifaces_exclude;
+};
+
+METHOD(kernel_interface_t, get_features, kernel_feature_t,
+       private_kernel_interface_t *this)
+{
+       kernel_feature_t features = 0;
+
+       if (this->ipsec && this->ipsec->get_features)
+       {
+               features |= this->ipsec->get_features(this->ipsec);
+       }
+       if (this->net && this->net->get_features)
+       {
+               features |= this->net->get_features(this->net);
+       }
+       return features;
+}
+
+METHOD(kernel_interface_t, get_spi, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       u_int8_t protocol, u_int32_t *spi)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->get_spi(this->ipsec, src, dst, protocol, spi);
+}
+
+METHOD(kernel_interface_t, get_cpi, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       u_int16_t *cpi)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->get_cpi(this->ipsec, src, dst, cpi);
+}
+
+/**
+ * Reqid mapping entry
+ */
+typedef struct {
+       /** allocated reqid */
+       u_int32_t reqid;
+       /** references to this entry */
+       u_int refs;
+       /** inbound mark used for SA */
+       mark_t mark_in;
+       /** outbound mark used for SA */
+       mark_t mark_out;
+       /** local traffic selectors */
+       array_t *local;
+       /** remote traffic selectors */
+       array_t *remote;
+} reqid_entry_t;
+
+/**
+ * Destroy a reqid mapping entry
+ */
+static void reqid_entry_destroy(reqid_entry_t *entry)
+{
+       array_destroy_offset(entry->local, offsetof(traffic_selector_t, destroy));
+       array_destroy_offset(entry->remote, offsetof(traffic_selector_t, destroy));
+       free(entry);
+}
+
+/**
+ * Hashtable hash function for reqid entries using reqid as key
+ */
+static u_int hash_reqid(reqid_entry_t *entry)
+{
+       return chunk_hash_inc(chunk_from_thing(entry->reqid),
+                               chunk_hash_inc(chunk_from_thing(entry->mark_in),
+                                       chunk_hash(chunk_from_thing(entry->mark_out))));
+}
+
+/**
+ * Hashtable equals function for reqid entries using reqid as key
+ */
+static bool equals_reqid(reqid_entry_t *a, reqid_entry_t *b)
+{
+       return a->reqid == b->reqid &&
+                  a->mark_in.value == b->mark_in.value &&
+                  a->mark_in.mask == b->mark_in.mask &&
+                  a->mark_out.value == b->mark_out.value &&
+                  a->mark_out.mask == b->mark_out.mask;
+}
+
+/**
+ * Hash an array of traffic selectors
+ */
+static u_int hash_ts_array(array_t *array, u_int hash)
+{
+       enumerator_t *enumerator;
+       traffic_selector_t *ts;
+
+       enumerator = array_create_enumerator(array);
+       while (enumerator->enumerate(enumerator, &ts))
+       {
+               hash = ts->hash(ts, hash);
+       }
+       enumerator->destroy(enumerator);
+
+       return hash;
+}
+
+/**
+ * Hashtable hash function for reqid entries using traffic selectors as key
+ */
+static u_int hash_reqid_by_ts(reqid_entry_t *entry)
+{
+       return hash_ts_array(entry->local, hash_ts_array(entry->remote,
+                       chunk_hash_inc(chunk_from_thing(entry->mark_in),
+                               chunk_hash(chunk_from_thing(entry->mark_out)))));
+}
+
+/**
+ * Compare two array with traffic selectors for equality
+ */
+static bool ts_array_equals(array_t *a, array_t *b)
+{
+       traffic_selector_t *tsa, *tsb;
+       enumerator_t *ae, *be;
+       bool equal = TRUE;
+
+       if (array_count(a) != array_count(b))
+       {
+               return FALSE;
+       }
+
+       ae = array_create_enumerator(a);
+       be = array_create_enumerator(b);
+       while (equal && ae->enumerate(ae, &tsa) && be->enumerate(be, &tsb))
+       {
+               equal = tsa->equals(tsa, tsb);
+       }
+       ae->destroy(ae);
+       be->destroy(be);
+
+       return equal;
+}
+
+/**
+ * Hashtable equals function for reqid entries using traffic selectors as key
+ */
+static bool equals_reqid_by_ts(reqid_entry_t *a, reqid_entry_t *b)
+{
+       return ts_array_equals(a->local, b->local) &&
+                  ts_array_equals(a->remote, b->remote) &&
+                  a->mark_in.value == b->mark_in.value &&
+                  a->mark_in.mask == b->mark_in.mask &&
+                  a->mark_out.value == b->mark_out.value &&
+                  a->mark_out.mask == b->mark_out.mask;
+}
+
+/**
+ * Create an array from copied traffic selector list items
+ */
+static array_t *array_from_ts_list(linked_list_t *list)
+{
+       enumerator_t *enumerator;
+       traffic_selector_t *ts;
+       array_t *array;
+
+       array = array_create(0, 0);
+
+       enumerator = list->create_enumerator(list);
+       while (enumerator->enumerate(enumerator, &ts))
+       {
+               array_insert(array, ARRAY_TAIL, ts->clone(ts));
+       }
+       enumerator->destroy(enumerator);
+
+       return array;
+}
+
+METHOD(kernel_interface_t, alloc_reqid, status_t,
+       private_kernel_interface_t *this,
+       linked_list_t *local_ts, linked_list_t *remote_ts,
+       mark_t mark_in, mark_t mark_out, u_int32_t *reqid)
+{
+       static u_int32_t counter = 0;
+       reqid_entry_t *entry = NULL, *tmpl;
+       status_t status = SUCCESS;
+
+       INIT(tmpl,
+               .local = array_from_ts_list(local_ts),
+               .remote = array_from_ts_list(remote_ts),
+               .mark_in = mark_in,
+               .mark_out = mark_out,
+               .reqid = *reqid,
+       );
+
+       this->mutex->lock(this->mutex);
+       if (tmpl->reqid)
+       {
+               /* search by reqid if given */
+               entry = this->reqids->get(this->reqids, tmpl);
+       }
+       if (entry)
+       {
+               /* we don't require a traffic selector match for explicit reqids,
+                * as we wan't to reuse a reqid for trap-triggered policies that
+                * got narrowed during negotiation. */
+               reqid_entry_destroy(tmpl);
+       }
+       else
+       {
+               /* search by traffic selectors */
+               entry = this->reqids_by_ts->get(this->reqids_by_ts, tmpl);
+               if (entry)
+               {
+                       reqid_entry_destroy(tmpl);
+               }
+               else
+               {
+                       /* none found, create a new entry, allocating a reqid */
+                       entry = tmpl;
+                       entry->reqid = ++counter;
+                       this->reqids_by_ts->put(this->reqids_by_ts, entry, entry);
+                       this->reqids->put(this->reqids, entry, entry);
+               }
+               *reqid = entry->reqid;
+       }
+       entry->refs++;
+       this->mutex->unlock(this->mutex);
+
+       return status;
+}
+
+METHOD(kernel_interface_t, release_reqid, status_t,
+       private_kernel_interface_t *this, u_int32_t reqid,
+       mark_t mark_in, mark_t mark_out)
+{
+       reqid_entry_t *entry, tmpl = {
+               .reqid = reqid,
+               .mark_in = mark_in,
+               .mark_out = mark_out,
+       };
+
+       this->mutex->lock(this->mutex);
+       entry = this->reqids->remove(this->reqids, &tmpl);
+       if (entry)
+       {
+               if (--entry->refs == 0)
+               {
+                       entry = this->reqids_by_ts->remove(this->reqids_by_ts, entry);
+                       if (entry)
+                       {
+                               reqid_entry_destroy(entry);
+                       }
+               }
+               else
+               {
+                       this->reqids->put(this->reqids, entry, entry);
+               }
+       }
+       this->mutex->unlock(this->mutex);
+
+       if (entry)
+       {
+               return SUCCESS;
+       }
+       return NOT_FOUND;
+}
+
+METHOD(kernel_interface_t, add_sa, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       u_int32_t spi, u_int8_t protocol, u_int32_t reqid, mark_t mark,
+       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, bool update,
+       linked_list_t *src_ts, linked_list_t *dst_ts)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
+                               mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode,
+                               ipcomp, cpi, replay_window, initiator, encap, esn, inbound,
+                               update, src_ts, dst_ts);
+}
+
+METHOD(kernel_interface_t, update_sa, status_t,
+       private_kernel_interface_t *this, u_int32_t spi, u_int8_t protocol,
+       u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
+       bool encap, bool new_encap, mark_t mark)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst,
+                                                                 new_src, new_dst, encap, new_encap, mark);
+}
+
+METHOD(kernel_interface_t, query_sa, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       u_int32_t spi, u_int8_t protocol, mark_t mark,
+       u_int64_t *bytes, u_int64_t *packets, time_t *time)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark,
+                                                                bytes, packets, time);
+}
+
+METHOD(kernel_interface_t, del_sa, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi,
+       u_int8_t protocol, u_int16_t cpi, mark_t mark)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark);
+}
+
+METHOD(kernel_interface_t, flush_sas, status_t,
+       private_kernel_interface_t *this)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->flush_sas(this->ipsec);
+}
+
+METHOD(kernel_interface_t, add_policy, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
+       mark_t mark, policy_priority_t priority)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts,
+                                                                  direction, type, sa, mark, priority);
+}
+
+METHOD(kernel_interface_t, query_policy, status_t,
+       private_kernel_interface_t *this, traffic_selector_t *src_ts,
+       traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
+       time_t *use_time)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts,
+                                                                        direction, mark, use_time);
+}
+
+METHOD(kernel_interface_t, del_policy, status_t,
+       private_kernel_interface_t *this, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, policy_type_t type, ipsec_sa_cfg_t *sa,
+       mark_t mark, policy_priority_t priority)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->del_policy(this->ipsec, src, dst, src_ts, dst_ts,
+                                                                  direction, type, sa, mark, priority);
+}
+
+METHOD(kernel_interface_t, flush_policies, status_t,
+       private_kernel_interface_t *this)
+{
+       if (!this->ipsec)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->ipsec->flush_policies(this->ipsec);
+}
+
+METHOD(kernel_interface_t, get_source_addr, host_t*,
+       private_kernel_interface_t *this, host_t *dest, host_t *src)
+{
+       if (!this->net)
+       {
+               return NULL;
+       }
+       return this->net->get_source_addr(this->net, dest, src);
+}
+
+METHOD(kernel_interface_t, get_nexthop, host_t*,
+       private_kernel_interface_t *this, host_t *dest, int prefix, host_t *src)
+{
+       if (!this->net)
+       {
+               return NULL;
+       }
+       return this->net->get_nexthop(this->net, dest, prefix, src);
+}
+
+METHOD(kernel_interface_t, get_interface, bool,
+       private_kernel_interface_t *this, host_t *host, char **name)
+{
+       if (!this->net)
+       {
+               return NULL;
+       }
+       return this->net->get_interface(this->net, host, name);
+}
+
+METHOD(kernel_interface_t, create_address_enumerator, enumerator_t*,
+       private_kernel_interface_t *this, kernel_address_type_t which)
+{
+       if (!this->net)
+       {
+               return enumerator_create_empty();
+       }
+       return this->net->create_address_enumerator(this->net, which);
+}
+
+METHOD(kernel_interface_t, add_ip, status_t,
+       private_kernel_interface_t *this, host_t *virtual_ip, int prefix,
+       char *iface)
+{
+       if (!this->net)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->net->add_ip(this->net, virtual_ip, prefix, iface);
+}
+
+METHOD(kernel_interface_t, del_ip, status_t,
+       private_kernel_interface_t *this, host_t *virtual_ip, int prefix, bool wait)
+{
+       if (!this->net)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->net->del_ip(this->net, virtual_ip, prefix, wait);
+}
+
+METHOD(kernel_interface_t, add_route, status_t,
+       private_kernel_interface_t *this, chunk_t dst_net,
+       u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
+{
+       if (!this->net)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->net->add_route(this->net, dst_net, prefixlen, gateway,
+                                                               src_ip, if_name);
+}
+
+METHOD(kernel_interface_t, del_route, status_t,
+       private_kernel_interface_t *this, chunk_t dst_net,
+       u_int8_t prefixlen, host_t *gateway, host_t *src_ip, char *if_name)
+{
+       if (!this->net)
+       {
+               return NOT_SUPPORTED;
+       }
+       return this->net->del_route(this->net, dst_net, prefixlen, gateway,
+                                                               src_ip, if_name);
+}
+
+METHOD(kernel_interface_t, bypass_socket, bool,
+       private_kernel_interface_t *this, int fd, int family)
+{
+       if (!this->ipsec)
+       {
+               return FALSE;
+       }
+       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, is_interface_usable, bool,
+       private_kernel_interface_t *this, const char *iface)
+{
+       status_t expected;
+
+       if (!this->ifaces_filter)
+       {
+               return TRUE;
+       }
+       expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS;
+       return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq,
+                                                                                  NULL, iface) == expected;
+}
+
+METHOD(kernel_interface_t, all_interfaces_usable, bool,
+       private_kernel_interface_t *this)
+{
+       return this->ifaces_filter == NULL;
+}
+
+METHOD(kernel_interface_t, get_address_by_ts, status_t,
+       private_kernel_interface_t *this, traffic_selector_t *ts,
+       host_t **ip, bool *vip)
+{
+       enumerator_t *addrs;
+       host_t *host;
+       int family;
+       bool found = FALSE;
+
+       DBG2(DBG_KNL, "getting a local address in traffic selector %R", ts);
+
+       /* if we have a family which includes localhost, we do not
+        * search for an IP, we use the default */
+       family = ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? AF_INET : AF_INET6;
+
+       if (family == AF_INET)
+       {
+               host = host_create_from_string("127.0.0.1", 0);
+       }
+       else
+       {
+               host = host_create_from_string("::1", 0);
+       }
+
+       if (ts->includes(ts, host))
+       {
+               *ip = host_create_any(family);
+               host->destroy(host);
+               DBG2(DBG_KNL, "using host %H", *ip);
+               return SUCCESS;
+       }
+       host->destroy(host);
+
+       /* try virtual IPs only first (on all interfaces) */
+       addrs = create_address_enumerator(this,
+                                                                         ADDR_TYPE_ALL ^ ADDR_TYPE_REGULAR);
+       while (addrs->enumerate(addrs, (void**)&host))
+       {
+               if (ts->includes(ts, host))
+               {
+                       found = TRUE;
+                       *ip = host->clone(host);
+                       if (vip)
+                       {
+                               *vip = TRUE;
+                       }
+                       break;
+               }
+       }
+       addrs->destroy(addrs);
+
+       if (!found)
+       {       /* then try the regular addresses (on all interfaces) */
+               addrs = create_address_enumerator(this,
+                                                                                 ADDR_TYPE_ALL ^ ADDR_TYPE_VIRTUAL);
+               while (addrs->enumerate(addrs, (void**)&host))
+               {
+                       if (ts->includes(ts, host))
+                       {
+                               found = TRUE;
+                               *ip = host->clone(host);
+                               if (vip)
+                               {
+                                       *vip = FALSE;
+                               }
+                               break;
+                       }
+               }
+               addrs->destroy(addrs);
+       }
+
+       if (!found)
+       {
+               DBG2(DBG_KNL, "no local address found in traffic selector %R", ts);
+               return FAILED;
+       }
+
+       DBG2(DBG_KNL, "using host %H", *ip);
+       return SUCCESS;
+}
+
+
+METHOD(kernel_interface_t, add_ipsec_interface, bool,
+       private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor)
+{
+       if (!this->ipsec)
+       {
+               this->ipsec_constructor = constructor;
+               this->ipsec = constructor();
+               return this->ipsec != NULL;
+       }
+       return FALSE;
+}
+
+METHOD(kernel_interface_t, remove_ipsec_interface, bool,
+       private_kernel_interface_t *this, kernel_ipsec_constructor_t constructor)
+{
+       if (constructor == this->ipsec_constructor && this->ipsec)
+       {
+               this->ipsec->destroy(this->ipsec);
+               this->ipsec = NULL;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+METHOD(kernel_interface_t, add_net_interface, bool,
+       private_kernel_interface_t *this, kernel_net_constructor_t constructor)
+{
+       if (!this->net)
+       {
+               this->net_constructor = constructor;
+               this->net = constructor();
+               return this->net != NULL;
+       }
+       return FALSE;
+}
+
+METHOD(kernel_interface_t, remove_net_interface, bool,
+       private_kernel_interface_t *this, kernel_net_constructor_t constructor)
+{
+       if (constructor == this->net_constructor && this->net)
+       {
+               this->net->destroy(this->net);
+               this->net = NULL;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+METHOD(kernel_interface_t, add_listener, void,
+       private_kernel_interface_t *this, kernel_listener_t *listener)
+{
+       this->mutex->lock(this->mutex);
+       this->listeners->insert_last(this->listeners, listener);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, remove_listener, void,
+       private_kernel_interface_t *this, kernel_listener_t *listener)
+{
+       this->mutex->lock(this->mutex);
+       this->listeners->remove(this->listeners, listener, NULL);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, acquire, void,
+       private_kernel_interface_t *this, u_int32_t reqid,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
+{
+       kernel_listener_t *listener;
+       enumerator_t *enumerator;
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &listener))
+       {
+               if (listener->acquire &&
+                       !listener->acquire(listener, reqid, src_ts, dst_ts))
+               {
+                       this->listeners->remove_at(this->listeners, enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, expire, void,
+       private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+       host_t *dst, bool hard)
+{
+       kernel_listener_t *listener;
+       enumerator_t *enumerator;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &listener))
+       {
+               if (listener->expire &&
+                       !listener->expire(listener, protocol, spi, dst, hard))
+               {
+                       this->listeners->remove_at(this->listeners, enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, mapping, void,
+       private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+       host_t *dst, host_t *remote)
+{
+       kernel_listener_t *listener;
+       enumerator_t *enumerator;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &listener))
+       {
+               if (listener->mapping &&
+                       !listener->mapping(listener, protocol, spi, dst, remote))
+               {
+                       this->listeners->remove_at(this->listeners, enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, migrate, void,
+       private_kernel_interface_t *this, u_int32_t reqid,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+       policy_dir_t direction, host_t *local, host_t *remote)
+{
+       kernel_listener_t *listener;
+       enumerator_t *enumerator;
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &listener))
+       {
+               if (listener->migrate &&
+                       !listener->migrate(listener, reqid, src_ts, dst_ts, direction,
+                                                          local, remote))
+               {
+                       this->listeners->remove_at(this->listeners, enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+static bool call_roam(kernel_listener_t *listener, bool *roam)
+{
+       return listener->roam && !listener->roam(listener, *roam);
+}
+
+METHOD(kernel_interface_t, roam, void,
+       private_kernel_interface_t *this, bool address)
+{
+       this->mutex->lock(this->mutex);
+       this->listeners->remove(this->listeners, &address, (void*)call_roam);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, tun, void,
+       private_kernel_interface_t *this, tun_device_t *tun, bool created)
+{
+       kernel_listener_t *listener;
+       enumerator_t *enumerator;
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &listener))
+       {
+               if (listener->tun &&
+                       !listener->tun(listener, tun, created))
+               {
+                       this->listeners->remove_at(this->listeners, enumerator);
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(kernel_interface_t, register_algorithm, void,
+       private_kernel_interface_t *this, u_int16_t alg_id, transform_type_t type,
+       u_int16_t kernel_id, char *kernel_name)
+{
+       kernel_algorithm_t *algorithm;
+
+       INIT(algorithm,
+               .type = type,
+               .ike = alg_id,
+               .kernel = kernel_id,
+               .name = strdup(kernel_name),
+       );
+
+       this->mutex_algs->lock(this->mutex_algs);
+       this->algorithms->insert_first(this->algorithms, algorithm);
+       this->mutex_algs->unlock(this->mutex_algs);
+}
+
+METHOD(kernel_interface_t, lookup_algorithm, bool,
+       private_kernel_interface_t *this, u_int16_t alg_id, transform_type_t type,
+       u_int16_t *kernel_id, char **kernel_name)
+{
+       kernel_algorithm_t *algorithm;
+       enumerator_t *enumerator;
+       bool found = FALSE;
+
+       this->mutex_algs->lock(this->mutex_algs);
+       enumerator = this->algorithms->create_enumerator(this->algorithms);
+       while (enumerator->enumerate(enumerator, &algorithm))
+       {
+               if (algorithm->type == type && algorithm->ike == alg_id)
+               {
+                       if (kernel_id)
+                       {
+                               *kernel_id = algorithm->kernel;
+                       }
+                       if (kernel_name)
+                       {
+                               *kernel_name = algorithm->name;
+                       }
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex_algs->unlock(this->mutex_algs);
+       return found;
+}
+
+METHOD(kernel_interface_t, destroy, void,
+       private_kernel_interface_t *this)
+{
+       kernel_algorithm_t *algorithm;
+
+       while (this->algorithms->remove_first(this->algorithms,
+                                                                                (void**)&algorithm) == SUCCESS)
+       {
+               free(algorithm->name);
+               free(algorithm);
+       }
+       this->algorithms->destroy(this->algorithms);
+       this->mutex_algs->destroy(this->mutex_algs);
+       DESTROY_IF(this->ipsec);
+       DESTROY_IF(this->net);
+       DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free);
+       this->reqids->destroy(this->reqids);
+       this->reqids_by_ts->destroy(this->reqids_by_ts);
+       this->listeners->destroy(this->listeners);
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/*
+ * Described in header-file
+ */
+kernel_interface_t *kernel_interface_create()
+{
+       private_kernel_interface_t *this;
+       char *ifaces;
+
+       INIT(this,
+               .public = {
+                       .get_features = _get_features,
+                       .get_spi = _get_spi,
+                       .get_cpi = _get_cpi,
+                       .alloc_reqid = _alloc_reqid,
+                       .release_reqid = _release_reqid,
+                       .add_sa = _add_sa,
+                       .update_sa = _update_sa,
+                       .query_sa = _query_sa,
+                       .del_sa = _del_sa,
+                       .flush_sas = _flush_sas,
+                       .add_policy = _add_policy,
+                       .query_policy = _query_policy,
+                       .del_policy = _del_policy,
+                       .flush_policies = _flush_policies,
+                       .get_source_addr = _get_source_addr,
+                       .get_nexthop = _get_nexthop,
+                       .get_interface = _get_interface,
+                       .create_address_enumerator = _create_address_enumerator,
+                       .add_ip = _add_ip,
+                       .del_ip = _del_ip,
+                       .add_route = _add_route,
+                       .del_route = _del_route,
+                       .bypass_socket = _bypass_socket,
+                       .enable_udp_decap = _enable_udp_decap,
+
+                       .is_interface_usable = _is_interface_usable,
+                       .all_interfaces_usable = _all_interfaces_usable,
+                       .get_address_by_ts = _get_address_by_ts,
+                       .add_ipsec_interface = _add_ipsec_interface,
+                       .remove_ipsec_interface = _remove_ipsec_interface,
+                       .add_net_interface = _add_net_interface,
+                       .remove_net_interface = _remove_net_interface,
+
+                       .add_listener = _add_listener,
+                       .remove_listener = _remove_listener,
+                       .register_algorithm = _register_algorithm,
+                       .lookup_algorithm = _lookup_algorithm,
+                       .acquire = _acquire,
+                       .expire = _expire,
+                       .mapping = _mapping,
+                       .migrate = _migrate,
+                       .roam = _roam,
+                       .tun = _tun,
+                       .destroy = _destroy,
+               },
+               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+               .listeners = linked_list_create(),
+               .mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT),
+               .algorithms = linked_list_create(),
+               .reqids = hashtable_create((hashtable_hash_t)hash_reqid,
+                                                                  (hashtable_equals_t)equals_reqid, 8),
+               .reqids_by_ts = hashtable_create((hashtable_hash_t)hash_reqid_by_ts,
+                                                                  (hashtable_equals_t)equals_reqid_by_ts, 8),
+       );
+
+       ifaces = lib->settings->get_str(lib->settings,
+                                                                       "%s.interfaces_use", NULL, lib->ns);
+       if (!ifaces)
+       {
+               this->ifaces_exclude = TRUE;
+               ifaces = lib->settings->get_str(lib->settings,
+                                                                       "%s.interfaces_ignore", NULL, lib->ns);
+       }
+       if (ifaces)
+       {
+               enumerator_t *enumerator;
+               char *iface;
+
+               enumerator = enumerator_create_token(ifaces, ",", " ");
+               while (enumerator->enumerate(enumerator, &iface))
+               {
+                       if (!this->ifaces_filter)
+                       {
+                               this->ifaces_filter = linked_list_create();
+                       }
+                       this->ifaces_filter->insert_last(this->ifaces_filter,
+                                                                                        strdup(iface));
+               }
+               enumerator->destroy(enumerator);
+       }
+
+       return &this->public;
+}
diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h
new file mode 100644 (file)
index 0000000..6793c6c
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+ * Copyright (C) 2006-2015 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/*
+ * Copyright (c) 2012 Nanoteq Pty Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @defgroup kernel_interface kernel_interface
+ * @{ @ingroup kernel
+ */
+
+#ifndef KERNEL_INTERFACE_H_
+#define KERNEL_INTERFACE_H_
+
+typedef struct kernel_interface_t kernel_interface_t;
+typedef enum kernel_feature_t kernel_feature_t;
+
+#include <networking/host.h>
+#include <crypto/prf_plus.h>
+
+#include <kernel/kernel_listener.h>
+#include <kernel/kernel_ipsec.h>
+#include <kernel/kernel_net.h>
+
+/**
+ * Bitfield of optional features a kernel backend supports.
+ *
+ * This feature-set is for both, kernel_ipsec_t and kernel_net_t. Each
+ * backend returns a subset of these features.
+ */
+enum kernel_feature_t {
+       /** IPsec can process ESPv3 (RFC 4303) TFC padded packets */
+       KERNEL_ESP_V3_TFC = (1<<0),
+       /** Networking requires an "exclude" route for IKE/ESP packets */
+       KERNEL_REQUIRE_EXCLUDE_ROUTE = (1<<1),
+       /** IPsec implementation requires UDP encapsulation of ESP packets */
+       KERNEL_REQUIRE_UDP_ENCAPSULATION = (1<<2),
+       /** IPsec backend does not require a policy reinstall on SA updates */
+       KERNEL_NO_POLICY_UPDATES = (1<<3),
+};
+
+/**
+ * Constructor function for ipsec kernel interface
+ */
+typedef kernel_ipsec_t* (*kernel_ipsec_constructor_t)(void);
+
+/**
+ * Constructor function for network kernel interface
+ */
+typedef kernel_net_t* (*kernel_net_constructor_t)(void);
+
+/**
+ * Manager and wrapper for different kernel interfaces.
+ *
+ * The kernel interface handles the communication with the kernel
+ * for SA and policy management and interface and IP address management.
+ */
+struct kernel_interface_t {
+
+       /**
+        * Get the feature set supported by the net and ipsec kernel backends.
+        *
+        * @return                              ORed feature-set of backends
+        */
+       kernel_feature_t (*get_features)(kernel_interface_t *this);
+
+       /**
+        * Get a SPI from the kernel.
+        *
+        * @param src           source address of SA
+        * @param dst           destination address of SA
+        * @param protocol      protocol for SA (ESP/AH)
+        * @param spi           allocated spi
+        * @return                      SUCCESS if operation completed
+        */
+       status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst,
+                                               u_int8_t protocol, u_int32_t *spi);
+
+       /**
+        * Get a Compression Parameter Index (CPI) from the kernel.
+        *
+        * @param src           source address of SA
+        * @param dst           destination address of SA
+        * @param cpi           allocated cpi
+        * @return                      SUCCESS if operation completed
+        */
+       status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst,
+                                               u_int16_t *cpi);
+
+       /**
+        * Allocate or confirm a reqid to use for a given SA pair.
+        *
+        * Each returned reqid by a successful call to alloc_reqid() must be
+        * released using release_reqid().
+        *
+        * The reqid parameter is an in/out parameter. If it points to non-zero,
+        * the reqid is confirmed and registered for use. If it points to zero,
+        * a reqid is allocated for the given selectors, and returned to reqid.
+        *
+        * @param local_ts      traffic selectors of local side for SA
+        * @param remote_ts     traffic selectors of remote side for SA
+        * @param mark_in       inbound mark on SA
+        * @param mark_out      outbound mark on SA
+        * @param reqid         allocated reqid
+        * @return                      SUCCESS if reqid allocated
+        */
+       status_t (*alloc_reqid)(kernel_interface_t *this,
+                                                       linked_list_t *local_ts, linked_list_t *remote_ts,
+                                                       mark_t mark_in, mark_t mark_out,
+                                                       u_int32_t *reqid);
+
+       /**
+        * Release a previously allocated reqid.
+        *
+        * @param reqid         reqid to release
+        * @param mark_in       inbound mark on SA
+        * @param mark_out      outbound mark on SA
+        * @return                      SUCCESS if reqid released
+        */
+       status_t (*release_reqid)(kernel_interface_t *this, u_int32_t reqid,
+                                                         mark_t mark_in, mark_t mark_out);
+
+       /**
+        * Add an SA to the SAD.
+        *
+        * This function does install a single SA for a single protocol in one
+        * direction.
+        *
+        * @param src                   source address for this SA
+        * @param dst                   destination address for this SA
+        * @param spi                   SPI allocated by us or remote peer
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param reqid                 reqid for this SA
+        * @param mark                  optional mark for this SA
+        * @param tfc                   Traffic Flow Confidentiality padding for this SA
+        * @param lifetime              lifetime_cfg_t for this SA
+        * @param enc_alg               Algorithm to use for encryption (ESP only)
+        * @param enc_key               key to use for encryption
+        * @param int_alg               Algorithm to use for integrity protection
+        * @param int_key               key to use for integrity protection
+        * @param mode                  mode of the SA (tunnel, transport)
+        * @param ipcomp                IPComp transform to use
+        * @param cpi                   CPI for IPComp
+        * @param replay_window anti-replay window size
+        * @param initiator             TRUE if initiator of the exchange creating this SA
+        * @param encap                 enable UDP encapsulation for NAT traversal
+        * @param esn                   TRUE to use Extended Sequence Numbers
+        * @param inbound               TRUE if this is an inbound SA
+        * @param update                TRUE if an SPI has already been allocated for SA
+        * @param src_ts                list of source traffic selectors
+        * @param dst_ts                list of destination traffic selectors
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*add_sa) (kernel_interface_t *this,
+                                               host_t *src, host_t *dst, u_int32_t spi,
+                                               u_int8_t protocol, u_int32_t reqid, mark_t mark,
+                                               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, bool update,
+                                               linked_list_t *src_ts, linked_list_t *dst_ts);
+
+       /**
+        * Update the hosts on an installed SA.
+        *
+        * We cannot directly update the destination address as the kernel
+        * requires the spi, the protocol AND the destination address (and family)
+        * to identify SAs. Therefore if the destination address changed we
+        * create a new SA and delete the old one.
+        *
+        * @param spi                   SPI of the SA
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param cpi                   CPI for IPComp, 0 if no IPComp is used
+        * @param src                   current source address
+        * @param dst                   current destination address
+        * @param new_src               new source address
+        * @param new_dst               new destination address
+        * @param encap                 current use of UDP encapsulation
+        * @param new_encap             new use of UDP encapsulation
+        * @param mark                  optional mark for this SA
+        * @return                              SUCCESS if operation completed, NOT_SUPPORTED if
+        *                                        the kernel interface can't update the SA
+        */
+       status_t (*update_sa)(kernel_interface_t *this,
+                                                 u_int32_t spi, u_int8_t protocol, u_int16_t cpi,
+                                                 host_t *src, host_t *dst,
+                                                 host_t *new_src, host_t *new_dst,
+                                                 bool encap, bool new_encap, mark_t mark);
+
+       /**
+        * Query the number of bytes processed by an SA from the SAD.
+        *
+        * @param src                   source address for this SA
+        * @param dst                   destination address for this SA
+        * @param spi                   SPI allocated by us or remote peer
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param mark                  optional mark for this SA
+        * @param[out] bytes    the number of bytes processed by SA
+        * @param[out] packets  number of packets processed by SA
+        * @param[out] time             last (monotonic) time of SA use
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
+                                                 u_int32_t spi, u_int8_t protocol, mark_t mark,
+                                                 u_int64_t *bytes, u_int64_t *packets, time_t *time);
+
+       /**
+        * Delete a previously installed SA from the SAD.
+        *
+        * @param src                   source address for this SA
+        * @param dst                   destination address for this SA
+        * @param spi                   SPI allocated by us or remote peer
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param cpi                   CPI for IPComp or 0
+        * @param mark                  optional mark for this SA
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
+                                               u_int32_t spi, u_int8_t protocol, u_int16_t cpi,
+                                               mark_t mark);
+
+       /**
+        * Flush all SAs from the SAD.
+        *
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*flush_sas) (kernel_interface_t *this);
+
+       /**
+        * Add a policy to the SPD.
+        *
+        * @param src                   source address of SA
+        * @param dst                   dest address of SA
+        * @param src_ts                traffic selector to match traffic source
+        * @param dst_ts                traffic selector to match traffic dest
+        * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
+        * @param type                  type of policy, POLICY_(IPSEC|PASS|DROP)
+        * @param sa                    details about the SA(s) tied to this policy
+        * @param mark                  mark for this policy
+        * @param priority              priority of this policy
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*add_policy) (kernel_interface_t *this,
+                                                       host_t *src, host_t *dst,
+                                                       traffic_selector_t *src_ts,
+                                                       traffic_selector_t *dst_ts,
+                                                       policy_dir_t direction, policy_type_t type,
+                                                       ipsec_sa_cfg_t *sa, mark_t mark,
+                                                       policy_priority_t priority);
+
+       /**
+        * Query the use time of a policy.
+        *
+        * The use time of a policy is the time the policy was used
+        * for the last time.
+        *
+        * @param src_ts                traffic selector to match traffic source
+        * @param dst_ts                traffic selector to match traffic dest
+        * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
+        * @param mark                  optional mark
+        * @param[out] use_time the (monotonic) time of this SA's last use
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*query_policy) (kernel_interface_t *this,
+                                                         traffic_selector_t *src_ts,
+                                                         traffic_selector_t *dst_ts,
+                                                         policy_dir_t direction, mark_t mark,
+                                                         time_t *use_time);
+
+       /**
+        * Remove a policy from the SPD.
+        *
+        * @param src                   source address of SA
+        * @param dst                   dest address of SA
+        * @param src_ts                traffic selector to match traffic source
+        * @param dst_ts                traffic selector to match traffic dest
+        * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
+        * @param type                  type of policy, POLICY_(IPSEC|PASS|DROP)
+        * @param sa                    details about the SA(s) tied to this policy
+        * @param mark                  mark for this policy
+        * @param priority              priority of the policy
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_policy) (kernel_interface_t *this,
+                                                       host_t *src, host_t *dst,
+                                                       traffic_selector_t *src_ts,
+                                                       traffic_selector_t *dst_ts,
+                                                       policy_dir_t direction, policy_type_t type,
+                                                       ipsec_sa_cfg_t *sa, mark_t mark,
+                                                       policy_priority_t priority);
+
+       /**
+        * Flush all policies from the SPD.
+        *
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*flush_policies) (kernel_interface_t *this);
+
+       /**
+        * Get our outgoing source address for a destination.
+        *
+        * Does a route lookup to get the source address used to reach dest.
+        * The returned host is allocated and must be destroyed.
+        * An optional src address can be used to check if a route is available
+        * for the given source to dest.
+        *
+        * @param dest                  target destination address
+        * @param src                   source address to check, or NULL
+        * @return                              outgoing source address, NULL if unreachable
+        */
+       host_t* (*get_source_addr)(kernel_interface_t *this,
+                                                          host_t *dest, host_t *src);
+
+       /**
+        * Get the next hop for a destination.
+        *
+        * Does a route lookup to get the next hop used to reach dest.
+        * The returned host is allocated and must be destroyed.
+        * An optional src address can be used to check if a route is available
+        * for the given source to dest.
+        *
+        * @param dest                  target destination address
+        * @param prefix                prefix length if dest is a subnet, -1 for auto
+        * @param src                   source address to check, or NULL
+        * @return                              next hop address, NULL if unreachable
+        */
+       host_t* (*get_nexthop)(kernel_interface_t *this, host_t *dest,
+                                                  int prefix, host_t *src);
+
+       /**
+        * Get the interface name of a local address. Interfaces that are down or
+        * ignored by config are not considered.
+        *
+        * @param host                  address to get interface name from
+        * @param name                  allocated interface name (optional)
+        * @return                              TRUE if interface found and usable
+        */
+       bool (*get_interface)(kernel_interface_t *this, host_t *host, char **name);
+
+       /**
+        * Creates an enumerator over all local addresses.
+        *
+        * This function blocks an internal cached address list until the
+        * enumerator gets destroyed.
+        * The hosts are read-only, do not modify of free.
+        *
+        * @param which                 a combination of address types to enumerate
+        * @return                              enumerator over host_t's
+        */
+       enumerator_t *(*create_address_enumerator) (kernel_interface_t *this,
+                                                                                               kernel_address_type_t which);
+
+       /**
+        * Add a virtual IP to an interface.
+        *
+        * Virtual IPs are attached to an interface. If an IP is added multiple
+        * times, the IP is refcounted and not removed until del_ip() was called
+        * as many times as add_ip().
+        *
+        * @param virtual_ip    virtual ip address to assign
+        * @param prefix                prefix length to install IP with, -1 for auto
+        * @param iface                 interface to install virtual IP on
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*add_ip) (kernel_interface_t *this, host_t *virtual_ip, int prefix,
+                                               char *iface);
+
+       /**
+        * Remove a virtual IP from an interface.
+        *
+        * The kernel interface uses refcounting, see add_ip().
+        *
+        * @param virtual_ip    virtual ip address to remove
+        * @param prefix                prefix length of the IP to uninstall, -1 for auto
+        * @param wait                  TRUE to wait untily IP is gone
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_ip) (kernel_interface_t *this, host_t *virtual_ip,
+                                               int prefix, bool wait);
+
+       /**
+        * Add a route.
+        *
+        * @param dst_net               destination net
+        * @param prefixlen             destination net prefix length
+        * @param gateway               gateway for this route
+        * @param src_ip                source ip of the route
+        * @param if_name               name of the interface the route is bound to
+        * @return                              SUCCESS if operation completed
+        *                                              ALREADY_DONE if the route already exists
+        */
+       status_t (*add_route) (kernel_interface_t *this, chunk_t dst_net,
+                                                  u_int8_t prefixlen, host_t *gateway, host_t *src_ip,
+                                                  char *if_name);
+
+       /**
+        * Delete a route.
+        *
+        * @param dst_net               destination net
+        * @param prefixlen             destination net prefix length
+        * @param gateway               gateway for this route
+        * @param src_ip                source ip of the route
+        * @param if_name               name of the interface the route is bound to
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_route) (kernel_interface_t *this, chunk_t dst_net,
+                                                  u_int8_t prefixlen, host_t *gateway, host_t *src_ip,
+                                                  char *if_name);
+
+       /**
+        * Set up a bypass policy for a given socket.
+        *
+        * @param fd                    socket file descriptor to setup policy for
+        * @param family                protocol family of the socket
+        * @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
+        */
+
+       /**
+        * Verifies that the given interface is usable and not excluded by
+        * configuration.
+        *
+        * @param iface                 interface name
+        * @return                              TRUE if usable
+        */
+       bool (*is_interface_usable)(kernel_interface_t *this, const char *iface);
+
+       /**
+        * Check if interfaces are excluded by config.
+        *
+        * @return                              TRUE if no interfaces are exclued by config
+        */
+       bool (*all_interfaces_usable)(kernel_interface_t *this);
+
+       /**
+        * Tries to find an IP address of a local interface that is included in the
+        * supplied traffic selector.
+        *
+        * @param ts                    traffic selector
+        * @param ip                    returned IP address (has to be destroyed)
+        * @param vip                   set to TRUE if returned address is a virtual IP
+        * @return                              SUCCESS if address found
+        */
+       status_t (*get_address_by_ts)(kernel_interface_t *this,
+                                                                 traffic_selector_t *ts, host_t **ip, bool *vip);
+
+       /**
+        * Register an ipsec kernel interface constructor on the manager.
+        *
+        * @param create                constructor to register
+        * @return                              TRUE if the ipsec kernel interface was registered
+        *                                              successfully, FALSE if an interface was already
+        *                                              registered or the registration failed
+        */
+       bool (*add_ipsec_interface)(kernel_interface_t *this,
+                                                               kernel_ipsec_constructor_t create);
+
+       /**
+        * Unregister an ipsec kernel interface constructor.
+        *
+        * @param create                constructor to unregister
+        * @return                              TRUE if the ipsec kernel interface was unregistered
+        *                                              successfully, FALSE otherwise
+        */
+       bool (*remove_ipsec_interface)(kernel_interface_t *this,
+                                                                  kernel_ipsec_constructor_t create);
+
+       /**
+        * Register a network kernel interface constructor on the manager.
+        *
+        * @param create                constructor to register
+        * @return                              TRUE if the kernel net interface was registered
+        *                                              successfully, FALSE if an interface was already
+        *                                              registered or the registration failed
+        */
+       bool (*add_net_interface)(kernel_interface_t *this,
+                                                         kernel_net_constructor_t create);
+
+       /**
+        * Unregister a network kernel interface constructor.
+        *
+        * @param create                constructor to unregister
+        * @return                              TRUE if the kernel net interface was unregistered
+        *                                              successfully, FALSE otherwise
+        */
+       bool (*remove_net_interface)(kernel_interface_t *this,
+                                                                kernel_net_constructor_t create);
+
+       /**
+        * Add a listener to the kernel interface.
+        *
+        * @param listener              listener to add
+        */
+       void (*add_listener)(kernel_interface_t *this,
+                                                kernel_listener_t *listener);
+
+       /**
+        * Remove a listener from the kernel interface.
+        *
+        * @param listener              listener to remove
+        */
+       void (*remove_listener)(kernel_interface_t *this,
+                                                       kernel_listener_t *listener);
+
+       /**
+        * Raise an acquire event.
+        *
+        * @param reqid                 reqid of the policy to acquire
+        * @param src_ts                source traffic selector
+        * @param dst_ts                destination traffic selector
+        */
+       void (*acquire)(kernel_interface_t *this, u_int32_t reqid,
+                                       traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
+
+       /**
+        * Raise an expire event.
+        *
+        * @param protocol              protocol of the expired SA
+        * @param spi                   spi of the expired SA
+        * @param dst                   destination address of expired SA
+        * @param hard                  TRUE if it is a hard expire, FALSE otherwise
+        */
+       void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+                                  host_t *dst, bool hard);
+
+       /**
+        * Raise a mapping event.
+        *
+        * @param protocol              protocol of affected SA
+        * @param spi                   spi of the SA
+        * @param dst                   original destination address of SA
+        * @param remote                new remote host
+        */
+       void (*mapping)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi,
+                                       host_t *dst, host_t *remote);
+
+       /**
+        * Raise a migrate event.
+        *
+        * @param reqid                 reqid of the policy
+        * @param src_ts                source traffic selector
+        * @param dst_ts                destination traffic selector
+        * @param direction             direction of the policy (in|out)
+        * @param local                 local host address to be used in the IKE_SA
+        * @param remote                remote host address to be used in the IKE_SA
+        */
+       void (*migrate)(kernel_interface_t *this, u_int32_t reqid,
+                                       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+                                       policy_dir_t direction, host_t *local, host_t *remote);
+
+       /**
+        * Raise a roam event.
+        *
+        * @param address               TRUE if address list, FALSE if routing changed
+        */
+       void (*roam)(kernel_interface_t *this, bool address);
+
+       /**
+        * Raise a tun event.
+        *
+        * @param tun                   TUN device
+        * @param created               TRUE if created, FALSE if going to be destroyed
+        */
+       void (*tun)(kernel_interface_t *this, tun_device_t *tun, bool created);
+
+       /**
+        * Register a new algorithm with the kernel interface.
+        *
+        * @param alg_id                        the IKE id of the algorithm
+        * @param type                          the transform type of the algorithm
+        * @param kernel_id                     the kernel id of the algorithm
+        * @param kernel_name           the kernel name of the algorithm
+        */
+       void (*register_algorithm)(kernel_interface_t *this, u_int16_t alg_id,
+                                                          transform_type_t type, u_int16_t kernel_id,
+                                                          char *kernel_name);
+
+       /**
+        * Return the kernel-specific id and/or name for an algorithms depending on
+        * the arguments specified.
+        *
+        * @param alg_id                        the IKE id of the algorithm
+        * @param type                          the transform type of the algorithm
+        * @param kernel_id                     the kernel id of the algorithm (optional)
+        * @param kernel_name           the kernel name of the algorithm (optional)
+        * @return                                      TRUE if algorithm was found
+        */
+       bool (*lookup_algorithm)(kernel_interface_t *this, u_int16_t alg_id,
+                                                        transform_type_t type, u_int16_t *kernel_id,
+                                                        char **kernel_name);
+
+       /**
+        * Destroys a kernel_interface_t object.
+        */
+       void (*destroy) (kernel_interface_t *this);
+};
+
+/**
+ * Creates an object of type kernel_interface_t.
+ */
+kernel_interface_t *kernel_interface_create(void);
+
+#endif /** KERNEL_INTERFACE_H_ @}*/
diff --git a/src/libcharon/kernel/kernel_ipsec.c b/src/libcharon/kernel/kernel_ipsec.c
new file mode 100644 (file)
index 0000000..0440f11
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "kernel_ipsec.h"
+
+#include <daemon.h>
+
+/**
+ * See header
+ */
+bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature,
+                                                  bool reg, void *data)
+{
+       if (reg)
+       {
+               return charon->kernel->add_ipsec_interface(charon->kernel,
+                                                                                       (kernel_ipsec_constructor_t)data);
+       }
+       else
+       {
+               return charon->kernel->remove_ipsec_interface(charon->kernel,
+                                                                                       (kernel_ipsec_constructor_t)data);
+       }
+}
diff --git a/src/libcharon/kernel/kernel_ipsec.h b/src/libcharon/kernel/kernel_ipsec.h
new file mode 100644 (file)
index 0000000..31e0630
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2006-2015 Tobias Brunner
+ * Copyright (C) 2006 Daniel Roethlisberger
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup kernel_ipsec kernel_ipsec
+ * @{ @ingroup kernel
+ */
+
+#ifndef KERNEL_IPSEC_H_
+#define KERNEL_IPSEC_H_
+
+typedef struct kernel_ipsec_t kernel_ipsec_t;
+
+#include <networking/host.h>
+#include <ipsec/ipsec_types.h>
+#include <selectors/traffic_selector.h>
+#include <plugins/plugin.h>
+#include <kernel/kernel_interface.h>
+
+/**
+ * Interface to the ipsec subsystem of the kernel.
+ *
+ * The kernel ipsec interface handles the communication with the kernel
+ * for SA and policy management. It allows setup of these, and provides
+ * further the handling of kernel events.
+ * Policy information are cached in the interface. This is necessary to do
+ * reference counting. The Linux kernel does not allow the same policy
+ * installed twice, but we need this as CHILD_SA exist multiple times
+ * when rekeying. Thats why we do reference counting of policies.
+ */
+struct kernel_ipsec_t {
+
+       /**
+        * Get the feature set supported by this kernel backend.
+        *
+        * @return                              ORed feature-set of backend
+        */
+       kernel_feature_t (*get_features)(kernel_ipsec_t *this);
+
+       /**
+        * Get a SPI from the kernel.
+        *
+        * @param src           source address of SA
+        * @param dst           destination address of SA
+        * @param protocol      protocol for SA (ESP/AH)
+        * @param spi           allocated spi
+        * @return                      SUCCESS if operation completed
+        */
+       status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
+                                               u_int8_t protocol, u_int32_t *spi);
+
+       /**
+        * Get a Compression Parameter Index (CPI) from the kernel.
+        *
+        * @param src           source address of SA
+        * @param dst           destination address of SA
+        * @param cpi           allocated cpi
+        * @return                      SUCCESS if operation completed
+        */
+       status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst,
+                                               u_int16_t *cpi);
+
+       /**
+        * Add an SA to the SAD.
+        *
+        * This function does install a single SA for a single protocol in one
+        * direction.
+        *
+        * @param src                   source address for this SA
+        * @param dst                   destination address for this SA
+        * @param spi                   SPI allocated by us or remote peer
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param reqid                 unique ID for this SA
+        * @param mark                  mark for this SA
+        * @param tfc                   Traffic Flow Confidentiality padding for this SA
+        * @param lifetime              lifetime_cfg_t for this SA
+        * @param enc_alg               Algorithm to use for encryption (ESP only)
+        * @param enc_key               key to use for encryption
+        * @param int_alg               Algorithm to use for integrity protection
+        * @param int_key               key to use for integrity protection
+        * @param mode                  mode of the SA (tunnel, transport)
+        * @param ipcomp                IPComp transform to use
+        * @param cpi                   CPI for IPComp
+        * @param replay_window anti-replay window size
+        * @param initiator             TRUE if initiator of the exchange creating this SA
+        * @param encap                 enable UDP encapsulation for NAT traversal
+        * @param esn                   TRUE to use Extended Sequence Numbers
+        * @param inbound               TRUE if this is an inbound SA
+        * @param update                TRUE if an SPI has already been allocated for SA
+        * @param src_ts                list of source traffic selectors
+        * @param dst_ts                list of destination traffic selectors
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*add_sa) (kernel_ipsec_t *this,
+                                               host_t *src, host_t *dst, u_int32_t spi,
+                                               u_int8_t protocol, u_int32_t reqid,
+                                               mark_t mark, 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, bool update,
+                                               linked_list_t *src_ts, linked_list_t *dst_ts);
+
+       /**
+        * Update the hosts on an installed SA.
+        *
+        * We cannot directly update the destination address as the kernel
+        * requires the spi, the protocol AND the destination address (and family)
+        * to identify SAs. Therefore if the destination address changed we
+        * create a new SA and delete the old one.
+        *
+        * @param spi                   SPI of the SA
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param cpi                   CPI for IPComp, 0 if no IPComp is used
+        * @param src                   current source address
+        * @param dst                   current destination address
+        * @param new_src               new source address
+        * @param new_dst               new destination address
+        * @param encap                 current use of UDP encapsulation
+        * @param new_encap             new use of UDP encapsulation
+        * @param mark                  optional mark for this SA
+        * @return                              SUCCESS if operation completed, NOT_SUPPORTED if
+        *                                        the kernel interface can't update the SA
+        */
+       status_t (*update_sa)(kernel_ipsec_t *this,
+                                                 u_int32_t spi, u_int8_t protocol, u_int16_t cpi,
+                                                 host_t *src, host_t *dst,
+                                                 host_t *new_src, host_t *new_dst,
+                                                 bool encap, bool new_encap, mark_t mark);
+
+       /**
+        * Query the number of bytes processed by an SA from the SAD.
+        *
+        * @param src                   source address for this SA
+        * @param dst                   destination address for this SA
+        * @param spi                   SPI allocated by us or remote peer
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param mark                  optional mark for this SA
+        * @param[out] bytes    the number of bytes processed by SA
+        * @param[out] packets  number of packets processed by SA
+        * @param[out] time             last (monotonic) time of SA use
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
+                                                 u_int32_t spi, u_int8_t protocol, mark_t mark,
+                                                 u_int64_t *bytes, u_int64_t *packets, time_t *time);
+
+       /**
+        * Delete a previusly installed SA from the SAD.
+        *
+        * @param src                   source address for this SA
+        * @param dst                   destination address for this SA
+        * @param spi                   SPI allocated by us or remote peer
+        * @param protocol              protocol for this SA (ESP/AH)
+        * @param cpi                   CPI for IPComp or 0
+        * @param mark                  optional mark for this SA
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
+                                               u_int32_t spi, u_int8_t protocol, u_int16_t cpi,
+                                               mark_t mark);
+
+       /**
+        * Flush all SAs from the SAD.
+        *
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*flush_sas) (kernel_ipsec_t *this);
+
+       /**
+        * Add a policy to the SPD.
+        *
+        * @param src                   source address of SA
+        * @param dst                   dest address of SA
+        * @param src_ts                traffic selector to match traffic source
+        * @param dst_ts                traffic selector to match traffic dest
+        * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
+        * @param type                  type of policy, POLICY_(IPSEC|PASS|DROP)
+        * @param sa                    details about the SA(s) tied to this policy
+        * @param mark                  mark for this policy
+        * @param priority              priority of this policy
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*add_policy) (kernel_ipsec_t *this,
+                                                       host_t *src, host_t *dst,
+                                                       traffic_selector_t *src_ts,
+                                                       traffic_selector_t *dst_ts,
+                                                       policy_dir_t direction, policy_type_t type,
+                                                       ipsec_sa_cfg_t *sa, mark_t mark,
+                                                       policy_priority_t priority);
+
+       /**
+        * Query the use time of a policy.
+        *
+        * The use time of a policy is the time the policy was used for the last
+        * time. It is not the system time, but a monotonic timestamp as returned
+        * by time_monotonic.
+        *
+        * @param src_ts                traffic selector to match traffic source
+        * @param dst_ts                traffic selector to match traffic dest
+        * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
+        * @param mark                  optional mark
+        * @param[out] use_time the monotonic timestamp of this SA's last use
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*query_policy) (kernel_ipsec_t *this,
+                                                         traffic_selector_t *src_ts,
+                                                         traffic_selector_t *dst_ts,
+                                                         policy_dir_t direction, mark_t mark,
+                                                         time_t *use_time);
+
+       /**
+        * Remove a policy from the SPD.
+        *
+        * @param src                   source address of SA
+        * @param dst                   dest address of SA
+        * @param src_ts                traffic selector to match traffic source
+        * @param dst_ts                traffic selector to match traffic dest
+        * @param direction             direction of traffic, POLICY_(IN|OUT|FWD)
+        * @param type                  type of policy, POLICY_(IPSEC|PASS|DROP)
+        * @param sa                    details about the SA(s) tied to this policy
+        * @param mark                  mark for this policy
+        * @param priority              priority of the policy
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_policy) (kernel_ipsec_t *this,
+                                                       host_t *src, host_t *dst,
+                                                       traffic_selector_t *src_ts,
+                                                       traffic_selector_t *dst_ts,
+                                                       policy_dir_t direction, policy_type_t type,
+                                                       ipsec_sa_cfg_t *sa, mark_t mark,
+                                                       policy_priority_t priority);
+
+       /**
+        * Flush all policies from the SPD.
+        *
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*flush_policies) (kernel_ipsec_t *this);
+
+       /**
+        * Install a bypass policy for the given socket.
+        *
+        * @param fd                    socket file descriptor to setup policy for
+        * @param family                protocol family of the socket
+        * @return                              TRUE of policy set up successfully
+        */
+       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);
+};
+
+/**
+ * Helper function to (un-)register IPsec kernel interfaces from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register an IPsec kernel interface constructor.
+ *
+ * @param plugin               plugin registering the kernel interface
+ * @param feature              associated plugin feature
+ * @param reg                  TRUE to register, FALSE to unregister
+ * @param data                 data passed to callback, an kernel_ipsec_constructor_t
+ */
+bool kernel_ipsec_register(plugin_t *plugin, plugin_feature_t *feature,
+                                                  bool reg, void *data);
+
+#endif /** KERNEL_IPSEC_H_ @}*/
diff --git a/src/libcharon/kernel/kernel_listener.h b/src/libcharon/kernel/kernel_listener.h
new file mode 100644 (file)
index 0000000..6426fae
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010-2013 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup kernel_listener kernel_listener
+ * @{ @ingroup kernel
+ */
+
+#ifndef KERNEL_LISTENER_H_
+#define KERNEL_LISTENER_H_
+
+typedef struct kernel_listener_t kernel_listener_t;
+
+#include <networking/host.h>
+#include <networking/tun_device.h>
+#include <selectors/traffic_selector.h>
+#include <kernel/kernel_ipsec.h>
+
+/**
+ * Interface for components interested in kernel events.
+ *
+ * All hooks are optional.
+ */
+struct kernel_listener_t {
+
+       /**
+        * Hook called if an acquire event for a policy is received.
+        *
+        * @param reqid                 reqid of the policy to acquire
+        * @param src_ts                source traffic selector
+        * @param dst_ts                destination traffic selector
+        * @return                              TRUE to remain registered, FALSE to unregister
+        */
+       bool (*acquire)(kernel_listener_t *this, u_int32_t reqid,
+                                       traffic_selector_t *src_ts, traffic_selector_t *dst_ts);
+
+       /**
+        * Hook called if an exire event for an IPsec SA is received.
+        *
+        * @param protocol              protocol of the expired SA
+        * @param spi                   spi of the expired SA
+        * @param dst                   destination address of expired SA
+        * @param hard                  TRUE if it is a hard expire, FALSE otherwise
+        * @return                              TRUE to remain registered, FALSE to unregister
+        */
+       bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+                                  host_t *dst, bool hard);
+
+       /**
+        * Hook called if the NAT mappings of an IPsec SA changed.
+        *
+        * @param protocol              IPsec protocol of affected SA
+        * @param spi                   spi of the SA
+        * @param dst                   old destinatino address of SA
+        * @param remote                new remote host
+        * @return                              TRUE to remain registered, FALSE to unregister
+        */
+       bool (*mapping)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi,
+                                       host_t *dst, host_t *remote);
+
+       /**
+        * Hook called if a migrate event for a policy is received.
+        *
+        * @param reqid                 reqid of the policy
+        * @param src_ts                source traffic selector
+        * @param dst_ts                destination traffic selector
+        * @param direction             direction of the policy (in|out)
+        * @param local                 local host address to be used in the IKE_SA
+        * @param remote                remote host address to be used in the IKE_SA
+        * @return                              TRUE to remain registered, FALSE to unregister
+        */
+       bool (*migrate)(kernel_listener_t *this, u_int32_t reqid,
+                                       traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
+                                       policy_dir_t direction, host_t *local, host_t *remote);
+
+       /**
+        * Hook called if changes in the networking layer occurred (interfaces
+        * up/down, routes added/deleted etc.).
+        *
+        * @param address               TRUE if address list, FALSE if routing changed
+        * @return                              TRUE to remain registered, FALSE to unregister
+        */
+       bool (*roam)(kernel_listener_t *this, bool address);
+
+       /**
+        * Hook called after a TUN device was created for a virtual IP address, or
+        * before such a device gets destroyed.
+        *
+        * @param tun                   TUN device
+        * @param created               TRUE if created, FALSE if going to be destroyed
+        */
+       bool (*tun)(kernel_listener_t *this, tun_device_t *tun, bool created);
+};
+
+#endif /** KERNEL_LISTENER_H_ @}*/
diff --git a/src/libcharon/kernel/kernel_net.c b/src/libcharon/kernel/kernel_net.c
new file mode 100644 (file)
index 0000000..f169cad
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "kernel_net.h"
+
+#include <daemon.h>
+
+/**
+ * See header
+ */
+bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature,
+                                                bool reg, void *data)
+{
+       if (reg)
+       {
+               return charon->kernel->add_net_interface(charon->kernel,
+                                                                                       (kernel_net_constructor_t)data);
+       }
+       else
+       {
+               return charon->kernel->remove_net_interface(charon->kernel,
+                                                                                       (kernel_net_constructor_t)data);
+       }
+}
diff --git a/src/libcharon/kernel/kernel_net.h b/src/libcharon/kernel/kernel_net.h
new file mode 100644 (file)
index 0000000..7fc644a
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2008-2012 Tobias Brunner
+ * Copyright (C) 2007 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup kernel_net kernel_net
+ * @{ @ingroup kernel
+ */
+
+#ifndef KERNEL_NET_H_
+#define KERNEL_NET_H_
+
+typedef struct kernel_net_t kernel_net_t;
+typedef enum kernel_address_type_t kernel_address_type_t;
+
+#include <collections/enumerator.h>
+#include <networking/host.h>
+#include <plugins/plugin.h>
+#include <kernel/kernel_interface.h>
+
+/**
+ * Type of addresses (e.g. when enumerating them)
+ */
+enum kernel_address_type_t {
+       /** normal addresses (on regular, up, non-ignored) interfaces */
+       ADDR_TYPE_REGULAR = (1 << 0),
+       /** addresses on down interfaces */
+       ADDR_TYPE_DOWN =  (1 << 1),
+       /** addresses on ignored interfaces */
+       ADDR_TYPE_IGNORED = (1 << 2),
+       /** addresses on loopback interfaces */
+       ADDR_TYPE_LOOPBACK = (1 << 3),
+       /** virtual IP addresses */
+       ADDR_TYPE_VIRTUAL = (1 << 4),
+       /** to enumerate all available addresses */
+       ADDR_TYPE_ALL = (1 << 5) - 1,
+};
+
+/**
+ * Interface to the network subsystem of the kernel.
+ *
+ * The kernel network interface handles the communication with the kernel
+ * for interface and IP address management.
+ */
+struct kernel_net_t {
+
+       /**
+        * Get the feature set supported by this kernel backend.
+        *
+        * @return                              ORed feature-set of backend
+        */
+       kernel_feature_t (*get_features)(kernel_net_t *this);
+
+       /**
+        * Get our outgoing source address for a destination.
+        *
+        * Does a route lookup to get the source address used to reach dest.
+        * The returned host is allocated and must be destroyed.
+        * An optional src address can be used to check if a route is available
+        * for the given source to dest.
+        *
+        * @param dest                  target destination address
+        * @param src                   source address to check, or NULL
+        * @return                              outgoing source address, NULL if unreachable
+        */
+       host_t* (*get_source_addr)(kernel_net_t *this, host_t *dest, host_t *src);
+
+       /**
+        * Get the next hop for a destination.
+        *
+        * Does a route lookup to get the next hop used to reach dest.
+        * The returned host is allocated and must be destroyed.
+        * An optional src address can be used to check if a route is available
+        * for the given source to dest.
+        *
+        * @param dest                  target destination address
+        * @param prefix                prefix length if dest is a subnet, -1 for auto
+        * @param src                   source address to check, or NULL
+        * @return                              next hop address, NULL if unreachable
+        */
+       host_t* (*get_nexthop)(kernel_net_t *this, host_t *dest, int prefix,
+                                                  host_t *src);
+
+       /**
+        * Get the interface name of a local address. Interfaces that are down or
+        * ignored by config are not considered.
+        *
+        * @param host                  address to get interface name from
+        * @param name                  allocated interface name (optional)
+        * @return                              TRUE if interface found and usable
+        */
+       bool (*get_interface) (kernel_net_t *this, host_t *host, char **name);
+
+       /**
+        * Creates an enumerator over all local addresses.
+        *
+        * This function blocks an internal cached address list until the
+        * enumerator gets destroyed.
+        * The hosts are read-only, do not modify of free.
+        *
+        * @param which                 a combination of address types to enumerate
+        * @return                              enumerator over host_t's
+        */
+       enumerator_t *(*create_address_enumerator) (kernel_net_t *this,
+                                                                                               kernel_address_type_t which);
+
+       /**
+        * Add a virtual IP to an interface.
+        *
+        * Virtual IPs are attached to an interface. If an IP is added multiple
+        * times, the IP is refcounted and not removed until del_ip() was called
+        * as many times as add_ip().
+        *
+        * @param virtual_ip    virtual ip address to assign
+        * @param prefix                prefix length to install with IP address, -1 for auto
+        * @param iface                 interface to install virtual IP on
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*add_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix,
+                                               char *iface);
+
+       /**
+        * Remove a virtual IP from an interface.
+        *
+        * The kernel interface uses refcounting, see add_ip().
+        *
+        * @param virtual_ip    virtual ip address to remove
+        * @param prefix                prefix length of the IP to uninstall, -1 for auto
+        * @param wait                  TRUE to wait until IP is gone
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_ip) (kernel_net_t *this, host_t *virtual_ip, int prefix,
+                                               bool wait);
+
+       /**
+        * Add a route.
+        *
+        * @param dst_net               destination net
+        * @param prefixlen             destination net prefix length
+        * @param gateway               gateway for this route
+        * @param src_ip                source ip of the route
+        * @param if_name               name of the interface the route is bound to
+        * @return                              SUCCESS if operation completed
+        *                                              ALREADY_DONE if the route already exists
+        */
+       status_t (*add_route) (kernel_net_t *this, chunk_t dst_net,
+                                                  u_int8_t prefixlen, host_t *gateway, host_t *src_ip,
+                                                  char *if_name);
+
+       /**
+        * Delete a route.
+        *
+        * @param dst_net               destination net
+        * @param prefixlen             destination net prefix length
+        * @param gateway               gateway for this route
+        * @param src_ip                source ip of the route
+        * @param if_name               name of the interface the route is bound to
+        * @return                              SUCCESS if operation completed
+        */
+       status_t (*del_route) (kernel_net_t *this, chunk_t dst_net,
+                                                  u_int8_t prefixlen, host_t *gateway, host_t *src_ip,
+                                                  char *if_name);
+
+       /**
+        * Destroy the implementation.
+        */
+       void (*destroy) (kernel_net_t *this);
+};
+
+/**
+ * Helper function to (un-)register net kernel interfaces from plugin features.
+ *
+ * This function is a plugin_feature_callback_t and can be used with the
+ * PLUGIN_CALLBACK macro to register an net kernel interface constructor.
+ *
+ * @param plugin               plugin registering the kernel interface
+ * @param feature              associated plugin feature
+ * @param reg                  TRUE to register, FALSE to unregister
+ * @param data                 data passed to callback, an kernel_net_constructor_t
+ */
+bool kernel_net_register(plugin_t *plugin, plugin_feature_t *feature,
+                                                bool reg, void *data);
+
+#endif /** KERNEL_NET_H_ @}*/
index a2f2016..ee357ca 100644 (file)
@@ -20,7 +20,6 @@
 
 #include "receiver.h"
 
-#include <hydra.h>
 #include <daemon.h>
 #include <network/socket.h>
 #include <processing/jobs/job.h>
@@ -451,9 +450,8 @@ static job_requeue_t receive_packets(private_receiver_t *this)
 
        dst = packet->get_destination(packet);
        src = packet->get_source(packet);
-       if (!hydra->kernel_interface->all_interfaces_usable(hydra->kernel_interface)
-               && !hydra->kernel_interface->get_interface(hydra->kernel_interface,
-                                                                                                  dst, NULL))
+       if (!charon->kernel->all_interfaces_usable(charon->kernel)
+               && !charon->kernel->get_interface(charon->kernel, dst, NULL))
        {
                DBG3(DBG_NET, "received packet from %#H to %#H on ignored interface",
                         src, dst);
index 33ee60d..ddb2706 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 1a0d6e6..e606a83 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 79c61b5..9f82f6e 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 6bc7e77..ecbb76d 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 366c902..e65ef36 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index b8c241d..d2d38ef 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_PIDDIR=\"${piddir}\"
 
index cc4d0ec..561efa0 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index badc7b7..62695aa 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 3c09db0..9ae68be 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index b8c1b40..0fd1d33 100644 (file)
@@ -31,7 +31,6 @@
 #include <threading/condvar.h>
 #include <threading/thread.h>
 
-#include <hydra.h>
 #include <daemon.h>
 #include <processing/jobs/callback_job.h>
 
@@ -209,8 +208,7 @@ static int prepare_dhcp(private_dhcp_socket_t *this,
        else
        {
                /* act as relay agent */
-               src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
-                                                                                                          this->dst, NULL);
+               src = charon->kernel->get_source_addr(charon->kernel, this->dst, NULL);
                if (src)
                {
                        memcpy(&dhcp->gateway_address, src->get_address(src).ptr,
index 1455625..8181bfc 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 338a114..32b850c 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_PIDDIR=\"${piddir}\"
 
index 75e8eaf..5d7ab84 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka
 
index ec145a3..d68bfc4 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka
 
index 58b827a..fd08846 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index c3a12ba..a7d1f62 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 6c5b43f..4c44962 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS =  \
index 16aa191..b27e8cc 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 4276a08..ded9bbe 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 8960b84..ef22616 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libtls
 
index bc7a776..78cf991 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libradius
 
index f681385..8d93077 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka
 
index c38e55e..5c5694c 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka \
        -DIPSEC_CONFDIR=\"${sysconfdir}\"
index 2292204..5e235e7 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka
 
index f40efbd..c0d7b91 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka
 
index 0fb6222..9e55bb1 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka
 
index b7d6fd4..f4c478d 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libsimaka \
        -DIPSEC_CONFDIR=\"${sysconfdir}\"
index 825beb8..551ecb3 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libtls
 
index 6fc78bc..186ae45 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libtls \
        -I$(top_srcdir)/src/libtncif \
index 3a7a8cd..3db20e3 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libtls \
        -I$(top_srcdir)/src/libradius
index 1c64bd2..766bb4c 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_PIDDIR=\"${piddir}\"
 
index d51ea88..7028819 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 0d862b0..6d96f3a 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index ce57313..7753529 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 07a3d49..40aaa7f 100644 (file)
@@ -27,7 +27,6 @@
 #include <ifaddrs.h>
 #include <net/if.h>
 
-#include <hydra.h>
 #include <daemon.h>
 #include <threading/thread.h>
 #include <processing/jobs/callback_job.h>
@@ -428,8 +427,7 @@ METHOD(forecast_forwarder_t, destroy, void,
                lib->watcher->remove(lib->watcher, this->kernel.pkt);
                close(this->kernel.pkt);
        }
-       hydra->kernel_interface->remove_listener(hydra->kernel_interface,
-                                                                                        &this->kernel.listener);
+       charon->kernel->remove_listener(charon->kernel, &this->kernel.listener);
        free(this);
 }
 
@@ -486,8 +484,8 @@ forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener)
 
        setup_interface(&this->kernel);
 
-       hydra->kernel_interface->add_listener(hydra->kernel_interface,
-                                                                                 &this->kernel.listener);
+       charon->kernel->add_listener(charon->kernel,
+                                                                                  &this->kernel.listener);
 
        lib->watcher->add(lib->watcher, this->kernel.pkt, WATCHER_READ,
                                          (watcher_cb_t)receive_casts, this);
index 50d3423..d501834 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -DIPSEC_PIDDIR=\"${piddir}\"
 
index aed63c1..b893300 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index 56946ae..7075701 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon
 
 AM_CFLAGS = \
index a4be404..6a8a968 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "kernel_iph_net.h"
 
-#include <hydra.h>
+#include <daemon.h>
 #include <threading/mutex.h>
 #include <collections/linked_list.h>
 #include <processing/jobs/callback_job.h>
@@ -130,7 +130,7 @@ static job_requeue_t roam_event(private_kernel_iph_net_t *this)
        this->roam_address = FALSE;
        this->mutex->unlock(this->mutex);
 
-       hydra->kernel_interface->roam(hydra->kernel_interface, address);
+       charon->kernel->roam(charon->kernel, address);
        return JOB_REQUEUE_NONE;
 }
 
index c5475e3..c163814 100644 (file)
@@ -17,8 +17,6 @@
 #include "kernel_iph_plugin.h"
 #include "kernel_iph_net.h"
 
-#include <hydra.h>
-
 typedef struct private_kernel_iph_plugin_t private_kernel_iph_plugin_t;
 
 /**
index eca2b23..4757280 100644 (file)
@@ -1,6 +1,5 @@
 AM_CPPFLAGS = \
        -I$(top_srcdir)/src/libstrongswan \
-       -I$(top_srcdir)/src/libhydra \
        -I$(top_srcdir)/src/libcharon \
        -I$(top_srcdir)/src/libipsec
 
index 9f5f4ed..4c8771e 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <library.h>
 #include <ipsec.h>
-#include <hydra.h>
+#include <daemon.h>
 #include <networking/tun_device.h>
 #include <threading/mutex.h>
 #include <utils/debug.h>
@@ -224,8 +224,7 @@ static inline bool policy_entry_equals(policy_entry_t *a,
  */
 static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard)
 {
-       hydra->kernel_interface->expire(hydra->kernel_interface, protocol,
-                                                                       spi, dst, hard);
+       charon->kernel->expire(charon->kernel, protocol, spi, dst, hard);
 }
 
 METHOD(kernel_ipsec_t, get_features, kernel_feature_t,
@@ -313,16 +312,13 @@ static void add_exclude_route(private_kernel_libipsec_ipsec_t *this,
        if (!route->exclude)
        {
                DBG2(DBG_KNL, "installing new exclude route for %H src %H", dst, src);
-               gtw = hydra->kernel_interface->get_nexthop(hydra->kernel_interface,
-                                                                                                  dst, -1, NULL);
+               gtw = charon->kernel->get_nexthop(charon->kernel, dst, -1, NULL);
                if (gtw)
                {
                        char *if_name = NULL;
 
-                       if (hydra->kernel_interface->get_interface(
-                                                                       hydra->kernel_interface, src, &if_name) &&
-                               hydra->kernel_interface->add_route(hydra->kernel_interface,
-                                                                       dst->get_address(dst),
+                       if (charon->kernel->get_interface(charon->kernel, src, &if_name) &&
+                               charon->kernel->add_route(charon->kernel, dst->get_address(dst),
                                                                        dst->get_family(dst) == AF_INET ? 32 : 128,
                                                                        gtw, src, if_name) == SUCCESS)
                        {
@@ -367,14 +363,12 @@ static void remove_exclude_route(private_kernel_libipsec_ipsec_t *this,
        dst = route->exclude->dst;
        DBG2(DBG_KNL, "uninstalling exclude route for %H src %H",
                 dst, route->exclude->src);
-       if (hydra->kernel_interface->get_interface(
-                                                                       hydra->kernel_interface,
-                                                                       route->exclude->src, &if_name) &&
-               hydra->kernel_interface->del_route(hydra->kernel_interface,
-                                                                       dst->get_address(dst),
-                                                                       dst->get_family(dst) == AF_INET ? 32 : 128,
-                                                                       route->exclude->gtw, route->exclude->src,
-                                                                       if_name) != SUCCESS)
+       if (charon->kernel->get_interface(charon->kernel, route->exclude->src,
+                                                                         &if_name) &&
+               charon->kernel->del_route(charon->kernel, dst->get_address(dst),
+                                                                 dst->get_family(dst) == AF_INET ? 32 : 128,
+                                                                 route->exclude->gtw, route->exclude->src,
+                                                                 if_name) != SUCCESS)
        {
                DBG1(DBG_KNL, "uninstalling exclude route for %H failed", dst);
        }
@@ -402,8 +396,8 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this,
                return TRUE;
        }
 
-       if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface,
-                                                                       src_ts, &src_ip, &is_virtual) != SUCCESS)
+       if (charon->kernel->get_address_by_ts(charon->kernel, src_ts, &src_ip,
+                                                                                 &is_virtual) != SUCCESS)
        {
                traffic_selector_t *multicast, *broadcast = NULL;
                bool ignore = FALSE;
@@ -444,8 +438,7 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this,
        );
 #ifndef __linux__
        /* on Linux we cant't install a gateway */
-       route->gateway = hydra->kernel_interface->get_nexthop(
-                                                                               hydra->kernel_interface, dst, -1, src);
+       route->gateway = charon->kernel->get_nexthop(charon->kernel, dst, -1, src);
 #endif
 
        if (policy->route)
@@ -459,9 +452,9 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this,
                        return TRUE;
                }
                /* uninstall previously installed route */
-               if (hydra->kernel_interface->del_route(hydra->kernel_interface,
-                                                                       old->dst_net, old->prefixlen, old->gateway,
-                                                                       old->src_ip, old->if_name) != SUCCESS)
+               if (charon->kernel->del_route(charon->kernel, old->dst_net,
+                                                                         old->prefixlen, old->gateway,
+                                                                         old->src_ip, old->if_name) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with policy "
                                 "%R === %R %N", src_ts, dst_ts, policy_dir_names,
@@ -490,9 +483,9 @@ static bool install_route(private_kernel_libipsec_ipsec_t *this,
        DBG2(DBG_KNL, "installing route: %R src %H dev %s",
                 dst_ts, route->src_ip, route->if_name);
 
-       switch (hydra->kernel_interface->add_route(hydra->kernel_interface,
-                                                       route->dst_net, route->prefixlen, route->gateway,
-                                                       route->src_ip, route->if_name))
+       switch (charon->kernel->add_route(charon->kernel, route->dst_net,
+                                                                         route->prefixlen, route->gateway,
+                                                                         route->src_ip, route->if_name))
        {
                case ALREADY_DONE:
                        /* route exists, do not uninstall */
@@ -598,9 +591,9 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
        {
                route_entry_t *route = policy->route;
 
-               if (hydra->kernel_interface->del_route(hydra->kernel_interface,
-                               route->dst_net, route->prefixlen, route->gateway, route->src_ip,
-                               route->if_name) != SUCCESS)
+               if (charon->kernel->del_route(charon->kernel, route->dst_net,
+                                                                         route->prefixlen, route->gateway,
+                                                                         route->src_ip, route->if_name) != SUCCESS)
                {
                        DBG1(DBG_KNL, "error uninstalling route installed with "
                                                  "policy %R === %R %N", src_ts, dst_ts,
@@ -629,9 +622,9 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
                {
                        route_entry_t *route = pol->route;
 
-                       hydra->kernel_interface->del_route(hydra->kernel_interface,
-                                       route->dst_net, route->prefixlen, route->gateway,
-                                       route->src_ip, route->if_name);
+                       charon->kernel->del_route(charon->kernel, route->dst_net,
+                                                                         route->prefixlen, route->gateway,
+                                                                         route->src_ip, route->if_name);
                        remove_exclude_route(this, route);
                }
                policy_entry_destroy(pol);
index 830954e..66141ad 100644 (file)
@@ -19,7 +19,6 @@
 #include "kernel_libipsec_router.h"
 
 #include <daemon.h>
-#include <hydra.h>
 #include <ipsec.h>
 #include <collections/hashtable.h>
 #include <networking/tun_device.h>
@@ -298,8 +297,7 @@ METHOD(kernel_libipsec_router_t, destroy, void,
                                                                                 (ipsec_outbound_cb_t)send_esp);
        ipsec->processor->unregister_inbound(ipsec->processor,
                                                                                 (ipsec_inbound_cb_t)deliver_plain);
-       hydra->kernel_interface->remove_listener(hydra->kernel_interface,
-                                                                                        &this->public.listener);
+       charon->kernel->remove_listener(charon->kernel, &this->public.listener);
        this->lock->destroy(this->lock);
        this->tuns->destroy(this->tuns);
        close(this->notify[0]);
@@ -351,8 +349,7 @@ kernel_libipsec_router_t *kernel_libipsec_router_create()
                                                                  (hashtable_equals_t)tun_entry_equals, 4);
        this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
 
-       hydra->kernel_interface->add_listener(hydra->kernel_interface,
-                                                                                 &this->public.listener);
+       charon->kernel->add_listener(charon->kernel, &this->public.listener);
        ipsec->processor->register_outbound(ipsec->processor, send_esp, NULL);
        ipsec->processor->register_inbound(ipsec->processor,
                                                                        (ipsec_inbound_cb_t)deliver_plain, this);
diff --git a/src/libcharon/plugins/kernel_netlink/.gitignore b/src/libcharon/plugins/kernel_netlink/.gitignore
new file mode 100644 (file)
index 0000000..2b29f27
--- /dev/null
@@ -0,0 +1 @@
+tests
diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.am b/src/libcharon/plugins/kernel_netlink/Makefile.am
new file mode 100644 (file)
index 0000000..973e2c2
--- /dev/null
@@ -0,0 +1,44 @@
+AM_CPPFLAGS = \
+       -I${linux_headers} \
+       -I$(top_srcdir)/src/libstrongswan \
+       -I$(top_srcdir)/src/libcharon \
+       -DROUTING_TABLE=${routing_table} \
+       -DROUTING_TABLE_PRIO=${routing_table_prio}
+
+AM_CFLAGS = \
+       $(PLUGIN_CFLAGS)
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-kernel-netlink.la
+else
+plugin_LTLIBRARIES = libstrongswan-kernel-netlink.la
+endif
+
+libstrongswan_kernel_netlink_la_SOURCES = \
+       kernel_netlink_plugin.h kernel_netlink_plugin.c \
+       kernel_netlink_ipsec.h kernel_netlink_ipsec.c \
+       kernel_netlink_net.h kernel_netlink_net.c \
+       kernel_netlink_shared.h kernel_netlink_shared.c
+
+libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version
+
+
+TESTS = tests
+
+check_PROGRAMS = $(TESTS)
+
+tests_SOURCES = \
+       tests.h tests.c \
+       suites/test_socket.c \
+       kernel_netlink_shared.c
+
+tests_CFLAGS = \
+       -I$(top_srcdir)/src/libstrongswan \
+       -I$(top_srcdir)/src/libstrongswan/tests \
+       -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \
+       @COVERAGE_CFLAGS@
+
+tests_LDFLAGS = @COVERAGE_LDFLAGS@
+tests_LDADD = \
+       $(top_builddir)/src/libstrongswan/libstrongswan.la \
+       $(top_builddir)/src/libstrongswan/tests/libtest.la
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
new file mode 100644 (file)
index 0000000..275aa6c
--- /dev/null
@@ -0,0 +1,2963 @@
+/*
+ * Copyright (C) 2006-2015 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
+ * Copyright (C) 2008 Andreas Steffen
+ * Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
+ * Copyright (C) 2006 Daniel Roethlisberger
+ * Copyright (C) 2005 Jan Hutter
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+#include <linux/ipsec.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/xfrm.h>
+#include <linux/udp.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "kernel_netlink_ipsec.h"
+#include "kernel_netlink_shared.h"
+
+#include <daemon.h>
+#include <utils/debug.h>
+#include <threading/mutex.h>
+#include <collections/array.h>
+#include <collections/hashtable.h>
+#include <collections/linked_list.h>
+
+/** Required for Linux 2.6.26 kernel and later */
+#ifndef XFRM_STATE_AF_UNSPEC
+#define XFRM_STATE_AF_UNSPEC 32
+#endif
+
+/** From linux/in.h */
+#ifndef IP_XFRM_POLICY
+#define IP_XFRM_POLICY 17
+#endif
+
+/** Missing on uclibc */
+#ifndef IPV6_XFRM_POLICY
+#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
+
+/** Base priority for installed policies */
+#define PRIO_BASE 384
+
+/** Default lifetime of an acquire XFRM state (in seconds) */
+#define DEFAULT_ACQUIRE_LIFETIME 165
+
+/**
+ * Map the limit for bytes and packets to XFRM_INF by default
+ */
+#define XFRM_LIMIT(x) ((x) == 0 ? XFRM_INF : (x))
+
+/**
+ * Create ORable bitfield of XFRM NL groups
+ */
+#define XFRMNLGRP(x) (1<<(XFRMNLGRP_##x-1))
+
+/**
+ * Returns a pointer to the first rtattr following the nlmsghdr *nlh and the
+ * 'usual' netlink data x like 'struct xfrm_usersa_info'
+ */
+#define XFRM_RTA(nlh, x) ((struct rtattr*)(NLMSG_DATA(nlh) + \
+                                                                                  NLMSG_ALIGN(sizeof(x))))
+/**
+ * Returns the total size of attached rta data
+ * (after 'usual' netlink data x like 'struct xfrm_usersa_info')
+ */
+#define XFRM_PAYLOAD(nlh, x) NLMSG_PAYLOAD(nlh, sizeof(x))
+
+typedef struct kernel_algorithm_t kernel_algorithm_t;
+
+/**
+ * Mapping of IKEv2 kernel identifier to linux crypto API names
+ */
+struct kernel_algorithm_t {
+       /**
+        * Identifier specified in IKEv2
+        */
+       int ikev2;
+
+       /**
+        * Name of the algorithm in linux crypto API
+        */
+       char *name;
+};
+
+ENUM(xfrm_msg_names, XFRM_MSG_NEWSA, XFRM_MSG_MAPPING,
+       "XFRM_MSG_NEWSA",
+       "XFRM_MSG_DELSA",
+       "XFRM_MSG_GETSA",
+       "XFRM_MSG_NEWPOLICY",
+       "XFRM_MSG_DELPOLICY",
+       "XFRM_MSG_GETPOLICY",
+       "XFRM_MSG_ALLOCSPI",
+       "XFRM_MSG_ACQUIRE",
+       "XFRM_MSG_EXPIRE",
+       "XFRM_MSG_UPDPOLICY",
+       "XFRM_MSG_UPDSA",
+       "XFRM_MSG_POLEXPIRE",
+       "XFRM_MSG_FLUSHSA",
+       "XFRM_MSG_FLUSHPOLICY",
+       "XFRM_MSG_NEWAE",
+       "XFRM_MSG_GETAE",
+       "XFRM_MSG_REPORT",
+       "XFRM_MSG_MIGRATE",
+       "XFRM_MSG_NEWSADINFO",
+       "XFRM_MSG_GETSADINFO",
+       "XFRM_MSG_NEWSPDINFO",
+       "XFRM_MSG_GETSPDINFO",
+       "XFRM_MSG_MAPPING"
+);
+
+ENUM(xfrm_attr_type_names, XFRMA_UNSPEC, XFRMA_REPLAY_ESN_VAL,
+       "XFRMA_UNSPEC",
+       "XFRMA_ALG_AUTH",
+       "XFRMA_ALG_CRYPT",
+       "XFRMA_ALG_COMP",
+       "XFRMA_ENCAP",
+       "XFRMA_TMPL",
+       "XFRMA_SA",
+       "XFRMA_POLICY",
+       "XFRMA_SEC_CTX",
+       "XFRMA_LTIME_VAL",
+       "XFRMA_REPLAY_VAL",
+       "XFRMA_REPLAY_THRESH",
+       "XFRMA_ETIMER_THRESH",
+       "XFRMA_SRCADDR",
+       "XFRMA_COADDR",
+       "XFRMA_LASTUSED",
+       "XFRMA_POLICY_TYPE",
+       "XFRMA_MIGRATE",
+       "XFRMA_ALG_AEAD",
+       "XFRMA_KMADDRESS",
+       "XFRMA_ALG_AUTH_TRUNC",
+       "XFRMA_MARK",
+       "XFRMA_TFCPAD",
+       "XFRMA_REPLAY_ESN_VAL",
+);
+
+/**
+ * Algorithms for encryption
+ */
+static kernel_algorithm_t encryption_algs[] = {
+/*     {ENCR_DES_IV64,                         "***"                           }, */
+       {ENCR_DES,                                      "des"                           },
+       {ENCR_3DES,                                     "des3_ede"                      },
+/*     {ENCR_RC5,                                      "***"                           }, */
+/*     {ENCR_IDEA,                                     "***"                           }, */
+       {ENCR_CAST,                                     "cast5"                         },
+       {ENCR_BLOWFISH,                         "blowfish"                      },
+/*     {ENCR_3IDEA,                            "***"                           }, */
+/*     {ENCR_DES_IV32,                         "***"                           }, */
+       {ENCR_NULL,                                     "cipher_null"           },
+       {ENCR_AES_CBC,                          "aes"                           },
+       {ENCR_AES_CTR,                          "rfc3686(ctr(aes))"     },
+       {ENCR_AES_CCM_ICV8,                     "rfc4309(ccm(aes))"     },
+       {ENCR_AES_CCM_ICV12,            "rfc4309(ccm(aes))"     },
+       {ENCR_AES_CCM_ICV16,            "rfc4309(ccm(aes))"     },
+       {ENCR_AES_GCM_ICV8,                     "rfc4106(gcm(aes))"     },
+       {ENCR_AES_GCM_ICV12,            "rfc4106(gcm(aes))"     },
+       {ENCR_AES_GCM_ICV16,            "rfc4106(gcm(aes))"     },
+       {ENCR_NULL_AUTH_AES_GMAC,       "rfc4543(gcm(aes))"     },
+       {ENCR_CAMELLIA_CBC,                     "cbc(camellia)"         },
+/*     {ENCR_CAMELLIA_CTR,                     "***"                           }, */
+/*     {ENCR_CAMELLIA_CCM_ICV8,        "***"                           }, */
+/*     {ENCR_CAMELLIA_CCM_ICV12,       "***"                           }, */
+/*     {ENCR_CAMELLIA_CCM_ICV16,       "***"                           }, */
+       {ENCR_SERPENT_CBC,                      "serpent"                       },
+       {ENCR_TWOFISH_CBC,                      "twofish"                       },
+       {ENCR_CHACHA20_POLY1305,        "rfc7539esp(chacha20,poly1305)"},
+};
+
+/**
+ * Algorithms for integrity protection
+ */
+static kernel_algorithm_t integrity_algs[] = {
+       {AUTH_HMAC_MD5_96,                      "md5"                           },
+       {AUTH_HMAC_MD5_128,                     "hmac(md5)"                     },
+       {AUTH_HMAC_SHA1_96,                     "sha1"                          },
+       {AUTH_HMAC_SHA1_160,            "hmac(sha1)"            },
+       {AUTH_HMAC_SHA2_256_96,         "sha256"                        },
+       {AUTH_HMAC_SHA2_256_128,        "hmac(sha256)"          },
+       {AUTH_HMAC_SHA2_384_192,        "hmac(sha384)"          },
+       {AUTH_HMAC_SHA2_512_256,        "hmac(sha512)"          },
+/*     {AUTH_DES_MAC,                          "***"                           }, */
+/*     {AUTH_KPDK_MD5,                         "***"                           }, */
+       {AUTH_AES_XCBC_96,                      "xcbc(aes)"                     },
+};
+
+/**
+ * Algorithms for IPComp
+ */
+static kernel_algorithm_t compression_algs[] = {
+/*     {IPCOMP_OUI,                            "***"                           }, */
+       {IPCOMP_DEFLATE,                        "deflate"                       },
+       {IPCOMP_LZS,                            "lzs"                           },
+       {IPCOMP_LZJH,                           "lzjh"                          },
+};
+
+/**
+ * Look up a kernel algorithm name and its key size
+ */
+static char* lookup_algorithm(transform_type_t type, int ikev2)
+{
+       kernel_algorithm_t *list;
+       int i, count;
+       char *name;
+
+       switch (type)
+       {
+               case ENCRYPTION_ALGORITHM:
+                       list = encryption_algs;
+                       count = countof(encryption_algs);
+                       break;
+               case INTEGRITY_ALGORITHM:
+                       list = integrity_algs;
+                       count = countof(integrity_algs);
+                       break;
+               case COMPRESSION_ALGORITHM:
+                       list = compression_algs;
+                       count = countof(compression_algs);
+                       break;
+               default:
+                       return NULL;
+       }
+       for (i = 0; i < count; i++)
+       {
+               if (list[i].ikev2 == ikev2)
+               {
+                       return list[i].name;
+               }
+       }
+       if (charon->kernel->lookup_algorithm(charon->kernel, ikev2, type, NULL,
+                                                                                &name))
+       {
+               return name;
+       }
+       return NULL;
+}
+
+typedef struct private_kernel_netlink_ipsec_t private_kernel_netlink_ipsec_t;
+
+/**
+ * Private variables and functions of kernel_netlink class.
+ */
+struct private_kernel_netlink_ipsec_t {
+       /**
+        * Public part of the kernel_netlink_t object
+        */
+       kernel_netlink_ipsec_t public;
+
+       /**
+        * Mutex to lock access to installed policies
+        */
+       mutex_t *mutex;
+
+       /**
+        * Hash table of installed policies (policy_entry_t)
+        */
+       hashtable_t *policies;
+
+       /**
+        * Hash table of IPsec SAs using policies (ipsec_sa_t)
+        */
+       hashtable_t *sas;
+
+       /**
+        * Netlink xfrm socket (IPsec)
+        */
+       netlink_socket_t *socket_xfrm;
+
+       /**
+        * Netlink xfrm socket to receive acquire and expire events
+        */
+       int socket_xfrm_events;
+
+       /**
+        * Whether to install routes along policies
+        */
+       bool install_routes;
+
+       /**
+        * Whether to set protocol and ports on selector installed with transport
+        * mode IPsec SAs
+        */
+       bool proto_port_transport;
+
+       /**
+        * Whether to always use UPDATE to install policies
+        */
+       bool policy_update;
+
+       /**
+        * Installed port based IKE bypass policies, as bypass_t
+        */
+       array_t *bypass;
+};
+
+typedef struct route_entry_t route_entry_t;
+
+/**
+ * Installed routing entry
+ */
+struct route_entry_t {
+       /** Name of the interface the route is bound to */
+       char *if_name;
+
+       /** Source ip of the route */
+       host_t *src_ip;
+
+       /** Gateway for this route */
+       host_t *gateway;
+
+       /** Destination net */
+       chunk_t dst_net;
+
+       /** Destination net prefixlen */
+       u_int8_t prefixlen;
+};
+
+/**
+ * Destroy a route_entry_t object
+ */
+static void route_entry_destroy(route_entry_t *this)
+{
+       free(this->if_name);
+       this->src_ip->destroy(this->src_ip);
+       DESTROY_IF(this->gateway);
+       chunk_free(&this->dst_net);
+       free(this);
+}
+
+/**
+ * Compare two route_entry_t objects
+ */
+static bool route_entry_equals(route_entry_t *a, route_entry_t *b)
+{
+       return a->if_name && b->if_name && streq(a->if_name, b->if_name) &&
+                  a->src_ip->ip_equals(a->src_ip, b->src_ip) &&
+                  a->gateway->ip_equals(a->gateway, b->gateway) &&
+                  chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen;
+}
+
+typedef struct ipsec_sa_t ipsec_sa_t;
+
+/**
+ * IPsec SA assigned to a policy.
+ */
+struct ipsec_sa_t {
+       /** Source address of this SA */
+       host_t *src;
+
+       /** Destination address of this SA */
+       host_t *dst;
+
+       /** Optional mark */
+       mark_t mark;
+
+       /** Description of this SA */
+       ipsec_sa_cfg_t cfg;
+
+       /** Reference count for this SA */
+       refcount_t refcount;
+};
+
+/**
+ * Hash function for ipsec_sa_t objects
+ */
+static u_int ipsec_sa_hash(ipsec_sa_t *sa)
+{
+       return chunk_hash_inc(sa->src->get_address(sa->src),
+                                                 chunk_hash_inc(sa->dst->get_address(sa->dst),
+                                                 chunk_hash_inc(chunk_from_thing(sa->mark),
+                                                 chunk_hash(chunk_from_thing(sa->cfg)))));
+}
+
+/**
+ * Equality function for ipsec_sa_t objects
+ */
+static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa)
+{
+       return sa->src->ip_equals(sa->src, other_sa->src) &&
+                  sa->dst->ip_equals(sa->dst, other_sa->dst) &&
+                  memeq(&sa->mark, &other_sa->mark, sizeof(mark_t)) &&
+                  memeq(&sa->cfg, &other_sa->cfg, sizeof(ipsec_sa_cfg_t));
+}
+
+/**
+ * Allocate or reference an IPsec SA object
+ */
+static ipsec_sa_t *ipsec_sa_create(private_kernel_netlink_ipsec_t *this,
+                                                                  host_t *src, host_t *dst, mark_t mark,
+                                                                  ipsec_sa_cfg_t *cfg)
+{
+       ipsec_sa_t *sa, *found;
+       INIT(sa,
+               .src = src,
+               .dst = dst,
+               .mark = mark,
+               .cfg = *cfg,
+       );
+       found = this->sas->get(this->sas, sa);
+       if (!found)
+       {
+               sa->src = src->clone(src);
+               sa->dst = dst->clone(dst);
+               this->sas->put(this->sas, sa, sa);
+       }
+       else
+       {
+               free(sa);
+               sa = found;
+       }
+       ref_get(&sa->refcount);
+       return sa;
+}
+
+/**
+ * Release and destroy an IPsec SA object
+ */
+static void ipsec_sa_destroy(private_kernel_netlink_ipsec_t *this,
+                                                        ipsec_sa_t *sa)
+{
+       if (ref_put(&sa->refcount))
+       {
+               this->sas->remove(this->sas, sa);
+               DESTROY_IF(sa->src);
+               DESTROY_IF(sa->dst);
+               free(sa);
+       }
+}
+
+typedef struct policy_sa_t policy_sa_t;
+typedef struct policy_sa_fwd_t policy_sa_fwd_t;
+
+/**
+ * Mapping between a policy and an IPsec SA.
+ */
+struct policy_sa_t {
+       /** Priority assigned to the policy when installed with this SA */
+       u_int32_t priority;
+
+       /** Type of the policy */
+       policy_type_t type;
+
+       /** Assigned SA */
+       ipsec_sa_t *sa;
+};
+
+/**
+ * For forward policies we also cache the traffic selectors in order to install
+ * the route.
+ */
+struct policy_sa_fwd_t {
+       /** Generic interface */
+       policy_sa_t generic;
+
+       /** Source traffic selector of this policy */
+       traffic_selector_t *src_ts;
+
+       /** Destination traffic selector of this policy */
+       traffic_selector_t *dst_ts;
+};
+
+/**
+ * Create a policy_sa(_fwd)_t object
+ */
+static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
+       policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst,
+       traffic_selector_t *src_ts, traffic_selector_t *dst_ts, mark_t mark,
+       ipsec_sa_cfg_t *cfg)
+{
+       policy_sa_t *policy;
+
+       if (dir == POLICY_FWD)
+       {
+               policy_sa_fwd_t *fwd;
+               INIT(fwd,
+                       .src_ts = src_ts->clone(src_ts),
+                       .dst_ts = dst_ts->clone(dst_ts),
+               );
+               policy = &fwd->generic;
+       }
+       else
+       {
+               INIT(policy, .priority = 0);
+       }
+       policy->type = type;
+       policy->sa = ipsec_sa_create(this, src, dst, mark, cfg);
+       return policy;
+}
+
+/**
+ * Destroy a policy_sa(_fwd)_t object
+ */
+static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir,
+                                                         private_kernel_netlink_ipsec_t *this)
+{
+       if (*dir == POLICY_FWD)
+       {
+               policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)policy;
+               fwd->src_ts->destroy(fwd->src_ts);
+               fwd->dst_ts->destroy(fwd->dst_ts);
+       }
+       ipsec_sa_destroy(this, policy->sa);
+       free(policy);
+}
+
+typedef struct policy_entry_t policy_entry_t;
+
+/**
+ * Installed kernel policy.
+ */
+struct policy_entry_t {
+
+       /** Direction of this policy: in, out, forward */
+       u_int8_t direction;
+
+       /** Parameters of installed policy */
+       struct xfrm_selector sel;
+
+       /** Optional mark */
+       u_int32_t mark;
+
+       /** Associated route installed for this policy */
+       route_entry_t *route;
+
+       /** List of SAs this policy is used by, ordered by priority */
+       linked_list_t *used_by;
+
+       /** reqid for this policy */
+       u_int32_t reqid;
+};
+
+/**
+ * Destroy a policy_entry_t object
+ */
+static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this,
+                                                                policy_entry_t *policy)
+{
+       if (policy->route)
+       {
+               route_entry_destroy(policy->route);
+       }
+       if (policy->used_by)
+       {
+               policy->used_by->invoke_function(policy->used_by,
+                                                                               (linked_list_invoke_t)policy_sa_destroy,
+                                                                                &policy->direction, this);
+               policy->used_by->destroy(policy->used_by);
+       }
+       free(policy);
+}
+
+/**
+ * Hash function for policy_entry_t objects
+ */
+static u_int policy_hash(policy_entry_t *key)
+{
+       chunk_t chunk = chunk_from_thing(key->sel);
+       return chunk_hash_inc(chunk, chunk_hash(chunk_from_thing(key->mark)));
+}
+
+/**
+ * Equality function for policy_entry_t objects
+ */
+static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key)
+{
+       return memeq(&key->sel, &other_key->sel, sizeof(struct xfrm_selector)) &&
+                  key->mark == other_key->mark &&
+                  key->direction == other_key->direction;
+}
+
+/**
+ * Calculate the priority of a policy
+ */
+static inline u_int32_t get_priority(policy_entry_t *policy,
+                                                                        policy_priority_t prio)
+{
+       u_int32_t priority = PRIO_BASE;
+       switch (prio)
+       {
+               case POLICY_PRIORITY_FALLBACK:
+                       priority <<= 1;
+                       /* fall-through */
+               case POLICY_PRIORITY_ROUTED:
+                       priority <<= 1;
+                       /* fall-through */
+               case POLICY_PRIORITY_DEFAULT:
+                       priority <<= 1;
+                       /* fall-through */
+               case POLICY_PRIORITY_PASS:
+                       break;
+       }
+       /* calculate priority based on selector size, small size = high prio */
+       priority -= policy->sel.prefixlen_s;
+       priority -= policy->sel.prefixlen_d;
+       priority <<= 2; /* make some room for the two flags */
+       priority += policy->sel.sport_mask || policy->sel.dport_mask ? 0 : 2;
+       priority += policy->sel.proto ? 0 : 1;
+       return priority;
+}
+
+/**
+ * Convert the general ipsec mode to the one defined in xfrm.h
+ */
+static u_int8_t mode2kernel(ipsec_mode_t mode)
+{
+       switch (mode)
+       {
+               case MODE_TRANSPORT:
+                       return XFRM_MODE_TRANSPORT;
+               case MODE_TUNNEL:
+                       return XFRM_MODE_TUNNEL;
+               case MODE_BEET:
+                       return XFRM_MODE_BEET;
+               default:
+                       return mode;
+       }
+}
+
+/**
+ * Convert a host_t to a struct xfrm_address
+ */
+static void host2xfrm(host_t *host, xfrm_address_t *xfrm)
+{
+       chunk_t chunk = host->get_address(host);
+       memcpy(xfrm, chunk.ptr, min(chunk.len, sizeof(xfrm_address_t)));
+}
+
+/**
+ * Convert a struct xfrm_address to a host_t
+ */
+static host_t* xfrm2host(int family, xfrm_address_t *xfrm, u_int16_t port)
+{
+       chunk_t chunk;
+
+       switch (family)
+       {
+               case AF_INET:
+                       chunk = chunk_create((u_char*)&xfrm->a4, sizeof(xfrm->a4));
+                       break;
+               case AF_INET6:
+                       chunk = chunk_create((u_char*)&xfrm->a6, sizeof(xfrm->a6));
+                       break;
+               default:
+                       return NULL;
+       }
+       return host_create_from_chunk(family, chunk, ntohs(port));
+}
+
+/**
+ * Convert a traffic selector address range to subnet and its mask.
+ */
+static void ts2subnet(traffic_selector_t* ts,
+                                         xfrm_address_t *net, u_int8_t *mask)
+{
+       host_t *net_host;
+       chunk_t net_chunk;
+
+       ts->to_subnet(ts, &net_host, mask);
+       net_chunk = net_host->get_address(net_host);
+       memcpy(net, net_chunk.ptr, net_chunk.len);
+       net_host->destroy(net_host);
+}
+
+/**
+ * Convert a traffic selector port range to port/portmask
+ */
+static void ts2ports(traffic_selector_t* ts,
+                                        u_int16_t *port, u_int16_t *mask)
+{
+       /* Linux does not seem to accept complex portmasks. Only
+        * any or a specific port is allowed. We set to any, if we have
+        * a port range, or to a specific, if we have one port only.
+        */
+       u_int16_t from, to;
+
+       from = ts->get_from_port(ts);
+       to = ts->get_to_port(ts);
+
+       if (from == to)
+       {
+               *port = htons(from);
+               *mask = ~0;
+       }
+       else
+       {
+               *port = 0;
+               *mask = 0;
+       }
+}
+
+/**
+ * Convert a pair of traffic_selectors to an xfrm_selector
+ */
+static struct xfrm_selector ts2selector(traffic_selector_t *src,
+                                                                               traffic_selector_t *dst)
+{
+       struct xfrm_selector sel;
+       u_int16_t port;
+
+       memset(&sel, 0, sizeof(sel));
+       sel.family = (src->get_type(src) == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
+       /* src or dest proto may be "any" (0), use more restrictive one */
+       sel.proto = max(src->get_protocol(src), dst->get_protocol(dst));
+       ts2subnet(dst, &sel.daddr, &sel.prefixlen_d);
+       ts2subnet(src, &sel.saddr, &sel.prefixlen_s);
+       ts2ports(dst, &sel.dport, &sel.dport_mask);
+       ts2ports(src, &sel.sport, &sel.sport_mask);
+       if ((sel.proto == IPPROTO_ICMP || sel.proto == IPPROTO_ICMPV6) &&
+               (sel.dport || sel.sport))
+       {
+               /* the kernel expects the ICMP type and code in the source and
+                * destination port fields, respectively. */
+               port = ntohs(max(sel.dport, sel.sport));
+               sel.sport = htons(traffic_selector_icmp_type(port));
+               sel.sport_mask = sel.sport ? ~0 : 0;
+               sel.dport = htons(traffic_selector_icmp_code(port));
+               sel.dport_mask = sel.dport ? ~0 : 0;
+       }
+       sel.ifindex = 0;
+       sel.user = 0;
+
+       return sel;
+}
+
+/**
+ * Convert an xfrm_selector to a src|dst traffic_selector
+ */
+static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src)
+{
+       u_char *addr;
+       u_int8_t prefixlen;
+       u_int16_t port = 0;
+       host_t *host = NULL;
+
+       if (src)
+       {
+               addr = (u_char*)&sel->saddr;
+               prefixlen = sel->prefixlen_s;
+               if (sel->sport_mask)
+               {
+                       port = ntohs(sel->sport);
+               }
+       }
+       else
+       {
+               addr = (u_char*)&sel->daddr;
+               prefixlen = sel->prefixlen_d;
+               if (sel->dport_mask)
+               {
+                       port = ntohs(sel->dport);
+               }
+       }
+       if (sel->proto == IPPROTO_ICMP || sel->proto == IPPROTO_ICMPV6)
+       {       /* convert ICMP[v6] message type and code as supplied by the kernel in
+                * source and destination ports (both in network order) */
+               port = (sel->sport >> 8) | (sel->dport & 0xff00);
+               port = ntohs(port);
+       }
+       /* The Linux 2.6 kernel does not set the selector's family field,
+        * so as a kludge we additionally test the prefix length.
+        */
+       if (sel->family == AF_INET || sel->prefixlen_s == 32)
+       {
+               host = host_create_from_chunk(AF_INET, chunk_create(addr, 4), 0);
+       }
+       else if (sel->family == AF_INET6 || sel->prefixlen_s == 128)
+       {
+               host = host_create_from_chunk(AF_INET6, chunk_create(addr, 16), 0);
+       }
+
+       if (host)
+       {
+               return traffic_selector_create_from_subnet(host, prefixlen,
+                                                                                       sel->proto, port, port ?: 65535);
+       }
+       return NULL;
+}
+
+/**
+ * Process a XFRM_MSG_ACQUIRE from kernel
+ */
+static void process_acquire(private_kernel_netlink_ipsec_t *this,
+                                                       struct nlmsghdr *hdr)
+{
+       struct xfrm_user_acquire *acquire;
+       struct rtattr *rta;
+       size_t rtasize;
+       traffic_selector_t *src_ts, *dst_ts;
+       u_int32_t reqid = 0;
+       int proto = 0;
+
+       acquire = NLMSG_DATA(hdr);
+       rta = XFRM_RTA(hdr, struct xfrm_user_acquire);
+       rtasize = XFRM_PAYLOAD(hdr, struct xfrm_user_acquire);
+
+       DBG2(DBG_KNL, "received a XFRM_MSG_ACQUIRE");
+
+       while (RTA_OK(rta, rtasize))
+       {
+               DBG2(DBG_KNL, "  %N", xfrm_attr_type_names, rta->rta_type);
+
+               if (rta->rta_type == XFRMA_TMPL)
+               {
+                       struct xfrm_user_tmpl* tmpl;
+                       tmpl = (struct xfrm_user_tmpl*)RTA_DATA(rta);
+                       reqid = tmpl->reqid;
+                       proto = tmpl->id.proto;
+               }
+               rta = RTA_NEXT(rta, rtasize);
+       }
+       switch (proto)
+       {
+               case 0:
+               case IPPROTO_ESP:
+               case IPPROTO_AH:
+                       break;
+               default:
+                       /* acquire for AH/ESP only, not for IPCOMP */
+                       return;
+       }
+       src_ts = selector2ts(&acquire->sel, TRUE);
+       dst_ts = selector2ts(&acquire->sel, FALSE);
+
+       charon->kernel->acquire(charon->kernel, reqid, src_ts, dst_ts);
+}
+
+/**
+ * Process a XFRM_MSG_EXPIRE from kernel
+ */
+static void process_expire(private_kernel_netlink_ipsec_t *this,
+                                                  struct nlmsghdr *hdr)
+{
+       struct xfrm_user_expire *expire;
+       u_int32_t spi;
+       u_int8_t protocol;
+       host_t *dst;
+
+       expire = NLMSG_DATA(hdr);
+       protocol = expire->state.id.proto;
+       spi = expire->state.id.spi;
+
+       DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE");
+
+       if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH)
+       {
+               dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0);
+               if (dst)
+               {
+                       charon->kernel->expire(charon->kernel, protocol, spi, dst,
+                                                                  expire->hard != 0);
+                       dst->destroy(dst);
+               }
+       }
+}
+
+/**
+ * Process a XFRM_MSG_MIGRATE from kernel
+ */
+static void process_migrate(private_kernel_netlink_ipsec_t *this,
+                                                       struct nlmsghdr *hdr)
+{
+       struct xfrm_userpolicy_id *policy_id;
+       struct rtattr *rta;
+       size_t rtasize;
+       traffic_selector_t *src_ts, *dst_ts;
+       host_t *local = NULL, *remote = NULL;
+       host_t *old_src = NULL, *old_dst = NULL;
+       host_t *new_src = NULL, *new_dst = NULL;
+       u_int32_t reqid = 0;
+       policy_dir_t dir;
+
+       policy_id = NLMSG_DATA(hdr);
+       rta     = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
+       rtasize = XFRM_PAYLOAD(hdr, struct xfrm_userpolicy_id);
+
+       DBG2(DBG_KNL, "received a XFRM_MSG_MIGRATE");
+
+       src_ts = selector2ts(&policy_id->sel, TRUE);
+       dst_ts = selector2ts(&policy_id->sel, FALSE);
+       dir = (policy_dir_t)policy_id->dir;
+
+       DBG2(DBG_KNL, "  policy: %R === %R %N", src_ts, dst_ts, policy_dir_names);
+
+       while (RTA_OK(rta, rtasize))
+       {
+               DBG2(DBG_KNL, "  %N", xfrm_attr_type_names, rta->rta_type);
+               if (rta->rta_type == XFRMA_KMADDRESS)
+               {
+                       struct xfrm_user_kmaddress *kmaddress;
+
+                       kmaddress = (struct xfrm_user_kmaddress*)RTA_DATA(rta);
+                       local  = xfrm2host(kmaddress->family, &kmaddress->local, 0);
+                       remote = xfrm2host(kmaddress->family, &kmaddress->remote, 0);
+                       DBG2(DBG_KNL, "  kmaddress: %H...%H", local, remote);
+               }
+               else if (rta->rta_type == XFRMA_MIGRATE)
+               {
+                       struct xfrm_user_migrate *migrate;
+
+                       migrate = (struct xfrm_user_migrate*)RTA_DATA(rta);
+                       old_src = xfrm2host(migrate->old_family, &migrate->old_saddr, 0);
+                       old_dst = xfrm2host(migrate->old_family, &migrate->old_daddr, 0);
+                       new_src = xfrm2host(migrate->new_family, &migrate->new_saddr, 0);
+                       new_dst = xfrm2host(migrate->new_family, &migrate->new_daddr, 0);
+                       reqid = migrate->reqid;
+                       DBG2(DBG_KNL, "  migrate %H...%H to %H...%H, reqid {%u}",
+                                                  old_src, old_dst, new_src, new_dst, reqid);
+                       DESTROY_IF(old_src);
+                       DESTROY_IF(old_dst);
+                       DESTROY_IF(new_src);
+                       DESTROY_IF(new_dst);
+               }
+               rta = RTA_NEXT(rta, rtasize);
+       }
+
+       if (src_ts && dst_ts && local && remote)
+       {
+               charon->kernel->migrate(charon->kernel, reqid, src_ts, dst_ts, dir,
+                                                               local, remote);
+       }
+       else
+       {
+               DESTROY_IF(src_ts);
+               DESTROY_IF(dst_ts);
+   &nbs