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