xref: /dpdk/examples/ipsec-secgw/ipsec_worker.c (revision aae4f5e0)
14965dda0SLukasz Bartosik /* SPDX-License-Identifier: BSD-3-Clause
24965dda0SLukasz Bartosik  * Copyright(c) 2010-2016 Intel Corporation
34965dda0SLukasz Bartosik  * Copyright (C) 2020 Marvell International Ltd.
44965dda0SLukasz Bartosik  */
59ad50c29SLukasz Bartosik #include <rte_acl.h>
64965dda0SLukasz Bartosik #include <rte_event_eth_tx_adapter.h>
79ad50c29SLukasz Bartosik #include <rte_lpm.h>
89ad50c29SLukasz Bartosik #include <rte_lpm6.h>
94965dda0SLukasz Bartosik 
104965dda0SLukasz Bartosik #include "event_helper.h"
114965dda0SLukasz Bartosik #include "ipsec.h"
124965dda0SLukasz Bartosik #include "ipsec-secgw.h"
139ad50c29SLukasz Bartosik #include "ipsec_worker.h"
149ad50c29SLukasz Bartosik 
15ea28ab88SNithin Dabilpuram struct port_drv_mode_data {
16ea28ab88SNithin Dabilpuram 	struct rte_security_session *sess;
17ea28ab88SNithin Dabilpuram 	struct rte_security_ctx *ctx;
18ea28ab88SNithin Dabilpuram };
19ea28ab88SNithin Dabilpuram 
209ad50c29SLukasz Bartosik static inline enum pkt_type
process_ipsec_get_pkt_type(struct rte_mbuf * pkt,uint8_t ** nlp)219ad50c29SLukasz Bartosik process_ipsec_get_pkt_type(struct rte_mbuf *pkt, uint8_t **nlp)
229ad50c29SLukasz Bartosik {
239ad50c29SLukasz Bartosik 	struct rte_ether_hdr *eth;
242e7abb8bSNithin Dabilpuram 	uint32_t ptype = pkt->packet_type;
259ad50c29SLukasz Bartosik 
269ad50c29SLukasz Bartosik 	eth = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
272e7abb8bSNithin Dabilpuram 	rte_prefetch0(eth);
282e7abb8bSNithin Dabilpuram 
292e7abb8bSNithin Dabilpuram 	if (RTE_ETH_IS_IPV4_HDR(ptype)) {
309ad50c29SLukasz Bartosik 		*nlp = RTE_PTR_ADD(eth, RTE_ETHER_HDR_LEN +
319ad50c29SLukasz Bartosik 				offsetof(struct ip, ip_p));
322e7abb8bSNithin Dabilpuram 		if ((ptype & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_ESP)
339ad50c29SLukasz Bartosik 			return PKT_TYPE_IPSEC_IPV4;
349ad50c29SLukasz Bartosik 		else
359ad50c29SLukasz Bartosik 			return PKT_TYPE_PLAIN_IPV4;
362e7abb8bSNithin Dabilpuram 	} else if (RTE_ETH_IS_IPV6_HDR(ptype)) {
379ad50c29SLukasz Bartosik 		*nlp = RTE_PTR_ADD(eth, RTE_ETHER_HDR_LEN +
389ad50c29SLukasz Bartosik 				offsetof(struct ip6_hdr, ip6_nxt));
392e7abb8bSNithin Dabilpuram 		if ((ptype & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_ESP)
409ad50c29SLukasz Bartosik 			return PKT_TYPE_IPSEC_IPV6;
419ad50c29SLukasz Bartosik 		else
429ad50c29SLukasz Bartosik 			return PKT_TYPE_PLAIN_IPV6;
439ad50c29SLukasz Bartosik 	}
449ad50c29SLukasz Bartosik 
459ad50c29SLukasz Bartosik 	/* Unknown/Unsupported type */
469ad50c29SLukasz Bartosik 	return PKT_TYPE_INVALID;
479ad50c29SLukasz Bartosik }
489ad50c29SLukasz Bartosik 
499ad50c29SLukasz Bartosik static inline void
update_mac_addrs(struct rte_mbuf * pkt,uint16_t portid)509ad50c29SLukasz Bartosik update_mac_addrs(struct rte_mbuf *pkt, uint16_t portid)
519ad50c29SLukasz Bartosik {
529ad50c29SLukasz Bartosik 	struct rte_ether_hdr *ethhdr;
539ad50c29SLukasz Bartosik 
549ad50c29SLukasz Bartosik 	ethhdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
5504d43857SDmitry Kozlyuk 	memcpy(&ethhdr->src_addr, &ethaddr_tbl[portid].src, RTE_ETHER_ADDR_LEN);
5604d43857SDmitry Kozlyuk 	memcpy(&ethhdr->dst_addr, &ethaddr_tbl[portid].dst, RTE_ETHER_ADDR_LEN);
579ad50c29SLukasz Bartosik }
584965dda0SLukasz Bartosik 
594965dda0SLukasz Bartosik static inline void
ipsec_event_pre_forward(struct rte_mbuf * m,unsigned int port_id)604965dda0SLukasz Bartosik ipsec_event_pre_forward(struct rte_mbuf *m, unsigned int port_id)
614965dda0SLukasz Bartosik {
624965dda0SLukasz Bartosik 	/* Save the destination port in the mbuf */
634965dda0SLukasz Bartosik 	m->port = port_id;
644965dda0SLukasz Bartosik 
654965dda0SLukasz Bartosik 	/* Save eth queue for Tx */
664965dda0SLukasz Bartosik 	rte_event_eth_tx_adapter_txq_set(m, 0);
674965dda0SLukasz Bartosik }
684965dda0SLukasz Bartosik 
694965dda0SLukasz Bartosik static inline void
ev_vector_attr_init(struct rte_event_vector * vec)7086738ebeSSrujana Challa ev_vector_attr_init(struct rte_event_vector *vec)
7186738ebeSSrujana Challa {
7286738ebeSSrujana Challa 	vec->attr_valid = 1;
7386738ebeSSrujana Challa 	vec->port = 0xFFFF;
7486738ebeSSrujana Challa 	vec->queue = 0;
7586738ebeSSrujana Challa }
7686738ebeSSrujana Challa 
7786738ebeSSrujana Challa static inline void
ev_vector_attr_update(struct rte_event_vector * vec,struct rte_mbuf * pkt)7886738ebeSSrujana Challa ev_vector_attr_update(struct rte_event_vector *vec, struct rte_mbuf *pkt)
7986738ebeSSrujana Challa {
8086738ebeSSrujana Challa 	if (vec->port == 0xFFFF) {
8186738ebeSSrujana Challa 		vec->port = pkt->port;
8286738ebeSSrujana Challa 		return;
8386738ebeSSrujana Challa 	}
8486738ebeSSrujana Challa 	if (vec->attr_valid && (vec->port != pkt->port))
8586738ebeSSrujana Challa 		vec->attr_valid = 0;
8686738ebeSSrujana Challa }
8786738ebeSSrujana Challa 
8886738ebeSSrujana Challa static inline void
prepare_out_sessions_tbl(struct sa_ctx * sa_out,struct port_drv_mode_data * data,uint16_t size)894965dda0SLukasz Bartosik prepare_out_sessions_tbl(struct sa_ctx *sa_out,
90ea28ab88SNithin Dabilpuram 			 struct port_drv_mode_data *data,
91ea28ab88SNithin Dabilpuram 			 uint16_t size)
924965dda0SLukasz Bartosik {
934965dda0SLukasz Bartosik 	struct rte_ipsec_session *pri_sess;
944965dda0SLukasz Bartosik 	struct ipsec_sa *sa;
954965dda0SLukasz Bartosik 	uint32_t i;
964965dda0SLukasz Bartosik 
974965dda0SLukasz Bartosik 	if (!sa_out)
984965dda0SLukasz Bartosik 		return;
994965dda0SLukasz Bartosik 
1004965dda0SLukasz Bartosik 	for (i = 0; i < sa_out->nb_sa; i++) {
1014965dda0SLukasz Bartosik 
1024965dda0SLukasz Bartosik 		sa = &sa_out->sa[i];
1034965dda0SLukasz Bartosik 		if (!sa)
1044965dda0SLukasz Bartosik 			continue;
1054965dda0SLukasz Bartosik 
1064965dda0SLukasz Bartosik 		pri_sess = ipsec_get_primary_session(sa);
1074965dda0SLukasz Bartosik 		if (!pri_sess)
1084965dda0SLukasz Bartosik 			continue;
1094965dda0SLukasz Bartosik 
1104965dda0SLukasz Bartosik 		if (pri_sess->type !=
1114965dda0SLukasz Bartosik 			RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL) {
1124965dda0SLukasz Bartosik 
1134965dda0SLukasz Bartosik 			RTE_LOG(ERR, IPSEC, "Invalid session type %d\n",
1144965dda0SLukasz Bartosik 				pri_sess->type);
1154965dda0SLukasz Bartosik 			continue;
1164965dda0SLukasz Bartosik 		}
1174965dda0SLukasz Bartosik 
1184965dda0SLukasz Bartosik 		if (sa->portid >= size) {
1194965dda0SLukasz Bartosik 			RTE_LOG(ERR, IPSEC,
1204965dda0SLukasz Bartosik 				"Port id >= than table size %d, %d\n",
1214965dda0SLukasz Bartosik 				sa->portid, size);
1224965dda0SLukasz Bartosik 			continue;
1234965dda0SLukasz Bartosik 		}
1244965dda0SLukasz Bartosik 
1254965dda0SLukasz Bartosik 		/* Use only first inline session found for a given port */
126ea28ab88SNithin Dabilpuram 		if (data[sa->portid].sess)
1274965dda0SLukasz Bartosik 			continue;
128ea28ab88SNithin Dabilpuram 		data[sa->portid].sess = pri_sess->security.ses;
129ea28ab88SNithin Dabilpuram 		data[sa->portid].ctx = pri_sess->security.ctx;
1304965dda0SLukasz Bartosik 	}
1314965dda0SLukasz Bartosik }
1324965dda0SLukasz Bartosik 
1339ad50c29SLukasz Bartosik static inline int
check_sp(struct sp_ctx * sp,const uint8_t * nlp,uint32_t * sa_idx)1349ad50c29SLukasz Bartosik check_sp(struct sp_ctx *sp, const uint8_t *nlp, uint32_t *sa_idx)
1359ad50c29SLukasz Bartosik {
1369ad50c29SLukasz Bartosik 	uint32_t res;
1379ad50c29SLukasz Bartosik 
1389ad50c29SLukasz Bartosik 	if (unlikely(sp == NULL))
1399ad50c29SLukasz Bartosik 		return 0;
1409ad50c29SLukasz Bartosik 
1419ad50c29SLukasz Bartosik 	rte_acl_classify((struct rte_acl_ctx *)sp, &nlp, &res, 1,
1429ad50c29SLukasz Bartosik 			DEFAULT_MAX_CATEGORIES);
1439ad50c29SLukasz Bartosik 
144ab722af6SAnkur Dwivedi 	if (unlikely(res == DISCARD))
1459ad50c29SLukasz Bartosik 		return 0;
1469ad50c29SLukasz Bartosik 	else if (res == BYPASS) {
1479ad50c29SLukasz Bartosik 		*sa_idx = -1;
1489ad50c29SLukasz Bartosik 		return 1;
1499ad50c29SLukasz Bartosik 	}
1509ad50c29SLukasz Bartosik 
1519ad50c29SLukasz Bartosik 	*sa_idx = res - 1;
1529ad50c29SLukasz Bartosik 	return 1;
1539ad50c29SLukasz Bartosik }
1549ad50c29SLukasz Bartosik 
15586738ebeSSrujana Challa static inline void
check_sp_bulk(struct sp_ctx * sp,struct traffic_type * ip,struct traffic_type * ipsec)15686738ebeSSrujana Challa check_sp_bulk(struct sp_ctx *sp, struct traffic_type *ip,
15786738ebeSSrujana Challa 	      struct traffic_type *ipsec)
15886738ebeSSrujana Challa {
15986738ebeSSrujana Challa 	uint32_t i, j, res;
16086738ebeSSrujana Challa 	struct rte_mbuf *m;
16186738ebeSSrujana Challa 
16286738ebeSSrujana Challa 	if (unlikely(sp == NULL || ip->num == 0))
16386738ebeSSrujana Challa 		return;
16486738ebeSSrujana Challa 
16586738ebeSSrujana Challa 	rte_acl_classify((struct rte_acl_ctx *)sp, ip->data, ip->res, ip->num,
16686738ebeSSrujana Challa 			 DEFAULT_MAX_CATEGORIES);
16786738ebeSSrujana Challa 
16886738ebeSSrujana Challa 	j = 0;
16986738ebeSSrujana Challa 	for (i = 0; i < ip->num; i++) {
17086738ebeSSrujana Challa 		m = ip->pkts[i];
17186738ebeSSrujana Challa 		res = ip->res[i];
17286738ebeSSrujana Challa 		if (unlikely(res == DISCARD))
17386738ebeSSrujana Challa 			free_pkts(&m, 1);
17486738ebeSSrujana Challa 		else if (res == BYPASS)
17586738ebeSSrujana Challa 			ip->pkts[j++] = m;
17686738ebeSSrujana Challa 		else {
17786738ebeSSrujana Challa 			ipsec->res[ipsec->num] = res - 1;
17886738ebeSSrujana Challa 			ipsec->pkts[ipsec->num++] = m;
17986738ebeSSrujana Challa 		}
18086738ebeSSrujana Challa 	}
18186738ebeSSrujana Challa 	ip->num = j;
18286738ebeSSrujana Challa }
18386738ebeSSrujana Challa 
18486738ebeSSrujana Challa static inline void
check_sp_sa_bulk(struct sp_ctx * sp,struct sa_ctx * sa_ctx,struct traffic_type * ip)18586738ebeSSrujana Challa check_sp_sa_bulk(struct sp_ctx *sp, struct sa_ctx *sa_ctx,
18686738ebeSSrujana Challa 		 struct traffic_type *ip)
18786738ebeSSrujana Challa {
18886738ebeSSrujana Challa 	struct ipsec_sa *sa;
18986738ebeSSrujana Challa 	uint32_t i, j, res;
19086738ebeSSrujana Challa 	struct rte_mbuf *m;
19186738ebeSSrujana Challa 
19286738ebeSSrujana Challa 	if (unlikely(sp == NULL || ip->num == 0))
19386738ebeSSrujana Challa 		return;
19486738ebeSSrujana Challa 
19586738ebeSSrujana Challa 	rte_acl_classify((struct rte_acl_ctx *)sp, ip->data, ip->res, ip->num,
19686738ebeSSrujana Challa 			 DEFAULT_MAX_CATEGORIES);
19786738ebeSSrujana Challa 
19886738ebeSSrujana Challa 	j = 0;
19986738ebeSSrujana Challa 	for (i = 0; i < ip->num; i++) {
20086738ebeSSrujana Challa 		m = ip->pkts[i];
20186738ebeSSrujana Challa 		res = ip->res[i];
20286738ebeSSrujana Challa 		if (unlikely(res == DISCARD))
20386738ebeSSrujana Challa 			free_pkts(&m, 1);
20486738ebeSSrujana Challa 		else if (res == BYPASS)
20586738ebeSSrujana Challa 			ip->pkts[j++] = m;
20686738ebeSSrujana Challa 		else {
20786738ebeSSrujana Challa 			sa = *(struct ipsec_sa **)rte_security_dynfield(m);
2085fb245baSNithin Dabilpuram 			if (sa == NULL) {
20986738ebeSSrujana Challa 				free_pkts(&m, 1);
2105fb245baSNithin Dabilpuram 				continue;
2115fb245baSNithin Dabilpuram 			}
21286738ebeSSrujana Challa 
21386738ebeSSrujana Challa 			/* SPI on the packet should match with the one in SA */
2145fb245baSNithin Dabilpuram 			if (unlikely(sa->spi != sa_ctx->sa[res - 1].spi)) {
21586738ebeSSrujana Challa 				free_pkts(&m, 1);
2165fb245baSNithin Dabilpuram 				continue;
2175fb245baSNithin Dabilpuram 			}
21886738ebeSSrujana Challa 
21986738ebeSSrujana Challa 			ip->pkts[j++] = m;
22086738ebeSSrujana Challa 		}
22186738ebeSSrujana Challa 	}
22286738ebeSSrujana Challa 	ip->num = j;
22386738ebeSSrujana Challa }
22486738ebeSSrujana Challa 
2259ad50c29SLukasz Bartosik static inline uint16_t
route4_pkt(struct rte_mbuf * pkt,struct rt_ctx * rt_ctx)2269ad50c29SLukasz Bartosik route4_pkt(struct rte_mbuf *pkt, struct rt_ctx *rt_ctx)
2279ad50c29SLukasz Bartosik {
2289ad50c29SLukasz Bartosik 	uint32_t dst_ip;
2299ad50c29SLukasz Bartosik 	uint16_t offset;
2309ad50c29SLukasz Bartosik 	uint32_t hop;
2319ad50c29SLukasz Bartosik 	int ret;
2329ad50c29SLukasz Bartosik 
2339ad50c29SLukasz Bartosik 	offset = RTE_ETHER_HDR_LEN + offsetof(struct ip, ip_dst);
2349ad50c29SLukasz Bartosik 	dst_ip = *rte_pktmbuf_mtod_offset(pkt, uint32_t *, offset);
2359ad50c29SLukasz Bartosik 	dst_ip = rte_be_to_cpu_32(dst_ip);
2369ad50c29SLukasz Bartosik 
2379ad50c29SLukasz Bartosik 	ret = rte_lpm_lookup((struct rte_lpm *)rt_ctx, dst_ip, &hop);
2389ad50c29SLukasz Bartosik 
2399ad50c29SLukasz Bartosik 	if (ret == 0) {
2409ad50c29SLukasz Bartosik 		/* We have a hit */
2419ad50c29SLukasz Bartosik 		return hop;
2429ad50c29SLukasz Bartosik 	}
2439ad50c29SLukasz Bartosik 
2449ad50c29SLukasz Bartosik 	/* else */
2459ad50c29SLukasz Bartosik 	return RTE_MAX_ETHPORTS;
2469ad50c29SLukasz Bartosik }
2479ad50c29SLukasz Bartosik 
2489ad50c29SLukasz Bartosik /* TODO: To be tested */
2499ad50c29SLukasz Bartosik static inline uint16_t
route6_pkt(struct rte_mbuf * pkt,struct rt_ctx * rt_ctx)2509ad50c29SLukasz Bartosik route6_pkt(struct rte_mbuf *pkt, struct rt_ctx *rt_ctx)
2519ad50c29SLukasz Bartosik {
2529ad50c29SLukasz Bartosik 	uint8_t dst_ip[16];
2539ad50c29SLukasz Bartosik 	uint8_t *ip6_dst;
2549ad50c29SLukasz Bartosik 	uint16_t offset;
2559ad50c29SLukasz Bartosik 	uint32_t hop;
2569ad50c29SLukasz Bartosik 	int ret;
2579ad50c29SLukasz Bartosik 
2589ad50c29SLukasz Bartosik 	offset = RTE_ETHER_HDR_LEN + offsetof(struct ip6_hdr, ip6_dst);
2599ad50c29SLukasz Bartosik 	ip6_dst = rte_pktmbuf_mtod_offset(pkt, uint8_t *, offset);
2609ad50c29SLukasz Bartosik 	memcpy(&dst_ip[0], ip6_dst, 16);
2619ad50c29SLukasz Bartosik 
2629ad50c29SLukasz Bartosik 	ret = rte_lpm6_lookup((struct rte_lpm6 *)rt_ctx, dst_ip, &hop);
2639ad50c29SLukasz Bartosik 
2649ad50c29SLukasz Bartosik 	if (ret == 0) {
2659ad50c29SLukasz Bartosik 		/* We have a hit */
2669ad50c29SLukasz Bartosik 		return hop;
2679ad50c29SLukasz Bartosik 	}
2689ad50c29SLukasz Bartosik 
2699ad50c29SLukasz Bartosik 	/* else */
2709ad50c29SLukasz Bartosik 	return RTE_MAX_ETHPORTS;
2719ad50c29SLukasz Bartosik }
2729ad50c29SLukasz Bartosik 
2739ad50c29SLukasz Bartosik static inline uint16_t
get_route(struct rte_mbuf * pkt,struct route_table * rt,enum pkt_type type)2749ad50c29SLukasz Bartosik get_route(struct rte_mbuf *pkt, struct route_table *rt, enum pkt_type type)
2759ad50c29SLukasz Bartosik {
2769ad50c29SLukasz Bartosik 	if (type == PKT_TYPE_PLAIN_IPV4 || type == PKT_TYPE_IPSEC_IPV4)
2779ad50c29SLukasz Bartosik 		return route4_pkt(pkt, rt->rt4_ctx);
2789ad50c29SLukasz Bartosik 	else if (type == PKT_TYPE_PLAIN_IPV6 || type == PKT_TYPE_IPSEC_IPV6)
2799ad50c29SLukasz Bartosik 		return route6_pkt(pkt, rt->rt6_ctx);
2809ad50c29SLukasz Bartosik 
2819ad50c29SLukasz Bartosik 	return RTE_MAX_ETHPORTS;
2829ad50c29SLukasz Bartosik }
2839ad50c29SLukasz Bartosik 
2849ad50c29SLukasz Bartosik static inline int
process_ipsec_ev_inbound(struct ipsec_ctx * ctx,struct route_table * rt,struct rte_event * ev)2859ad50c29SLukasz Bartosik process_ipsec_ev_inbound(struct ipsec_ctx *ctx, struct route_table *rt,
2869ad50c29SLukasz Bartosik 		struct rte_event *ev)
2879ad50c29SLukasz Bartosik {
2889ad50c29SLukasz Bartosik 	struct ipsec_sa *sa = NULL;
2899ad50c29SLukasz Bartosik 	struct rte_mbuf *pkt;
2909ad50c29SLukasz Bartosik 	uint16_t port_id = 0;
2919ad50c29SLukasz Bartosik 	enum pkt_type type;
2929ad50c29SLukasz Bartosik 	uint32_t sa_idx;
2939ad50c29SLukasz Bartosik 	uint8_t *nlp;
2949ad50c29SLukasz Bartosik 
2959ad50c29SLukasz Bartosik 	/* Get pkt from event */
2969ad50c29SLukasz Bartosik 	pkt = ev->mbuf;
2979ad50c29SLukasz Bartosik 
2989ad50c29SLukasz Bartosik 	/* Check the packet type */
2999ad50c29SLukasz Bartosik 	type = process_ipsec_get_pkt_type(pkt, &nlp);
3009ad50c29SLukasz Bartosik 
3019ad50c29SLukasz Bartosik 	switch (type) {
3029ad50c29SLukasz Bartosik 	case PKT_TYPE_PLAIN_IPV4:
303daa02b5cSOlivier Matz 		if (pkt->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD) {
3049ad50c29SLukasz Bartosik 			if (unlikely(pkt->ol_flags &
305daa02b5cSOlivier Matz 				     RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {
3069ad50c29SLukasz Bartosik 				RTE_LOG(ERR, IPSEC,
3079ad50c29SLukasz Bartosik 					"Inbound security offload failed\n");
3089ad50c29SLukasz Bartosik 				goto drop_pkt_and_exit;
3099ad50c29SLukasz Bartosik 			}
310614af754SThomas Monjalon 			sa = *(struct ipsec_sa **)rte_security_dynfield(pkt);
3119ad50c29SLukasz Bartosik 		}
3129ad50c29SLukasz Bartosik 
3139ad50c29SLukasz Bartosik 		/* Check if we have a match */
3149ad50c29SLukasz Bartosik 		if (check_sp(ctx->sp4_ctx, nlp, &sa_idx) == 0) {
3159ad50c29SLukasz Bartosik 			/* No valid match */
3169ad50c29SLukasz Bartosik 			goto drop_pkt_and_exit;
3179ad50c29SLukasz Bartosik 		}
3189ad50c29SLukasz Bartosik 		break;
3199ad50c29SLukasz Bartosik 
3209ad50c29SLukasz Bartosik 	case PKT_TYPE_PLAIN_IPV6:
321daa02b5cSOlivier Matz 		if (pkt->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD) {
3229ad50c29SLukasz Bartosik 			if (unlikely(pkt->ol_flags &
323daa02b5cSOlivier Matz 				     RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {
3249ad50c29SLukasz Bartosik 				RTE_LOG(ERR, IPSEC,
3259ad50c29SLukasz Bartosik 					"Inbound security offload failed\n");
3269ad50c29SLukasz Bartosik 				goto drop_pkt_and_exit;
3279ad50c29SLukasz Bartosik 			}
328614af754SThomas Monjalon 			sa = *(struct ipsec_sa **)rte_security_dynfield(pkt);
3299ad50c29SLukasz Bartosik 		}
3309ad50c29SLukasz Bartosik 
3319ad50c29SLukasz Bartosik 		/* Check if we have a match */
3329ad50c29SLukasz Bartosik 		if (check_sp(ctx->sp6_ctx, nlp, &sa_idx) == 0) {
3339ad50c29SLukasz Bartosik 			/* No valid match */
3349ad50c29SLukasz Bartosik 			goto drop_pkt_and_exit;
3359ad50c29SLukasz Bartosik 		}
3369ad50c29SLukasz Bartosik 		break;
3379ad50c29SLukasz Bartosik 
3389ad50c29SLukasz Bartosik 	default:
3395315b774SNithin Dabilpuram 		RTE_LOG_DP(DEBUG, IPSEC_ESP, "Unsupported packet type = %d\n",
3405315b774SNithin Dabilpuram 			   type);
3419ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
3429ad50c29SLukasz Bartosik 	}
3439ad50c29SLukasz Bartosik 
3449ad50c29SLukasz Bartosik 	/* Check if the packet has to be bypassed */
3459ad50c29SLukasz Bartosik 	if (sa_idx == BYPASS)
3469ad50c29SLukasz Bartosik 		goto route_and_send_pkt;
3479ad50c29SLukasz Bartosik 
3489ad50c29SLukasz Bartosik 	/* Validate sa_idx */
3499ad50c29SLukasz Bartosik 	if (sa_idx >= ctx->sa_ctx->nb_sa)
3509ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
3519ad50c29SLukasz Bartosik 
3529ad50c29SLukasz Bartosik 	/* Else the packet has to be protected with SA */
3539ad50c29SLukasz Bartosik 
3549ad50c29SLukasz Bartosik 	/* If the packet was IPsec processed, then SA pointer should be set */
3559ad50c29SLukasz Bartosik 	if (sa == NULL)
3569ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
3579ad50c29SLukasz Bartosik 
3589ad50c29SLukasz Bartosik 	/* SPI on the packet should match with the one in SA */
3599ad50c29SLukasz Bartosik 	if (unlikely(sa->spi != ctx->sa_ctx->sa[sa_idx].spi))
3609ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
3619ad50c29SLukasz Bartosik 
3629ad50c29SLukasz Bartosik route_and_send_pkt:
3639ad50c29SLukasz Bartosik 	port_id = get_route(pkt, rt, type);
3649ad50c29SLukasz Bartosik 	if (unlikely(port_id == RTE_MAX_ETHPORTS)) {
3659ad50c29SLukasz Bartosik 		/* no match */
3669ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
3679ad50c29SLukasz Bartosik 	}
3689ad50c29SLukasz Bartosik 	/* else, we have a matching route */
3699ad50c29SLukasz Bartosik 
3709ad50c29SLukasz Bartosik 	/* Update mac addresses */
3719ad50c29SLukasz Bartosik 	update_mac_addrs(pkt, port_id);
3729ad50c29SLukasz Bartosik 
3739ad50c29SLukasz Bartosik 	/* Update the event with the dest port */
3749ad50c29SLukasz Bartosik 	ipsec_event_pre_forward(pkt, port_id);
3759ad50c29SLukasz Bartosik 	return PKT_FORWARDED;
3769ad50c29SLukasz Bartosik 
3779ad50c29SLukasz Bartosik drop_pkt_and_exit:
3789ad50c29SLukasz Bartosik 	RTE_LOG(ERR, IPSEC, "Inbound packet dropped\n");
3799ad50c29SLukasz Bartosik 	rte_pktmbuf_free(pkt);
3809ad50c29SLukasz Bartosik 	ev->mbuf = NULL;
3819ad50c29SLukasz Bartosik 	return PKT_DROPPED;
3829ad50c29SLukasz Bartosik }
3839ad50c29SLukasz Bartosik 
3849ad50c29SLukasz Bartosik static inline int
process_ipsec_ev_outbound(struct ipsec_ctx * ctx,struct route_table * rt,struct rte_event * ev)3859ad50c29SLukasz Bartosik process_ipsec_ev_outbound(struct ipsec_ctx *ctx, struct route_table *rt,
3869ad50c29SLukasz Bartosik 		struct rte_event *ev)
3879ad50c29SLukasz Bartosik {
3889ad50c29SLukasz Bartosik 	struct rte_ipsec_session *sess;
3899ad50c29SLukasz Bartosik 	struct sa_ctx *sa_ctx;
3909ad50c29SLukasz Bartosik 	struct rte_mbuf *pkt;
3919ad50c29SLukasz Bartosik 	uint16_t port_id = 0;
3929ad50c29SLukasz Bartosik 	struct ipsec_sa *sa;
3939ad50c29SLukasz Bartosik 	enum pkt_type type;
3949ad50c29SLukasz Bartosik 	uint32_t sa_idx;
3959ad50c29SLukasz Bartosik 	uint8_t *nlp;
3969ad50c29SLukasz Bartosik 
3979ad50c29SLukasz Bartosik 	/* Get pkt from event */
3989ad50c29SLukasz Bartosik 	pkt = ev->mbuf;
3999ad50c29SLukasz Bartosik 
4009ad50c29SLukasz Bartosik 	/* Check the packet type */
4019ad50c29SLukasz Bartosik 	type = process_ipsec_get_pkt_type(pkt, &nlp);
4029ad50c29SLukasz Bartosik 
4039ad50c29SLukasz Bartosik 	switch (type) {
4049ad50c29SLukasz Bartosik 	case PKT_TYPE_PLAIN_IPV4:
4059ad50c29SLukasz Bartosik 		/* Check if we have a match */
4069ad50c29SLukasz Bartosik 		if (check_sp(ctx->sp4_ctx, nlp, &sa_idx) == 0) {
4079ad50c29SLukasz Bartosik 			/* No valid match */
4089ad50c29SLukasz Bartosik 			goto drop_pkt_and_exit;
4099ad50c29SLukasz Bartosik 		}
4109ad50c29SLukasz Bartosik 		break;
4119ad50c29SLukasz Bartosik 	case PKT_TYPE_PLAIN_IPV6:
4129ad50c29SLukasz Bartosik 		/* Check if we have a match */
4139ad50c29SLukasz Bartosik 		if (check_sp(ctx->sp6_ctx, nlp, &sa_idx) == 0) {
4149ad50c29SLukasz Bartosik 			/* No valid match */
4159ad50c29SLukasz Bartosik 			goto drop_pkt_and_exit;
4169ad50c29SLukasz Bartosik 		}
4179ad50c29SLukasz Bartosik 		break;
4189ad50c29SLukasz Bartosik 	default:
4199ad50c29SLukasz Bartosik 		/*
4209ad50c29SLukasz Bartosik 		 * Only plain IPv4 & IPv6 packets are allowed
4219ad50c29SLukasz Bartosik 		 * on protected port. Drop the rest.
4229ad50c29SLukasz Bartosik 		 */
4239ad50c29SLukasz Bartosik 		RTE_LOG(ERR, IPSEC, "Unsupported packet type = %d\n", type);
4249ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
4259ad50c29SLukasz Bartosik 	}
4269ad50c29SLukasz Bartosik 
4279ad50c29SLukasz Bartosik 	/* Check if the packet has to be bypassed */
4289ad50c29SLukasz Bartosik 	if (sa_idx == BYPASS) {
4299ad50c29SLukasz Bartosik 		port_id = get_route(pkt, rt, type);
4309ad50c29SLukasz Bartosik 		if (unlikely(port_id == RTE_MAX_ETHPORTS)) {
4319ad50c29SLukasz Bartosik 			/* no match */
4329ad50c29SLukasz Bartosik 			goto drop_pkt_and_exit;
4339ad50c29SLukasz Bartosik 		}
4349ad50c29SLukasz Bartosik 		/* else, we have a matching route */
4359ad50c29SLukasz Bartosik 		goto send_pkt;
4369ad50c29SLukasz Bartosik 	}
4379ad50c29SLukasz Bartosik 
4389ad50c29SLukasz Bartosik 	/* Validate sa_idx */
4392e7abb8bSNithin Dabilpuram 	if (unlikely(sa_idx >= ctx->sa_ctx->nb_sa))
4409ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
4419ad50c29SLukasz Bartosik 
4429ad50c29SLukasz Bartosik 	/* Else the packet has to be protected */
4439ad50c29SLukasz Bartosik 
4449ad50c29SLukasz Bartosik 	/* Get SA ctx*/
4459ad50c29SLukasz Bartosik 	sa_ctx = ctx->sa_ctx;
4469ad50c29SLukasz Bartosik 
4479ad50c29SLukasz Bartosik 	/* Get SA */
4489ad50c29SLukasz Bartosik 	sa = &(sa_ctx->sa[sa_idx]);
4499ad50c29SLukasz Bartosik 
4509ad50c29SLukasz Bartosik 	/* Get IPsec session */
4519ad50c29SLukasz Bartosik 	sess = ipsec_get_primary_session(sa);
4529ad50c29SLukasz Bartosik 
4539ad50c29SLukasz Bartosik 	/* Allow only inline protocol for now */
4542e7abb8bSNithin Dabilpuram 	if (unlikely(sess->type != RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)) {
4559ad50c29SLukasz Bartosik 		RTE_LOG(ERR, IPSEC, "SA type not supported\n");
4569ad50c29SLukasz Bartosik 		goto drop_pkt_and_exit;
4579ad50c29SLukasz Bartosik 	}
4589ad50c29SLukasz Bartosik 
459ea28ab88SNithin Dabilpuram 	rte_security_set_pkt_metadata(sess->security.ctx,
460ea28ab88SNithin Dabilpuram 				      sess->security.ses, pkt, NULL);
4619ad50c29SLukasz Bartosik 
4629ad50c29SLukasz Bartosik 	/* Mark the packet for Tx security offload */
463daa02b5cSOlivier Matz 	pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
4649ad50c29SLukasz Bartosik 
4659ad50c29SLukasz Bartosik 	/* Get the port to which this pkt need to be submitted */
4669ad50c29SLukasz Bartosik 	port_id = sa->portid;
4679ad50c29SLukasz Bartosik 
4689ad50c29SLukasz Bartosik send_pkt:
469ea28ab88SNithin Dabilpuram 	/* Provide L2 len for Outbound processing */
470ea28ab88SNithin Dabilpuram 	pkt->l2_len = RTE_ETHER_HDR_LEN;
471ea28ab88SNithin Dabilpuram 
4729ad50c29SLukasz Bartosik 	/* Update mac addresses */
4739ad50c29SLukasz Bartosik 	update_mac_addrs(pkt, port_id);
4749ad50c29SLukasz Bartosik 
4759ad50c29SLukasz Bartosik 	/* Update the event with the dest port */
4769ad50c29SLukasz Bartosik 	ipsec_event_pre_forward(pkt, port_id);
4779ad50c29SLukasz Bartosik 	return PKT_FORWARDED;
4789ad50c29SLukasz Bartosik 
4799ad50c29SLukasz Bartosik drop_pkt_and_exit:
4809ad50c29SLukasz Bartosik 	RTE_LOG(ERR, IPSEC, "Outbound packet dropped\n");
4819ad50c29SLukasz Bartosik 	rte_pktmbuf_free(pkt);
4829ad50c29SLukasz Bartosik 	ev->mbuf = NULL;
4839ad50c29SLukasz Bartosik 	return PKT_DROPPED;
4849ad50c29SLukasz Bartosik }
4859ad50c29SLukasz Bartosik 
48686738ebeSSrujana Challa static inline int
ipsec_ev_route_pkts(struct rte_event_vector * vec,struct route_table * rt,struct ipsec_traffic * t,struct sa_ctx * sa_ctx)48786738ebeSSrujana Challa ipsec_ev_route_pkts(struct rte_event_vector *vec, struct route_table *rt,
48886738ebeSSrujana Challa 		    struct ipsec_traffic *t, struct sa_ctx *sa_ctx)
48986738ebeSSrujana Challa {
49086738ebeSSrujana Challa 	struct rte_ipsec_session *sess;
49186738ebeSSrujana Challa 	uint32_t sa_idx, i, j = 0;
49286738ebeSSrujana Challa 	uint16_t port_id = 0;
49386738ebeSSrujana Challa 	struct rte_mbuf *pkt;
49486738ebeSSrujana Challa 	struct ipsec_sa *sa;
49586738ebeSSrujana Challa 
49686738ebeSSrujana Challa 	/* Route IPv4 packets */
49786738ebeSSrujana Challa 	for (i = 0; i < t->ip4.num; i++) {
49886738ebeSSrujana Challa 		pkt = t->ip4.pkts[i];
49986738ebeSSrujana Challa 		port_id = route4_pkt(pkt, rt->rt4_ctx);
50086738ebeSSrujana Challa 		if (port_id != RTE_MAX_ETHPORTS) {
50186738ebeSSrujana Challa 			/* Update mac addresses */
50286738ebeSSrujana Challa 			update_mac_addrs(pkt, port_id);
50386738ebeSSrujana Challa 			/* Update the event with the dest port */
50486738ebeSSrujana Challa 			ipsec_event_pre_forward(pkt, port_id);
50586738ebeSSrujana Challa 			ev_vector_attr_update(vec, pkt);
50686738ebeSSrujana Challa 			vec->mbufs[j++] = pkt;
50786738ebeSSrujana Challa 		} else
50886738ebeSSrujana Challa 			free_pkts(&pkt, 1);
50986738ebeSSrujana Challa 	}
51086738ebeSSrujana Challa 
51186738ebeSSrujana Challa 	/* Route IPv6 packets */
51286738ebeSSrujana Challa 	for (i = 0; i < t->ip6.num; i++) {
51386738ebeSSrujana Challa 		pkt = t->ip6.pkts[i];
51486738ebeSSrujana Challa 		port_id = route6_pkt(pkt, rt->rt6_ctx);
51586738ebeSSrujana Challa 		if (port_id != RTE_MAX_ETHPORTS) {
51686738ebeSSrujana Challa 			/* Update mac addresses */
51786738ebeSSrujana Challa 			update_mac_addrs(pkt, port_id);
51886738ebeSSrujana Challa 			/* Update the event with the dest port */
51986738ebeSSrujana Challa 			ipsec_event_pre_forward(pkt, port_id);
52086738ebeSSrujana Challa 			ev_vector_attr_update(vec, pkt);
52186738ebeSSrujana Challa 			vec->mbufs[j++] = pkt;
52286738ebeSSrujana Challa 		} else
52386738ebeSSrujana Challa 			free_pkts(&pkt, 1);
52486738ebeSSrujana Challa 	}
52586738ebeSSrujana Challa 
52686738ebeSSrujana Challa 	/* Route ESP packets */
52786738ebeSSrujana Challa 	for (i = 0; i < t->ipsec.num; i++) {
52886738ebeSSrujana Challa 		/* Validate sa_idx */
52986738ebeSSrujana Challa 		sa_idx = t->ipsec.res[i];
53086738ebeSSrujana Challa 		pkt = t->ipsec.pkts[i];
53186738ebeSSrujana Challa 		if (unlikely(sa_idx >= sa_ctx->nb_sa))
53286738ebeSSrujana Challa 			free_pkts(&pkt, 1);
53386738ebeSSrujana Challa 		else {
53486738ebeSSrujana Challa 			/* Else the packet has to be protected */
53586738ebeSSrujana Challa 			sa = &(sa_ctx->sa[sa_idx]);
53686738ebeSSrujana Challa 			/* Get IPsec session */
53786738ebeSSrujana Challa 			sess = ipsec_get_primary_session(sa);
53886738ebeSSrujana Challa 			/* Allow only inline protocol for now */
53986738ebeSSrujana Challa 			if (unlikely(sess->type !=
54086738ebeSSrujana Challa 				RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL)) {
54186738ebeSSrujana Challa 				RTE_LOG(ERR, IPSEC, "SA type not supported\n");
54286738ebeSSrujana Challa 				free_pkts(&pkt, 1);
5435fb245baSNithin Dabilpuram 				continue;
54486738ebeSSrujana Challa 			}
54586738ebeSSrujana Challa 			rte_security_set_pkt_metadata(sess->security.ctx,
54686738ebeSSrujana Challa 						sess->security.ses, pkt, NULL);
54786738ebeSSrujana Challa 
54886738ebeSSrujana Challa 			pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
54986738ebeSSrujana Challa 			port_id = sa->portid;
55086738ebeSSrujana Challa 			update_mac_addrs(pkt, port_id);
55186738ebeSSrujana Challa 			ipsec_event_pre_forward(pkt, port_id);
55286738ebeSSrujana Challa 			ev_vector_attr_update(vec, pkt);
55386738ebeSSrujana Challa 			vec->mbufs[j++] = pkt;
55486738ebeSSrujana Challa 		}
55586738ebeSSrujana Challa 	}
55686738ebeSSrujana Challa 
55786738ebeSSrujana Challa 	return j;
55886738ebeSSrujana Challa }
55986738ebeSSrujana Challa 
56086738ebeSSrujana Challa static inline void
classify_pkt(struct rte_mbuf * pkt,struct ipsec_traffic * t)56186738ebeSSrujana Challa classify_pkt(struct rte_mbuf *pkt, struct ipsec_traffic *t)
56286738ebeSSrujana Challa {
56386738ebeSSrujana Challa 	enum pkt_type type;
56486738ebeSSrujana Challa 	uint8_t *nlp;
56586738ebeSSrujana Challa 
56686738ebeSSrujana Challa 	/* Check the packet type */
56786738ebeSSrujana Challa 	type = process_ipsec_get_pkt_type(pkt, &nlp);
56886738ebeSSrujana Challa 
56986738ebeSSrujana Challa 	switch (type) {
57086738ebeSSrujana Challa 	case PKT_TYPE_PLAIN_IPV4:
57186738ebeSSrujana Challa 		t->ip4.data[t->ip4.num] = nlp;
57286738ebeSSrujana Challa 		t->ip4.pkts[(t->ip4.num)++] = pkt;
57386738ebeSSrujana Challa 		break;
57486738ebeSSrujana Challa 	case PKT_TYPE_PLAIN_IPV6:
57586738ebeSSrujana Challa 		t->ip6.data[t->ip6.num] = nlp;
57686738ebeSSrujana Challa 		t->ip6.pkts[(t->ip6.num)++] = pkt;
57786738ebeSSrujana Challa 		break;
57886738ebeSSrujana Challa 	default:
5795315b774SNithin Dabilpuram 		RTE_LOG_DP(DEBUG, IPSEC_ESP, "Unsupported packet type = %d\n",
5805315b774SNithin Dabilpuram 			   type);
58186738ebeSSrujana Challa 		free_pkts(&pkt, 1);
58286738ebeSSrujana Challa 		break;
58386738ebeSSrujana Challa 	}
58486738ebeSSrujana Challa }
58586738ebeSSrujana Challa 
58686738ebeSSrujana Challa static inline int
process_ipsec_ev_inbound_vector(struct ipsec_ctx * ctx,struct route_table * rt,struct rte_event_vector * vec)58786738ebeSSrujana Challa process_ipsec_ev_inbound_vector(struct ipsec_ctx *ctx, struct route_table *rt,
58886738ebeSSrujana Challa 				struct rte_event_vector *vec)
58986738ebeSSrujana Challa {
59086738ebeSSrujana Challa 	struct ipsec_traffic t;
59186738ebeSSrujana Challa 	struct rte_mbuf *pkt;
59286738ebeSSrujana Challa 	int i;
59386738ebeSSrujana Challa 
59486738ebeSSrujana Challa 	t.ip4.num = 0;
59586738ebeSSrujana Challa 	t.ip6.num = 0;
59686738ebeSSrujana Challa 	t.ipsec.num = 0;
59786738ebeSSrujana Challa 
59886738ebeSSrujana Challa 	for (i = 0; i < vec->nb_elem; i++) {
59986738ebeSSrujana Challa 		/* Get pkt from event */
60086738ebeSSrujana Challa 		pkt = vec->mbufs[i];
60186738ebeSSrujana Challa 
60286738ebeSSrujana Challa 		if (pkt->ol_flags & RTE_MBUF_F_RX_SEC_OFFLOAD) {
60386738ebeSSrujana Challa 			if (unlikely(pkt->ol_flags &
60486738ebeSSrujana Challa 				     RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {
60586738ebeSSrujana Challa 				RTE_LOG(ERR, IPSEC,
60686738ebeSSrujana Challa 					"Inbound security offload failed\n");
60786738ebeSSrujana Challa 				free_pkts(&pkt, 1);
60886738ebeSSrujana Challa 				continue;
60986738ebeSSrujana Challa 			}
61086738ebeSSrujana Challa 		}
61186738ebeSSrujana Challa 
61286738ebeSSrujana Challa 		classify_pkt(pkt, &t);
61386738ebeSSrujana Challa 	}
61486738ebeSSrujana Challa 
61586738ebeSSrujana Challa 	check_sp_sa_bulk(ctx->sp4_ctx, ctx->sa_ctx, &t.ip4);
61686738ebeSSrujana Challa 	check_sp_sa_bulk(ctx->sp6_ctx, ctx->sa_ctx, &t.ip6);
61786738ebeSSrujana Challa 
61886738ebeSSrujana Challa 	return ipsec_ev_route_pkts(vec, rt, &t, ctx->sa_ctx);
61986738ebeSSrujana Challa }
62086738ebeSSrujana Challa 
62186738ebeSSrujana Challa static inline int
process_ipsec_ev_outbound_vector(struct ipsec_ctx * ctx,struct route_table * rt,struct rte_event_vector * vec)62286738ebeSSrujana Challa process_ipsec_ev_outbound_vector(struct ipsec_ctx *ctx, struct route_table *rt,
62386738ebeSSrujana Challa 				 struct rte_event_vector *vec)
62486738ebeSSrujana Challa {
62586738ebeSSrujana Challa 	struct ipsec_traffic t;
62686738ebeSSrujana Challa 	struct rte_mbuf *pkt;
62786738ebeSSrujana Challa 	uint32_t i;
62886738ebeSSrujana Challa 
62986738ebeSSrujana Challa 	t.ip4.num = 0;
63086738ebeSSrujana Challa 	t.ip6.num = 0;
63186738ebeSSrujana Challa 	t.ipsec.num = 0;
63286738ebeSSrujana Challa 
63386738ebeSSrujana Challa 	for (i = 0; i < vec->nb_elem; i++) {
63486738ebeSSrujana Challa 		/* Get pkt from event */
63586738ebeSSrujana Challa 		pkt = vec->mbufs[i];
63686738ebeSSrujana Challa 
63786738ebeSSrujana Challa 		classify_pkt(pkt, &t);
63886738ebeSSrujana Challa 
63986738ebeSSrujana Challa 		/* Provide L2 len for Outbound processing */
64086738ebeSSrujana Challa 		pkt->l2_len = RTE_ETHER_HDR_LEN;
64186738ebeSSrujana Challa 	}
64286738ebeSSrujana Challa 
64386738ebeSSrujana Challa 	check_sp_bulk(ctx->sp4_ctx, &t.ip4, &t.ipsec);
64486738ebeSSrujana Challa 	check_sp_bulk(ctx->sp6_ctx, &t.ip6, &t.ipsec);
64586738ebeSSrujana Challa 
64686738ebeSSrujana Challa 	return ipsec_ev_route_pkts(vec, rt, &t, ctx->sa_ctx);
64786738ebeSSrujana Challa }
64886738ebeSSrujana Challa 
64986738ebeSSrujana Challa static inline int
process_ipsec_ev_drv_mode_outbound_vector(struct rte_event_vector * vec,struct port_drv_mode_data * data)65086738ebeSSrujana Challa process_ipsec_ev_drv_mode_outbound_vector(struct rte_event_vector *vec,
65186738ebeSSrujana Challa 					  struct port_drv_mode_data *data)
65286738ebeSSrujana Challa {
65386738ebeSSrujana Challa 	struct rte_mbuf *pkt;
65486738ebeSSrujana Challa 	int16_t port_id;
65586738ebeSSrujana Challa 	uint32_t i;
65686738ebeSSrujana Challa 	int j = 0;
65786738ebeSSrujana Challa 
65886738ebeSSrujana Challa 	for (i = 0; i < vec->nb_elem; i++) {
65986738ebeSSrujana Challa 		pkt = vec->mbufs[i];
66086738ebeSSrujana Challa 		port_id = pkt->port;
66186738ebeSSrujana Challa 
66286738ebeSSrujana Challa 		if (unlikely(!data[port_id].sess)) {
66386738ebeSSrujana Challa 			free_pkts(&pkt, 1);
66486738ebeSSrujana Challa 			continue;
66586738ebeSSrujana Challa 		}
66686738ebeSSrujana Challa 		ipsec_event_pre_forward(pkt, port_id);
66786738ebeSSrujana Challa 		/* Save security session */
66886738ebeSSrujana Challa 		rte_security_set_pkt_metadata(data[port_id].ctx,
66986738ebeSSrujana Challa 					      data[port_id].sess, pkt,
67086738ebeSSrujana Challa 					      NULL);
67186738ebeSSrujana Challa 
67286738ebeSSrujana Challa 		/* Mark the packet for Tx security offload */
67386738ebeSSrujana Challa 		pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
67486738ebeSSrujana Challa 
67586738ebeSSrujana Challa 		/* Provide L2 len for Outbound processing */
67686738ebeSSrujana Challa 		pkt->l2_len = RTE_ETHER_HDR_LEN;
67786738ebeSSrujana Challa 
67886738ebeSSrujana Challa 		vec->mbufs[j++] = pkt;
67986738ebeSSrujana Challa 	}
68086738ebeSSrujana Challa 
68186738ebeSSrujana Challa 	return j;
68286738ebeSSrujana Challa }
68386738ebeSSrujana Challa 
68486738ebeSSrujana Challa static inline void
ipsec_ev_vector_process(struct lcore_conf_ev_tx_int_port_wrkr * lconf,struct eh_event_link_info * links,struct rte_event * ev)68586738ebeSSrujana Challa ipsec_ev_vector_process(struct lcore_conf_ev_tx_int_port_wrkr *lconf,
68686738ebeSSrujana Challa 			struct eh_event_link_info *links,
68786738ebeSSrujana Challa 			struct rte_event *ev)
68886738ebeSSrujana Challa {
68986738ebeSSrujana Challa 	struct rte_event_vector *vec = ev->vec;
69086738ebeSSrujana Challa 	struct rte_mbuf *pkt;
69186738ebeSSrujana Challa 	int ret;
69286738ebeSSrujana Challa 
69386738ebeSSrujana Challa 	pkt = vec->mbufs[0];
69486738ebeSSrujana Challa 
69586738ebeSSrujana Challa 	ev_vector_attr_init(vec);
69686738ebeSSrujana Challa 	if (is_unprotected_port(pkt->port))
69786738ebeSSrujana Challa 		ret = process_ipsec_ev_inbound_vector(&lconf->inbound,
69886738ebeSSrujana Challa 						      &lconf->rt, vec);
69986738ebeSSrujana Challa 	else
70086738ebeSSrujana Challa 		ret = process_ipsec_ev_outbound_vector(&lconf->outbound,
70186738ebeSSrujana Challa 						       &lconf->rt, vec);
70286738ebeSSrujana Challa 
7035fb245baSNithin Dabilpuram 	if (likely(ret > 0)) {
70486738ebeSSrujana Challa 		vec->nb_elem = ret;
70586738ebeSSrujana Challa 		rte_event_eth_tx_adapter_enqueue(links[0].eventdev_id,
70686738ebeSSrujana Challa 						 links[0].event_port_id,
70786738ebeSSrujana Challa 						 ev, 1, 0);
7085fb245baSNithin Dabilpuram 	} else {
7095fb245baSNithin Dabilpuram 		rte_mempool_put(rte_mempool_from_obj(vec), vec);
71086738ebeSSrujana Challa 	}
71186738ebeSSrujana Challa }
71286738ebeSSrujana Challa 
71386738ebeSSrujana Challa static inline void
ipsec_ev_vector_drv_mode_process(struct eh_event_link_info * links,struct rte_event * ev,struct port_drv_mode_data * data)71486738ebeSSrujana Challa ipsec_ev_vector_drv_mode_process(struct eh_event_link_info *links,
71586738ebeSSrujana Challa 				 struct rte_event *ev,
71686738ebeSSrujana Challa 				 struct port_drv_mode_data *data)
71786738ebeSSrujana Challa {
71886738ebeSSrujana Challa 	struct rte_event_vector *vec = ev->vec;
71986738ebeSSrujana Challa 	struct rte_mbuf *pkt;
72086738ebeSSrujana Challa 
72186738ebeSSrujana Challa 	pkt = vec->mbufs[0];
72286738ebeSSrujana Challa 
72386738ebeSSrujana Challa 	if (!is_unprotected_port(pkt->port))
72486738ebeSSrujana Challa 		vec->nb_elem = process_ipsec_ev_drv_mode_outbound_vector(vec,
72586738ebeSSrujana Challa 									 data);
72686738ebeSSrujana Challa 	if (vec->nb_elem > 0)
72786738ebeSSrujana Challa 		rte_event_eth_tx_adapter_enqueue(links[0].eventdev_id,
72886738ebeSSrujana Challa 						 links[0].event_port_id,
72986738ebeSSrujana Challa 						 ev, 1, 0);
7305fb245baSNithin Dabilpuram 	else
7315fb245baSNithin Dabilpuram 		rte_mempool_put(rte_mempool_from_obj(vec), vec);
73286738ebeSSrujana Challa }
73386738ebeSSrujana Challa 
7344965dda0SLukasz Bartosik /*
7354965dda0SLukasz Bartosik  * Event mode exposes various operating modes depending on the
7364965dda0SLukasz Bartosik  * capabilities of the event device and the operating mode
7374965dda0SLukasz Bartosik  * selected.
7384965dda0SLukasz Bartosik  */
7394965dda0SLukasz Bartosik 
740*aae4f5e0SPavan Nikhilesh static void
ipsec_event_port_flush(uint8_t eventdev_id __rte_unused,struct rte_event ev,void * args __rte_unused)741*aae4f5e0SPavan Nikhilesh ipsec_event_port_flush(uint8_t eventdev_id __rte_unused, struct rte_event ev,
742*aae4f5e0SPavan Nikhilesh 		       void *args __rte_unused)
743*aae4f5e0SPavan Nikhilesh {
744*aae4f5e0SPavan Nikhilesh 	rte_pktmbuf_free(ev.mbuf);
745*aae4f5e0SPavan Nikhilesh }
746*aae4f5e0SPavan Nikhilesh 
7474965dda0SLukasz Bartosik /* Workers registered */
7489ad50c29SLukasz Bartosik #define IPSEC_EVENTMODE_WORKERS		2
7494965dda0SLukasz Bartosik 
7504965dda0SLukasz Bartosik /*
7514965dda0SLukasz Bartosik  * Event mode worker
7524965dda0SLukasz Bartosik  * Operating parameters : non-burst - Tx internal port - driver mode
7534965dda0SLukasz Bartosik  */
7544965dda0SLukasz Bartosik static void
ipsec_wrkr_non_burst_int_port_drv_mode(struct eh_event_link_info * links,uint8_t nb_links)7554965dda0SLukasz Bartosik ipsec_wrkr_non_burst_int_port_drv_mode(struct eh_event_link_info *links,
7564965dda0SLukasz Bartosik 		uint8_t nb_links)
7574965dda0SLukasz Bartosik {
758ea28ab88SNithin Dabilpuram 	struct port_drv_mode_data data[RTE_MAX_ETHPORTS];
75922bfcba4SPavan Nikhilesh 	unsigned int nb_rx = 0, nb_tx;
7604965dda0SLukasz Bartosik 	struct rte_mbuf *pkt;
7614965dda0SLukasz Bartosik 	struct rte_event ev;
7624965dda0SLukasz Bartosik 	uint32_t lcore_id;
7634965dda0SLukasz Bartosik 	int32_t socket_id;
7644965dda0SLukasz Bartosik 	int16_t port_id;
7654965dda0SLukasz Bartosik 
7664965dda0SLukasz Bartosik 	/* Check if we have links registered for this lcore */
7674965dda0SLukasz Bartosik 	if (nb_links == 0) {
7684965dda0SLukasz Bartosik 		/* No links registered - exit */
7694965dda0SLukasz Bartosik 		return;
7704965dda0SLukasz Bartosik 	}
7714965dda0SLukasz Bartosik 
772ea28ab88SNithin Dabilpuram 	memset(&data, 0, sizeof(struct port_drv_mode_data));
773ea28ab88SNithin Dabilpuram 
7744965dda0SLukasz Bartosik 	/* Get core ID */
7754965dda0SLukasz Bartosik 	lcore_id = rte_lcore_id();
7764965dda0SLukasz Bartosik 
7774965dda0SLukasz Bartosik 	/* Get socket ID */
7784965dda0SLukasz Bartosik 	socket_id = rte_lcore_to_socket_id(lcore_id);
7794965dda0SLukasz Bartosik 
7804965dda0SLukasz Bartosik 	/*
7814965dda0SLukasz Bartosik 	 * Prepare security sessions table. In outbound driver mode
7824965dda0SLukasz Bartosik 	 * we always use first session configured for a given port
7834965dda0SLukasz Bartosik 	 */
784ea28ab88SNithin Dabilpuram 	prepare_out_sessions_tbl(socket_ctx[socket_id].sa_out, data,
7854965dda0SLukasz Bartosik 				 RTE_MAX_ETHPORTS);
7864965dda0SLukasz Bartosik 
7874965dda0SLukasz Bartosik 	RTE_LOG(INFO, IPSEC,
7884965dda0SLukasz Bartosik 		"Launching event mode worker (non-burst - Tx internal port - "
7894965dda0SLukasz Bartosik 		"driver mode) on lcore %d\n", lcore_id);
7904965dda0SLukasz Bartosik 
7914965dda0SLukasz Bartosik 	/* We have valid links */
7924965dda0SLukasz Bartosik 
7934965dda0SLukasz Bartosik 	/* Check if it's single link */
7944965dda0SLukasz Bartosik 	if (nb_links != 1) {
7954965dda0SLukasz Bartosik 		RTE_LOG(INFO, IPSEC,
7964965dda0SLukasz Bartosik 			"Multiple links not supported. Using first link\n");
7974965dda0SLukasz Bartosik 	}
7984965dda0SLukasz Bartosik 
7994965dda0SLukasz Bartosik 	RTE_LOG(INFO, IPSEC, " -- lcoreid=%u event_port_id=%u\n", lcore_id,
8004965dda0SLukasz Bartosik 			links[0].event_port_id);
8014965dda0SLukasz Bartosik 	while (!force_quit) {
8024965dda0SLukasz Bartosik 		/* Read packet from event queues */
8034965dda0SLukasz Bartosik 		nb_rx = rte_event_dequeue_burst(links[0].eventdev_id,
8044965dda0SLukasz Bartosik 				links[0].event_port_id,
8054965dda0SLukasz Bartosik 				&ev,	/* events */
8064965dda0SLukasz Bartosik 				1,	/* nb_events */
8074965dda0SLukasz Bartosik 				0	/* timeout_ticks */);
8084965dda0SLukasz Bartosik 
8094965dda0SLukasz Bartosik 		if (nb_rx == 0)
8104965dda0SLukasz Bartosik 			continue;
8114965dda0SLukasz Bartosik 
81286738ebeSSrujana Challa 		switch (ev.event_type) {
81386738ebeSSrujana Challa 		case RTE_EVENT_TYPE_ETH_RX_ADAPTER_VECTOR:
81486738ebeSSrujana Challa 		case RTE_EVENT_TYPE_ETHDEV_VECTOR:
81586738ebeSSrujana Challa 			ipsec_ev_vector_drv_mode_process(links, &ev, data);
81686738ebeSSrujana Challa 			continue;
81786738ebeSSrujana Challa 		case RTE_EVENT_TYPE_ETHDEV:
81886738ebeSSrujana Challa 			break;
81986738ebeSSrujana Challa 		default:
82086738ebeSSrujana Challa 			RTE_LOG(ERR, IPSEC, "Invalid event type %u",
82186738ebeSSrujana Challa 				ev.event_type);
82286738ebeSSrujana Challa 			continue;
82386738ebeSSrujana Challa 		}
82486738ebeSSrujana Challa 
8254965dda0SLukasz Bartosik 		pkt = ev.mbuf;
8264965dda0SLukasz Bartosik 		port_id = pkt->port;
8274965dda0SLukasz Bartosik 
8284965dda0SLukasz Bartosik 		rte_prefetch0(rte_pktmbuf_mtod(pkt, void *));
8294965dda0SLukasz Bartosik 
8304965dda0SLukasz Bartosik 		/* Process packet */
8314965dda0SLukasz Bartosik 		ipsec_event_pre_forward(pkt, port_id);
8324965dda0SLukasz Bartosik 
8334965dda0SLukasz Bartosik 		if (!is_unprotected_port(port_id)) {
8344965dda0SLukasz Bartosik 
835ea28ab88SNithin Dabilpuram 			if (unlikely(!data[port_id].sess)) {
8364965dda0SLukasz Bartosik 				rte_pktmbuf_free(pkt);
8374965dda0SLukasz Bartosik 				continue;
8384965dda0SLukasz Bartosik 			}
8394965dda0SLukasz Bartosik 
8404965dda0SLukasz Bartosik 			/* Save security session */
841ea28ab88SNithin Dabilpuram 			rte_security_set_pkt_metadata(data[port_id].ctx,
842ea28ab88SNithin Dabilpuram 						      data[port_id].sess, pkt,
843ea28ab88SNithin Dabilpuram 						      NULL);
8444965dda0SLukasz Bartosik 
8454965dda0SLukasz Bartosik 			/* Mark the packet for Tx security offload */
846daa02b5cSOlivier Matz 			pkt->ol_flags |= RTE_MBUF_F_TX_SEC_OFFLOAD;
847ea28ab88SNithin Dabilpuram 
848ea28ab88SNithin Dabilpuram 			/* Provide L2 len for Outbound processing */
849ea28ab88SNithin Dabilpuram 			pkt->l2_len = RTE_ETHER_HDR_LEN;
8504965dda0SLukasz Bartosik 		}
8514965dda0SLukasz Bartosik 
8524965dda0SLukasz Bartosik 		/*
8534965dda0SLukasz Bartosik 		 * Since tx internal port is available, events can be
8544965dda0SLukasz Bartosik 		 * directly enqueued to the adapter and it would be
8554965dda0SLukasz Bartosik 		 * internally submitted to the eth device.
8564965dda0SLukasz Bartosik 		 */
85722bfcba4SPavan Nikhilesh 		nb_tx = rte_event_eth_tx_adapter_enqueue(links[0].eventdev_id,
8584965dda0SLukasz Bartosik 							 links[0].event_port_id,
8594965dda0SLukasz Bartosik 							 &ev, /* events */
8604965dda0SLukasz Bartosik 							 1,   /* nb_events */
8614965dda0SLukasz Bartosik 							 0 /* flags */);
86222bfcba4SPavan Nikhilesh 		if (!nb_tx)
86322bfcba4SPavan Nikhilesh 			rte_pktmbuf_free(ev.mbuf);
86422bfcba4SPavan Nikhilesh 	}
86522bfcba4SPavan Nikhilesh 
86622bfcba4SPavan Nikhilesh 	if (ev.u64) {
86722bfcba4SPavan Nikhilesh 		ev.op = RTE_EVENT_OP_RELEASE;
86822bfcba4SPavan Nikhilesh 		rte_event_enqueue_burst(links[0].eventdev_id,
86922bfcba4SPavan Nikhilesh 					links[0].event_port_id, &ev, 1);
8704965dda0SLukasz Bartosik 	}
871*aae4f5e0SPavan Nikhilesh 
872*aae4f5e0SPavan Nikhilesh 	rte_event_port_quiesce(links[0].eventdev_id, links[0].event_port_id,
873*aae4f5e0SPavan Nikhilesh 			       ipsec_event_port_flush, NULL);
8744965dda0SLukasz Bartosik }
8754965dda0SLukasz Bartosik 
8769ad50c29SLukasz Bartosik /*
8779ad50c29SLukasz Bartosik  * Event mode worker
8789ad50c29SLukasz Bartosik  * Operating parameters : non-burst - Tx internal port - app mode
8799ad50c29SLukasz Bartosik  */
8809ad50c29SLukasz Bartosik static void
ipsec_wrkr_non_burst_int_port_app_mode(struct eh_event_link_info * links,uint8_t nb_links)8819ad50c29SLukasz Bartosik ipsec_wrkr_non_burst_int_port_app_mode(struct eh_event_link_info *links,
8829ad50c29SLukasz Bartosik 		uint8_t nb_links)
8839ad50c29SLukasz Bartosik {
8849ad50c29SLukasz Bartosik 	struct lcore_conf_ev_tx_int_port_wrkr lconf;
88522bfcba4SPavan Nikhilesh 	unsigned int nb_rx = 0, nb_tx;
8869ad50c29SLukasz Bartosik 	struct rte_event ev;
8879ad50c29SLukasz Bartosik 	uint32_t lcore_id;
8889ad50c29SLukasz Bartosik 	int32_t socket_id;
8899ad50c29SLukasz Bartosik 	int ret;
8909ad50c29SLukasz Bartosik 
8919ad50c29SLukasz Bartosik 	/* Check if we have links registered for this lcore */
8929ad50c29SLukasz Bartosik 	if (nb_links == 0) {
8939ad50c29SLukasz Bartosik 		/* No links registered - exit */
8949ad50c29SLukasz Bartosik 		return;
8959ad50c29SLukasz Bartosik 	}
8969ad50c29SLukasz Bartosik 
8979ad50c29SLukasz Bartosik 	/* We have valid links */
8989ad50c29SLukasz Bartosik 
8999ad50c29SLukasz Bartosik 	/* Get core ID */
9009ad50c29SLukasz Bartosik 	lcore_id = rte_lcore_id();
9019ad50c29SLukasz Bartosik 
9029ad50c29SLukasz Bartosik 	/* Get socket ID */
9039ad50c29SLukasz Bartosik 	socket_id = rte_lcore_to_socket_id(lcore_id);
9049ad50c29SLukasz Bartosik 
9059ad50c29SLukasz Bartosik 	/* Save routing table */
9069ad50c29SLukasz Bartosik 	lconf.rt.rt4_ctx = socket_ctx[socket_id].rt_ip4;
9079ad50c29SLukasz Bartosik 	lconf.rt.rt6_ctx = socket_ctx[socket_id].rt_ip6;
9089ad50c29SLukasz Bartosik 	lconf.inbound.sp4_ctx = socket_ctx[socket_id].sp_ip4_in;
9099ad50c29SLukasz Bartosik 	lconf.inbound.sp6_ctx = socket_ctx[socket_id].sp_ip6_in;
9109ad50c29SLukasz Bartosik 	lconf.inbound.sa_ctx = socket_ctx[socket_id].sa_in;
9119ad50c29SLukasz Bartosik 	lconf.inbound.session_pool = socket_ctx[socket_id].session_pool;
9129ad50c29SLukasz Bartosik 	lconf.inbound.session_priv_pool =
9139ad50c29SLukasz Bartosik 			socket_ctx[socket_id].session_priv_pool;
9149ad50c29SLukasz Bartosik 	lconf.outbound.sp4_ctx = socket_ctx[socket_id].sp_ip4_out;
9159ad50c29SLukasz Bartosik 	lconf.outbound.sp6_ctx = socket_ctx[socket_id].sp_ip6_out;
9169ad50c29SLukasz Bartosik 	lconf.outbound.sa_ctx = socket_ctx[socket_id].sa_out;
9179ad50c29SLukasz Bartosik 	lconf.outbound.session_pool = socket_ctx[socket_id].session_pool;
9189ad50c29SLukasz Bartosik 	lconf.outbound.session_priv_pool =
9199ad50c29SLukasz Bartosik 			socket_ctx[socket_id].session_priv_pool;
9209ad50c29SLukasz Bartosik 
9219ad50c29SLukasz Bartosik 	RTE_LOG(INFO, IPSEC,
9229ad50c29SLukasz Bartosik 		"Launching event mode worker (non-burst - Tx internal port - "
9239ad50c29SLukasz Bartosik 		"app mode) on lcore %d\n", lcore_id);
9249ad50c29SLukasz Bartosik 
9259ad50c29SLukasz Bartosik 	/* Check if it's single link */
9269ad50c29SLukasz Bartosik 	if (nb_links != 1) {
9279ad50c29SLukasz Bartosik 		RTE_LOG(INFO, IPSEC,
9289ad50c29SLukasz Bartosik 			"Multiple links not supported. Using first link\n");
9299ad50c29SLukasz Bartosik 	}
9309ad50c29SLukasz Bartosik 
9319ad50c29SLukasz Bartosik 	RTE_LOG(INFO, IPSEC, " -- lcoreid=%u event_port_id=%u\n", lcore_id,
9329ad50c29SLukasz Bartosik 		links[0].event_port_id);
9339ad50c29SLukasz Bartosik 
9349ad50c29SLukasz Bartosik 	while (!force_quit) {
9359ad50c29SLukasz Bartosik 		/* Read packet from event queues */
9369ad50c29SLukasz Bartosik 		nb_rx = rte_event_dequeue_burst(links[0].eventdev_id,
9379ad50c29SLukasz Bartosik 				links[0].event_port_id,
9389ad50c29SLukasz Bartosik 				&ev,     /* events */
9399ad50c29SLukasz Bartosik 				1,       /* nb_events */
9409ad50c29SLukasz Bartosik 				0        /* timeout_ticks */);
9419ad50c29SLukasz Bartosik 
9429ad50c29SLukasz Bartosik 		if (nb_rx == 0)
9439ad50c29SLukasz Bartosik 			continue;
9449ad50c29SLukasz Bartosik 
94586738ebeSSrujana Challa 		switch (ev.event_type) {
94686738ebeSSrujana Challa 		case RTE_EVENT_TYPE_ETH_RX_ADAPTER_VECTOR:
94786738ebeSSrujana Challa 		case RTE_EVENT_TYPE_ETHDEV_VECTOR:
94886738ebeSSrujana Challa 			ipsec_ev_vector_process(&lconf, links, &ev);
94986738ebeSSrujana Challa 			continue;
95086738ebeSSrujana Challa 		case RTE_EVENT_TYPE_ETHDEV:
95186738ebeSSrujana Challa 			break;
95286738ebeSSrujana Challa 		default:
9539ad50c29SLukasz Bartosik 			RTE_LOG(ERR, IPSEC, "Invalid event type %u",
9549ad50c29SLukasz Bartosik 				ev.event_type);
9559ad50c29SLukasz Bartosik 			continue;
9569ad50c29SLukasz Bartosik 		}
9579ad50c29SLukasz Bartosik 
9589ad50c29SLukasz Bartosik 		if (is_unprotected_port(ev.mbuf->port))
9599ad50c29SLukasz Bartosik 			ret = process_ipsec_ev_inbound(&lconf.inbound,
9609ad50c29SLukasz Bartosik 							&lconf.rt, &ev);
9619ad50c29SLukasz Bartosik 		else
9629ad50c29SLukasz Bartosik 			ret = process_ipsec_ev_outbound(&lconf.outbound,
9639ad50c29SLukasz Bartosik 							&lconf.rt, &ev);
9649ad50c29SLukasz Bartosik 		if (ret != 1)
9659ad50c29SLukasz Bartosik 			/* The pkt has been dropped */
9669ad50c29SLukasz Bartosik 			continue;
9679ad50c29SLukasz Bartosik 
9689ad50c29SLukasz Bartosik 		/*
9699ad50c29SLukasz Bartosik 		 * Since tx internal port is available, events can be
9709ad50c29SLukasz Bartosik 		 * directly enqueued to the adapter and it would be
9719ad50c29SLukasz Bartosik 		 * internally submitted to the eth device.
9729ad50c29SLukasz Bartosik 		 */
97322bfcba4SPavan Nikhilesh 		nb_tx = rte_event_eth_tx_adapter_enqueue(links[0].eventdev_id,
9749ad50c29SLukasz Bartosik 							 links[0].event_port_id,
9759ad50c29SLukasz Bartosik 							 &ev, /* events */
9769ad50c29SLukasz Bartosik 							 1,   /* nb_events */
9779ad50c29SLukasz Bartosik 							 0 /* flags */);
97822bfcba4SPavan Nikhilesh 		if (!nb_tx)
97922bfcba4SPavan Nikhilesh 			rte_pktmbuf_free(ev.mbuf);
98022bfcba4SPavan Nikhilesh 	}
98122bfcba4SPavan Nikhilesh 
98222bfcba4SPavan Nikhilesh 	if (ev.u64) {
98322bfcba4SPavan Nikhilesh 		ev.op = RTE_EVENT_OP_RELEASE;
98422bfcba4SPavan Nikhilesh 		rte_event_enqueue_burst(links[0].eventdev_id,
98522bfcba4SPavan Nikhilesh 					links[0].event_port_id, &ev, 1);
9869ad50c29SLukasz Bartosik 	}
987*aae4f5e0SPavan Nikhilesh 
988*aae4f5e0SPavan Nikhilesh 	rte_event_port_quiesce(links[0].eventdev_id, links[0].event_port_id,
989*aae4f5e0SPavan Nikhilesh 			       ipsec_event_port_flush, NULL);
9909ad50c29SLukasz Bartosik }
9919ad50c29SLukasz Bartosik 
9924965dda0SLukasz Bartosik static uint8_t
ipsec_eventmode_populate_wrkr_params(struct eh_app_worker_params * wrkrs)9934965dda0SLukasz Bartosik ipsec_eventmode_populate_wrkr_params(struct eh_app_worker_params *wrkrs)
9944965dda0SLukasz Bartosik {
9954965dda0SLukasz Bartosik 	struct eh_app_worker_params *wrkr;
9964965dda0SLukasz Bartosik 	uint8_t nb_wrkr_param = 0;
9974965dda0SLukasz Bartosik 
9984965dda0SLukasz Bartosik 	/* Save workers */
9994965dda0SLukasz Bartosik 	wrkr = wrkrs;
10004965dda0SLukasz Bartosik 
10014965dda0SLukasz Bartosik 	/* Non-burst - Tx internal port - driver mode */
10024965dda0SLukasz Bartosik 	wrkr->cap.burst = EH_RX_TYPE_NON_BURST;
10034965dda0SLukasz Bartosik 	wrkr->cap.tx_internal_port = EH_TX_TYPE_INTERNAL_PORT;
10044965dda0SLukasz Bartosik 	wrkr->cap.ipsec_mode = EH_IPSEC_MODE_TYPE_DRIVER;
10054965dda0SLukasz Bartosik 	wrkr->worker_thread = ipsec_wrkr_non_burst_int_port_drv_mode;
10064965dda0SLukasz Bartosik 	wrkr++;
10079ad50c29SLukasz Bartosik 	nb_wrkr_param++;
10089ad50c29SLukasz Bartosik 
10099ad50c29SLukasz Bartosik 	/* Non-burst - Tx internal port - app mode */
10109ad50c29SLukasz Bartosik 	wrkr->cap.burst = EH_RX_TYPE_NON_BURST;
10119ad50c29SLukasz Bartosik 	wrkr->cap.tx_internal_port = EH_TX_TYPE_INTERNAL_PORT;
10129ad50c29SLukasz Bartosik 	wrkr->cap.ipsec_mode = EH_IPSEC_MODE_TYPE_APP;
10139ad50c29SLukasz Bartosik 	wrkr->worker_thread = ipsec_wrkr_non_burst_int_port_app_mode;
10149ad50c29SLukasz Bartosik 	nb_wrkr_param++;
10154965dda0SLukasz Bartosik 
10164965dda0SLukasz Bartosik 	return nb_wrkr_param;
10174965dda0SLukasz Bartosik }
10184965dda0SLukasz Bartosik 
10194965dda0SLukasz Bartosik static void
ipsec_eventmode_worker(struct eh_conf * conf)10204965dda0SLukasz Bartosik ipsec_eventmode_worker(struct eh_conf *conf)
10214965dda0SLukasz Bartosik {
10224965dda0SLukasz Bartosik 	struct eh_app_worker_params ipsec_wrkr[IPSEC_EVENTMODE_WORKERS] = {
10234965dda0SLukasz Bartosik 					{{{0} }, NULL } };
10244965dda0SLukasz Bartosik 	uint8_t nb_wrkr_param;
10254965dda0SLukasz Bartosik 
10264965dda0SLukasz Bartosik 	/* Populate l2fwd_wrkr params */
10274965dda0SLukasz Bartosik 	nb_wrkr_param = ipsec_eventmode_populate_wrkr_params(ipsec_wrkr);
10284965dda0SLukasz Bartosik 
10294965dda0SLukasz Bartosik 	/*
10304965dda0SLukasz Bartosik 	 * Launch correct worker after checking
10314965dda0SLukasz Bartosik 	 * the event device's capabilities.
10324965dda0SLukasz Bartosik 	 */
10334965dda0SLukasz Bartosik 	eh_launch_worker(conf, ipsec_wrkr, nb_wrkr_param);
10344965dda0SLukasz Bartosik }
10354965dda0SLukasz Bartosik 
ipsec_launch_one_lcore(void * args)10364965dda0SLukasz Bartosik int ipsec_launch_one_lcore(void *args)
10374965dda0SLukasz Bartosik {
10384965dda0SLukasz Bartosik 	struct eh_conf *conf;
10394965dda0SLukasz Bartosik 
10404965dda0SLukasz Bartosik 	conf = (struct eh_conf *)args;
10414965dda0SLukasz Bartosik 
10424965dda0SLukasz Bartosik 	if (conf->mode == EH_PKT_TRANSFER_MODE_POLL) {
10434965dda0SLukasz Bartosik 		/* Run in poll mode */
10444965dda0SLukasz Bartosik 		ipsec_poll_mode_worker();
10454965dda0SLukasz Bartosik 	} else if (conf->mode == EH_PKT_TRANSFER_MODE_EVENT) {
10464965dda0SLukasz Bartosik 		/* Run in event mode */
10474965dda0SLukasz Bartosik 		ipsec_eventmode_worker(conf);
10484965dda0SLukasz Bartosik 	}
10494965dda0SLukasz Bartosik 	return 0;
10504965dda0SLukasz Bartosik }
1051