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