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_ip_frag.h> 13 #include <rte_security.h> 14 #include <rte_flow.h> 15 #include <rte_ipsec.h> 16 17 #include "event_helper.h" 18 #include "ipsec-secgw.h" 19 20 #define RTE_LOGTYPE_IPSEC_ESP RTE_LOGTYPE_USER2 21 #define RTE_LOGTYPE_IPSEC_IPIP RTE_LOGTYPE_USER3 22 23 #define MAX_INFLIGHT 128 24 #define MAX_QP_PER_LCORE 256 25 26 #define MAX_DIGEST_SIZE 32 /* Bytes -- 256 bits */ 27 28 #define IV_OFFSET (sizeof(struct rte_crypto_op) + \ 29 sizeof(struct rte_crypto_sym_op)) 30 31 #define DEFAULT_MAX_CATEGORIES 1 32 33 #define INVALID_SPI (0) 34 35 #define DISCARD INVALID_SPI 36 #define BYPASS UINT32_MAX 37 38 #define IPSEC_XFORM_MAX 2 39 40 #define IP6_VERSION (6) 41 42 #define SATP_OUT_IPV4(t) \ 43 ((((t) & RTE_IPSEC_SATP_MODE_MASK) == RTE_IPSEC_SATP_MODE_TRANS && \ 44 (((t) & RTE_IPSEC_SATP_IPV_MASK) == RTE_IPSEC_SATP_IPV4)) || \ 45 ((t) & RTE_IPSEC_SATP_MODE_MASK) == RTE_IPSEC_SATP_MODE_TUNLV4) 46 47 #define BAD_PORT ((uint16_t)-1) 48 49 struct rte_crypto_xform; 50 struct ipsec_xform; 51 struct rte_mbuf; 52 53 struct ipsec_sa; 54 /* 55 * Keeps number of configured SA's for each address family: 56 */ 57 struct ipsec_sa_cnt { 58 uint32_t nb_v4; 59 uint32_t nb_v6; 60 }; 61 62 typedef int32_t (*ipsec_xform_fn)(struct rte_mbuf *m, struct ipsec_sa *sa, 63 struct rte_crypto_op *cop); 64 65 struct ip_addr { 66 union { 67 uint32_t ip4; 68 union { 69 uint64_t ip6[2]; 70 uint8_t ip6_b[16]; 71 } ip6; 72 } ip; 73 }; 74 75 #define MAX_KEY_SIZE 64 76 /* 77 * application wide SA parameters 78 */ 79 struct app_sa_prm { 80 uint32_t enable; /* use librte_ipsec API for ipsec pkt processing */ 81 uint32_t window_size; /* replay window size */ 82 uint32_t enable_esn; /* enable/disable ESN support */ 83 uint32_t cache_sz; /* per lcore SA cache size */ 84 uint32_t udp_encap; /* enable/disable UDP Encapsulation */ 85 uint64_t flags; /* rte_ipsec_sa_prm.flags */ 86 }; 87 88 extern struct app_sa_prm app_sa_prm; 89 90 struct flow_info { 91 struct rte_flow *rx_def_flow; 92 }; 93 94 extern struct flow_info flow_info_tbl[RTE_MAX_ETHPORTS]; 95 96 enum { 97 IPSEC_SESSION_PRIMARY = 0, 98 IPSEC_SESSION_FALLBACK = 1, 99 IPSEC_SESSION_MAX 100 }; 101 102 #define IPSEC_SA_OFFLOAD_FALLBACK_FLAG (1) 103 104 static inline struct ipsec_sa * 105 ipsec_mask_saptr(void *ptr) 106 { 107 uintptr_t i = (uintptr_t)ptr; 108 static const uintptr_t mask = IPSEC_SA_OFFLOAD_FALLBACK_FLAG; 109 110 i &= ~mask; 111 112 return (struct ipsec_sa *)i; 113 } 114 115 struct __rte_cache_aligned ipsec_sa { 116 struct rte_ipsec_session sessions[IPSEC_SESSION_MAX]; 117 uint32_t spi; 118 struct cdev_qp *cqp[RTE_MAX_LCORE]; 119 uint64_t seq; 120 rte_be32_t salt; 121 uint32_t fallback_sessions; 122 enum rte_crypto_cipher_algorithm cipher_algo; 123 enum rte_crypto_auth_algorithm auth_algo; 124 enum rte_crypto_aead_algorithm aead_algo; 125 uint16_t digest_len; 126 uint16_t iv_len; 127 uint16_t block_size; 128 uint16_t flags; 129 #define IP4_TUNNEL (1 << 0) 130 #define IP6_TUNNEL (1 << 1) 131 #define TRANSPORT (1 << 2) 132 #define IP4_TRANSPORT (1 << 3) 133 #define IP6_TRANSPORT (1 << 4) 134 #define SA_TELEMETRY_ENABLE (1 << 5) 135 #define SA_REASSEMBLY_ENABLE (1 << 6) 136 137 struct ip_addr src; 138 struct ip_addr dst; 139 struct { 140 uint16_t sport; 141 uint16_t dport; 142 } udp; 143 uint8_t cipher_key[MAX_KEY_SIZE]; 144 uint16_t cipher_key_len; 145 uint8_t auth_key[MAX_KEY_SIZE]; 146 uint16_t auth_key_len; 147 uint16_t aad_len; 148 union { 149 struct rte_crypto_sym_xform *xforms; 150 struct rte_security_ipsec_xform *sec_xform; 151 }; 152 enum rte_security_ipsec_sa_direction direction; 153 uint8_t udp_encap; 154 uint16_t portid; 155 uint64_t esn; 156 uint16_t mss; 157 uint8_t fdir_qid; 158 uint8_t fdir_flag; 159 160 #define MAX_RTE_FLOW_PATTERN (5) 161 #define MAX_RTE_FLOW_ACTIONS (3) 162 struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN]; 163 struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS]; 164 struct rte_flow_attr attr; 165 union { 166 struct rte_flow_item_ipv4 ipv4_spec; 167 struct rte_flow_item_ipv6 ipv6_spec; 168 }; 169 struct rte_flow_item_udp udp_spec; 170 struct rte_flow_item_esp esp_spec; 171 struct rte_flow *flow; 172 struct rte_security_session_conf sess_conf; 173 }; 174 175 struct ipsec_xf { 176 struct rte_crypto_sym_xform a; 177 struct rte_crypto_sym_xform b; 178 }; 179 180 struct ipsec_sad { 181 struct rte_ipsec_sad *sad_v4; 182 struct rte_ipsec_sad *sad_v6; 183 }; 184 185 struct sa_ctx { 186 void *satbl; /* pointer to array of rte_ipsec_sa objects*/ 187 struct ipsec_sad sad; 188 struct ipsec_xf *xf; 189 uint32_t nb_sa; 190 struct ipsec_sa sa[]; 191 }; 192 193 struct __rte_cache_aligned ipsec_mbuf_metadata { 194 struct ipsec_sa *sa; 195 struct rte_crypto_op cop; 196 struct rte_crypto_sym_op sym_cop; 197 uint8_t buf[32]; 198 }; 199 200 #define IS_TRANSPORT(flags) ((flags) & TRANSPORT) 201 202 #define IS_TUNNEL(flags) ((flags) & (IP4_TUNNEL | IP6_TUNNEL)) 203 204 #define IS_IP4(flags) ((flags) & (IP4_TUNNEL | IP4_TRANSPORT)) 205 206 #define IS_IP6(flags) ((flags) & (IP6_TUNNEL | IP6_TRANSPORT)) 207 208 #define IS_IP4_TUNNEL(flags) ((flags) & IP4_TUNNEL) 209 210 #define IS_IP6_TUNNEL(flags) ((flags) & IP6_TUNNEL) 211 212 #define IS_HW_REASSEMBLY_EN(flags) ((flags) & SA_REASSEMBLY_ENABLE) 213 /* 214 * Macro for getting ipsec_sa flags statuses without version of protocol 215 * used for transport (IP4_TRANSPORT and IP6_TRANSPORT flags). 216 */ 217 #define WITHOUT_TRANSPORT_VERSION(flags) \ 218 ((flags) & (IP4_TUNNEL | \ 219 IP6_TUNNEL | \ 220 TRANSPORT)) 221 222 struct cdev_qp { 223 uint16_t id; 224 uint16_t qp; 225 uint16_t in_flight; 226 uint16_t len; 227 struct rte_crypto_op *buf[MAX_PKT_BURST]; 228 }; 229 230 struct ipsec_ctx { 231 struct rte_hash *cdev_map; 232 struct sp_ctx *sp4_ctx; 233 struct sp_ctx *sp6_ctx; 234 struct sa_ctx *sa_ctx; 235 uint16_t nb_qps; 236 uint16_t last_qp; 237 struct cdev_qp tbl[MAX_QP_PER_LCORE]; 238 struct rte_mbuf *ol_pkts[MAX_PKT_BURST]; 239 uint16_t ol_pkts_cnt; 240 uint64_t ipv4_offloads; 241 uint64_t ipv6_offloads; 242 uint32_t lcore_id; 243 }; 244 245 struct offloads { 246 uint64_t ipv4_offloads; 247 uint64_t ipv6_offloads; 248 }; 249 250 extern struct offloads tx_offloads; 251 252 /* 253 * This structure is used for the key in hash table. 254 * Padding is to force the struct to use 8 bytes, 255 * to ensure memory is not read past this structs boundary 256 * (hash key calculation reads 8 bytes if this struct is size 5 bytes). 257 */ 258 struct cdev_key { 259 uint32_t lcore_id; 260 uint8_t cipher_algo; 261 uint8_t auth_algo; 262 uint8_t aead_algo; 263 uint8_t padding; /* padding to 8-byte size should be zeroed */ 264 }; 265 266 struct socket_ctx { 267 struct sa_ctx *sa_in; 268 struct sa_ctx *sa_out; 269 struct sp_ctx *sp_ip4_in; 270 struct sp_ctx *sp_ip4_out; 271 struct sp_ctx *sp_ip6_in; 272 struct sp_ctx *sp_ip6_out; 273 struct rt_ctx *rt_ip4; 274 struct rt_ctx *rt_ip6; 275 struct rte_mempool *mbuf_pool[RTE_MAX_ETHPORTS]; 276 struct rte_mempool *mbuf_pool_indir; 277 struct rte_mempool *session_pool; 278 }; 279 280 struct cnt_blk { 281 uint32_t salt; 282 uint64_t iv; 283 uint32_t cnt; 284 } __rte_packed; 285 286 struct __rte_cache_aligned lcore_rx_queue { 287 uint16_t port_id; 288 uint16_t queue_id; 289 void *sec_ctx; 290 }; 291 292 struct buffer { 293 uint16_t len; 294 struct rte_mbuf *m_table[MAX_PKT_BURST]; 295 }; 296 297 struct __rte_cache_aligned lcore_conf { 298 uint16_t nb_rx_queue; 299 struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE]; 300 uint16_t tx_queue_id[RTE_MAX_ETHPORTS]; 301 struct buffer tx_mbufs[RTE_MAX_ETHPORTS]; 302 struct ipsec_ctx inbound; 303 struct ipsec_ctx outbound; 304 struct rt_ctx *rt4_ctx; 305 struct rt_ctx *rt6_ctx; 306 struct { 307 struct rte_ip_frag_tbl *tbl; 308 struct rte_mempool *pool_indir; 309 struct rte_ip_frag_death_row dr; 310 } frag; 311 }; 312 313 extern struct lcore_conf lcore_conf[RTE_MAX_LCORE]; 314 315 /* Socket ctx */ 316 extern struct socket_ctx socket_ctx[NB_SOCKETS]; 317 318 void 319 ipsec_poll_mode_worker(void); 320 321 int 322 ipsec_launch_one_lcore(void *args); 323 324 extern struct ipsec_sa *sa_out; 325 extern uint32_t nb_sa_out; 326 327 extern struct ipsec_sa *sa_in; 328 extern uint32_t nb_sa_in; 329 330 uint16_t 331 ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 332 uint16_t nb_pkts, uint16_t len); 333 334 uint16_t 335 ipsec_outbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 336 uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len); 337 338 uint16_t 339 ipsec_inbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 340 uint16_t len); 341 342 uint16_t 343 ipsec_outbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[], 344 uint16_t len); 345 346 void 347 ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf); 348 349 void 350 ipsec_cqp_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf); 351 352 static inline uint16_t 353 ipsec_metadata_size(void) 354 { 355 return sizeof(struct ipsec_mbuf_metadata); 356 } 357 358 static inline struct ipsec_mbuf_metadata * 359 get_priv(struct rte_mbuf *m) 360 { 361 return rte_mbuf_to_priv(m); 362 } 363 364 static inline void * 365 get_cnt_blk(struct rte_mbuf *m) 366 { 367 struct ipsec_mbuf_metadata *priv = get_priv(m); 368 369 return &priv->buf[0]; 370 } 371 372 static inline void * 373 get_aad(struct rte_mbuf *m) 374 { 375 struct ipsec_mbuf_metadata *priv = get_priv(m); 376 377 return &priv->buf[16]; 378 } 379 380 static inline void * 381 get_sym_cop(struct rte_crypto_op *cop) 382 { 383 return (cop + 1); 384 } 385 386 static inline struct rte_ipsec_session * 387 ipsec_get_primary_session(struct ipsec_sa *sa) 388 { 389 return &sa->sessions[IPSEC_SESSION_PRIMARY]; 390 } 391 392 static inline struct rte_ipsec_session * 393 ipsec_get_fallback_session(struct ipsec_sa *sa) 394 { 395 return &sa->sessions[IPSEC_SESSION_FALLBACK]; 396 } 397 398 static inline enum rte_security_session_action_type 399 ipsec_get_action_type(struct ipsec_sa *sa) 400 { 401 struct rte_ipsec_session *ips; 402 ips = ipsec_get_primary_session(sa); 403 return ips->type; 404 } 405 406 int 407 inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx); 408 409 void 410 inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[], 411 void *sa[], uint16_t nb_pkts); 412 413 void 414 outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[], 415 void *sa[], uint16_t nb_pkts); 416 417 void 418 sp4_init(struct socket_ctx *ctx, int32_t socket_id); 419 420 void 421 sp6_init(struct socket_ctx *ctx, int32_t socket_id); 422 423 /* 424 * Search through SP rules for given SPI. 425 * Returns first rule index if found(greater or equal then zero), 426 * or -ENOENT otherwise. 427 */ 428 int 429 sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], 430 uint32_t mask[2]); 431 int 432 sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2], 433 uint32_t mask[2]); 434 435 /* 436 * Search through SA entries for given SPI. 437 * Returns first entry index if found(greater or equal then zero), 438 * or -ENOENT otherwise. 439 */ 440 int 441 sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound); 442 443 void 444 sa_init(struct socket_ctx *ctx, int32_t socket_id, 445 struct lcore_conf *lcore_conf, 446 const struct eventmode_conf *em_conf); 447 448 void 449 rt_init(struct socket_ctx *ctx, int32_t socket_id); 450 451 int 452 sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads, 453 uint64_t *tx_offloads, uint8_t *hw_reassembly); 454 455 int 456 add_dst_ethaddr(uint16_t port, const struct rte_ether_addr *addr); 457 458 void 459 enqueue_cop_burst(struct cdev_qp *cqp); 460 461 int 462 create_lookaside_session(struct ipsec_ctx *ipsec_ctx[], 463 struct socket_ctx *skt_ctx, const struct eventmode_conf *em_conf, 464 struct ipsec_sa *sa, struct rte_ipsec_session *ips); 465 466 int 467 create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa, 468 struct rte_ipsec_session *ips); 469 int 470 check_flow_params(uint16_t fdir_portid, uint8_t fdir_qid); 471 472 int 473 create_ipsec_esp_flow(struct ipsec_sa *sa); 474 475 uint32_t 476 get_nb_crypto_sessions(void); 477 478 #endif /* __IPSEC_H__ */ 479