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