xref: /freebsd/sys/netipsec/ipsec_offload.h (revision 66f0e2017f7cd804f31ae4fc2ad38607d85a08d3)
1ef2a572bSKonstantin Belousov /*-
2ef2a572bSKonstantin Belousov  * Copyright (c) 2021,2022 NVIDIA CORPORATION & AFFILIATES. ALL RIGHTS RESERVED.
3ef2a572bSKonstantin Belousov  *
4ef2a572bSKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
5ef2a572bSKonstantin Belousov  * modification, are permitted provided that the following conditions
6ef2a572bSKonstantin Belousov  * are met:
7ef2a572bSKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
8ef2a572bSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
9ef2a572bSKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
10ef2a572bSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
11ef2a572bSKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
12ef2a572bSKonstantin Belousov  *
13ef2a572bSKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14ef2a572bSKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15ef2a572bSKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16ef2a572bSKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17ef2a572bSKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18ef2a572bSKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19ef2a572bSKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20ef2a572bSKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21ef2a572bSKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22ef2a572bSKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23ef2a572bSKonstantin Belousov  * SUCH DAMAGE.
24ef2a572bSKonstantin Belousov  */
25ef2a572bSKonstantin Belousov 
26ef2a572bSKonstantin Belousov #ifndef _NETIPSEC_IPSEC_OFFLOAD_H_
27ef2a572bSKonstantin Belousov #define _NETIPSEC_IPSEC_OFFLOAD_H_
28ef2a572bSKonstantin Belousov 
29ef2a572bSKonstantin Belousov #ifdef _KERNEL
30ef2a572bSKonstantin Belousov #include <sys/errno.h>
31ef2a572bSKonstantin Belousov #include <net/if.h>
32ef2a572bSKonstantin Belousov #include <net/if_var.h>
33ef2a572bSKonstantin Belousov 
34ef2a572bSKonstantin Belousov struct secpolicy;
35ef2a572bSKonstantin Belousov struct secasvar;
36ef2a572bSKonstantin Belousov struct inpcb;
37ef2a572bSKonstantin Belousov 
38ef2a572bSKonstantin Belousov struct ipsec_accel_out_tag {
39ef2a572bSKonstantin Belousov 	struct m_tag tag;
40ef2a572bSKonstantin Belousov 	uint16_t drv_spi;
41ef2a572bSKonstantin Belousov };
42ef2a572bSKonstantin Belousov 
43ef2a572bSKonstantin Belousov struct ipsec_accel_in_tag {
44ef2a572bSKonstantin Belousov 	struct m_tag tag;
45ef2a572bSKonstantin Belousov 	uint16_t drv_spi;
46ef2a572bSKonstantin Belousov };
47ef2a572bSKonstantin Belousov 
48ef2a572bSKonstantin Belousov #define	IPSEC_ACCEL_DRV_SPI_BYPASS	2
49ef2a572bSKonstantin Belousov #define	IPSEC_ACCEL_DRV_SPI_MIN		3
50ef2a572bSKonstantin Belousov #define	IPSEC_ACCEL_DRV_SPI_MAX		0xffff
51ef2a572bSKonstantin Belousov 
52ef2a572bSKonstantin Belousov extern void (*ipsec_accel_sa_newkey_p)(struct secasvar *sav);
53ef2a572bSKonstantin Belousov extern void (*ipsec_accel_sa_install_input_p)(struct secasvar *sav,
54ef2a572bSKonstantin Belousov     const union sockaddr_union *dst_address, int sproto, uint32_t spi);
55ef2a572bSKonstantin Belousov extern void (*ipsec_accel_forget_sav_p)(struct secasvar *sav);
56ef2a572bSKonstantin Belousov extern void (*ipsec_accel_spdadd_p)(struct secpolicy *sp, struct inpcb *inp);
57ef2a572bSKonstantin Belousov extern void (*ipsec_accel_spddel_p)(struct secpolicy *sp);
58ef2a572bSKonstantin Belousov extern int (*ipsec_accel_sa_lifetime_op_p)(struct secasvar *sav,
59ef2a572bSKonstantin Belousov     struct seclifetime *lft_c, if_t ifp, enum IF_SA_CNT_WHICH op,
60ef2a572bSKonstantin Belousov     struct rm_priotracker *sahtree_trackerp);
61ef2a572bSKonstantin Belousov extern void (*ipsec_accel_sync_p)(void);
62ef2a572bSKonstantin Belousov extern bool (*ipsec_accel_is_accel_sav_p)(struct secasvar *sav);
63ef2a572bSKonstantin Belousov extern struct mbuf *(*ipsec_accel_key_setaccelif_p)(struct secasvar *sav);
6465f264dcSKonstantin Belousov extern void (*ipsec_accel_on_ifdown_p)(struct ifnet *ifp);
6565f264dcSKonstantin Belousov extern void (*ipsec_accel_drv_sa_lifetime_update_p)(struct secasvar *sav,
6665f264dcSKonstantin Belousov     if_t ifp, u_int drv_spi, uint64_t octets, uint64_t allocs);
67*66f0e201SKonstantin Belousov extern int (*ipsec_accel_drv_sa_lifetime_fetch_p)(struct secasvar *sav,
68*66f0e201SKonstantin Belousov     if_t ifp, u_int drv_spi, uint64_t *octets, uint64_t *allocs);
69ef2a572bSKonstantin Belousov 
70ef2a572bSKonstantin Belousov #ifdef IPSEC_OFFLOAD
71ef2a572bSKonstantin Belousov /*
72ef2a572bSKonstantin Belousov  * Have to use ipsec_accel_sa_install_input_p indirection because
73ef2a572bSKonstantin Belousov  * key.c is unconditionally included into the static kernel.
74ef2a572bSKonstantin Belousov  */
75ef2a572bSKonstantin Belousov static inline void
ipsec_accel_sa_newkey(struct secasvar * sav)76ef2a572bSKonstantin Belousov ipsec_accel_sa_newkey(struct secasvar *sav)
77ef2a572bSKonstantin Belousov {
78ef2a572bSKonstantin Belousov 	void (*p)(struct secasvar *sav);
79ef2a572bSKonstantin Belousov 
80ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_sa_newkey_p);
81ef2a572bSKonstantin Belousov 	if (p != NULL)
82ef2a572bSKonstantin Belousov 		p(sav);
83ef2a572bSKonstantin Belousov }
84ef2a572bSKonstantin Belousov 
85ef2a572bSKonstantin Belousov static inline void
ipsec_accel_forget_sav(struct secasvar * sav)86ef2a572bSKonstantin Belousov ipsec_accel_forget_sav(struct secasvar *sav)
87ef2a572bSKonstantin Belousov {
88ef2a572bSKonstantin Belousov 	void (*p)(struct secasvar *sav);
89ef2a572bSKonstantin Belousov 
90ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_forget_sav_p);
91ef2a572bSKonstantin Belousov 	if (p != NULL)
92ef2a572bSKonstantin Belousov 		p(sav);
93ef2a572bSKonstantin Belousov }
94ef2a572bSKonstantin Belousov 
95ef2a572bSKonstantin Belousov static inline void
ipsec_accel_spdadd(struct secpolicy * sp,struct inpcb * inp)96ef2a572bSKonstantin Belousov ipsec_accel_spdadd(struct secpolicy *sp, struct inpcb *inp)
97ef2a572bSKonstantin Belousov {
98ef2a572bSKonstantin Belousov 	void (*p)(struct secpolicy *sp, struct inpcb *inp);
99ef2a572bSKonstantin Belousov 
100ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_spdadd_p);
101ef2a572bSKonstantin Belousov 	if (p != NULL)
102ef2a572bSKonstantin Belousov 		p(sp, inp);
103ef2a572bSKonstantin Belousov }
104ef2a572bSKonstantin Belousov 
105ef2a572bSKonstantin Belousov static inline void
ipsec_accel_spddel(struct secpolicy * sp)106ef2a572bSKonstantin Belousov ipsec_accel_spddel(struct secpolicy *sp)
107ef2a572bSKonstantin Belousov {
108ef2a572bSKonstantin Belousov 	void (*p)(struct secpolicy *sp);
109ef2a572bSKonstantin Belousov 
110ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_spddel_p);
111ef2a572bSKonstantin Belousov 	if (p != NULL)
112ef2a572bSKonstantin Belousov 		p(sp);
113ef2a572bSKonstantin Belousov }
114ef2a572bSKonstantin Belousov 
115ef2a572bSKonstantin Belousov static inline int
ipsec_accel_sa_lifetime_op(struct secasvar * sav,struct seclifetime * lft_c,if_t ifp,enum IF_SA_CNT_WHICH op,struct rm_priotracker * sahtree_trackerp)116ef2a572bSKonstantin Belousov ipsec_accel_sa_lifetime_op(struct secasvar *sav,
117ef2a572bSKonstantin Belousov     struct seclifetime *lft_c, if_t ifp, enum IF_SA_CNT_WHICH op,
118ef2a572bSKonstantin Belousov     struct rm_priotracker *sahtree_trackerp)
119ef2a572bSKonstantin Belousov {
120ef2a572bSKonstantin Belousov 	int (*p)(struct secasvar *sav, struct seclifetime *lft_c, if_t ifp,
121ef2a572bSKonstantin Belousov 	    enum IF_SA_CNT_WHICH op, struct rm_priotracker *sahtree_trackerp);
122ef2a572bSKonstantin Belousov 
123ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_sa_lifetime_op_p);
124ef2a572bSKonstantin Belousov 	if (p != NULL)
125ef2a572bSKonstantin Belousov 		return (p(sav, lft_c, ifp, op, sahtree_trackerp));
126ef2a572bSKonstantin Belousov 	return (ENOTSUP);
127ef2a572bSKonstantin Belousov }
128ef2a572bSKonstantin Belousov 
129ef2a572bSKonstantin Belousov static inline void
ipsec_accel_sync(void)130ef2a572bSKonstantin Belousov ipsec_accel_sync(void)
131ef2a572bSKonstantin Belousov {
132ef2a572bSKonstantin Belousov 	void (*p)(void);
133ef2a572bSKonstantin Belousov 
134ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_sync_p);
135ef2a572bSKonstantin Belousov 	if (p != NULL)
136ef2a572bSKonstantin Belousov 		p();
137ef2a572bSKonstantin Belousov }
138ef2a572bSKonstantin Belousov 
139ef2a572bSKonstantin Belousov static inline bool
ipsec_accel_is_accel_sav(struct secasvar * sav)140ef2a572bSKonstantin Belousov ipsec_accel_is_accel_sav(struct secasvar *sav)
141ef2a572bSKonstantin Belousov {
142ef2a572bSKonstantin Belousov 	bool (*p)(struct secasvar *sav);
143ef2a572bSKonstantin Belousov 
144ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_is_accel_sav_p);
145ef2a572bSKonstantin Belousov 	if (p != NULL)
146ef2a572bSKonstantin Belousov 		return (p(sav));
147ef2a572bSKonstantin Belousov 	return (false);
148ef2a572bSKonstantin Belousov }
149ef2a572bSKonstantin Belousov 
150ef2a572bSKonstantin Belousov static inline struct mbuf *
ipsec_accel_key_setaccelif(struct secasvar * sav)151ef2a572bSKonstantin Belousov ipsec_accel_key_setaccelif(struct secasvar *sav)
152ef2a572bSKonstantin Belousov {
153ef2a572bSKonstantin Belousov 	struct mbuf *(*p)(struct secasvar *sav);
154ef2a572bSKonstantin Belousov 
155ef2a572bSKonstantin Belousov 	p = atomic_load_ptr(&ipsec_accel_key_setaccelif_p);
156ef2a572bSKonstantin Belousov 	if (p != NULL)
157ef2a572bSKonstantin Belousov 		return (p(sav));
158ef2a572bSKonstantin Belousov 	return (NULL);
159ef2a572bSKonstantin Belousov }
160ef2a572bSKonstantin Belousov 
161ef2a572bSKonstantin Belousov 
162ef2a572bSKonstantin Belousov #else
163ef2a572bSKonstantin Belousov #define	ipsec_accel_sa_newkey(a)
164ef2a572bSKonstantin Belousov #define	ipsec_accel_forget_sav(a)
165ef2a572bSKonstantin Belousov #define	ipsec_accel_spdadd(a, b)
166ef2a572bSKonstantin Belousov #define	ipsec_accel_spddel(a)
167ef2a572bSKonstantin Belousov #define	ipsec_accel_sa_lifetime_op(a, b, c, d, e)
168ef2a572bSKonstantin Belousov #define	ipsec_accel_sync()
169ef2a572bSKonstantin Belousov #define	ipsec_accel_is_accel_sav(a)
170ef2a572bSKonstantin Belousov #define	ipsec_accel_key_setaccelif(a)
171ef2a572bSKonstantin Belousov #endif
172ef2a572bSKonstantin Belousov 
173ef2a572bSKonstantin Belousov void ipsec_accel_forget_sav_impl(struct secasvar *sav);
174ef2a572bSKonstantin Belousov void ipsec_accel_spdadd_impl(struct secpolicy *sp, struct inpcb *inp);
175ef2a572bSKonstantin Belousov void ipsec_accel_spddel_impl(struct secpolicy *sp);
176ef2a572bSKonstantin Belousov 
177ef2a572bSKonstantin Belousov #ifdef IPSEC_OFFLOAD
178ef2a572bSKonstantin Belousov int ipsec_accel_input(struct mbuf *m, int offset, int proto);
179ef2a572bSKonstantin Belousov bool ipsec_accel_output(struct ifnet *ifp, struct mbuf *m,
180ef2a572bSKonstantin Belousov     struct inpcb *inp, struct secpolicy *sp, struct secasvar *sav, int af,
181240b7bfeSKonstantin Belousov     int mtu, int *hwassist);
182ef2a572bSKonstantin Belousov void ipsec_accel_forget_sav(struct secasvar *sav);
183ef2a572bSKonstantin Belousov #else
184ef2a572bSKonstantin Belousov #define	ipsec_accel_input(a, b, c) (ENXIO)
185240b7bfeSKonstantin Belousov #define	ipsec_accel_output(a, b, c, d, e, f, g, h) ({	\
186240b7bfeSKonstantin Belousov 	*h = 0;						\
187240b7bfeSKonstantin Belousov 	false;						\
188240b7bfeSKonstantin Belousov })
189ef2a572bSKonstantin Belousov #define	ipsec_accel_forget_sav(a)
190ef2a572bSKonstantin Belousov #endif
191ef2a572bSKonstantin Belousov 
192ef2a572bSKonstantin Belousov struct ipsec_accel_in_tag *ipsec_accel_input_tag_lookup(const struct mbuf *);
193ef2a572bSKonstantin Belousov void ipsec_accel_on_ifdown(struct ifnet *ifp);
194ef2a572bSKonstantin Belousov void ipsec_accel_drv_sa_lifetime_update(struct secasvar *sav, if_t ifp,
195ef2a572bSKonstantin Belousov     u_int drv_spi, uint64_t octets, uint64_t allocs);
196*66f0e201SKonstantin Belousov int ipsec_accel_drv_sa_lifetime_fetch(struct secasvar *sav,
197*66f0e201SKonstantin Belousov     if_t ifp, u_int drv_spi, uint64_t *octets, uint64_t *allocs);
198ef2a572bSKonstantin Belousov 
199ef2a572bSKonstantin Belousov #endif	/* _KERNEL */
200ef2a572bSKonstantin Belousov 
201ef2a572bSKonstantin Belousov #endif	/* _NETIPSEC_IPSEC_OFFLOAD_H_ */
202