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