DPDK logo

Elixir Cross Referencer

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright(c) 2016-2017 Intel Corporation
 */

#ifndef __IPSEC_H__
#define __IPSEC_H__

#include <stdint.h>

#include <rte_byteorder.h>
#include <rte_crypto.h>
#include <rte_security.h>
#include <rte_flow.h>
#include <rte_ipsec.h>

#include "ipsec-secgw.h"

#define RTE_LOGTYPE_IPSEC_ESP   RTE_LOGTYPE_USER2
#define RTE_LOGTYPE_IPSEC_IPIP  RTE_LOGTYPE_USER3

#define MAX_INFLIGHT 128
#define MAX_QP_PER_LCORE 256

#define MAX_DIGEST_SIZE 32 /* Bytes -- 256 bits */

#define IPSEC_OFFLOAD_ESN_SOFTLIMIT 0xffffff00

#define IV_OFFSET		(sizeof(struct rte_crypto_op) + \
				sizeof(struct rte_crypto_sym_op))

#define DEFAULT_MAX_CATEGORIES	1

#define INVALID_SPI (0)

#define DISCARD	INVALID_SPI
#define BYPASS	UINT32_MAX

#define IPSEC_XFORM_MAX 2

#define IP6_VERSION (6)

struct rte_crypto_xform;
struct ipsec_xform;
struct rte_mbuf;

struct ipsec_sa;
/*
 * Keeps number of configured SA's for each address family:
 */
struct ipsec_sa_cnt {
	uint32_t	nb_v4;
	uint32_t	nb_v6;
};

typedef int32_t (*ipsec_xform_fn)(struct rte_mbuf *m, struct ipsec_sa *sa,
		struct rte_crypto_op *cop);

struct ip_addr {
	union {
		uint32_t ip4;
		union {
			uint64_t ip6[2];
			uint8_t ip6_b[16];
		} ip6;
	} ip;
};

#define MAX_KEY_SIZE		36

/*
 * application wide SA parameters
 */
struct app_sa_prm {
	uint32_t enable; /* use librte_ipsec API for ipsec pkt processing */
	uint32_t window_size; /* replay window size */
	uint32_t enable_esn;  /* enable/disable ESN support */
	uint32_t cache_sz;	/* per lcore SA cache size */
	uint64_t flags;       /* rte_ipsec_sa_prm.flags */
};

extern struct app_sa_prm app_sa_prm;

struct flow_info {
	struct rte_flow *rx_def_flow;
};

extern struct flow_info flow_info_tbl[RTE_MAX_ETHPORTS];

enum {
	IPSEC_SESSION_PRIMARY = 0,
	IPSEC_SESSION_FALLBACK = 1,
	IPSEC_SESSION_MAX
};

#define IPSEC_SA_OFFLOAD_FALLBACK_FLAG (1)

static inline struct ipsec_sa *
ipsec_mask_saptr(void *ptr)
{
	uintptr_t i = (uintptr_t)ptr;
	static const uintptr_t mask = IPSEC_SA_OFFLOAD_FALLBACK_FLAG;

	i &= ~mask;

	return (struct ipsec_sa *)i;
}

struct ipsec_sa {
	struct rte_ipsec_session sessions[IPSEC_SESSION_MAX];
	uint32_t spi;
	uint32_t cdev_id_qp;
	uint64_t seq;
	uint32_t salt;
	uint32_t fallback_sessions;
	enum rte_crypto_cipher_algorithm cipher_algo;
	enum rte_crypto_auth_algorithm auth_algo;
	enum rte_crypto_aead_algorithm aead_algo;
	uint16_t digest_len;
	uint16_t iv_len;
	uint16_t block_size;
	uint16_t flags;
#define IP4_TUNNEL (1 << 0)
#define IP6_TUNNEL (1 << 1)
#define TRANSPORT  (1 << 2)
#define IP4_TRANSPORT (1 << 3)
#define IP6_TRANSPORT (1 << 4)
	struct ip_addr src;
	struct ip_addr dst;
	uint8_t cipher_key[MAX_KEY_SIZE];
	uint16_t cipher_key_len;
	uint8_t auth_key[MAX_KEY_SIZE];
	uint16_t auth_key_len;
	uint16_t aad_len;
	union {
		struct rte_crypto_sym_xform *xforms;
		struct rte_security_ipsec_xform *sec_xform;
	};
	enum rte_security_ipsec_sa_direction direction;
	uint16_t portid;
	uint8_t fdir_qid;
	uint8_t fdir_flag;

#define MAX_RTE_FLOW_PATTERN (4)
#define MAX_RTE_FLOW_ACTIONS (3)
	struct rte_flow_item pattern[MAX_RTE_FLOW_PATTERN];
	struct rte_flow_action action[MAX_RTE_FLOW_ACTIONS];
	struct rte_flow_attr attr;
	union {
		struct rte_flow_item_ipv4 ipv4_spec;
		struct rte_flow_item_ipv6 ipv6_spec;
	};
	struct rte_flow_item_esp esp_spec;
	struct rte_flow *flow;
	struct rte_security_session_conf sess_conf;
} __rte_cache_aligned;

