diff options
| author | Yves-Alexis Perez <corsac@debian.org> | 2013-10-17 21:23:38 +0200 |
|---|---|---|
| committer | Yves-Alexis Perez <corsac@debian.org> | 2013-10-17 21:23:38 +0200 |
| commit | 9d37ad77ef660b92ea51b69d74e14f931d2a04e2 (patch) | |
| tree | d6bbb4a5fed1959f8675df9ee7c03713b543fcc9 /src/libhydra/plugins/kernel_pfkey | |
| parent | 104f57d4b0fb6d7547d6898352eaa5fb4b222010 (diff) | |
| parent | e5ee4e7fcdd58b7d86bf1b458da2c63e8e19627b (diff) | |
| download | vyos-strongswan-9d37ad77ef660b92ea51b69d74e14f931d2a04e2.tar.gz vyos-strongswan-9d37ad77ef660b92ea51b69d74e14f931d2a04e2.zip | |
Merge tag 'v5.1.0-1' into sid
tag strongSwan 5.1.0-1
Diffstat (limited to 'src/libhydra/plugins/kernel_pfkey')
| -rw-r--r-- | src/libhydra/plugins/kernel_pfkey/Makefile.am | 8 | ||||
| -rw-r--r-- | src/libhydra/plugins/kernel_pfkey/Makefile.in | 151 | ||||
| -rw-r--r-- | src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 653 | ||||
| -rw-r--r-- | src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c | 6 |
4 files changed, 586 insertions, 232 deletions
diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.am b/src/libhydra/plugins/kernel_pfkey/Makefile.am index 1d1488a6b..bb5d0d7f7 100644 --- a/src/libhydra/plugins/kernel_pfkey/Makefile.am +++ b/src/libhydra/plugins/kernel_pfkey/Makefile.am @@ -1,8 +1,10 @@ - -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra -AM_CFLAGS = -rdynamic +AM_CFLAGS = \ + -rdynamic if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.in b/src/libhydra/plugins/kernel_pfkey/Makefile.in index 14c924b6f..fd95afd09 100644 --- a/src/libhydra/plugins/kernel_pfkey/Makefile.in +++ b/src/libhydra/plugins/kernel_pfkey/Makefile.in @@ -1,9 +1,9 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -16,6 +16,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -45,10 +62,11 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ $(top_srcdir)/m4/macros/with.m4 \ $(top_srcdir)/m4/macros/enable-disable.m4 \ $(top_srcdir)/m4/macros/add-plugin.m4 \ - $(top_srcdir)/configure.in + $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; @@ -72,6 +90,12 @@ am__nobase_list = $(am__nobase_strip_setup); \ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_kernel_pfkey_la_LIBADD = @@ -79,49 +103,77 @@ am_libstrongswan_kernel_pfkey_la_OBJECTS = kernel_pfkey_plugin.lo \ kernel_pfkey_ipsec.lo libstrongswan_kernel_pfkey_la_OBJECTS = \ $(am_libstrongswan_kernel_pfkey_la_OBJECTS) -libstrongswan_kernel_pfkey_la_LINK = $(LIBTOOL) --tag=CC \ +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +libstrongswan_kernel_pfkey_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) \ $(libstrongswan_kernel_pfkey_la_LDFLAGS) $(LDFLAGS) -o $@ @MONOLITHIC_FALSE@am_libstrongswan_kernel_pfkey_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_kernel_pfkey_la_rpath = -DEFAULT_INCLUDES = -I.@am__isrc@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libstrongswan_kernel_pfkey_la_SOURCES) DIST_SOURCES = $(libstrongswan_kernel_pfkey_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BFDLIB = @BFDLIB@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ @@ -130,13 +182,16 @@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ +GENHTML = @GENHTML@ GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ @@ -149,6 +204,7 @@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MYSQLCFLAG = @MYSQLCFLAG@ MYSQLCONFIG = @MYSQLCONFIG@ @@ -176,11 +232,13 @@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SOCKLIB = @SOCKLIB@ STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ VERSION = @VERSION@ YACC = @YACC@ YFLAGS = @YFLAGS@ @@ -188,6 +246,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ @@ -196,8 +255,6 @@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ attest_plugins = @attest_plugins@ -axis2c_CFLAGS = @axis2c_CFLAGS@ -axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -206,14 +263,19 @@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ datadir = @datadir@ datarootdir = @datarootdir@ dbusservicedir = @dbusservicedir@ -default_pkcs11 = @default_pkcs11@ +dev_headers = @dev_headers@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ h_plugins = @h_plugins@ @@ -227,17 +289,17 @@ imcvdir = @imcvdir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ ipsecdir = @ipsecdir@ ipsecgroup = @ipsecgroup@ ipseclibdir = @ipseclibdir@ ipsecuser = @ipsecuser@ -libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ libexecdir = @libexecdir@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ -lt_ECHO = @lt_ECHO@ maemo_CFLAGS = @maemo_CFLAGS@ maemo_LIBS = @maemo_LIBS@ manager_plugins = @manager_plugins@ @@ -247,16 +309,15 @@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ -p_plugins = @p_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ piddir = @piddir@ pki_plugins = @pki_plugins@ plugindir = @plugindir@ -pluto_plugins = @pluto_plugins@ pool_plugins = @pool_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ @@ -284,10 +345,14 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan \ +AM_CPPFLAGS = \ + -I${linux_headers} \ + -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra -AM_CFLAGS = -rdynamic +AM_CFLAGS = \ + -rdynamic + @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-kernel-pfkey.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la libstrongswan_kernel_pfkey_la_SOURCES = \ @@ -340,7 +405,6 @@ clean-noinstLTLIBRARIES: done install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -348,6 +412,8 @@ install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } @@ -369,8 +435,8 @@ clean-pluginLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done -libstrongswan-kernel-pfkey.la: $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_DEPENDENCIES) - $(libstrongswan_kernel_pfkey_la_LINK) $(am_libstrongswan_kernel_pfkey_la_rpath) $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_LIBADD) $(LIBS) +libstrongswan-kernel-pfkey.la: $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_pfkey_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_kernel_pfkey_la_LINK) $(am_libstrongswan_kernel_pfkey_la_rpath) $(libstrongswan_kernel_pfkey_la_OBJECTS) $(libstrongswan_kernel_pfkey_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -382,25 +448,25 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_pfkey_plugin.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< .c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -507,10 +573,15 @@ install-am: all-am installcheck: installcheck-am install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi mostlyclean-generic: clean-generic: diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index da10edffe..668c581e1 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2011 Tobias Brunner + * Copyright (C) 2008-2012 Tobias Brunner * Copyright (C) 2008 Andreas Steffen * Hochschule fuer Technik Rapperswil * @@ -51,17 +51,18 @@ #include <unistd.h> #include <time.h> #include <errno.h> +#ifdef __APPLE__ +#include <sys/sysctl.h> +#endif #include "kernel_pfkey_ipsec.h" #include <hydra.h> -#include <debug.h> -#include <utils/host.h> -#include <utils/linked_list.h> -#include <utils/hashtable.h> -#include <threading/thread.h> +#include <utils/debug.h> +#include <networking/host.h> +#include <collections/linked_list.h> +#include <collections/hashtable.h> #include <threading/mutex.h> -#include <processing/jobs/callback_job.h> /** non linux specific */ #ifndef IPPROTO_COMP @@ -99,6 +100,20 @@ #define IPV6_IPSEC_POLICY 34 #endif +/* from linux/udp.h */ +#ifndef UDP_ENCAP +#define UDP_ENCAP 100 +#endif + +#ifndef UDP_ENCAP_ESPINUDP +#define UDP_ENCAP_ESPINUDP 2 +#endif + +/* this is not defined on some platforms */ +#ifndef SOL_UDP +#define SOL_UDP IPPROTO_UDP +#endif + /** default priority of installed policies */ #define PRIO_BASE 512 @@ -163,6 +178,11 @@ struct private_kernel_pfkey_ipsec_t linked_list_t *policies; /** + * List of exclude routes (exclude_route_t) + */ + linked_list_t *excludes; + + /** * Hash table of IPsec SAs using policies (ipsec_sa_t) */ hashtable_t *sas; @@ -173,11 +193,6 @@ struct private_kernel_pfkey_ipsec_t bool install_routes; /** - * job receiving PF_KEY events - */ - callback_job_t *job; - - /** * mutex to lock access to the PF_KEY socket */ mutex_t *mutex_pfkey; @@ -198,6 +213,33 @@ struct private_kernel_pfkey_ipsec_t int seq; }; +typedef struct exclude_route_t exclude_route_t; + +/** + * Exclude route definition + */ +struct exclude_route_t { + /** destination address of exclude */ + host_t *dst; + /** source address for route */ + host_t *src; + /** nexthop exclude has been installed */ + host_t *gtw; + /** references to this route */ + int refs; +}; + +/** + * clean up a route exclude entry + */ +static void exclude_route_destroy(exclude_route_t *this) +{ + this->dst->destroy(this->dst); + this->src->destroy(this->src); + this->gtw->destroy(this->gtw); + free(this); +} + typedef struct route_entry_t route_entry_t; /** @@ -218,6 +260,9 @@ struct route_entry_t { /** destination net prefixlen */ u_int8_t prefixlen; + + /** reference to exclude route, if any */ + exclude_route_t *exclude; }; /** @@ -238,8 +283,9 @@ static void route_entry_destroy(route_entry_t *this) 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->equals(a->src_ip, b->src_ip) && - a->gateway->equals(a->gateway, b->gateway) && + a->src_ip->ip_equals(a->src_ip, b->src_ip) && + a->gateway && b->gateway && + a->gateway->ip_equals(a->gateway, b->gateway) && chunk_equals(a->dst_net, b->dst_net) && a->prefixlen == b->prefixlen; } @@ -327,7 +373,7 @@ static void ipsec_sa_destroy(private_kernel_pfkey_ipsec_t *this, } typedef struct policy_sa_t policy_sa_t; -typedef struct policy_sa_fwd_t policy_sa_fwd_t; +typedef struct policy_sa_in_t policy_sa_in_t; /** * Mapping between a policy and an IPsec SA. @@ -344,10 +390,10 @@ struct policy_sa_t { }; /** - * For forward policies we also cache the traffic selectors in order to install + * For input policies we also cache the traffic selectors in order to install * the route. */ -struct policy_sa_fwd_t { +struct policy_sa_in_t { /** Generic interface */ policy_sa_t generic; @@ -359,7 +405,7 @@ struct policy_sa_fwd_t { }; /** - * Create a policy_sa(_fwd)_t object + * Create a policy_sa(_in)_t object */ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this, policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst, @@ -367,14 +413,14 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this, { policy_sa_t *policy; - if (dir == POLICY_FWD) + if (dir == POLICY_IN) { - policy_sa_fwd_t *fwd; - INIT(fwd, + policy_sa_in_t *in; + INIT(in, .src_ts = src_ts->clone(src_ts), .dst_ts = dst_ts->clone(dst_ts), ); - policy = &fwd->generic; + policy = &in->generic; } else { @@ -386,16 +432,16 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this, } /** - * Destroy a policy_sa(_fwd)_t object + * Destroy a policy_sa(_in)_t object */ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, private_kernel_pfkey_ipsec_t *this) { - if (*dir == POLICY_FWD) + if (*dir == POLICY_IN) { - policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)policy; - fwd->src_ts->destroy(fwd->src_ts); - fwd->dst_ts->destroy(fwd->dst_ts); + policy_sa_in_t *in = (policy_sa_in_t*)policy; + in->src_ts->destroy(in->src_ts); + in->dst_ts->destroy(in->dst_ts); } ipsec_sa_destroy(this, policy->sa); free(policy); @@ -795,8 +841,22 @@ static kernel_algorithm_t compression_algs[] = { /** * Look up a kernel algorithm ID and its key size */ -static int lookup_algorithm(kernel_algorithm_t *list, int ikev2) +static int lookup_algorithm(transform_type_t type, int ikev2) { + kernel_algorithm_t *list; + u_int16_t alg = 0; + + switch (type) + { + case ENCRYPTION_ALGORITHM: + list = encryption_algs; + break; + case INTEGRITY_ALGORITHM: + list = integrity_algs; + break; + default: + return 0; + } while (list->ikev2 != END_OF_LIST) { if (ikev2 == list->ikev2) @@ -805,18 +865,21 @@ static int lookup_algorithm(kernel_algorithm_t *list, int ikev2) } list++; } - return 0; + hydra->kernel_interface->lookup_algorithm(hydra->kernel_interface, ikev2, + type, &alg, NULL); + return alg; } /** - * Copy a host_t as sockaddr_t to the given memory location. Ports are - * reset to zero as per RFC 2367. + * Copy a host_t as sockaddr_t to the given memory location. * @return the number of bytes copied */ -static size_t hostcpy(void *dest, host_t *host) +static size_t hostcpy(void *dest, host_t *host, bool include_port) { sockaddr_t *addr = host->get_sockaddr(host), *dest_addr = dest; socklen_t *len = host->get_sockaddr_len(host); + u_int16_t port = htons(host->get_port(host)); + memcpy(dest, addr, *len); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN dest_addr->sa_len = *len; @@ -826,13 +889,13 @@ static size_t hostcpy(void *dest, host_t *host) case AF_INET: { struct sockaddr_in *sin = dest; - sin->sin_port = 0; + sin->sin_port = include_port ? port : 0; break; } case AF_INET6: { struct sockaddr_in6 *sin6 = dest; - sin6->sin6_port = 0; + sin6->sin6_port = include_port ? port : 0; break; } } @@ -842,9 +905,9 @@ static size_t hostcpy(void *dest, host_t *host) /** * add a host behind an sadb_address extension */ -static void host2ext(host_t *host, struct sadb_address *ext) +static void host2ext(host_t *host, struct sadb_address *ext, bool include_port) { - size_t len = hostcpy(ext + 1, host); + size_t len = hostcpy(ext + 1, host, include_port); ext->sadb_address_len = PFKEY_LEN(sizeof(*ext) + len); } @@ -852,13 +915,13 @@ static void host2ext(host_t *host, struct sadb_address *ext) * add a host to the given sadb_msg */ static void add_addr_ext(struct sadb_msg *msg, host_t *host, u_int16_t type, - u_int8_t proto, u_int8_t prefixlen) + u_int8_t proto, u_int8_t prefixlen, bool include_port) { struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); addr->sadb_address_exttype = type; addr->sadb_address_proto = proto; addr->sadb_address_prefixlen = prefixlen; - host2ext(host, addr); + host2ext(host, addr, include_port); PFKEY_EXT_ADD(msg, addr); } @@ -916,6 +979,10 @@ static traffic_selector_t* sadb_address2ts(struct sadb_address *address) { traffic_selector_t *ts; host_t *host; + u_int8_t proto; + + proto = address->sadb_address_proto; + proto = proto == IPSEC_PROTO_ANY ? 0 : proto; /* The Linux 2.6 kernel does not set the protocol and port information * in the src and dst sadb_address extensions of the SADB_ACQUIRE message. @@ -923,8 +990,8 @@ static traffic_selector_t* sadb_address2ts(struct sadb_address *address) host = host_create_from_sockaddr((sockaddr_t*)&address[1]); ts = traffic_selector_create_from_subnet(host, address->sadb_address_prefixlen, - address->sadb_address_proto, - host->get_port(host)); + proto, host->get_port(host), + host->get_port(host) ?: 65535); return ts; } @@ -1060,7 +1127,7 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket } if (msg->sadb_msg_seq != this->seq) { - DBG1(DBG_KNL, "received PF_KEY message with unexpected sequence " + DBG2(DBG_KNL, "received PF_KEY message with unexpected sequence " "number, was %d expected %d", msg->sadb_msg_seq, this->seq); if (msg->sadb_msg_seq == 0) @@ -1292,11 +1359,13 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, { struct sockaddr_in *sin = (struct sockaddr_in*)sa; sin->sin_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); + break; } case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa; sin6->sin6_port = htons(response.x_natt_dport->sadb_x_nat_t_port_port); + break; } default: break; @@ -1314,31 +1383,28 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, /** * Receives events from kernel */ -static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) +static bool receive_events(private_kernel_pfkey_ipsec_t *this, int fd, + watcher_event_t event) { unsigned char buf[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg = (struct sadb_msg*)buf; - bool oldstate; int len; - oldstate = thread_cancelability(TRUE); - len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0); - thread_cancelability(oldstate); - + len = recvfrom(this->socket_events, buf, sizeof(buf), MSG_DONTWAIT, NULL, 0); if (len < 0) { switch (errno) { case EINTR: /* interrupted, try again */ - return JOB_REQUEUE_DIRECT; + return TRUE; case EAGAIN: /* no data ready, select again */ - return JOB_REQUEUE_DIRECT; + return TRUE; default: DBG1(DBG_KNL, "unable to receive from PF_KEY event socket"); sleep(1); - return JOB_REQUEUE_FAIR; + return TRUE; } } @@ -1346,17 +1412,17 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) { DBG2(DBG_KNL, "received corrupted PF_KEY message"); - return JOB_REQUEUE_DIRECT; + return TRUE; } if (msg->sadb_msg_pid != 0) { /* not from kernel. not interested, try another one */ - return JOB_REQUEUE_DIRECT; + return TRUE; } if (msg->sadb_msg_len > len / PFKEY_ALIGNMENT) { DBG1(DBG_KNL, "buffer was too small to receive the complete " "PF_KEY message"); - return JOB_REQUEUE_DIRECT; + return TRUE; } switch (msg->sadb_msg_type) @@ -1381,7 +1447,7 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) break; } - return JOB_REQUEUE_DIRECT; + return TRUE; } METHOD(kernel_ipsec_t, get_spi, status_t, @@ -1410,8 +1476,8 @@ METHOD(kernel_ipsec_t, get_spi, status_t, sa2->sadb_x_sa2_reqid = reqid; PFKEY_EXT_ADD(msg, sa2); - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg); range->sadb_spirange_exttype = SADB_EXT_SPIRANGE; @@ -1455,8 +1521,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, 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, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn, + bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts) { unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; @@ -1497,8 +1563,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, sa->sadb_sa_len = PFKEY_LEN(len); sa->sadb_sa_spi = spi; sa->sadb_sa_replay = (protocol == IPPROTO_COMP) ? 0 : 32; - sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg); - sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg); + sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg); + sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg); PFKEY_EXT_ADD(msg, sa); sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); @@ -1508,8 +1574,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, sa2->sadb_x_sa2_reqid = reqid; PFKEY_EXT_ADD(msg, sa2); - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; @@ -1639,7 +1705,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though * it is not used for anything. */ add_anyaddr_ext(msg, dst->get_family(dst), SADB_EXT_ADDRESS_SRC); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); if (pfkey_send(this, msg, &out, &len) != SUCCESS) { @@ -1735,7 +1801,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t, METHOD(kernel_ipsec_t, query_sa, status_t, private_kernel_pfkey_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_int32_t spi, u_int8_t protocol, mark_t mark, + u_int64_t *bytes, u_int64_t *packets, u_int32_t *time) { unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; @@ -1762,8 +1829,8 @@ METHOD(kernel_ipsec_t, query_sa, status_t, /* the Linux Kernel doesn't care for the src address, but other systems do * (e.g. FreeBSD) */ - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); if (pfkey_send(this, msg, &out, &len) != SUCCESS) { @@ -1784,7 +1851,27 @@ METHOD(kernel_ipsec_t, query_sa, status_t, free(out); return FAILED; } - *bytes = response.lft_current->sadb_lifetime_bytes; + if (bytes) + { + *bytes = response.lft_current->sadb_lifetime_bytes; + } + if (packets) + { + /* not supported by PF_KEY */ + *packets = 0; + } + if (time) + { +#ifdef __APPLE__ + /* OS X uses the "last" time of use in usetime */ + *time = response.lft_current->sadb_lifetime_usetime; +#else /* !__APPLE__ */ + /* on Linux, sadb_lifetime_usetime is set to the "first" time of use, + * which is actually correct according to PF_KEY. We have to query + * policies for the last usetime. */ + *time = 0; +#endif /* !__APPLE__ */ + } free(out); return SUCCESS; @@ -1818,8 +1905,8 @@ METHOD(kernel_ipsec_t, del_sa, status_t, /* the Linux Kernel doesn't care for the src address, but other systems do * (e.g. FreeBSD) */ - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0); - add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0); + add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); + add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); if (pfkey_send(this, msg, &out, &len) != SUCCESS) { @@ -1874,6 +1961,228 @@ METHOD(kernel_ipsec_t, flush_sas, status_t, } /** + * Add an explicit exclude route to a routing entry + */ +static void add_exclude_route(private_kernel_pfkey_ipsec_t *this, + route_entry_t *route, host_t *src, host_t *dst) +{ + enumerator_t *enumerator; + exclude_route_t *exclude; + host_t *gtw; + + enumerator = this->excludes->create_enumerator(this->excludes); + while (enumerator->enumerate(enumerator, &exclude)) + { + if (dst->ip_equals(dst, exclude->dst)) + { + route->exclude = exclude; + exclude->refs++; + } + } + enumerator->destroy(enumerator); + + 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, 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), + dst->get_family(dst) == AF_INET ? 32 : 128, + gtw, src, if_name) == SUCCESS) + { + INIT(exclude, + .dst = dst->clone(dst), + .src = src->clone(src), + .gtw = gtw->clone(gtw), + .refs = 1, + ); + route->exclude = exclude; + this->excludes->insert_last(this->excludes, exclude); + } + else + { + DBG1(DBG_KNL, "installing exclude route for %H failed", dst); + } + gtw->destroy(gtw); + free(if_name); + } + else + { + DBG1(DBG_KNL, "gateway lookup for for %H failed", dst); + } + } +} + +/** + * Remove an exclude route attached to a routing entry + */ +static void remove_exclude_route(private_kernel_pfkey_ipsec_t *this, + route_entry_t *route) +{ + if (route->exclude) + { + enumerator_t *enumerator; + exclude_route_t *exclude; + bool removed = FALSE; + host_t *dst; + + enumerator = this->excludes->create_enumerator(this->excludes); + while (enumerator->enumerate(enumerator, &exclude)) + { + if (route->exclude == exclude) + { + if (--exclude->refs == 0) + { + this->excludes->remove_at(this->excludes, enumerator); + removed = TRUE; + break; + } + } + } + enumerator->destroy(enumerator); + + if (removed) + { + char *if_name = NULL; + + 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) + { + DBG1(DBG_KNL, "uninstalling exclude route for %H failed", dst); + } + exclude_route_destroy(route->exclude); + free(if_name); + } + route->exclude = NULL; + } +} + +/** + * Try to install a route to the given inbound policy + */ +static bool install_route(private_kernel_pfkey_ipsec_t *this, + policy_entry_t *policy, policy_sa_in_t *in) +{ + route_entry_t *route, *old; + host_t *host, *src, *dst; + bool is_virtual; + + if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, + in->dst_ts, &host, &is_virtual) != SUCCESS) + { + return FALSE; + } + + /* switch src/dst, as we handle an IN policy */ + src = in->generic.sa->dst; + dst = in->generic.sa->src; + + INIT(route, + .prefixlen = policy->src.mask, + .src_ip = host, + .gateway = hydra->kernel_interface->get_nexthop( + hydra->kernel_interface, dst, src), + .dst_net = chunk_clone(policy->src.net->get_address(policy->src.net)), + ); + + /* if the IP is virtual, we install the route over the interface it has + * been installed on. Otherwise we use the interface we use for IKE, as + * this is required for example on Linux. */ + if (is_virtual) + { + src = route->src_ip; + } + + /* get interface for route, using source address */ + if (!hydra->kernel_interface->get_interface(hydra->kernel_interface, + src, &route->if_name)) + { + route_entry_destroy(route); + return FALSE; + } + + if (policy->route) + { + old = policy->route; + + if (route_entry_equals(old, route)) + { /* such a route already exists */ + route_entry_destroy(route); + 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) + { + DBG1(DBG_KNL, "error uninstalling route installed with policy " + "%R === %R %N", in->src_ts, in->dst_ts, + policy_dir_names, policy->direction); + } + route_entry_destroy(old); + policy->route = NULL; + } + + /* if remote traffic selector covers the IKE peer, add an exclude route */ + if (hydra->kernel_interface->get_features( + hydra->kernel_interface) & KERNEL_REQUIRE_EXCLUDE_ROUTE) + { + if (in->src_ts->is_host(in->src_ts, dst)) + { + DBG1(DBG_KNL, "can't install route for %R === %R %N, conflicts " + "with IKE traffic", in->src_ts, in->dst_ts, policy_dir_names, + policy->direction); + route_entry_destroy(route); + return FALSE; + } + if (in->src_ts->includes(in->src_ts, dst)) + { + add_exclude_route(this, route, in->generic.sa->dst, dst); + } + } + + DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s", + in->src_ts, route->gateway, 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)) + { + case ALREADY_DONE: + /* route exists, do not uninstall */ + remove_exclude_route(this, route); + route_entry_destroy(route); + return TRUE; + case SUCCESS: + /* cache the installed route */ + policy->route = route; + return TRUE; + default: + DBG1(DBG_KNL, "installing route failed: %R via %H src %H dev %s", + in->src_ts, route->gateway, route->src_ip, route->if_name); + remove_exclude_route(this, route); + route_entry_destroy(route); + return FALSE; + } +} + +/** * Add or update a policy in the kernel. * * Note: The mutex has to be locked when entering this function. @@ -1919,9 +2228,9 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, req->sadb_x_ipsecrequest_level = IPSEC_LEVEL_UNIQUE; if (ipsec->cfg.mode == MODE_TUNNEL) { - len = hostcpy(req + 1, ipsec->src); + len = hostcpy(req + 1, ipsec->src, FALSE); req->sadb_x_ipsecrequest_len += len; - len = hostcpy((char*)(req + 1) + len, ipsec->dst); + len = hostcpy((char*)(req + 1) + len, ipsec->dst, FALSE); req->sadb_x_ipsecrequest_len += len; } @@ -1929,9 +2238,9 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, PFKEY_EXT_ADD(msg, pol); add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, - policy->src.mask); + policy->src.mask, TRUE); add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, - policy->dst.mask); + policy->dst.mask, TRUE); #ifdef __FreeBSD__ { /* on FreeBSD a lifetime has to be defined to be able to later query @@ -1969,8 +2278,8 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, /* we try to find the policy again and update the kernel index */ this->mutex->lock(this->mutex); - if (this->policies->find_last(this->policies, NULL, - (void**)&policy) != SUCCESS) + if (this->policies->find_first(this->policies, NULL, + (void**)&policy) != SUCCESS) { DBG2(DBG_KNL, "unable to update index, the policy is already gone, " "ignoring"); @@ -1986,85 +2295,10 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, * - we are in tunnel mode * - routing is not disabled via strongswan.conf */ - if (policy->direction == POLICY_FWD && + if (policy->direction == POLICY_IN && ipsec->cfg.mode != MODE_TRANSPORT && this->install_routes) { - route_entry_t *route = malloc_thing(route_entry_t); - policy_sa_fwd_t *fwd = (policy_sa_fwd_t*)mapping; - - if (hydra->kernel_interface->get_address_by_ts(hydra->kernel_interface, - fwd->dst_ts, &route->src_ip) == SUCCESS) - { - /* get the nexthop to src (src as we are in POLICY_FWD).*/ - route->gateway = hydra->kernel_interface->get_nexthop( - hydra->kernel_interface, ipsec->src); - /* install route via outgoing interface */ - route->if_name = hydra->kernel_interface->get_interface( - hydra->kernel_interface, ipsec->dst); - route->dst_net = chunk_clone(policy->src.net->get_address( - policy->src.net)); - route->prefixlen = policy->src.mask; - - if (!route->if_name) - { - this->mutex->unlock(this->mutex); - route_entry_destroy(route); - return SUCCESS; - } - - if (policy->route) - { - route_entry_t *old = policy->route; - if (route_entry_equals(old, route)) - { /* keep previously installed route. since it might have - * still been removed by an address change, we install it - * again but ignore the result */ - hydra->kernel_interface->add_route(hydra->kernel_interface, - route->dst_net, route->prefixlen, route->gateway, - route->src_ip, route->if_name); - this->mutex->unlock(this->mutex); - route_entry_destroy(route); - return SUCCESS; - } - /* 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) - { - DBG1(DBG_KNL, "error uninstalling route installed with " - "policy %R === %R %N", fwd->src_ts, - fwd->dst_ts, policy_dir_names, - policy->direction); - } - route_entry_destroy(old); - policy->route = NULL; - } - - DBG2(DBG_KNL, "installing route: %R via %H src %H dev %s", - fwd->src_ts, route->gateway, 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)) - { - default: - DBG1(DBG_KNL, "unable to install source route for %H", - route->src_ip); - /* FALL */ - case ALREADY_DONE: - /* route exists, do not uninstall */ - route_entry_destroy(route); - break; - case SUCCESS: - /* cache the installed route */ - policy->route = route; - break; - } - } - else - { - free(route); - } + install_route(this, policy, (policy_sa_in_t*)mapping); } this->mutex->unlock(this->mutex); return SUCCESS; @@ -2102,7 +2336,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t, } else { /* use the new one, if we have no such policy */ - this->policies->insert_last(this->policies, policy); + this->policies->insert_first(this->policies, policy); policy->used_by = linked_list_create(); } @@ -2200,9 +2434,9 @@ METHOD(kernel_ipsec_t, query_policy, status_t, PFKEY_EXT_ADD(msg, pol); add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, - policy->src.mask); + policy->src.mask, TRUE); add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, - policy->dst.mask); + policy->dst.mask, TRUE); this->mutex->unlock(this->mutex); @@ -2230,7 +2464,7 @@ METHOD(kernel_ipsec_t, query_policy, status_t, } else if (response.lft_current == NULL) { - DBG1(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " + DBG2(DBG_KNL, "unable to query policy %R === %R %N: kernel reports no " "use time", src_ts, dst_ts, policy_dir_names, direction); free(out); return FAILED; @@ -2259,9 +2493,9 @@ METHOD(kernel_ipsec_t, del_policy, status_t, struct sadb_msg *msg, *out; struct sadb_x_policy *pol; policy_entry_t *policy, *found = NULL; - policy_sa_t *mapping; + policy_sa_t *mapping, *to_remove = NULL; enumerator_t *enumerator; - bool is_installed = TRUE; + bool first = TRUE, is_installed = TRUE; u_int32_t priority; size_t len; @@ -2291,19 +2525,31 @@ METHOD(kernel_ipsec_t, del_policy, status_t, policy_entry_destroy(policy, this); policy = found; - /* remove mapping to SA by reqid and priority */ + /* remove mapping to SA by reqid and priority, if multiple match, which + * could happen when rekeying due to an address change, remove the oldest */ priority = get_priority(policy, prio); enumerator = policy->used_by->create_enumerator(policy->used_by); while (enumerator->enumerate(enumerator, (void**)&mapping)) { if (reqid == mapping->sa->cfg.reqid && priority == mapping->priority) { - policy->used_by->remove_at(policy->used_by, enumerator); + to_remove = mapping; + is_installed = first; + } + else if (priority < mapping->priority) + { break; } - is_installed = FALSE; + first = FALSE; } enumerator->destroy(enumerator); + if (!to_remove) + { /* sanity check */ + this->mutex->unlock(this->mutex); + return SUCCESS; + } + policy->used_by->remove(policy->used_by, to_remove, NULL); + mapping = to_remove; if (policy->used_by->get_count(policy->used_by) > 0) { /* policy is used by more SAs, keep in kernel */ @@ -2344,9 +2590,9 @@ METHOD(kernel_ipsec_t, del_policy, status_t, PFKEY_EXT_ADD(msg, pol); add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, - policy->src.mask); + policy->src.mask, TRUE); add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, - policy->dst.mask); + policy->dst.mask, TRUE); if (policy->route) { @@ -2359,6 +2605,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, "policy %R === %R %N", src_ts, dst_ts, policy_dir_names, direction); } + remove_exclude_route(this, route); } this->policies->remove(this->policies, found, NULL); @@ -2497,25 +2744,49 @@ METHOD(kernel_ipsec_t, bypass_socket, bool, return TRUE; } -METHOD(kernel_ipsec_t, destroy, void, - private_kernel_pfkey_ipsec_t *this) +METHOD(kernel_ipsec_t, enable_udp_decap, bool, + private_kernel_pfkey_ipsec_t *this, int fd, int family, u_int16_t port) { - if (this->job) +#ifndef __APPLE__ + int type = UDP_ENCAP_ESPINUDP; + + if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0) { - this->job->cancel(this->job); + DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno)); + return FALSE; } +#else /* __APPLE__ */ + int intport = port; + + if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &intport, + sizeof(intport)) != 0) + { + DBG1(DBG_KNL, "could not set net.inet.ipsec.esp_port to %d: %s", + port, strerror(errno)); + return FALSE; + } +#endif /* __APPLE__ */ + + return TRUE; +} + +METHOD(kernel_ipsec_t, destroy, void, + private_kernel_pfkey_ipsec_t *this) +{ if (this->socket > 0) { close(this->socket); } if (this->socket_events > 0) { + lib->watcher->remove(lib->watcher, this->socket_events); close(this->socket_events); } this->policies->invoke_function(this->policies, (linked_list_invoke_t)policy_entry_destroy, this); this->policies->destroy(this->policies); + this->excludes->destroy(this->excludes); this->sas->destroy(this->sas); this->mutex->destroy(this->mutex); this->mutex_pfkey->destroy(this->mutex_pfkey); @@ -2528,6 +2799,7 @@ METHOD(kernel_ipsec_t, destroy, void, kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() { private_kernel_pfkey_ipsec_t *this; + bool register_for_events = TRUE; INIT(this, .public = { @@ -2544,10 +2816,12 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() .del_policy = _del_policy, .flush_policies = _flush_policies, .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, .destroy = _destroy, }, }, .policies = linked_list_create(), + .excludes = linked_list_create(), .sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash, (hashtable_equals_t)ipsec_sa_equals, 32), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), @@ -2557,9 +2831,9 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() hydra->daemon), ); - if (streq(hydra->daemon, "pluto")) - { /* no routes for pluto, they are installed via updown script */ - this->install_routes = FALSE; + if (streq(hydra->daemon, "starter")) + { /* starter has no threads, so we do not register for kernel events */ + register_for_events = FALSE; } /* create a PF_KEY socket to communicate with the kernel */ @@ -2571,28 +2845,29 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() return NULL; } - /* create a PF_KEY socket for ACQUIRE & EXPIRE */ - this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); - if (this->socket_events <= 0) + if (register_for_events) { - DBG1(DBG_KNL, "unable to create PF_KEY event socket"); - destroy(this); - return NULL; - } + /* create a PF_KEY socket for ACQUIRE & EXPIRE */ + this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + if (this->socket_events <= 0) + { + DBG1(DBG_KNL, "unable to create PF_KEY event socket"); + destroy(this); + return NULL; + } - /* register the event socket */ - if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || - register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) - { - DBG1(DBG_KNL, "unable to register PF_KEY event socket"); - destroy(this); - return NULL; - } + /* register the event socket */ + if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || + register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) + { + DBG1(DBG_KNL, "unable to register PF_KEY event socket"); + destroy(this); + return NULL; + } - this->job = callback_job_create_with_prio((callback_job_cb_t)receive_events, - this, NULL, NULL, JOB_PRIO_CRITICAL); - lib->processor->queue_job(lib->processor, (job_t*)this->job); + lib->watcher->add(lib->watcher, this->socket_events, WATCHER_READ, + (watcher_cb_t)receive_events, this); + } return &this->public; } - diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c index 894175402..61d576547 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_plugin.c @@ -62,6 +62,12 @@ plugin_t *kernel_pfkey_plugin_create() { private_kernel_pfkey_plugin_t *this; + if (!lib->caps->check(lib->caps, CAP_NET_ADMIN)) + { /* required to open PF_KEY sockets */ + DBG1(DBG_KNL, "kernel-pfkey plugin requires CAP_NET_ADMIN capability"); + return NULL; + } + INIT(this, .public = { .plugin = { |
