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