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