net/virtio: fix incorrect cast of void *
[dpdk.git] / ipsec / misc.h
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 move_bad_mbufs(struct rte_mbuf *mb[], const uint32_t bad_idx[], uint32_t nb_mb,
20         uint32_t nb_bad)
21 {
22         uint32_t i, j, k;
23         struct rte_mbuf *drb[nb_bad];
24
25         j = 0;
26         k = 0;
27
28         /* copy bad ones into a temp place */
29         for (i = 0; i != nb_mb; i++) {
30                 if (j != nb_bad && i == bad_idx[j])
31                         drb[j++] = mb[i];
32                 else
33                         mb[k++] = mb[i];
34         }
35
36         /* copy bad ones after the good ones */
37         for (i = 0; i != nb_bad; i++)
38                 mb[k + i] = drb[i];
39 }
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         plen = mb->pkt_len;
53         n = *ofs;
54
55         if (n == plen) {
56                 ms = rte_pktmbuf_lastseg(mb);
57                 n = n + rte_pktmbuf_data_len(ms) - plen;
58         } else {
59                 ms = mb;
60                 for (k = rte_pktmbuf_data_len(ms); n >= k;
61                                 k = rte_pktmbuf_data_len(ms)) {
62                         ms = ms->next;
63                         n -= k;
64                 }
65         }
66
67         *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 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         slen = ms->data_len;
91         ms->data_len = ofs;
92
93         /* tail spawns through multiple segments */
94         if (slen < ofs + len) {
95                 mn = ms->next;
96                 ms->next = NULL;
97                 for (n = 0; mn != NULL; n++) {
98                         ms = mn->next;
99                         rte_pktmbuf_free_seg(mn);
100                         mn = ms;
101                 }
102                 mb->nb_segs -= n;
103         }
104
105         mb->pkt_len -= len;
106 }
107
108 /*
109  * process packets using sync crypto engine.
110  * expects *num* to be greater than zero.
111  */
112 static inline void
113 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 {
120         uint32_t i, j, n;
121         int32_t vcnt, vofs;
122         int32_t st[num];
123         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         for (i = 0; i != num; i++) {
132
133                 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                 if (vcnt < 0) {
138                         /* fill the request structure */
139                         symvec.sgl = &vecpkt[j];
140                         symvec.iv = &iv[j];
141                         symvec.digest = &dgst[j];
142                         symvec.aad = &aad[j];
143                         symvec.status = &st[j];
144                         symvec.num = i - j;
145
146                         /* flush vec array and try again */
147                         n += rte_cryptodev_sym_cpu_crypto_process(
148                                 ss->crypto.dev_id, ss->crypto.ses, ofs,
149                                 &symvec);
150                         vofs = 0;
151                         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                 vecpkt[i].vec = &vec[vofs];
158                 vecpkt[i].num = vcnt;
159                 vofs += vcnt;
160         }
161
162         /* fill the request structure */
163         symvec.sgl = &vecpkt[j];
164         symvec.iv = &iv[j];
165         symvec.aad = &aad[j];
166         symvec.digest = &dgst[j];
167         symvec.status = &st[j];
168         symvec.num = i - j;
169
170         n += rte_cryptodev_sym_cpu_crypto_process(ss->crypto.dev_id,
171                 ss->crypto.ses, ofs, &symvec);
172
173         j = num - n;
174         for (i = 0; j != 0 && i != num; i++) {
175                 if (st[i] != 0) {
176                         mb[i]->ol_flags |= PKT_RX_SEC_OFFLOAD_FAILED;
177                         j--;
178                 }
179         }
180 }
181
182 #endif /* _MISC_H_ */