xref: /freebsd/sys/netipsec/ipsec_offload.h (revision 357378bbdedf24ce2b90e9bd831af4a9db3ec70a)
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 
68 #ifdef IPSEC_OFFLOAD
69 /*
70  * Have to use ipsec_accel_sa_install_input_p indirection because
71  * key.c is unconditionally included into the static kernel.
72  */
73 static inline void
74 ipsec_accel_sa_newkey(struct secasvar *sav)
75 {
76 	void (*p)(struct secasvar *sav);
77 
78 	p = atomic_load_ptr(&ipsec_accel_sa_newkey_p);
79 	if (p != NULL)
80 		p(sav);
81 }
82 
83 static inline void
84 ipsec_accel_forget_sav(struct secasvar *sav)
85 {
86 	void (*p)(struct secasvar *sav);
87 
88 	p = atomic_load_ptr(&ipsec_accel_forget_sav_p);
89 	if (p != NULL)
90 		p(sav);
91 }
92 
93 static inline void
94 ipsec_accel_spdadd(struct secpolicy *sp, struct inpcb *inp)
95 {
96 	void (*p)(struct secpolicy *sp, struct inpcb *inp);
97 
98 	p = atomic_load_ptr(&ipsec_accel_spdadd_p);
99 	if (p != NULL)
100 		p(sp, inp);
101 }
102 
103 static inline void
104 ipsec_accel_spddel(struct secpolicy *sp)
105 {
106 	void (*p)(struct secpolicy *sp);
107 
108 	p = atomic_load_ptr(&ipsec_accel_spddel_p);
109 	if (p != NULL)
110 		p(sp);
111 }
112 
113 static inline int
114 ipsec_accel_sa_lifetime_op(struct secasvar *sav,
115     struct seclifetime *lft_c, if_t ifp, enum IF_SA_CNT_WHICH op,
116     struct rm_priotracker *sahtree_trackerp)
117 {
118 	int (*p)(struct secasvar *sav, struct seclifetime *lft_c, if_t ifp,
119 	    enum IF_SA_CNT_WHICH op, struct rm_priotracker *sahtree_trackerp);
120 
121 	p = atomic_load_ptr(&ipsec_accel_sa_lifetime_op_p);
122 	if (p != NULL)
123 		return (p(sav, lft_c, ifp, op, sahtree_trackerp));
124 	return (ENOTSUP);
125 }
126 
127 static inline void
128 ipsec_accel_sync(void)
129 {
130 	void (*p)(void);
131 
132 	p = atomic_load_ptr(&ipsec_accel_sync_p);
133 	if (p != NULL)
134 		p();
135 }
136 
137 static inline bool
138 ipsec_accel_is_accel_sav(struct secasvar *sav)
139 {
140 	bool (*p)(struct secasvar *sav);
141 
142 	p = atomic_load_ptr(&ipsec_accel_is_accel_sav_p);
143 	if (p != NULL)
144 		return (p(sav));
145 	return (false);
146 }
147 
148 static inline struct mbuf *
149 ipsec_accel_key_setaccelif(struct secasvar *sav)
150 {
151 	struct mbuf *(*p)(struct secasvar *sav);
152 
153 	p = atomic_load_ptr(&ipsec_accel_key_setaccelif_p);
154 	if (p != NULL)
155 		return (p(sav));
156 	return (NULL);
157 }
158 
159 
160 #else
161 #define	ipsec_accel_sa_newkey(a)
162 #define	ipsec_accel_forget_sav(a)
163 #define	ipsec_accel_spdadd(a, b)
164 #define	ipsec_accel_spddel(a)
165 #define	ipsec_accel_sa_lifetime_op(a, b, c, d, e)
166 #define	ipsec_accel_sync()
167 #define	ipsec_accel_is_accel_sav(a)
168 #define	ipsec_accel_key_setaccelif(a)
169 #endif
170 
171 void ipsec_accel_forget_sav_impl(struct secasvar *sav);
172 void ipsec_accel_spdadd_impl(struct secpolicy *sp, struct inpcb *inp);
173 void ipsec_accel_spddel_impl(struct secpolicy *sp);
174 
175 #ifdef IPSEC_OFFLOAD
176 int ipsec_accel_input(struct mbuf *m, int offset, int proto);
177 bool ipsec_accel_output(struct ifnet *ifp, struct mbuf *m,
178     struct inpcb *inp, struct secpolicy *sp, struct secasvar *sav, int af,
179     int mtu, int *hwassist);
180 void ipsec_accel_forget_sav(struct secasvar *sav);
181 #else
182 #define	ipsec_accel_input(a, b, c) (ENXIO)
183 #define	ipsec_accel_output(a, b, c, d, e, f, g, h) ({	\
184 	*h = 0;						\
185 	false;						\
186 })
187 #define	ipsec_accel_forget_sav(a)
188 #endif
189 
190 struct ipsec_accel_in_tag *ipsec_accel_input_tag_lookup(const struct mbuf *);
191 void ipsec_accel_on_ifdown(struct ifnet *ifp);
192 void ipsec_accel_drv_sa_lifetime_update(struct secasvar *sav, if_t ifp,
193     u_int drv_spi, uint64_t octets, uint64_t allocs);
194 
195 #endif	/* _KERNEL */
196 
197 #endif	/* _NETIPSEC_IPSEC_OFFLOAD_H_ */
198