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