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