struct ipsec_xf {
	struct rte_crypto_sym_xform a;
	struct rte_crypto_sym_xform b;
};

struct ipsec_sad {
	struct rte_ipsec_sad *sad_v4;
	struct rte_ipsec_sad *sad_v6;
};

struct sa_ctx {
	void *satbl; /* pointer to array of rte_ipsec_sa objects*/
	struct ipsec_sad sad;
	struct ipsec_xf *xf;
	uint32_t nb_sa;
	struct ipsec_sa sa[];
};

struct ipsec_mbuf_metadata {
	struct ipsec_sa *sa;
	struct rte_crypto_op cop;
	struct rte_crypto_sym_op sym_cop;
	uint8_t buf[32];
} __rte_cache_aligned;

#define IS_TRANSPORT(flags) ((flags) & TRANSPORT)

#define IS_TUNNEL(flags) ((flags) & (IP4_TUNNEL | IP6_TUNNEL))

#define IS_IP4(flags) ((flags) & (IP4_TUNNEL | IP4_TRANSPORT))

#define IS_IP6(flags) ((flags) & (IP6_TUNNEL | IP6_TRANSPORT))

#define IS_IP4_TUNNEL(flags) ((flags) & IP4_TUNNEL)

#define IS_IP6_TUNNEL(flags) ((flags) & IP6_TUNNEL)

/*
 * Macro for getting ipsec_sa flags statuses without version of protocol
 * used for transport (IP4_TRANSPORT and IP6_TRANSPORT flags).
 */
#define WITHOUT_TRANSPORT_VERSION(flags) \
		((flags) & (IP4_TUNNEL | \
			IP6_TUNNEL | \
			TRANSPORT))

struct cdev_qp {
	uint16_t id;
	uint16_t qp;
	uint16_t in_flight;
	uint16_t len;
	struct rte_crypto_op *buf[MAX_PKT_BURST] __rte_aligned(sizeof(void *));
};

struct ipsec_ctx {
	struct rte_hash *cdev_map;
	struct sp_ctx *sp4_ctx;
	struct sp_ctx *sp6_ctx;
	struct sa_ctx *sa_ctx;
	uint16_t nb_qps;
	uint16_t last_qp;
	struct cdev_qp tbl[MAX_QP_PER_LCORE];
	struct rte_mempool *session_pool;
	struct rte_mempool *session_priv_pool;
	struct rte_mbuf *ol_pkts[MAX_PKT_BURST] __rte_aligned(sizeof(void *));
	uint16_t ol_pkts_cnt;
	uint64_t ipv4_offloads;
	uint64_t ipv6_offloads;
};

struct cdev_key {
	uint16_t lcore_id;
	uint8_t cipher_algo;
	uint8_t auth_algo;
	uint8_t aead_algo;
};

struct socket_ctx {
	struct sa_ctx *sa_in;
	struct sa_ctx *sa_out;
	struct sp_ctx *sp_ip4_in;
	struct sp_ctx *sp_ip4_out;
	struct sp_ctx *sp_ip6_in;
	struct sp_ctx *sp_ip6_out;
	struct rt_ctx *rt_ip4;
	struct rt_ctx *rt_ip6;
	struct rte_mempool *mbuf_pool;
	struct rte_mempool *mbuf_pool_indir;
	struct rte_mempool *session_pool;
	struct rte_mempool *session_priv_pool;
};

struct cnt_blk {
	uint32_t salt;
	uint64_t iv;
	uint32_t cnt;
} __rte_packed;

/* Socket ctx */
extern struct socket_ctx socket_ctx[NB_SOCKETS];

