diff options
Diffstat (limited to 'src/charon/plugins/kernel_pfkey')
-rw-r--r-- | src/charon/plugins/kernel_pfkey/Makefile.am | 2 | ||||
-rw-r--r-- | src/charon/plugins/kernel_pfkey/Makefile.in | 145 | ||||
-rw-r--r-- | src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 392 | ||||
-rw-r--r-- | src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c | 6 |
4 files changed, 309 insertions, 236 deletions
diff --git a/src/charon/plugins/kernel_pfkey/Makefile.am b/src/charon/plugins/kernel_pfkey/Makefile.am index e03a0ca02..a72c6a999 100644 --- a/src/charon/plugins/kernel_pfkey/Makefile.am +++ b/src/charon/plugins/kernel_pfkey/Makefile.am @@ -1,5 +1,5 @@ -INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon +INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon AM_CFLAGS = -rdynamic diff --git a/src/charon/plugins/kernel_pfkey/Makefile.in b/src/charon/plugins/kernel_pfkey/Makefile.in index e01510127..8a0961a7d 100644 --- a/src/charon/plugins/kernel_pfkey/Makefile.in +++ b/src/charon/plugins/kernel_pfkey/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.10.2 from Makefile.am. +# Makefile.in generated by automake 1.11 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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,8 +17,9 @@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c @@ -35,19 +37,41 @@ host_triplet = @host@ subdir = src/charon/plugins/kernel_pfkey DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" -pluginLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(plugin_LTLIBRARIES) libstrongswan_kernel_pfkey_la_LIBADD = am_libstrongswan_kernel_pfkey_la_OBJECTS = kernel_pfkey_plugin.lo \ @@ -61,6 +85,7 @@ libstrongswan_kernel_pfkey_la_LINK = $(LIBTOOL) --tag=CC \ DEFAULT_INCLUDES = -I.@am__isrc@ 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) \ @@ -108,25 +133,22 @@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@ -IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@ LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ -LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ -LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ -LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LINUX_HEADERS = @LINUX_HEADERS@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ @@ -138,11 +160,14 @@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ +PTHREADLIB = @PTHREADLIB@ RANLIB = @RANLIB@ +RTLIB = @RTLIB@ RUBY = @RUBY@ RUBYINCLUDE = @RUBYINCLUDE@ SED = @SED@ @@ -171,9 +196,9 @@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ -confdir = @confdir@ datadir = @datadir@ datarootdir = @datarootdir@ +default_pkcs11 = @default_pkcs11@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ @@ -196,7 +221,7 @@ ipsecuser = @ipsecuser@ libdir = @libdir@ libexecdir = @libexecdir@ libstrongswan_plugins = @libstrongswan_plugins@ -linuxdir = @linuxdir@ +linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ @@ -204,6 +229,7 @@ mandir = @mandir@ mkdir_p = @mkdir_p@ nm_CFLAGS = @nm_CFLAGS@ nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ piddir = @piddir@ @@ -212,10 +238,12 @@ pluto_plugins = @pluto_plugins@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ +random_device = @random_device@ resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ -simreader = @simreader@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ @@ -223,9 +251,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon +INCLUDES = -I${linux_headers} -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon AM_CFLAGS = -rdynamic plugin_LTLIBRARIES = libstrongswan-kernel-pfkey.la libstrongswan_kernel_pfkey_la_SOURCES = kernel_pfkey_plugin.h kernel_pfkey_plugin.c \ @@ -245,9 +274,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/kernel_pfkey/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/charon/plugins/kernel_pfkey/Makefile + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/charon/plugins/kernel_pfkey/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/charon/plugins/kernel_pfkey/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -265,23 +294,28 @@ $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" - @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ if test -f $$p; then \ - f=$(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(pluginLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(plugindir)/$$f"; \ + list2="$$list2 $$p"; \ else :; fi; \ - done + done; \ + test -z "$$list2" || { \ + 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)"; \ + } uninstall-pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \ - p=$(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$p'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$p"; \ + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginLTLIBRARIES: @@ -306,21 +340,21 @@ distclean-compile: .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< @@ -343,7 +377,7 @@ tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ + set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -351,29 +385,34 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ + test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique + $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -394,13 +433,17 @@ distdir: $(DISTFILES) if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @@ -431,6 +474,7 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -452,6 +496,8 @@ dvi-am: html: html-am +html-am: + info: info-am info-am: @@ -460,18 +506,28 @@ install-data-am: install-pluginLTLIBRARIES install-dvi: install-dvi-am +install-dvi-am: + install-exec-am: install-html: install-html-am +install-html-am: + install-info: install-info-am +install-info-am: + install-man: install-pdf: install-pdf-am +install-pdf-am: + install-ps: install-ps-am +install-ps-am: + installcheck-am: maintainer-clean: maintainer-clean-am @@ -510,6 +566,7 @@ uninstall-am: uninstall-pluginLTLIBRARIES mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-pluginLTLIBRARIES + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 1f83e8f39..9c50746ac 100644 --- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -49,14 +49,15 @@ #endif /*HAVE_NATT*/ #include <unistd.h> -#include <pthread.h> +#include <time.h> #include <errno.h> #include "kernel_pfkey_ipsec.h" #include <daemon.h> #include <utils/host.h> -#include <utils/mutex.h> +#include <threading/thread.h> +#include <threading/mutex.h> #include <processing/jobs/callback_job.h> #include <processing/jobs/acquire_job.h> #include <processing/jobs/migrate_job.h> @@ -151,42 +152,42 @@ struct private_kernel_pfkey_ipsec_t * Public part of the kernel_pfkey_t object. */ kernel_pfkey_ipsec_t public; - + /** * mutex to lock access to various lists */ mutex_t *mutex; - + /** * List of installed policies (policy_entry_t) */ linked_list_t *policies; - + /** * whether to install routes along policies */ 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; - + /** * PF_KEY socket to communicate with the kernel */ int socket; - + /** * PF_KEY socket to receive acquire and expire events */ int socket_events; - + /** * sequence number for messages sent to the kernel */ @@ -201,10 +202,10 @@ typedef struct route_entry_t route_entry_t; 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; @@ -233,16 +234,16 @@ typedef struct policy_entry_t policy_entry_t; * installed kernel policy. */ struct policy_entry_t { - + /** reqid of this policy */ u_int32_t reqid; - + /** index assigned by the kernel */ u_int32_t index; - + /** direction of this policy: in, out, forward */ u_int8_t direction; - + /** parameters of installed policy */ struct { /** subnet and port */ @@ -252,10 +253,10 @@ struct policy_entry_t { /** protocol */ u_int8_t proto; } src, dst; - + /** associated route installed for this policy */ route_entry_t *route; - + /** by how many CHILD_SA's this policy is used */ u_int refcount; }; @@ -272,15 +273,15 @@ static policy_entry_t *create_policy_entry(traffic_selector_t *src_ts, policy->direction = dir; policy->route = NULL; policy->refcount = 0; - + src_ts->to_subnet(src_ts, &policy->src.net, &policy->src.mask); dst_ts->to_subnet(dst_ts, &policy->dst.net, &policy->dst.mask); - + /* src or dest proto may be "any" (0), use more restrictive one */ policy->src.proto = max(src_ts->get_protocol(src_ts), dst_ts->get_protocol(dst_ts)); policy->src.proto = policy->src.proto ? policy->src.proto : IPSEC_PROTO_ANY; policy->dst.proto = policy->src.proto; - + return policy; } @@ -328,7 +329,7 @@ struct pfkey_msg_t * PF_KEY message base */ struct sadb_msg *msg; - + /** * PF_KEY message extensions */ @@ -518,7 +519,7 @@ struct kernel_algorithm_t { * Identifier specified in IKEv2 */ int ikev2; - + /** * Identifier as defined in pfkeyv2.h */ @@ -652,19 +653,19 @@ static void add_encap_ext(struct sadb_msg *msg, host_t *src, host_t *dst) { struct sadb_x_nat_t_type* nat_type; struct sadb_x_nat_t_port* nat_port; - + nat_type = (struct sadb_x_nat_t_type*)PFKEY_EXT_ADD_NEXT(msg); nat_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; nat_type->sadb_x_nat_t_type_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_type)); nat_type->sadb_x_nat_t_type_type = UDP_ENCAP_ESPINUDP; PFKEY_EXT_ADD(msg, nat_type); - + nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_SPORT; nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port)); nat_port->sadb_x_nat_t_port_port = htons(src->get_port(src)); PFKEY_EXT_ADD(msg, nat_port); - + nat_port = (struct sadb_x_nat_t_port*)PFKEY_EXT_ADD_NEXT(msg); nat_port->sadb_x_nat_t_port_exttype = SADB_X_EXT_NAT_T_DPORT; nat_port->sadb_x_nat_t_port_len = PFKEY_LEN(sizeof(struct sadb_x_nat_t_port)); @@ -682,8 +683,8 @@ static traffic_selector_t* sadb_address2ts(struct sadb_address *address) host_t *host; /* 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. - */ + * in the src and dst sadb_address extensions of the SADB_ACQUIRE message. + */ 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)); @@ -697,15 +698,15 @@ static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) { struct sadb_ext* ext; size_t len; - + memset(out, 0, sizeof(pfkey_msg_t)); out->msg = msg; - + len = msg->sadb_msg_len; len -= PFKEY_LEN(sizeof(struct sadb_msg)); - + ext = (struct sadb_ext*)(((char*)msg) + sizeof(struct sadb_msg)); - + while (len >= PFKEY_LEN(sizeof(struct sadb_ext))) { DBG3(DBG_KNL, " %N", sadb_ext_type_names, ext->sadb_ext_type); @@ -716,20 +717,20 @@ static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) sadb_ext_type_names, ext->sadb_ext_type); break; } - + if ((ext->sadb_ext_type > SADB_EXT_MAX) || (!ext->sadb_ext_type)) { DBG1(DBG_KNL, "type of PF_KEY extension (%d) is invalid", ext->sadb_ext_type); break; } - + if (out->ext[ext->sadb_ext_type]) { DBG1(DBG_KNL, "duplicate %N extension", sadb_ext_type_names, ext->sadb_ext_type); break; } - + out->ext[ext->sadb_ext_type] = ext; ext = PFKEY_EXT_NEXT_LEN(ext, len); } @@ -739,7 +740,7 @@ static status_t parse_pfkey_message(struct sadb_msg *msg, pfkey_msg_t *out) DBG1(DBG_KNL, "PF_KEY message length is invalid"); return FAILED; } - + return SUCCESS; } @@ -752,7 +753,7 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket unsigned char buf[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg; int in_len, len; - + this->mutex_pfkey->lock(this->mutex_pfkey); /* FIXME: our usage of sequence numbers is probably wrong. check RFC 2367, @@ -779,13 +780,13 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket } break; } - + while (TRUE) { msg = (struct sadb_msg*)buf; - + len = recv(socket, buf, sizeof(buf), 0); - + if (len < 0) { if (errno == EINTR) @@ -844,13 +845,13 @@ static status_t pfkey_send_socket(private_kernel_pfkey_ipsec_t *this, int socket } break; } - + *out_len = len; *out = (struct sadb_msg*)malloc(len); memcpy(*out, buf, len); - + this->mutex_pfkey->unlock(this->mutex_pfkey); - + return SUCCESS; } @@ -873,7 +874,7 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* traffic_selector_t *src_ts, *dst_ts; policy_entry_t *policy; job_t *job; - + switch (msg->sadb_msg_satype) { case SADB_SATYPE_UNSPEC: @@ -885,13 +886,13 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* return; } DBG2(DBG_KNL, "received an SADB_ACQUIRE"); - + if (parse_pfkey_message(msg, &response) != SUCCESS) { DBG1(DBG_KNL, "parsing SADB_ACQUIRE from kernel failed"); return; } - + index = response.x_policy->sadb_x_policy_id; this->mutex->lock(this->mutex); if (this->policies->find_first(this->policies, @@ -907,7 +908,7 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* src_ts = sadb_address2ts(response.src); dst_ts = sadb_address2ts(response.dst); this->mutex->unlock(this->mutex); - + DBG1(DBG_KNL, "creating acquire job for policy %R === %R with reqid {%u}", src_ts, dst_ts, reqid); job = (job_t*)acquire_job_create(reqid, src_ts, dst_ts); @@ -924,27 +925,27 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* u_int32_t spi, reqid; bool hard; job_t *job; - + DBG2(DBG_KNL, "received an SADB_EXPIRE"); - + if (parse_pfkey_message(msg, &response) != SUCCESS) { DBG1(DBG_KNL, "parsing SADB_EXPIRE from kernel failed"); return; } - + protocol = proto_satype2ike(msg->sadb_msg_satype); spi = response.sa->sadb_sa_spi; reqid = response.x_sa2->sadb_x_sa2_reqid; hard = response.lft_hard != NULL; - + if (protocol != PROTO_ESP && protocol != PROTO_AH) { DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and reqid {%u} " "which is not a CHILD_SA", ntohl(spi), reqid); return; } - + DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}", hard ? "delete" : "rekey", protocol_id_names, protocol, ntohl(spi), reqid); @@ -984,7 +985,7 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* dir = kernel2dir(response.x_policy->sadb_x_policy_dir); DBG2(DBG_KNL, " policy %R === %R %N, id %u", src_ts, dst_ts, policy_dir_names, dir); - + /* SADB_X_EXT_KMADDRESS is not present in unpatched kernels < 2.6.28 */ if (response.x_kmaddress) { @@ -999,7 +1000,7 @@ static void process_migrate(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* remote = host_create_from_sockaddr(remote_addr); DBG2(DBG_KNL, " kmaddress: %H...%H", local, remote); } - + if (src_ts && dst_ts && local && remote) { DBG1(DBG_KNL, "creating migrate job for policy %R === %R %N with reqid {%u}", @@ -1028,24 +1029,24 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* u_int32_t spi, reqid; host_t *host; job_t *job; - + DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING"); - + if (parse_pfkey_message(msg, &response) != SUCCESS) { DBG1(DBG_KNL, "parsing SADB_X_NAT_T_NEW_MAPPING from kernel failed"); return; } - + if (!response.x_sa2) { DBG1(DBG_KNL, "received SADB_X_NAT_T_NEW_MAPPING is missing required information"); return; } - + spi = response.sa->sadb_sa_spi; reqid = response.x_sa2->sadb_x_sa2_reqid; - + if (proto_satype2ike(msg->sadb_msg_satype) == PROTO_ESP) { sockaddr_t *sa = (sockaddr_t*)(response.dst + 1); @@ -1083,12 +1084,13 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) { unsigned char buf[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg = (struct sadb_msg*)buf; - int len, oldstate; - - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); + int len; + bool oldstate; + + oldstate = thread_cancelability(TRUE); len = recvfrom(this->socket_events, buf, sizeof(buf), 0, NULL, 0); - pthread_setcancelstate(oldstate, NULL); - + thread_cancelability(oldstate); + if (len < 0) { switch (errno) @@ -1105,7 +1107,7 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) return JOB_REQUEUE_FAIR; } } - + if (len < sizeof(struct sadb_msg) || msg->sadb_msg_len < PFKEY_LEN(sizeof(struct sadb_msg))) { @@ -1121,7 +1123,7 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) DBG1(DBG_KNL, "buffer was too small to receive the complete PF_KEY message"); return JOB_REQUEUE_DIRECT; } - + switch (msg->sadb_msg_type) { case SADB_ACQUIRE: @@ -1143,7 +1145,7 @@ static job_requeue_t receive_events(private_kernel_pfkey_ipsec_t *this) default: break; } - + return JOB_REQUEUE_DIRECT; } @@ -1162,31 +1164,31 @@ static status_t get_spi(private_kernel_pfkey_ipsec_t *this, pfkey_msg_t response; u_int32_t received_spi = 0; size_t len; - + memset(&request, 0, sizeof(request)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_GETSPI; msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange)); 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); - + range = (struct sadb_spirange*)PFKEY_EXT_ADD_NEXT(msg); range->sadb_spirange_exttype = SADB_EXT_SPIRANGE; range->sadb_spirange_len = PFKEY_LEN(sizeof(struct sadb_spirange)); range->sadb_spirange_min = 0xc0000000; range->sadb_spirange_max = 0xcFFFFFFF; PFKEY_EXT_ADD(msg, range); - + if (pfkey_send(this, msg, &out, &len) == SUCCESS) { if (out->sadb_msg_errno) @@ -1200,12 +1202,12 @@ static status_t get_spi(private_kernel_pfkey_ipsec_t *this, } free(out); } - + if (received_spi == 0) { return FAILED; } - + *spi = received_spi; return SUCCESS; } @@ -1226,11 +1228,12 @@ static status_t get_cpi(private_kernel_pfkey_ipsec_t *this, static status_t add_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, - u_int64_t expire_soft, u_int64_t expire_hard, + 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 inbound) + bool encap, bool inbound, traffic_selector_t *src_ts, + traffic_selector_t *dst_ts) { unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; @@ -1239,11 +1242,11 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, struct sadb_lifetime *lft; struct sadb_key *key; size_t len; - + memset(&request, 0, sizeof(request)); - + DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", ntohl(spi), reqid); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD; @@ -1273,29 +1276,35 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, sa->sadb_sa_auth = lookup_algorithm(integrity_algs, int_alg); sa->sadb_sa_encrypt = lookup_algorithm(encryption_algs, enc_alg); PFKEY_EXT_ADD(msg, sa); - + sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange)); sa2->sadb_x_sa2_mode = mode2kernel(mode); 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); - + lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); - lft->sadb_lifetime_addtime = expire_soft; + lft->sadb_lifetime_allocations = lifetime->packets.rekey; + lft->sadb_lifetime_bytes = lifetime->bytes.rekey; + lft->sadb_lifetime_addtime = lifetime->time.rekey; + lft->sadb_lifetime_usetime = 0; /* we only use addtime */ PFKEY_EXT_ADD(msg, lft); - + lft = (struct sadb_lifetime*)PFKEY_EXT_ADD_NEXT(msg); lft->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; lft->sadb_lifetime_len = PFKEY_LEN(sizeof(struct sadb_lifetime)); - lft->sadb_lifetime_addtime = expire_hard; + lft->sadb_lifetime_allocations = lifetime->packets.life; + lft->sadb_lifetime_bytes = lifetime->bytes.life; + lft->sadb_lifetime_addtime = lifetime->time.life; + lft->sadb_lifetime_usetime = 0; /* we only use addtime */ PFKEY_EXT_ADD(msg, lft); - + if (enc_alg != ENCR_UNDEFINED) { if (!sa->sadb_sa_encrypt) @@ -1306,16 +1315,16 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, } DBG2(DBG_KNL, " using encryption algorithm %N with key size %d", encryption_algorithm_names, enc_alg, enc_key.len * 8); - + key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); key->sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; key->sadb_key_bits = enc_key.len * 8; key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + enc_key.len); memcpy(key + 1, enc_key.ptr, enc_key.len); - + PFKEY_EXT_ADD(msg, key); } - + if (int_alg != AUTH_UNDEFINED) { if (!sa->sadb_sa_auth) @@ -1326,16 +1335,16 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, } DBG2(DBG_KNL, " using integrity algorithm %N with key size %d", integrity_algorithm_names, int_alg, int_key.len * 8); - + key = (struct sadb_key*)PFKEY_EXT_ADD_NEXT(msg); key->sadb_key_exttype = SADB_EXT_KEY_AUTH; key->sadb_key_bits = int_key.len * 8; key->sadb_key_len = PFKEY_LEN(sizeof(struct sadb_key) + int_key.len); memcpy(key + 1, int_key.ptr, int_key.len); - + PFKEY_EXT_ADD(msg, key); } - + if (ipcomp != IPCOMP_NONE) { /*TODO*/ @@ -1347,7 +1356,7 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, add_encap_ext(msg, src, dst); } #endif /*HAVE_NATT*/ - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi)); @@ -1360,7 +1369,7 @@ static status_t add_sa(private_kernel_pfkey_ipsec_t *this, free(out); return FAILED; } - + free(out); return SUCCESS; } @@ -1379,7 +1388,7 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, struct sadb_sa *sa; pfkey_msg_t response; size_t len; - + /* we can't update the SA if any of the ip addresses have changed. * that's because we can't use SADB_UPDATE and by deleting and readding the * SA the sequence numbers would get lost */ @@ -1390,28 +1399,28 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, " are not supported", ntohl(spi)); return NOT_SUPPORTED; } - + memset(&request, 0, sizeof(request)); - + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_GET; msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); sa->sadb_sa_exttype = SADB_EXT_SA; sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); sa->sadb_sa_spi = spi; PFKEY_EXT_ADD(msg, sa); - + /* 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); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", @@ -1432,18 +1441,18 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, free(out); return FAILED; } - + DBG2(DBG_KNL, "updating SAD entry with SPI %.8x from %#H..%#H to %#H..%#H", ntohl(spi), src, dst, new_src, new_dst); - + memset(&request, 0, sizeof(request)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_UPDATE; msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + #ifdef __APPLE__ { struct sadb_sa_2 *sa_2; @@ -1460,32 +1469,32 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, PFKEY_EXT_COPY(msg, response.sa); #endif PFKEY_EXT_COPY(msg, response.x_sa2); - + PFKEY_EXT_COPY(msg, response.src); PFKEY_EXT_COPY(msg, response.dst); - + PFKEY_EXT_COPY(msg, response.lft_soft); PFKEY_EXT_COPY(msg, response.lft_hard); - + if (response.key_encr) { PFKEY_EXT_COPY(msg, response.key_encr); } - + if (response.key_auth) { PFKEY_EXT_COPY(msg, response.key_auth); } - + #ifdef HAVE_NATT if (new_encap) { add_encap_ext(msg, new_src, new_dst); } #endif /*HAVE_NATT*/ - + free(out); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x", ntohl(spi)); @@ -1499,7 +1508,7 @@ static status_t update_sa(private_kernel_pfkey_ipsec_t *this, return FAILED; } free(out); - + return SUCCESS; } @@ -1515,29 +1524,29 @@ static status_t query_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, struct sadb_sa *sa; pfkey_msg_t response; size_t len; - + memset(&request, 0, sizeof(request)); - + DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_GET; msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); sa->sadb_sa_exttype = SADB_EXT_SA; sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); sa->sadb_sa_spi = spi; PFKEY_EXT_ADD(msg, sa); - + /* 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); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to query SAD entry with SPI %.8x", ntohl(spi)); @@ -1573,29 +1582,29 @@ static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, struct sadb_msg *msg, *out; struct sadb_sa *sa; size_t len; - + memset(&request, 0, sizeof(request)); - + DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_DELETE; msg->sadb_msg_satype = proto_ike2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + sa = (struct sadb_sa*)PFKEY_EXT_ADD_NEXT(msg); sa->sadb_sa_exttype = SADB_EXT_SA; sa->sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa)); sa->sadb_sa_spi = spi; PFKEY_EXT_ADD(msg, sa); - + /* 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); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi)); @@ -1608,7 +1617,7 @@ static status_t del_sa(private_kernel_pfkey_ipsec_t *this, host_t *src, free(out); return FAILED; } - + DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi)); free(out); return SUCCESS; @@ -1633,16 +1642,16 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, policy_entry_t *policy, *found = NULL; pfkey_msg_t response; size_t len; - + if (dir2kernel(direction) == IPSEC_DIR_INVALID) { /* FWD policies are not supported on all platforms */ return SUCCESS; } - + /* create a policy */ policy = create_policy_entry(src_ts, dst_ts, direction, reqid); - + /* find a matching policy */ this->mutex->lock(this->mutex); if (this->policies->find_first(this->policies, @@ -1662,18 +1671,18 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, this->policies->insert_last(this->policies, policy); policy->refcount = 1; } - + memset(&request, 0, sizeof(request)); - + DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts, policy_dir_names, direction); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = found ? SADB_X_SPDUPDATE : SADB_X_SPDADD; msg->sadb_msg_satype = 0; msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); @@ -1687,7 +1696,7 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, pol->sadb_x_policy_priority -= policy->src.proto != IPSEC_PROTO_ANY ? 2 : 0; pol->sadb_x_policy_priority -= policy->src.net->get_port(policy->src.net) ? 1 : 0; #endif - + /* one or more sadb_x_ipsecrequest extensions are added to the sadb_x_policy extension */ req = (struct sadb_x_ipsecrequest*)(pol + 1); req->sadb_x_ipsecrequest_proto = proto_ike2ip(protocol); @@ -1707,15 +1716,15 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, memcpy((u_int8_t*)(req + 1) + sl, sa, sl); req->sadb_x_ipsecrequest_len += sl * 2; } - + pol->sadb_x_policy_len += PFKEY_LEN(req->sadb_x_ipsecrequest_len); PFKEY_EXT_ADD(msg, pol); - + add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, policy->src.mask); add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, policy->dst.mask); - + #ifdef __FreeBSD__ { /* on FreeBSD a lifetime has to be defined to be able to later query * the current use time. */ @@ -1727,9 +1736,9 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, PFKEY_EXT_ADD(msg, lft); } #endif - + this->mutex->unlock(this->mutex); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to add policy %R === %R %N", src_ts, dst_ts, @@ -1751,9 +1760,9 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, free(out); return FAILED; } - + this->mutex->lock(this->mutex); - + /* we try to find the policy again and update the kernel index */ if (this->policies->find_last(this->policies, NULL, (void**)&policy) != SUCCESS) { @@ -1765,7 +1774,7 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, } policy->index = response.x_policy->sadb_x_policy_id; free(out); - + /* install a route, if: * - we are NOT updating a policy * - this is a forward policy (to just get one for each child) @@ -1778,7 +1787,7 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, this->install_routes) { route_entry_t *route = malloc_thing(route_entry_t); - + if (charon->kernel_interface->get_address_by_ts(charon->kernel_interface, dst_ts, &route->src_ip) == SUCCESS) { @@ -1789,7 +1798,7 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, charon->kernel_interface, dst); route->dst_net = chunk_clone(policy->src.net->get_address(policy->src.net)); route->prefixlen = policy->src.mask; - + switch (charon->kernel_interface->add_route(charon->kernel_interface, route->dst_net, route->prefixlen, route->gateway, route->src_ip, route->if_name)) @@ -1813,9 +1822,9 @@ static status_t add_policy(private_kernel_pfkey_ipsec_t *this, free(route); } } - + this->mutex->unlock(this->mutex); - + return SUCCESS; } @@ -1833,19 +1842,19 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this, policy_entry_t *policy, *found = NULL; pfkey_msg_t response; size_t len; - + if (dir2kernel(direction) == IPSEC_DIR_INVALID) { /* FWD policies are not supported on all platforms */ return NOT_FOUND; } - + DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts, policy_dir_names, direction); /* create a policy */ policy = create_policy_entry(src_ts, dst_ts, direction, 0); - + /* find a matching policy */ this->mutex->lock(this->mutex); if (this->policies->find_first(this->policies, @@ -1859,15 +1868,15 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this, } policy_entry_destroy(policy); policy = found; - + memset(&request, 0, sizeof(request)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_X_SPDGET; msg->sadb_msg_satype = 0; msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; pol->sadb_x_policy_id = policy->index; @@ -1875,14 +1884,14 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this, pol->sadb_x_policy_dir = dir2kernel(direction); pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; PFKEY_EXT_ADD(msg, pol); - + add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, policy->src.mask); add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, policy->dst.mask); - + this->mutex->unlock(this->mutex); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to query policy %R === %R %N", src_ts, dst_ts, @@ -1911,11 +1920,18 @@ static status_t query_policy(private_kernel_pfkey_ipsec_t *this, free(out); return FAILED; } - - *use_time = response.lft_current->sadb_lifetime_usetime; - + /* we need the monotonic time, but the kernel returns system time. */ + if (response.lft_current->sadb_lifetime_usetime) + { + *use_time = time_monotonic(NULL) - + (time(NULL) - response.lft_current->sadb_lifetime_usetime); + } + else + { + *use_time = 0; + } free(out); - + return SUCCESS; } @@ -1933,19 +1949,19 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this, policy_entry_t *policy, *found = NULL; route_entry_t *route; size_t len; - + if (dir2kernel(direction) == IPSEC_DIR_INVALID) { /* FWD policies are not supported on all platforms */ return SUCCESS; } - + DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts, policy_dir_names, direction); - + /* create a policy */ policy = create_policy_entry(src_ts, dst_ts, direction, 0); - + /* find a matching policy */ this->mutex->lock(this->mutex); if (this->policies->find_first(this->policies, @@ -1973,31 +1989,31 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this, return NOT_FOUND; } this->mutex->unlock(this->mutex); - + memset(&request, 0, sizeof(request)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_X_SPDDELETE; msg->sadb_msg_satype = 0; msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + pol = (struct sadb_x_policy*)PFKEY_EXT_ADD_NEXT(msg); pol->sadb_x_policy_exttype = SADB_X_EXT_POLICY; pol->sadb_x_policy_len = PFKEY_LEN(sizeof(struct sadb_x_policy)); pol->sadb_x_policy_dir = dir2kernel(direction); pol->sadb_x_policy_type = IPSEC_POLICY_IPSEC; PFKEY_EXT_ADD(msg, pol); - + add_addr_ext(msg, policy->src.net, SADB_EXT_ADDRESS_SRC, policy->src.proto, policy->src.mask); add_addr_ext(msg, policy->dst.net, SADB_EXT_ADDRESS_DST, policy->dst.proto, policy->dst.mask); - + route = policy->route; policy->route = NULL; policy_entry_destroy(policy); - + if (pfkey_send(this, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts, @@ -2013,7 +2029,7 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this, return FAILED; } free(out); - + if (route) { if (charon->kernel_interface->del_route(charon->kernel_interface, @@ -2026,7 +2042,7 @@ static status_t del_policy(private_kernel_pfkey_ipsec_t *this, } route_entry_destroy(route); } - + return SUCCESS; } @@ -2038,15 +2054,15 @@ static status_t register_pfkey_socket(private_kernel_pfkey_ipsec_t *this, u_int8 unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; size_t len; - + memset(&request, 0, sizeof(request)); - + msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; msg->sadb_msg_type = SADB_REGISTER; msg->sadb_msg_satype = satype; msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - + if (pfkey_send_socket(this, this->socket_events, msg, &out, &len) != SUCCESS) { DBG1(DBG_KNL, "unable to register PF_KEY socket"); @@ -2085,13 +2101,13 @@ static bool add_bypass_policies(private_kernel_pfkey_ipsec_t *this) int fd, family, port; enumerator_t *sockets; bool status = TRUE; - + sockets = charon->socket->create_enumerator(charon->socket); while (sockets->enumerate(sockets, &fd, &family, &port)) { struct sadb_x_policy policy; u_int sol, ipsec_policy; - + switch (family) { case AF_INET: @@ -2109,12 +2125,12 @@ static bool add_bypass_policies(private_kernel_pfkey_ipsec_t *this) default: continue; } - + memset(&policy, 0, sizeof(policy)); policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t); policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY; policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS; - + policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND; if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0) { @@ -2142,18 +2158,18 @@ static bool add_bypass_policies(private_kernel_pfkey_ipsec_t *this) kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() { private_kernel_pfkey_ipsec_t *this = malloc_thing(private_kernel_pfkey_ipsec_t); - + /* public functions */ this->public.interface.get_spi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi; this->public.interface.get_cpi = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,u_int16_t*))get_cpi; - this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool))add_sa; + this->public.interface.add_sa = (status_t(*)(kernel_ipsec_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,lifetime_cfg_t*,u_int16_t,chunk_t,u_int16_t,chunk_t,ipsec_mode_t,u_int16_t,u_int16_t,bool,bool,traffic_selector_t*,traffic_selector_t*))add_sa; this->public.interface.update_sa = (status_t(*)(kernel_ipsec_t*,u_int32_t,protocol_id_t,u_int16_t,host_t*,host_t*,host_t*,host_t*,bool,bool))update_sa; this->public.interface.query_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int64_t*))query_sa; this->public.interface.del_sa = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,u_int32_t,protocol_id_t,u_int16_t))del_sa; this->public.interface.add_policy = (status_t(*)(kernel_ipsec_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t,protocol_id_t,u_int32_t,ipsec_mode_t,u_int16_t,u_int16_t,bool))add_policy; this->public.interface.query_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; this->public.interface.del_policy = (status_t(*)(kernel_ipsec_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,bool))del_policy; - + this->public.interface.destroy = (void(*)(kernel_ipsec_t*)) destroy; /* private members */ @@ -2163,37 +2179,37 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() this->install_routes = lib->settings->get_bool(lib->settings, "charon.install_routes", TRUE); this->seq = 0; - + /* create a PF_KEY socket to communicate with the kernel */ this->socket = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); if (this->socket <= 0) { charon->kill(charon, "unable to create PF_KEY socket"); } - + /* create a PF_KEY socket for ACQUIRE & EXPIRE */ this->socket_events = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); if (this->socket_events <= 0) { charon->kill(charon, "unable to create PF_KEY event socket"); } - + /* add bypass policies on the sockets used by charon */ if (!add_bypass_policies(this)) { charon->kill(charon, "unable to add bypass policies on sockets"); } - + /* register the event socket */ if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) { charon->kill(charon, "unable to register PF_KEY event socket"); } - + this->job = callback_job_create((callback_job_cb_t)receive_events, this, NULL, NULL); charon->processor->queue_job(charon->processor, (job_t*)this->job); - + return &this->public; } diff --git a/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c b/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c index 09dc4780d..3380c328c 100644 --- a/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c +++ b/src/charon/plugins/kernel_pfkey/kernel_pfkey_plugin.c @@ -47,10 +47,10 @@ static void destroy(private_kernel_pfkey_plugin_t *this) plugin_t *plugin_create() { private_kernel_pfkey_plugin_t *this = malloc_thing(private_kernel_pfkey_plugin_t); - + this->public.plugin.destroy = (void(*)(plugin_t*))destroy; - + charon->kernel_interface->add_ipsec_interface(charon->kernel_interface, (kernel_ipsec_constructor_t)kernel_pfkey_ipsec_create); - + return &this->public.plugin; } |