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