1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2016-2017 Intel Corporation 3 */ 4 5 #ifndef __IPSEC_H__ 6 #define __IPSEC_H__ 7 8 #include <stdint.h> 9 10 #include <rte_byteorder.h> 11 #include <rte_crypto.h> 12 #include <rte_security.h> 13 #include <rte_flow.h> 14 15 #define RTE_LOGTYPE_IPSEC RTE_LOGTYPE_USER1 16 #define RTE_LOGTYPE_IPSEC_ESP RTE_LOGTYPE_USER2 17 #define RTE_LOGTYPE_IPSEC_IPIP RTE_LOGTYPE_USER3 18 19 #define MAX_PKT_BURST 32 20 #define MAX_INFLIGHT 128 21 #define MAX_QP_PER_LCORE 256 22 23 #define MAX_DIGEST_SIZE 32 /* Bytes -- 256 bits */ 24 25 #define IPSEC_OFFLOAD_ESN_SOFTLIMIT 0xffffff00 26 27 #define IV_OFFSET (sizeof(struct rte_crypto_op) + \ 28 sizeof(struct rte_crypto_sym_op)) 29 30 #define uint32_t_to_char(ip, a, b, c, d) do {\ 31 *a = (uint8_t)(ip >> 24 & 0xff);\ 32 *b = (uint8_t)(ip >> 16 & 0xff);\ 33 *c = (uint8_t)(ip >> 8 & 0xff);\ 34 *d = (uint8_t)(ip & 0xff);\ 35 } while (0) 36 37 #define DEFAULT_MAX_CATEGORIES 1 38 39 #define IPSEC_SA_MAX_ENTRIES (128) /* must be power of 2, max 2 power 30 */ 40 #define SPI2IDX(spi) (spi & (IPSEC_SA_MAX_ENTRIES - 1)) 41 #define INVALID_SPI (0) 42 43 #define DISCARD INVALID_SPI 44 #define BYPASS UINT32_MAX 45 46 #define IPSEC_XFORM_MAX 2 47 48 #define IP6_VERSION (6) 49 50 struct rte_crypto_xform; 51 struct ipsec_xform; 52 struct rte_mbuf; 53 54 struct ipsec_sa; 55 56 typedef int32_t (*ipsec_xform_fn)(struct rte_mbuf *m, struct ipsec_sa *sa, 57 struct rte_crypto_op *cop); 58 59 struct ip_addr { 60 union { 61 uint32_t ip4; 62 union { 63 uint64_t ip6[2]; 64 uint8_t ip6_b[16]; 65 } ip6; 66 } ip; 67 }; 68 69 #define MAX_KEY_SIZE 32 70 71 struct ipsec_sa { 72 uint32_t spi; 73 uint32_t cdev_id_qp; 74 uint64_t seq; 75 uint32_t salt; 76 union { 77 struct rte_cryptodev_sym_session *crypto_session; 78 struct rte_security_session *sec_session; 79 }; 80 enum rte_crypto_cipher_algorithm cipher_algo; 81 enum rte_crypto_auth_algorithm auth_algo; 82 enum rte_crypto_aead_algorithm aead_algo; 83 uint16_t digest_len; 84 uint16_t iv_len; 85 uint16_t block_size; 86 uint16_t flags; 87 #define IP4_TUNNEL (1 << 0) 88 #define IP6_TUNNEL (1 << 1) 89 #define TRANSPORT (1 << 2) 90 struct ip_addr src; 91 struct ip_addr dst; 92 uint8_t cipher_key[MAX_KEY_SIZE]; 93 uint16_t cipher_key_len; 94 uint8_t auth_key[MAX_KEY_SIZE]; 95 uint16_t auth_key_len; 96 uint16_t aad_len; 97 union { 98 struct rte_crypto_sym_xform *xforms; 99 struct rte_security_ipsec_xform *sec_xform; 100 }; 101 enum rte_security_session_action_type type; 102 enum rte_security_ipsec_sa_direction direction; 103 uint16_t portid; 104 struct rte_security_ctx *security_ctx; 105 uint32_t ol_flags; 106 107 #define MAX_RTE_FLOW_PATTERN (4) 108 #define MAX_RTE_FLOW_ACTIONS (3) 109 struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN]; 110 struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS]; 111 struct rte_flow_attr attr; 112 union { 113 struct rte_flow_item_ipv4 ipv4_spec; 114 struct rte_flow_item_ipv6 ipv6_spec; 115 }; 116 struct rte_flow_item_esp esp_spec; 117 struct rte_flow *flow; 118 struct rte_security_session_conf sess_conf; 119 } __rte_cache_aligned; 120 121 struct ipsec_mbuf_metadata { 122 struct ipsec_sa *sa; 123 struct rte_crypto_op cop; 124 struct rte_crypto_sym_op sym_cop; 125 uint8_t buf[32]; 126 } __rte_cache_aligned; 127 128 struct cdev_qp { 129 uint16_t id; 130 uint16_t qp; 131 uint16_t in_flight; 132 uint16_t len; 133 struct rte_crypto_op *buf[MAX_PKT_BURST] __rte_aligned(sizeof(void *)); 134 }; 135 136 struct ipsec_ctx { 137 struct rte_hash *cdev_map; 138 struct sp_ctx *sp4_ctx; 139 struct sp_ctx *sp6_ctx; 140 struct sa_ctx *sa_ctx; 141 uint16_t nb_qps; 142 uint16_t last_qp; 143 struct cdev_qp tbl[MAX_QP_PER_LCORE]; 144 struct rte_mempool *session_pool; 145 struct rte_mbuf *ol_pkts[MAX_PKT_BURST] __rte_aligned(sizeof(void *)); 146 uint16_t ol_pkts_cnt; 147 }; 148 149 struct cdev_key { 150 uint16_t lcore_id; 151 uint8_t cipher_algo; 152 uint8_t auth_algo; 153 uint8_t aead_algo; 154 }; 155 156 struct socket_ctx { 157 struct sa_ctx *sa_in; 158 struct sa_ctx *sa_out; 159 struct sp_ctx *sp_ip4_in; 160 struct sp_ctx *sp_ip4_out; 161 struct sp_ctx *sp_ip6_in; 162 struct sp_ctx *sp_ip6_out; 163 struct rt_ctx *rt_ip4; 164 struct rt_ctx *rt_ip6; 165 struct rte_mempool *mbuf_pool; 166 struct rte_mempool *session_pool; 167 }; 168 169 struct cnt_blk { 170 uint32_t salt; 171 uint64_t iv; 172 uint32_t cnt; 173 } __attribute__((packed)); 174 175 uint16_t 176 ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 177 uint16_t nb_pkts, uint16_t len); 178 179 uint16_t 180 ipsec_outbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 181 uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len); 182 183 uint16_t 184 ipsec_inbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 185 uint16_t len); 186 187 uint16_t 188 ipsec_outbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 189 uint16_t len); 190 191 static inline uint16_t 192 ipsec_metadata_size(void) 193 { 194 return sizeof(struct ipsec_mbuf_metadata); 195 } 196 197 static inline struct ipsec_mbuf_metadata * 198 get_priv(struct rte_mbuf *m) 199 { 200 return rte_mbuf_to_priv(m); 201 } 202 203 static inline void * 204 get_cnt_blk(struct rte_mbuf *m) 205 { 206 struct ipsec_mbuf_metadata *priv = get_priv(m); 207 208 return &priv->buf[0]; 209 } 210 211 static inline void * 212 get_aad(struct rte_mbuf *m) 213 { 214 struct ipsec_mbuf_metadata *priv = get_priv(m); 215 216 return &priv->buf[16]; 217 } 218 219 static inline void * 220 get_sym_cop(struct rte_crypto_op *cop) 221 { 222 return (cop + 1); 223 } 224 225 int 226 inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx); 227 228 void 229 inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], 230 struct ipsec_sa *sa[], uint16_t nb_pkts); 231 232 void 233 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[], 234 struct ipsec_sa *sa[], uint16_t nb_pkts); 235 236 void 237 sp4_init(struct socket_ctx *ctx, int32_t socket_id); 238 239 void 240 sp6_init(struct socket_ctx *ctx, int32_t socket_id); 241 242 /* 243 * Search through SA entries for given SPI. 244 * Returns first entry index if found(greater or equal then zero), 245 * or -ENOENT otherwise. 246 */ 247 int 248 sa_spi_present(uint32_t spi, int inbound); 249 250 void 251 sa_init(struct socket_ctx *ctx, int32_t socket_id); 252 253 void 254 rt_init(struct socket_ctx *ctx, int32_t socket_id); 255 256 void 257 enqueue_cop_burst(struct cdev_qp *cqp); 258 259 #endif /* __IPSEC_H__ */ 260