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 #include <netipsec/xform.h> 34 35 struct secpolicy; 36 struct secasvar; 37 struct inpcb; 38 39 struct ipsec_accel_out_tag { 40 struct m_tag tag; 41 uint16_t drv_spi; 42 }; 43 44 struct ipsec_accel_in_tag { 45 struct m_tag tag; 46 struct xform_history xh; /* Must be first to mimic IPSEC_IN_DONE */ 47 uint16_t drv_spi; 48 }; 49 50 #define IPSEC_ACCEL_DRV_SPI_BYPASS 2 51 #define IPSEC_ACCEL_DRV_SPI_MIN 3 52 #define IPSEC_ACCEL_DRV_SPI_MAX 0xffff 53 54 extern void (*ipsec_accel_sa_newkey_p)(struct secasvar *sav); 55 extern void (*ipsec_accel_sa_install_input_p)(struct secasvar *sav, 56 const union sockaddr_union *dst_address, int sproto, uint32_t spi); 57 extern void (*ipsec_accel_forget_sav_p)(struct secasvar *sav); 58 extern void (*ipsec_accel_spdadd_p)(struct secpolicy *sp, struct inpcb *inp); 59 extern void (*ipsec_accel_spddel_p)(struct secpolicy *sp); 60 extern int (*ipsec_accel_sa_lifetime_op_p)(struct secasvar *sav, 61 struct seclifetime *lft_c, if_t ifp, enum IF_SA_CNT_WHICH op, 62 struct rm_priotracker *sahtree_trackerp); 63 extern void (*ipsec_accel_sync_p)(void); 64 extern bool (*ipsec_accel_is_accel_sav_p)(struct secasvar *sav); 65 extern struct mbuf *(*ipsec_accel_key_setaccelif_p)(struct secasvar *sav); 66 extern void (*ipsec_accel_on_ifdown_p)(struct ifnet *ifp); 67 extern void (*ipsec_accel_drv_sa_lifetime_update_p)(struct secasvar *sav, 68 if_t ifp, u_int drv_spi, uint64_t octets, uint64_t allocs); 69 extern int (*ipsec_accel_drv_sa_lifetime_fetch_p)(struct secasvar *sav, 70 if_t ifp, u_int drv_spi, uint64_t *octets, uint64_t *allocs); 71 extern bool (*ipsec_accel_fill_xh_p)(if_t ifp, uint32_t drv_spi, 72 struct xform_history *xh); 73 74 #ifdef IPSEC_OFFLOAD 75 /* 76 * Have to use ipsec_accel_sa_install_input_p indirection because 77 * key.c is unconditionally included into the static kernel. 78 */ 79 static inline void 80 ipsec_accel_sa_newkey(struct secasvar *sav) 81 { 82 void (*p)(struct secasvar *sav); 83 84 p = atomic_load_ptr(&ipsec_accel_sa_newkey_p); 85 if (p != NULL) 86 p(sav); 87 } 88 89 static inline void 90 ipsec_accel_forget_sav(struct secasvar *sav) 91 { 92 void (*p)(struct secasvar *sav); 93 94 p = atomic_load_ptr(&ipsec_accel_forget_sav_p); 95 if (p != NULL) 96 p(sav); 97 } 98 99 static inline void 100 ipsec_accel_spdadd(struct secpolicy *sp, struct inpcb *inp) 101 { 102 void (*p)(struct secpolicy *sp, struct inpcb *inp); 103 104 p = atomic_load_ptr(&ipsec_accel_spdadd_p); 105 if (p != NULL) 106 p(sp, inp); 107 } 108 109 static inline void 110 ipsec_accel_spddel(struct secpolicy *sp) 111 { 112 void (*p)(struct secpolicy *sp); 113 114 p = atomic_load_ptr(&ipsec_accel_spddel_p); 115 if (p != NULL) 116 p(sp); 117 } 118 119 static inline int 120 ipsec_accel_sa_lifetime_op(struct secasvar *sav, 121 struct seclifetime *lft_c, if_t ifp, enum IF_SA_CNT_WHICH op, 122 struct rm_priotracker *sahtree_trackerp) 123 { 124 int (*p)(struct secasvar *sav, struct seclifetime *lft_c, if_t ifp, 125 enum IF_SA_CNT_WHICH op, struct rm_priotracker *sahtree_trackerp); 126 127 p = atomic_load_ptr(&ipsec_accel_sa_lifetime_op_p); 128 if (p != NULL) 129 return (p(sav, lft_c, ifp, op, sahtree_trackerp)); 130 return (ENOTSUP); 131 } 132 133 static inline void 134 ipsec_accel_sync(void) 135 { 136 void (*p)(void); 137 138 p = atomic_load_ptr(&ipsec_accel_sync_p); 139 if (p != NULL) 140 p(); 141 } 142 143 static inline bool 144 ipsec_accel_is_accel_sav(struct secasvar *sav) 145 { 146 bool (*p)(struct secasvar *sav); 147 148 p = atomic_load_ptr(&ipsec_accel_is_accel_sav_p); 149 if (p != NULL) 150 return (p(sav)); 151 return (false); 152 } 153 154 static inline struct mbuf * 155 ipsec_accel_key_setaccelif(struct secasvar *sav) 156 { 157 struct mbuf *(*p)(struct secasvar *sav); 158 159 p = atomic_load_ptr(&ipsec_accel_key_setaccelif_p); 160 if (p != NULL) 161 return (p(sav)); 162 return (NULL); 163 } 164 165 static inline bool 166 ipsec_accel_fill_xh(if_t ifp, uint32_t drv_spi, struct xform_history *xh) 167 { 168 bool (*p)(if_t ifp, uint32_t drv_spi, struct xform_history *xh); 169 170 p = atomic_load_ptr(&ipsec_accel_fill_xh_p); 171 if (p != NULL) 172 return (p(ifp, drv_spi, xh)); 173 return (false); 174 } 175 176 #else 177 #define ipsec_accel_sa_newkey(a) 178 #define ipsec_accel_forget_sav(a) 179 #define ipsec_accel_spdadd(a, b) 180 #define ipsec_accel_spddel(a) 181 #define ipsec_accel_sa_lifetime_op(a, b, c, d, e) 182 #define ipsec_accel_sync() 183 #define ipsec_accel_is_accel_sav(a) 184 #define ipsec_accel_key_setaccelif(a) 185 #define ipsec_accel_fill_xh(a, b, c) (false) 186 #endif 187 188 void ipsec_accel_forget_sav_impl(struct secasvar *sav); 189 void ipsec_accel_spdadd_impl(struct secpolicy *sp, struct inpcb *inp); 190 void ipsec_accel_spddel_impl(struct secpolicy *sp); 191 192 #ifdef IPSEC_OFFLOAD 193 int ipsec_accel_input(struct mbuf *m, int offset, int proto); 194 bool ipsec_accel_output(struct ifnet *ifp, struct mbuf *m, 195 struct inpcb *inp, struct secpolicy *sp, struct secasvar *sav, int af, 196 int mtu, int *hwassist); 197 void ipsec_accel_forget_sav(struct secasvar *sav); 198 struct xform_history; 199 #else 200 #define ipsec_accel_input(a, b, c) (ENXIO) 201 #define ipsec_accel_output(a, b, c, d, e, f, g, h) ({ \ 202 *h = 0; \ 203 false; \ 204 }) 205 #define ipsec_accel_forget_sav(a) 206 #endif 207 208 struct ipsec_accel_in_tag *ipsec_accel_input_tag_lookup(const struct mbuf *); 209 void ipsec_accel_on_ifdown(struct ifnet *ifp); 210 void ipsec_accel_drv_sa_lifetime_update(struct secasvar *sav, if_t ifp, 211 u_int drv_spi, uint64_t octets, uint64_t allocs); 212 int ipsec_accel_drv_sa_lifetime_fetch(struct secasvar *sav, 213 if_t ifp, u_int drv_spi, uint64_t *octets, uint64_t *allocs); 214 215 #endif /* _KERNEL */ 216 217 #endif /* _NETIPSEC_IPSEC_OFFLOAD_H_ */ 218