xref: /dpdk/lib/ipsec/misc.h (revision 99a2dd955fba6e4cc23b77d590a033650ced9c45)
1*99a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2*99a2dd95SBruce Richardson  * Copyright(c) 2018-2020 Intel Corporation
3*99a2dd95SBruce Richardson  */
4*99a2dd95SBruce Richardson 
5*99a2dd95SBruce Richardson #ifndef _MISC_H_
6*99a2dd95SBruce Richardson #define _MISC_H_
7*99a2dd95SBruce Richardson 
8*99a2dd95SBruce Richardson /**
9*99a2dd95SBruce Richardson  * @file misc.h
10*99a2dd95SBruce Richardson  * Contains miscellaneous functions/structures/macros used internally
11*99a2dd95SBruce Richardson  * by ipsec library.
12*99a2dd95SBruce Richardson  */
13*99a2dd95SBruce Richardson 
14*99a2dd95SBruce Richardson /*
15*99a2dd95SBruce Richardson  * Move bad (unprocessed) mbufs beyond the good (processed) ones.
16*99a2dd95SBruce Richardson  * bad_idx[] contains the indexes of bad mbufs inside the mb[].
17*99a2dd95SBruce Richardson  */
18*99a2dd95SBruce Richardson static inline void
19*99a2dd95SBruce Richardson move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t bad_idx[], uint32_t nb_mb,
20*99a2dd95SBruce Richardson 	uint32_t nb_bad)
21*99a2dd95SBruce Richardson {
22*99a2dd95SBruce Richardson 	uint32_t i, j, k;
23*99a2dd95SBruce Richardson 	struct rte_mbuf *drb[nb_bad];
24*99a2dd95SBruce Richardson 
25*99a2dd95SBruce Richardson 	j = 0;
26*99a2dd95SBruce Richardson 	k = 0;
27*99a2dd95SBruce Richardson 
28*99a2dd95SBruce Richardson 	/* copy bad ones into a temp place */
29*99a2dd95SBruce Richardson 	for (i = 0; i != nb_mb; i++) {
30*99a2dd95SBruce Richardson 		if (j != nb_bad && i == bad_idx[j])
31*99a2dd95SBruce Richardson 			drb[j++] = mb[i];
32*99a2dd95SBruce Richardson 		else
33*99a2dd95SBruce Richardson 			mb[k++] = mb[i];
34*99a2dd95SBruce Richardson 	}
35*99a2dd95SBruce Richardson 
36*99a2dd95SBruce Richardson 	/* copy bad ones after the good ones */
37*99a2dd95SBruce Richardson 	for (i = 0; i != nb_bad; i++)
38*99a2dd95SBruce Richardson 		mb[k + i] = drb[i];
39*99a2dd95SBruce Richardson }
40*99a2dd95SBruce Richardson 
41*99a2dd95SBruce Richardson /*
42*99a2dd95SBruce Richardson  * Find packet's segment for the specified offset.
43*99a2dd95SBruce Richardson  * ofs - at input should contain required offset, at output would contain
44*99a2dd95SBruce Richardson  * offset value within the segment.
45*99a2dd95SBruce Richardson  */
46*99a2dd95SBruce Richardson static inline struct rte_mbuf *
47*99a2dd95SBruce Richardson mbuf_get_seg_ofs(struct rte_mbuf *mb, uint32_t *ofs)
48*99a2dd95SBruce Richardson {
49*99a2dd95SBruce Richardson 	uint32_t k, n, plen;
50*99a2dd95SBruce Richardson 	struct rte_mbuf *ms;
51*99a2dd95SBruce Richardson 
52*99a2dd95SBruce Richardson 	plen = mb->pkt_len;
53*99a2dd95SBruce Richardson 	n = *ofs;
54*99a2dd95SBruce Richardson 
55*99a2dd95SBruce Richardson 	if (n == plen) {
56*99a2dd95SBruce Richardson 		ms = rte_pktmbuf_lastseg(mb);
57*99a2dd95SBruce Richardson 		n = n + rte_pktmbuf_data_len(ms) - plen;
58*99a2dd95SBruce Richardson 	} else {
59*99a2dd95SBruce Richardson 		ms = mb;
60*99a2dd95SBruce Richardson 		for (k = rte_pktmbuf_data_len(ms); n >= k;
61*99a2dd95SBruce Richardson 				k = rte_pktmbuf_data_len(ms)) {
62*99a2dd95SBruce Richardson 			ms = ms->next;
63*99a2dd95SBruce Richardson 			n -= k;
64*99a2dd95SBruce Richardson 		}
65*99a2dd95SBruce Richardson 	}
66*99a2dd95SBruce Richardson 
67*99a2dd95SBruce Richardson 	*ofs = n;
68*99a2dd95SBruce Richardson 	return ms;
69*99a2dd95SBruce Richardson }
70*99a2dd95SBruce Richardson 
71*99a2dd95SBruce Richardson /*
72*99a2dd95SBruce Richardson  * Trim multi-segment packet at the specified offset, and free
73*99a2dd95SBruce Richardson  * all unused segments.
74*99a2dd95SBruce Richardson  * mb - input packet
75*99a2dd95SBruce Richardson  * ms - segment where to cut
76*99a2dd95SBruce Richardson  * ofs - offset within the *ms*
77*99a2dd95SBruce Richardson  * len - length to cut (from given offset to the end of the packet)
78*99a2dd95SBruce Richardson  * Can be used in conjunction with mbuf_get_seg_ofs():
79*99a2dd95SBruce Richardson  * ofs = new_len;
80*99a2dd95SBruce Richardson  * ms = mbuf_get_seg_ofs(mb, &ofs);
81*99a2dd95SBruce Richardson  * mbuf_cut_seg_ofs(mb, ms, ofs, mb->pkt_len - new_len);
82*99a2dd95SBruce Richardson  */
83*99a2dd95SBruce Richardson static inline void
84*99a2dd95SBruce Richardson mbuf_cut_seg_ofs(struct rte_mbuf *mb, struct rte_mbuf *ms, uint32_t ofs,
85*99a2dd95SBruce Richardson 	uint32_t len)
86*99a2dd95SBruce Richardson {
87*99a2dd95SBruce Richardson 	uint32_t n, slen;
88*99a2dd95SBruce Richardson 	struct rte_mbuf *mn;
89*99a2dd95SBruce Richardson 
90*99a2dd95SBruce Richardson 	slen = ms->data_len;
91*99a2dd95SBruce Richardson 	ms->data_len = ofs;
92*99a2dd95SBruce Richardson 
93*99a2dd95SBruce Richardson 	/* tail spawns through multiple segments */
94*99a2dd95SBruce Richardson 	if (slen < ofs + len) {
95*99a2dd95SBruce Richardson 		mn = ms->next;
96*99a2dd95SBruce Richardson 		ms->next = NULL;
97*99a2dd95SBruce Richardson 		for (n = 0; mn != NULL; n++) {
98*99a2dd95SBruce Richardson 			ms = mn->next;
99*99a2dd95SBruce Richardson 			rte_pktmbuf_free_seg(mn);
100*99a2dd95SBruce Richardson 			mn = ms;
101*99a2dd95SBruce Richardson 		}
102*99a2dd95SBruce Richardson 		mb->nb_segs -= n;
103*99a2dd95SBruce Richardson 	}
104*99a2dd95SBruce Richardson 
105*99a2dd95SBruce Richardson 	mb->pkt_len -= len;
106*99a2dd95SBruce Richardson }
107*99a2dd95SBruce Richardson 
108*99a2dd95SBruce Richardson /*
109*99a2dd95SBruce Richardson  * process packets using sync crypto engine.
110*99a2dd95SBruce Richardson  * expects *num* to be greater than zero.
111*99a2dd95SBruce Richardson  */
112*99a2dd95SBruce Richardson static inline void
113*99a2dd95SBruce Richardson cpu_crypto_bulk(const struct rte_ipsec_session *ss,
114*99a2dd95SBruce Richardson 	union rte_crypto_sym_ofs ofs, struct rte_mbuf *mb[],
115*99a2dd95SBruce Richardson 	struct rte_crypto_va_iova_ptr iv[],
116*99a2dd95SBruce Richardson 	struct rte_crypto_va_iova_ptr aad[],
117*99a2dd95SBruce Richardson 	struct rte_crypto_va_iova_ptr dgst[], uint32_t l4ofs[],
118*99a2dd95SBruce Richardson 	uint32_t clen[], uint32_t num)
119*99a2dd95SBruce Richardson {
120*99a2dd95SBruce Richardson 	uint32_t i, j, n;
121*99a2dd95SBruce Richardson 	int32_t vcnt, vofs;
122*99a2dd95SBruce Richardson 	int32_t st[num];
123*99a2dd95SBruce Richardson 	struct rte_crypto_sgl vecpkt[num];
124*99a2dd95SBruce Richardson 	struct rte_crypto_vec vec[UINT8_MAX];
125*99a2dd95SBruce Richardson 	struct rte_crypto_sym_vec symvec;
126*99a2dd95SBruce Richardson 
127*99a2dd95SBruce Richardson 	const uint32_t vnum = RTE_DIM(vec);
128*99a2dd95SBruce Richardson 
129*99a2dd95SBruce Richardson 	j = 0, n = 0;
130*99a2dd95SBruce Richardson 	vofs = 0;
131*99a2dd95SBruce Richardson 	for (i = 0; i != num; i++) {
132*99a2dd95SBruce Richardson 
133*99a2dd95SBruce Richardson 		vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i],
134*99a2dd95SBruce Richardson 			&vec[vofs], vnum - vofs);
135*99a2dd95SBruce Richardson 
136*99a2dd95SBruce Richardson 		/* not enough space in vec[] to hold all segments */
137*99a2dd95SBruce Richardson 		if (vcnt < 0) {
138*99a2dd95SBruce Richardson 			/* fill the request structure */
139*99a2dd95SBruce Richardson 			symvec.sgl = &vecpkt[j];
140*99a2dd95SBruce Richardson 			symvec.iv = &iv[j];
141*99a2dd95SBruce Richardson 			symvec.digest = &dgst[j];
142*99a2dd95SBruce Richardson 			symvec.aad = &aad[j];
143*99a2dd95SBruce Richardson 			symvec.status = &st[j];
144*99a2dd95SBruce Richardson 			symvec.num = i - j;
145*99a2dd95SBruce Richardson 
146*99a2dd95SBruce Richardson 			/* flush vec array and try again */
147*99a2dd95SBruce Richardson 			n += rte_cryptodev_sym_cpu_crypto_process(
148*99a2dd95SBruce Richardson 				ss->crypto.dev_id, ss->crypto.ses, ofs,
149*99a2dd95SBruce Richardson 				&symvec);
150*99a2dd95SBruce Richardson 			vofs = 0;
151*99a2dd95SBruce Richardson 			vcnt = rte_crypto_mbuf_to_vec(mb[i], l4ofs[i], clen[i],
152*99a2dd95SBruce Richardson 				vec, vnum);
153*99a2dd95SBruce Richardson 			RTE_ASSERT(vcnt > 0);
154*99a2dd95SBruce Richardson 			j = i;
155*99a2dd95SBruce Richardson 		}
156*99a2dd95SBruce Richardson 
157*99a2dd95SBruce Richardson 		vecpkt[i].vec = &vec[vofs];
158*99a2dd95SBruce Richardson 		vecpkt[i].num = vcnt;
159*99a2dd95SBruce Richardson 		vofs += vcnt;
160*99a2dd95SBruce Richardson 	}
161*99a2dd95SBruce Richardson 
162*99a2dd95SBruce Richardson 	/* fill the request structure */
163*99a2dd95SBruce Richardson 	symvec.sgl = &vecpkt[j];
164*99a2dd95SBruce Richardson 	symvec.iv = &iv[j];
165*99a2dd95SBruce Richardson 	symvec.aad = &aad[j];
166*99a2dd95SBruce Richardson 	symvec.digest = &dgst[j];
167*99a2dd95SBruce Richardson 	symvec.status = &st[j];
168*99a2dd95SBruce Richardson 	symvec.num = i - j;
169*99a2dd95SBruce Richardson 
170*99a2dd95SBruce Richardson 	n += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id,
171*99a2dd95SBruce Richardson 		ss->crypto.ses, ofs, &symvec);
172*99a2dd95SBruce Richardson 
173*99a2dd95SBruce Richardson 	j = num - n;
174*99a2dd95SBruce Richardson 	for (i = 0; j != 0 && i != num; i++) {
175*99a2dd95SBruce Richardson 		if (st[i] != 0) {
176*99a2dd95SBruce Richardson 			mb[i]->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED;
177*99a2dd95SBruce Richardson 			j--;
178*99a2dd95SBruce Richardson 		}
179*99a2dd95SBruce Richardson 	}
180*99a2dd95SBruce Richardson }
181*99a2dd95SBruce Richardson 
182*99a2dd95SBruce Richardson #endif /* _MISC_H_ */
183