void
ipsec_poll_mode_worker(void);

int
ipsec_launch_one_lcore(void *args);

extern struct ipsec_sa *sa_out;
extern uint32_t nb_sa_out;

extern struct ipsec_sa *sa_in;
extern uint32_t nb_sa_in;

uint16_t
ipsec_inbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
		uint16_t nb_pkts, uint16_t len);

uint16_t
ipsec_outbound(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
		uint32_t sa_idx[], uint16_t nb_pkts, uint16_t len);

uint16_t
ipsec_inbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
		uint16_t len);

uint16_t
ipsec_outbound_cqp_dequeue(struct ipsec_ctx *ctx, struct rte_mbuf *pkts[],
		uint16_t len);

void
ipsec_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf);

void
ipsec_cqp_process(struct ipsec_ctx *ctx, struct ipsec_traffic *trf);

static inline uint16_t
ipsec_metadata_size(void)
{
	return sizeof(struct ipsec_mbuf_metadata);
}

static inline struct ipsec_mbuf_metadata *
get_priv(struct rte_mbuf *m)
{
	return rte_mbuf_to_priv(m);
}

static inline void *
get_cnt_blk(struct rte_mbuf *m)
{
	struct ipsec_mbuf_metadata *priv = get_priv(m);

	return &priv->buf[0];
}

static inline void *
get_aad(struct rte_mbuf *m)
{
	struct ipsec_mbuf_metadata *priv = get_priv(m);

	return &priv->buf[16];
}

static inline void *
get_sym_cop(struct rte_crypto_op *cop)
{
	return (cop + 1);
}

static inline struct rte_ipsec_session *
ipsec_get_primary_session(struct ipsec_sa *sa)
{
	return &sa->sessions[IPSEC_SESSION_PRIMARY];
}

static inline struct rte_ipsec_session *
ipsec_get_fallback_session(struct ipsec_sa *sa)
{
	return &sa->sessions[IPSEC_SESSION_FALLBACK];
}

static inline enum rte_security_session_action_type
ipsec_get_action_type(struct ipsec_sa *sa)
{
	struct rte_ipsec_session *ips;
	ips = ipsec_get_primary_session(sa);
	return ips->type;
}

int
inbound_sa_check(struct sa_ctx *sa_ctx, struct rte_mbuf *m, uint32_t sa_idx);

void
inbound_sa_lookup(struct sa_ctx *sa_ctx, struct rte_mbuf *pkts[],
		void *sa[], uint16_t nb_pkts);

void
outbound_sa_lookup(struct sa_ctx *sa_ctx, uint32_t sa_idx[],
		void *sa[], uint16_t nb_pkts);

void
sp4_init(struct socket_ctx *ctx, int32_t socket_id);

void
sp6_init(struct socket_ctx *ctx, int32_t socket_id);

/*
 * Search through SP rules for given SPI.
 * Returns first rule index if found(greater or equal then zero),
 * or -ENOENT otherwise.
 */
int
sp4_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
			uint32_t mask[2]);
int
sp6_spi_present(uint32_t spi, int inbound, struct ip_addr ip_addr[2],
			uint32_t mask[2]);

/*
 * Search through SA entries for given SPI.
 * Returns first entry index if found(greater or equal then zero),
 * or -ENOENT otherwise.
 */
int
sa_spi_present(struct sa_ctx *sa_ctx, uint32_t spi, int inbound);

void
sa_init(struct socket_ctx *ctx, int32_t socket_id);

void
rt_init(struct socket_ctx *ctx, int32_t socket_id);

int
sa_check_offloads(uint16_t port_id, uint64_t *rx_offloads,
		uint64_t *tx_offloads);

int
add_dst_ethaddr(uint16_t port, const struct rte_ether_addr *addr);

void
enqueue_cop_burst(struct cdev_qp *cqp);

int
create_lookaside_session(struct ipsec_ctx *ipsec_ctx, struct ipsec_sa *sa,
		struct rte_ipsec_session *ips);

int
create_inline_session(struct socket_ctx *skt_ctx, struct ipsec_sa *sa,
		struct rte_ipsec_session *ips);
int
check_flow_params(uint16_t fdir_portid, uint8_t fdir_qid);

int
create_ipsec_esp_flow(struct ipsec_sa *sa);

uint32_t
get_nb_crypto_sessions(void);

#endif /* __IPSEC_H__ */