xref: /dpdk/examples/ipsec-secgw/ipsec.h (revision 42a8fc7daa46256d150278fc9a7a846e27945a0c)
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__ */
460