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