1*fcf59617SAndrey V. Elsukov /*- 2*fcf59617SAndrey V. Elsukov * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org> 3*fcf59617SAndrey V. Elsukov * All rights reserved. 4*fcf59617SAndrey V. Elsukov * 5*fcf59617SAndrey V. Elsukov * Redistribution and use in source and binary forms, with or without 6*fcf59617SAndrey V. Elsukov * modification, are permitted provided that the following conditions 7*fcf59617SAndrey V. Elsukov * are met: 8*fcf59617SAndrey V. Elsukov * 9*fcf59617SAndrey V. Elsukov * 1. Redistributions of source code must retain the above copyright 10*fcf59617SAndrey V. Elsukov * notice, this list of conditions and the following disclaimer. 11*fcf59617SAndrey V. Elsukov * 2. Redistributions in binary form must reproduce the above copyright 12*fcf59617SAndrey V. Elsukov * notice, this list of conditions and the following disclaimer in the 13*fcf59617SAndrey V. Elsukov * documentation and/or other materials provided with the distribution. 14*fcf59617SAndrey V. Elsukov * 15*fcf59617SAndrey V. Elsukov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16*fcf59617SAndrey V. Elsukov * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17*fcf59617SAndrey V. Elsukov * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18*fcf59617SAndrey V. Elsukov * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19*fcf59617SAndrey V. Elsukov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20*fcf59617SAndrey V. Elsukov * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21*fcf59617SAndrey V. Elsukov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22*fcf59617SAndrey V. Elsukov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23*fcf59617SAndrey V. Elsukov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24*fcf59617SAndrey V. Elsukov * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25*fcf59617SAndrey V. Elsukov */ 26*fcf59617SAndrey V. Elsukov 27*fcf59617SAndrey V. Elsukov #include "opt_inet.h" 28*fcf59617SAndrey V. Elsukov #include "opt_inet6.h" 29*fcf59617SAndrey V. Elsukov #include "opt_ipsec.h" 30*fcf59617SAndrey V. Elsukov 31*fcf59617SAndrey V. Elsukov #include <sys/cdefs.h> 32*fcf59617SAndrey V. Elsukov __FBSDID("$FreeBSD$"); 33*fcf59617SAndrey V. Elsukov 34*fcf59617SAndrey V. Elsukov #include <sys/param.h> 35*fcf59617SAndrey V. Elsukov #include <sys/systm.h> 36*fcf59617SAndrey V. Elsukov #include <sys/kernel.h> 37*fcf59617SAndrey V. Elsukov #include <sys/lock.h> 38*fcf59617SAndrey V. Elsukov #include <sys/malloc.h> 39*fcf59617SAndrey V. Elsukov #include <sys/mbuf.h> 40*fcf59617SAndrey V. Elsukov #include <sys/module.h> 41*fcf59617SAndrey V. Elsukov #include <sys/priv.h> 42*fcf59617SAndrey V. Elsukov #include <sys/rmlock.h> 43*fcf59617SAndrey V. Elsukov #include <sys/socket.h> 44*fcf59617SAndrey V. Elsukov #include <sys/sockopt.h> 45*fcf59617SAndrey V. Elsukov #include <sys/syslog.h> 46*fcf59617SAndrey V. Elsukov #include <sys/proc.h> 47*fcf59617SAndrey V. Elsukov 48*fcf59617SAndrey V. Elsukov #include <netinet/in.h> 49*fcf59617SAndrey V. Elsukov #include <netinet/in_pcb.h> 50*fcf59617SAndrey V. Elsukov 51*fcf59617SAndrey V. Elsukov #include <netipsec/ipsec.h> 52*fcf59617SAndrey V. Elsukov #include <netipsec/ipsec6.h> 53*fcf59617SAndrey V. Elsukov #include <netipsec/key.h> 54*fcf59617SAndrey V. Elsukov #include <netipsec/key_debug.h> 55*fcf59617SAndrey V. Elsukov 56*fcf59617SAndrey V. Elsukov #include <netipsec/ipsec_support.h> 57*fcf59617SAndrey V. Elsukov 58*fcf59617SAndrey V. Elsukov #ifdef INET 59*fcf59617SAndrey V. Elsukov static const struct ipsec_methods ipv4_methods = { 60*fcf59617SAndrey V. Elsukov .input = ipsec4_input, 61*fcf59617SAndrey V. Elsukov .forward = ipsec4_forward, 62*fcf59617SAndrey V. Elsukov .output = ipsec4_output, 63*fcf59617SAndrey V. Elsukov .pcbctl = ipsec4_pcbctl, 64*fcf59617SAndrey V. Elsukov .capability = ipsec4_capability, 65*fcf59617SAndrey V. Elsukov .check_policy = ipsec4_in_reject, 66*fcf59617SAndrey V. Elsukov .hdrsize = ipsec_hdrsiz_inpcb, 67*fcf59617SAndrey V. Elsukov .udp_input = udp_ipsec_input, 68*fcf59617SAndrey V. Elsukov .udp_pcbctl = udp_ipsec_pcbctl, 69*fcf59617SAndrey V. Elsukov }; 70*fcf59617SAndrey V. Elsukov #ifndef KLD_MODULE 71*fcf59617SAndrey V. Elsukov static const struct ipsec_support ipv4_ipsec = { 72*fcf59617SAndrey V. Elsukov .enabled = IPSEC_MODULE_ENABLED, 73*fcf59617SAndrey V. Elsukov .methods = &ipv4_methods 74*fcf59617SAndrey V. Elsukov }; 75*fcf59617SAndrey V. Elsukov const struct ipsec_support * const ipv4_ipsec_support = &ipv4_ipsec; 76*fcf59617SAndrey V. Elsukov #endif /* !KLD_MODULE */ 77*fcf59617SAndrey V. Elsukov #endif /* INET */ 78*fcf59617SAndrey V. Elsukov 79*fcf59617SAndrey V. Elsukov #ifdef INET6 80*fcf59617SAndrey V. Elsukov static const struct ipsec_methods ipv6_methods = { 81*fcf59617SAndrey V. Elsukov .input = ipsec6_input, 82*fcf59617SAndrey V. Elsukov .forward = ipsec6_forward, 83*fcf59617SAndrey V. Elsukov .output = ipsec6_output, 84*fcf59617SAndrey V. Elsukov .pcbctl = ipsec6_pcbctl, 85*fcf59617SAndrey V. Elsukov .capability = ipsec6_capability, 86*fcf59617SAndrey V. Elsukov .check_policy = ipsec6_in_reject, 87*fcf59617SAndrey V. Elsukov .hdrsize = ipsec_hdrsiz_inpcb, 88*fcf59617SAndrey V. Elsukov }; 89*fcf59617SAndrey V. Elsukov #ifndef KLD_MODULE 90*fcf59617SAndrey V. Elsukov static const struct ipsec_support ipv6_ipsec = { 91*fcf59617SAndrey V. Elsukov .enabled = IPSEC_MODULE_ENABLED, 92*fcf59617SAndrey V. Elsukov .methods = &ipv6_methods 93*fcf59617SAndrey V. Elsukov }; 94*fcf59617SAndrey V. Elsukov const struct ipsec_support * const ipv6_ipsec_support = &ipv6_ipsec; 95*fcf59617SAndrey V. Elsukov #endif /* !KLD_MODULE */ 96*fcf59617SAndrey V. Elsukov #endif /* INET6 */ 97*fcf59617SAndrey V. Elsukov 98*fcf59617SAndrey V. Elsukov /* 99*fcf59617SAndrey V. Elsukov * Always register ipsec module. 100*fcf59617SAndrey V. Elsukov * Even when IPsec is build in the kernel, we need to have 101*fcf59617SAndrey V. Elsukov * module registered. This will prevent to load ipsec.ko. 102*fcf59617SAndrey V. Elsukov */ 103*fcf59617SAndrey V. Elsukov static int 104*fcf59617SAndrey V. Elsukov ipsec_modevent(module_t mod, int type, void *data) 105*fcf59617SAndrey V. Elsukov { 106*fcf59617SAndrey V. Elsukov 107*fcf59617SAndrey V. Elsukov switch (type) { 108*fcf59617SAndrey V. Elsukov case MOD_LOAD: 109*fcf59617SAndrey V. Elsukov /* All xforms are registered via SYSINIT */ 110*fcf59617SAndrey V. Elsukov if (!ipsec_initialized()) 111*fcf59617SAndrey V. Elsukov return (ENOMEM); 112*fcf59617SAndrey V. Elsukov #ifdef KLD_MODULE 113*fcf59617SAndrey V. Elsukov #ifdef INET 114*fcf59617SAndrey V. Elsukov ipsec_support_enable(ipv4_ipsec_support, &ipv4_methods); 115*fcf59617SAndrey V. Elsukov #endif 116*fcf59617SAndrey V. Elsukov #ifdef INET6 117*fcf59617SAndrey V. Elsukov ipsec_support_enable(ipv6_ipsec_support, &ipv6_methods); 118*fcf59617SAndrey V. Elsukov #endif 119*fcf59617SAndrey V. Elsukov #endif /* KLD_MODULE */ 120*fcf59617SAndrey V. Elsukov break; 121*fcf59617SAndrey V. Elsukov case MOD_UNLOAD: 122*fcf59617SAndrey V. Elsukov /* All xforms are unregistered via SYSUNINIT */ 123*fcf59617SAndrey V. Elsukov #ifdef KLD_MODULE 124*fcf59617SAndrey V. Elsukov #ifdef INET 125*fcf59617SAndrey V. Elsukov ipsec_support_disable(ipv4_ipsec_support); 126*fcf59617SAndrey V. Elsukov #endif 127*fcf59617SAndrey V. Elsukov #ifdef INET6 128*fcf59617SAndrey V. Elsukov ipsec_support_disable(ipv6_ipsec_support); 129*fcf59617SAndrey V. Elsukov #endif 130*fcf59617SAndrey V. Elsukov #endif /* KLD_MODULE */ 131*fcf59617SAndrey V. Elsukov break; 132*fcf59617SAndrey V. Elsukov default: 133*fcf59617SAndrey V. Elsukov return (EOPNOTSUPP); 134*fcf59617SAndrey V. Elsukov } 135*fcf59617SAndrey V. Elsukov return (0); 136*fcf59617SAndrey V. Elsukov } 137*fcf59617SAndrey V. Elsukov 138*fcf59617SAndrey V. Elsukov static moduledata_t ipsec_mod = { 139*fcf59617SAndrey V. Elsukov "ipsec", 140*fcf59617SAndrey V. Elsukov ipsec_modevent, 141*fcf59617SAndrey V. Elsukov 0 142*fcf59617SAndrey V. Elsukov }; 143*fcf59617SAndrey V. Elsukov 144*fcf59617SAndrey V. Elsukov DECLARE_MODULE(ipsec, ipsec_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); 145*fcf59617SAndrey V. Elsukov MODULE_VERSION(ipsec, 1); 146*fcf59617SAndrey V. Elsukov #ifdef KLD_MODULE 147*fcf59617SAndrey V. Elsukov MODULE_DEPEND(ipsec, ipsec_support, 1, 1, 1); 148*fcf59617SAndrey V. Elsukov #endif 149