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