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 #ifndef _NETIPSEC_IPSEC_SUPPORT_H_ 28 #define _NETIPSEC_IPSEC_SUPPORT_H_ 29 30 #ifdef _KERNEL 31 #if defined(IPSEC) || defined(IPSEC_SUPPORT) 32 struct ifnet; 33 struct mbuf; 34 struct inpcb; 35 struct tcphdr; 36 struct sockopt; 37 struct sockaddr; 38 struct ipsec_support; 39 struct tcpmd5_support; 40 struct icmp; 41 struct ip6ctlparam; 42 43 typedef union { 44 struct icmp *icmp; 45 struct ip6ctlparam *ip6cp; 46 } ipsec_ctlinput_param_t __attribute__((__transparent_union__)); 47 48 size_t ipsec_hdrsiz_inpcb(struct inpcb *); 49 int ipsec_init_pcbpolicy(struct inpcb *); 50 int ipsec_delete_pcbpolicy(struct inpcb *); 51 int ipsec_copy_pcbpolicy(struct inpcb *, struct inpcb *); 52 53 #if defined(INET) || defined(INET6) 54 int udp_ipsec_input(struct mbuf *, int, int); 55 int udp_ipsec_pcbctl(struct inpcb *, struct sockopt *); 56 #endif 57 #ifdef INET 58 int ipsec4_in_reject(const struct mbuf *, struct inpcb *); 59 int ipsec4_input(struct mbuf *, int, int); 60 int ipsec4_forward(struct mbuf *); 61 int ipsec4_pcbctl(struct inpcb *, struct sockopt *); 62 int ipsec4_output(struct ifnet *, struct mbuf *, struct inpcb *, u_long); 63 int ipsec4_capability(struct mbuf *, u_int); 64 int ipsec4_ctlinput(ipsec_ctlinput_param_t); 65 #endif /* INET */ 66 67 #ifdef INET6 68 int ipsec6_input(struct mbuf *, int, int); 69 int ipsec6_in_reject(const struct mbuf *, struct inpcb *); 70 int ipsec6_forward(struct mbuf *); 71 int ipsec6_pcbctl(struct inpcb *, struct sockopt *); 72 int ipsec6_output(struct ifnet *, struct mbuf *, struct inpcb *, u_long); 73 int ipsec6_capability(struct mbuf *, u_int); 74 int ipsec6_ctlinput(ipsec_ctlinput_param_t); 75 #endif /* INET6 */ 76 77 struct ipsec_methods { 78 int (*input)(struct mbuf *, int, int); 79 int (*check_policy)(const struct mbuf *, struct inpcb *); 80 int (*forward)(struct mbuf *); 81 int (*output)(struct ifnet *, struct mbuf *, struct inpcb *, 82 u_long); 83 int (*pcbctl)(struct inpcb *, struct sockopt *); 84 size_t (*hdrsize)(struct inpcb *); 85 int (*capability)(struct mbuf *, u_int); 86 int (*ctlinput)(ipsec_ctlinput_param_t); 87 88 int (*udp_input)(struct mbuf *, int, int); 89 int (*udp_pcbctl)(struct inpcb *, struct sockopt *); 90 }; 91 #define IPSEC_CAP_OPERABLE 1 92 #define IPSEC_CAP_BYPASS_FILTER 2 93 94 struct tcpmd5_methods { 95 int (*input)(struct mbuf *, struct tcphdr *, u_char *); 96 int (*output)(struct mbuf *, struct tcphdr *, u_char *); 97 int (*pcbctl)(struct inpcb *, struct sockopt *); 98 }; 99 100 #define IPSEC_MODULE_ENABLED 0x0001 101 #define IPSEC_ENABLED(proto) \ 102 ((proto ## _ipsec_support)->enabled & IPSEC_MODULE_ENABLED) 103 #define TCPMD5_ENABLED() IPSEC_ENABLED(tcp) 104 105 #ifdef TCP_SIGNATURE 106 /* TCP-MD5 build in the kernel */ 107 struct tcpmd5_support { 108 const u_int enabled; 109 const struct tcpmd5_methods * const methods; 110 }; 111 extern const struct tcpmd5_support * const tcp_ipsec_support; 112 113 #define TCPMD5_INPUT(m, ...) \ 114 (*tcp_ipsec_support->methods->input)(m, __VA_ARGS__) 115 #define TCPMD5_OUTPUT(m, ...) \ 116 (*tcp_ipsec_support->methods->output)(m, __VA_ARGS__) 117 #define TCPMD5_PCBCTL(inp, sopt) \ 118 (*tcp_ipsec_support->methods->pcbctl)(inp, sopt) 119 #elif defined(IPSEC_SUPPORT) 120 /* TCP-MD5 build as module */ 121 struct tcpmd5_support { 122 volatile u_int enabled; 123 const struct tcpmd5_methods * volatile methods; 124 }; 125 extern struct tcpmd5_support * const tcp_ipsec_support; 126 127 void tcpmd5_support_enable(const struct tcpmd5_methods * const); 128 void tcpmd5_support_disable(void); 129 130 int tcpmd5_kmod_pcbctl(struct tcpmd5_support * const, struct inpcb *, 131 struct sockopt *); 132 int tcpmd5_kmod_input(struct tcpmd5_support * const, struct mbuf *, 133 struct tcphdr *, u_char *); 134 int tcpmd5_kmod_output(struct tcpmd5_support * const, struct mbuf *, 135 struct tcphdr *, u_char *); 136 #define TCPMD5_INPUT(m, ...) \ 137 tcpmd5_kmod_input(tcp_ipsec_support, m, __VA_ARGS__) 138 #define TCPMD5_OUTPUT(m, ...) \ 139 tcpmd5_kmod_output(tcp_ipsec_support, m, __VA_ARGS__) 140 #define TCPMD5_PCBCTL(inp, sopt) \ 141 tcpmd5_kmod_pcbctl(tcp_ipsec_support, inp, sopt) 142 #endif 143 144 #endif /* IPSEC || IPSEC_SUPPORT */ 145 146 #if defined(IPSEC) 147 struct ipsec_support { 148 const u_int enabled; 149 const struct ipsec_methods * const methods; 150 }; 151 extern const struct ipsec_support * const ipv4_ipsec_support; 152 extern const struct ipsec_support * const ipv6_ipsec_support; 153 154 #define IPSEC_INPUT(proto, m, ...) \ 155 (*(proto ## _ipsec_support)->methods->input)(m, __VA_ARGS__) 156 #define IPSEC_CHECK_POLICY(proto, m, ...) \ 157 (*(proto ## _ipsec_support)->methods->check_policy)(m, __VA_ARGS__) 158 #define IPSEC_FORWARD(proto, m) \ 159 (*(proto ## _ipsec_support)->methods->forward)(m) 160 #define IPSEC_OUTPUT(proto, m, ...) \ 161 (*(proto ## _ipsec_support)->methods->output)(m, __VA_ARGS__) 162 #define IPSEC_PCBCTL(proto, inp, sopt) \ 163 (*(proto ## _ipsec_support)->methods->pcbctl)(inp, sopt) 164 #define IPSEC_CAPS(proto, m, ...) \ 165 (*(proto ## _ipsec_support)->methods->capability)(m, __VA_ARGS__) 166 #define IPSEC_HDRSIZE(proto, inp) \ 167 (*(proto ## _ipsec_support)->methods->hdrsize)(inp) 168 #define IPSEC_CTLINPUT(proto, param) \ 169 (*(proto ## _ipsec_support)->methods->ctlinput)(param) 170 171 #define UDPENCAP_INPUT(proto, m, ...) \ 172 (*(proto ## _ipsec_support)->methods->udp_input)(m, __VA_ARGS__) 173 #define UDPENCAP_PCBCTL(proto, inp, sopt) \ 174 (*(proto ## _ipsec_support)->methods->udp_pcbctl)(inp, sopt) 175 176 #elif defined(IPSEC_SUPPORT) 177 struct ipsec_support { 178 volatile u_int enabled; 179 const struct ipsec_methods * volatile methods; 180 }; 181 extern struct ipsec_support * const ipv4_ipsec_support; 182 extern struct ipsec_support * const ipv6_ipsec_support; 183 184 void ipsec_support_enable(struct ipsec_support * const, 185 const struct ipsec_methods * const); 186 void ipsec_support_disable(struct ipsec_support * const); 187 188 int ipsec_kmod_input(struct ipsec_support * const, struct mbuf *, int, int); 189 int ipsec_kmod_check_policy(struct ipsec_support * const, struct mbuf *, 190 struct inpcb *); 191 int ipsec_kmod_forward(struct ipsec_support * const, struct mbuf *); 192 int ipsec_kmod_output(struct ipsec_support * const, struct ifnet *, 193 struct mbuf *, struct inpcb *, u_long); 194 int ipsec_kmod_pcbctl(struct ipsec_support * const, struct inpcb *, 195 struct sockopt *); 196 int ipsec_kmod_capability(struct ipsec_support * const, struct mbuf *, u_int); 197 size_t ipsec_kmod_hdrsize(struct ipsec_support * const, struct inpcb *); 198 int ipsec_kmod_ctlinput(struct ipsec_support *, ipsec_ctlinput_param_t); 199 int ipsec_kmod_udp_input(struct ipsec_support * const, struct mbuf *, int, int); 200 int ipsec_kmod_udp_pcbctl(struct ipsec_support * const, struct inpcb *, 201 struct sockopt *); 202 203 #define UDPENCAP_INPUT(proto, m, ...) \ 204 ipsec_kmod_udp_input(proto ## _ipsec_support, m, __VA_ARGS__) 205 #define UDPENCAP_PCBCTL(proto, inp, sopt) \ 206 ipsec_kmod_udp_pcbctl(proto ## _ipsec_support, inp, sopt) 207 208 #define IPSEC_INPUT(proto, ...) \ 209 ipsec_kmod_input(proto ## _ipsec_support, __VA_ARGS__) 210 #define IPSEC_CHECK_POLICY(proto, ...) \ 211 ipsec_kmod_check_policy(proto ## _ipsec_support, __VA_ARGS__) 212 #define IPSEC_FORWARD(proto, ...) \ 213 ipsec_kmod_forward(proto ## _ipsec_support, __VA_ARGS__) 214 #define IPSEC_OUTPUT(proto, ...) \ 215 ipsec_kmod_output(proto ## _ipsec_support, __VA_ARGS__) 216 #define IPSEC_PCBCTL(proto, ...) \ 217 ipsec_kmod_pcbctl(proto ## _ipsec_support, __VA_ARGS__) 218 #define IPSEC_CAPS(proto, ...) \ 219 ipsec_kmod_capability(proto ## _ipsec_support, __VA_ARGS__) 220 #define IPSEC_HDRSIZE(proto, ...) \ 221 ipsec_kmod_hdrsize(proto ## _ipsec_support, __VA_ARGS__) 222 #define IPSEC_CTLINPUT(proto, ...) \ 223 ipsec_kmod_ctlinput(proto ## _ipsec_support, __VA_ARGS__) 224 #endif /* IPSEC_SUPPORT */ 225 #endif /* _KERNEL */ 226 #endif /* _NETIPSEC_IPSEC_SUPPORT_H_ */ 227