]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
kernel-utun: use PF_KEY style setsockopts to create IKE bypass policies
authorMartin Willi <martin@revosec.ch>
Mon, 15 Apr 2013 14:53:41 +0000 (16:53 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Apr 2013 12:43:56 +0000 (14:43 +0200)
src/libhydra/plugins/kernel_utun/kernel_utun_ipsec.c

index c2beaaab49d7cb349ec7b765c5f846c18fe71111..413f5ece312e4f3136c1dd1d520774d2e43bfc44 100644 (file)
@@ -30,6 +30,8 @@
 #include <net/if_utun_crypto_ipsec.h>
 #include <netinet/in_var.h>
 #include <sys/kern_control.h>
+#include <net/pfkeyv2.h>
+#include <netinet6/ipsec.h>
 
 #include <hydra.h>
 #include <utils/debug.h>
@@ -410,11 +412,46 @@ METHOD(kernel_ipsec_t, flush_policies, status_t,
        return FAILED;
 }
 
-
 METHOD(kernel_ipsec_t, bypass_socket, bool,
        private_kernel_utun_ipsec_t *this, int fd, int family)
 {
-       return FALSE;
+       struct sadb_x_policy policy;
+       u_int sol, ipsec_policy;
+
+       switch (family)
+       {
+               case AF_INET:
+                       sol = IPPROTO_IP;
+                       ipsec_policy = IP_IPSEC_POLICY;
+                       break;
+               case AF_INET6:
+                       sol = IPPROTO_IPV6;
+                       ipsec_policy = IPV6_IPSEC_POLICY;
+                       break;
+               default:
+                       return FALSE;
+       }
+
+       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)
+       {
+               DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
+                        strerror(errno));
+               return FALSE;
+       }
+       policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+       if (setsockopt(fd, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+       {
+               DBG1(DBG_KNL, "unable to set IPSEC_POLICY on socket: %s",
+                        strerror(errno));
+               return FALSE;
+       }
+       return TRUE;
 }
 
 METHOD(kernel_ipsec_t, enable_udp_decap, bool,