blob: ceda617f8728f8da75828c2be508e918b4133646 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15/*
16 Copyright (c) 2005 Eliot Dresselhaus
17
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
25
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
28
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36*/
37
38/* Turn data structures into byte streams for saving or transport. */
39
40#include <vppinfra/heap.h>
41#include <vppinfra/pool.h>
42#include <vppinfra/serialize.h>
43
Dave Barachc3799992016-08-15 11:12:27 -040044void
45serialize_64 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070046{
47 u64 x = va_arg (*va, u64);
48 u32 lo, hi;
49 lo = x;
50 hi = x >> 32;
51 serialize_integer (m, lo, sizeof (lo));
52 serialize_integer (m, hi, sizeof (hi));
53}
54
Dave Barachc3799992016-08-15 11:12:27 -040055void
56serialize_32 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070057{
58 u32 x = va_arg (*va, u32);
59 serialize_integer (m, x, sizeof (x));
60}
61
Dave Barachc3799992016-08-15 11:12:27 -040062void
63serialize_16 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070064{
65 u32 x = va_arg (*va, u32);
66 serialize_integer (m, x, sizeof (u16));
67}
68
Dave Barachc3799992016-08-15 11:12:27 -040069void
70serialize_8 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070071{
72 u32 x = va_arg (*va, u32);
73 serialize_integer (m, x, sizeof (u8));
74}
75
Dave Barachc3799992016-08-15 11:12:27 -040076void
77unserialize_64 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070078{
Dave Barachc3799992016-08-15 11:12:27 -040079 u64 *x = va_arg (*va, u64 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070080 u32 lo, hi;
81 unserialize_integer (m, &lo, sizeof (lo));
82 unserialize_integer (m, &hi, sizeof (hi));
83 *x = ((u64) hi << 32) | (u64) lo;
84}
85
Dave Barachc3799992016-08-15 11:12:27 -040086void
87unserialize_32 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070088{
Dave Barachc3799992016-08-15 11:12:27 -040089 u32 *x = va_arg (*va, u32 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070090 unserialize_integer (m, x, sizeof (x[0]));
91}
92
Dave Barachc3799992016-08-15 11:12:27 -040093void
94unserialize_16 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -070095{
Dave Barachc3799992016-08-15 11:12:27 -040096 u16 *x = va_arg (*va, u16 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -070097 u32 t;
98 unserialize_integer (m, &t, sizeof (x[0]));
99 x[0] = t;
100}
101
Dave Barachc3799992016-08-15 11:12:27 -0400102void
103unserialize_8 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104{
Dave Barachc3799992016-08-15 11:12:27 -0400105 u8 *x = va_arg (*va, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700106 u32 t;
107 unserialize_integer (m, &t, sizeof (x[0]));
108 x[0] = t;
109}
110
Dave Barachc3799992016-08-15 11:12:27 -0400111void
112serialize_f64 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700113{
114 f64 x = va_arg (*va, f64);
Dave Barachc3799992016-08-15 11:12:27 -0400115 union
116 {
117 f64 f;
118 u64 i;
119 } y;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700120 y.f = x;
121 serialize (m, serialize_64, y.i);
122}
123
Dave Barachc3799992016-08-15 11:12:27 -0400124void
125serialize_f32 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700126{
127 f32 x = va_arg (*va, f64);
Dave Barachc3799992016-08-15 11:12:27 -0400128 union
129 {
130 f32 f;
131 u32 i;
132 } y;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700133 y.f = x;
134 serialize_integer (m, y.i, sizeof (y.i));
135}
136
Dave Barachc3799992016-08-15 11:12:27 -0400137void
138unserialize_f64 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700139{
Dave Barachc3799992016-08-15 11:12:27 -0400140 f64 *x = va_arg (*va, f64 *);
141 union
142 {
143 f64 f;
144 u64 i;
145 } y;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700146 unserialize (m, unserialize_64, &y.i);
147 *x = y.f;
148}
149
Dave Barachc3799992016-08-15 11:12:27 -0400150void
151unserialize_f32 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700152{
Dave Barachc3799992016-08-15 11:12:27 -0400153 f32 *x = va_arg (*va, f32 *);
154 union
155 {
156 f32 f;
157 u32 i;
158 } y;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700159 unserialize_integer (m, &y.i, sizeof (y.i));
160 *x = y.f;
161}
162
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200163__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400164serialize_cstring (serialize_main_t * m, char *s)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700165{
166 u32 len = s ? strlen (s) : 0;
Dave Barachc3799992016-08-15 11:12:27 -0400167 void *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700168
169 serialize_likely_small_unsigned_integer (m, len);
Dave Barachc3799992016-08-15 11:12:27 -0400170 if (len > 0)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700171 {
172 p = serialize_get (m, len);
Dave Barach178cf492018-11-13 16:34:13 -0500173 clib_memcpy_fast (p, s, len);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700174 }
175}
176
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200177__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400178unserialize_cstring (serialize_main_t * m, char **s)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179{
Dave Barachc3799992016-08-15 11:12:27 -0400180 char *p, *r = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700181 u32 len;
182
183 len = unserialize_likely_small_unsigned_integer (m);
184
185 /*
186 * Given broken enough data, we could get len = 0xFFFFFFFF.
187 * Add one, it overflows, we call vec_new (char, 0), then
188 * memcpy until we bus error.
189 */
190 if (len > 0 && len != 0xFFFFFFFF)
191 {
192 r = vec_new (char, len + 1);
193 p = unserialize_get (m, len);
Dave Barach178cf492018-11-13 16:34:13 -0500194 clib_memcpy_fast (r, p, len);
Dave Barachc3799992016-08-15 11:12:27 -0400195
Ed Warnickecb9cada2015-12-08 15:45:58 -0700196 /* Null terminate. */
197 r[len] = 0;
198 }
199 *s = r;
200}
201
202/* vec_serialize/vec_unserialize helper functions for basic vector types. */
Dave Barachc3799992016-08-15 11:12:27 -0400203void
204serialize_vec_8 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700205{
Dave Barachc3799992016-08-15 11:12:27 -0400206 u8 *s = va_arg (*va, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700207 u32 n = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400208 u8 *p = serialize_get (m, n * sizeof (u8));
Dave Barach178cf492018-11-13 16:34:13 -0500209 clib_memcpy_fast (p, s, n * sizeof (u8));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210}
211
Dave Barachc3799992016-08-15 11:12:27 -0400212void
213unserialize_vec_8 (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700214{
Dave Barachc3799992016-08-15 11:12:27 -0400215 u8 *s = va_arg (*va, u8 *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700216 u32 n = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400217 u8 *p = unserialize_get (m, n);
Dave Barach178cf492018-11-13 16:34:13 -0500218 clib_memcpy_fast (s, p, n);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700219}
220
221#define _(n_bits) \
222 void serialize_vec_##n_bits (serialize_main_t * m, va_list * va) \
223 { \
224 u##n_bits * s = va_arg (*va, u##n_bits *); \
225 u32 n = va_arg (*va, u32); \
226 u##n_bits * p = serialize_get (m, n * sizeof (s[0])); \
227 \
228 while (n >= 4) \
229 { \
230 p[0] = clib_host_to_net_u##n_bits (s[0]); \
231 p[1] = clib_host_to_net_u##n_bits (s[1]); \
232 p[2] = clib_host_to_net_u##n_bits (s[2]); \
233 p[3] = clib_host_to_net_u##n_bits (s[3]); \
234 s += 4; \
235 p += 4; \
236 n -= 4; \
237 } \
238 \
239 while (n >= 1) \
240 { \
241 p[0] = clib_host_to_net_u##n_bits (s[0]); \
242 s += 1; \
243 p += 1; \
244 n -= 1; \
245 } \
246 } \
247 \
248 void unserialize_vec_##n_bits (serialize_main_t * m, va_list * va) \
249 { \
250 u##n_bits * s = va_arg (*va, u##n_bits *); \
251 u32 n = va_arg (*va, u32); \
252 u##n_bits * p = unserialize_get (m, n * sizeof (s[0])); \
253 \
254 while (n >= 4) \
255 { \
256 s[0] = clib_net_to_host_mem_u##n_bits (&p[0]); \
257 s[1] = clib_net_to_host_mem_u##n_bits (&p[1]); \
258 s[2] = clib_net_to_host_mem_u##n_bits (&p[2]); \
259 s[3] = clib_net_to_host_mem_u##n_bits (&p[3]); \
260 s += 4; \
261 p += 4; \
262 n -= 4; \
263 } \
264 \
265 while (n >= 1) \
266 { \
267 s[0] = clib_net_to_host_mem_u##n_bits (&p[0]); \
268 s += 1; \
269 p += 1; \
270 n -= 1; \
271 } \
272 }
273
Dave Barachc3799992016-08-15 11:12:27 -0400274_(16);
275_(32);
276_(64);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700277
278#undef _
279
280#define SERIALIZE_VECTOR_CHUNK_SIZE 64
281
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200282__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400283serialize_vector (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700284{
Dave Barachc3799992016-08-15 11:12:27 -0400285 void *vec = va_arg (*va, void *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700286 u32 elt_bytes = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400287 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700288 u32 l = vec_len (vec);
Dave Barachc3799992016-08-15 11:12:27 -0400289 void *p = vec;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700290
291 serialize_integer (m, l, sizeof (l));
292
293 /* Serialize vector in chunks for cache locality. */
294 while (l != 0)
295 {
296 u32 n = clib_min (SERIALIZE_VECTOR_CHUNK_SIZE, l);
297 serialize (m, f, p, n);
298 l -= n;
299 p += SERIALIZE_VECTOR_CHUNK_SIZE * elt_bytes;
300 }
301}
302
303void *
Dave Barachc3799992016-08-15 11:12:27 -0400304unserialize_vector_ha (serialize_main_t * m,
Ed Warnickecb9cada2015-12-08 15:45:58 -0700305 u32 elt_bytes,
306 u32 header_bytes,
Dave Barachc3799992016-08-15 11:12:27 -0400307 u32 align, u32 max_length, serialize_function_t * f)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700308{
Dave Barachc3799992016-08-15 11:12:27 -0400309 void *v, *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700310 u32 l;
Damjan Marione4fa1d22022-04-11 18:41:49 +0200311 vec_attr_t va = { .align = align,
312 .elt_sz = elt_bytes,
313 .hdr_sz = header_bytes };
Ed Warnickecb9cada2015-12-08 15:45:58 -0700314
315 unserialize_integer (m, &l, sizeof (l));
316 if (l > max_length)
Dave Barachc3799992016-08-15 11:12:27 -0400317 serialize_error (&m->header,
318 clib_error_create ("bad vector length %d", l));
Damjan Marione4fa1d22022-04-11 18:41:49 +0200319
320 p = v = _vec_alloc_internal (l, &va);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700321
322 while (l != 0)
323 {
324 u32 n = clib_min (SERIALIZE_VECTOR_CHUNK_SIZE, l);
325 unserialize (m, f, p, n);
326 l -= n;
327 p += SERIALIZE_VECTOR_CHUNK_SIZE * elt_bytes;
328 }
329 return v;
330}
331
Dave Barachc3799992016-08-15 11:12:27 -0400332void
333unserialize_aligned_vector (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700334{
Dave Barachc3799992016-08-15 11:12:27 -0400335 void **vec = va_arg (*va, void **);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700336 u32 elt_bytes = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400337 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700338 u32 align = va_arg (*va, u32);
339
340 *vec = unserialize_vector_ha (m, elt_bytes,
341 /* header_bytes */ 0,
342 /* align */ align,
343 /* max_length */ ~0,
344 f);
345}
346
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200347__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400348unserialize_vector (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700349{
Dave Barachc3799992016-08-15 11:12:27 -0400350 void **vec = va_arg (*va, void **);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700351 u32 elt_bytes = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400352 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700353
354 *vec = unserialize_vector_ha (m, elt_bytes,
355 /* header_bytes */ 0,
356 /* align */ 0,
357 /* max_length */ ~0,
358 f);
359}
360
Dave Barachc3799992016-08-15 11:12:27 -0400361void
362serialize_bitmap (serialize_main_t * m, uword * b)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700363{
364 u32 l, i, n_u32s;
365
366 l = vec_len (b);
367 n_u32s = l * sizeof (b[0]) / sizeof (u32);
368 serialize_integer (m, n_u32s, sizeof (n_u32s));
369
370 /* Send 32 bit words, low-order word first on 64 bit. */
371 for (i = 0; i < l; i++)
372 {
373 serialize_integer (m, b[i], sizeof (u32));
374 if (BITS (uword) == 64)
375 serialize_integer (m, (u64) b[i] >> (u64) 32, sizeof (u32));
376 }
377}
378
Dave Barachc3799992016-08-15 11:12:27 -0400379uword *
380unserialize_bitmap (serialize_main_t * m)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700381{
Dave Barachc3799992016-08-15 11:12:27 -0400382 uword *b = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700383 u32 i, n_u32s;
384
385 unserialize_integer (m, &n_u32s, sizeof (n_u32s));
386 if (n_u32s == 0)
387 return b;
388
389 i = (n_u32s * sizeof (u32) + sizeof (b[0]) - 1) / sizeof (b[0]);
390 vec_resize (b, i);
391 for (i = 0; i < n_u32s; i++)
392 {
393 u32 data;
394 unserialize_integer (m, &data, sizeof (u32));
395
396 /* Low-word is first on 64 bit. */
397 if (BITS (uword) == 64)
398 {
399 if ((i % 2) == 0)
Dave Barachc3799992016-08-15 11:12:27 -0400400 b[i / 2] |= (u64) data << (u64) 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700401 else
Dave Barachc3799992016-08-15 11:12:27 -0400402 b[i / 2] |= (u64) data << (u64) 32;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700403 }
404 else
405 {
406 b[i] = data;
407 }
408 }
409
410 return b;
411}
412
Dave Barachc3799992016-08-15 11:12:27 -0400413void
414serialize_pool (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700415{
Dave Barachc3799992016-08-15 11:12:27 -0400416 void *pool = va_arg (*va, void *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700417 u32 elt_bytes = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400418 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700419 u32 l, lo, hi;
Dave Barachc3799992016-08-15 11:12:27 -0400420 pool_header_t *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700421
422 l = vec_len (pool);
423 serialize_integer (m, l, sizeof (u32));
424 if (l == 0)
425 return;
426 p = pool_header (pool);
427
428 /* No need to send free bitmap. Need to send index vector
429 to guarantee that unserialized pool will be identical. */
430 vec_serialize (m, p->free_indices, serialize_vec_32);
431
432 pool_foreach_region (lo, hi, pool,
Dave Barachc3799992016-08-15 11:12:27 -0400433 serialize (m, f, pool + lo * elt_bytes, hi - lo));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700434}
435
436static void *
437unserialize_pool_helper (serialize_main_t * m,
Dave Barachc3799992016-08-15 11:12:27 -0400438 u32 elt_bytes, u32 align, serialize_function_t * f)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700439{
Dave Barachc3799992016-08-15 11:12:27 -0400440 void *v;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700441 u32 i, l, lo, hi;
Dave Barachc3799992016-08-15 11:12:27 -0400442 pool_header_t *p;
Damjan Marione4fa1d22022-04-11 18:41:49 +0200443 vec_attr_t va = { .align = align,
444 .elt_sz = elt_bytes,
445 .hdr_sz = sizeof (pool_header_t) };
Ed Warnickecb9cada2015-12-08 15:45:58 -0700446
447 unserialize_integer (m, &l, sizeof (l));
448 if (l == 0)
449 {
450 return 0;
451 }
452
Damjan Marione4fa1d22022-04-11 18:41:49 +0200453 v = _vec_alloc_internal (l, &va);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700454 p = pool_header (v);
455
456 vec_unserialize (m, &p->free_indices, unserialize_vec_32);
457
458 /* Construct free bitmap. */
459 p->free_bitmap = 0;
460 for (i = 0; i < vec_len (p->free_indices); i++)
461 p->free_bitmap = clib_bitmap_ori (p->free_bitmap, p->free_indices[i]);
462
463 pool_foreach_region (lo, hi, v,
Dave Barachc3799992016-08-15 11:12:27 -0400464 unserialize (m, f, v + lo * elt_bytes, hi - lo));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700465
466 return v;
467}
468
Dave Barachc3799992016-08-15 11:12:27 -0400469void
470unserialize_pool (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700471{
Dave Barachc3799992016-08-15 11:12:27 -0400472 void **result = va_arg (*va, void **);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700473 u32 elt_bytes = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400474 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700475 *result = unserialize_pool_helper (m, elt_bytes, /* align */ 0, f);
476}
477
Dave Barachc3799992016-08-15 11:12:27 -0400478void
479unserialize_aligned_pool (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700480{
Dave Barachc3799992016-08-15 11:12:27 -0400481 void **result = va_arg (*va, void **);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700482 u32 elt_bytes = va_arg (*va, u32);
483 u32 align = va_arg (*va, u32);
Dave Barachc3799992016-08-15 11:12:27 -0400484 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700485 *result = unserialize_pool_helper (m, elt_bytes, align, f);
486}
487
Dave Barachc3799992016-08-15 11:12:27 -0400488static void
489serialize_vec_heap_elt (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700490{
Dave Barachc3799992016-08-15 11:12:27 -0400491 heap_elt_t *e = va_arg (*va, heap_elt_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700492 u32 i, n = va_arg (*va, u32);
493 for (i = 0; i < n; i++)
494 {
495 serialize_integer (m, e[i].offset, sizeof (e[i].offset));
496 serialize_integer (m, e[i].next, sizeof (e[i].next));
497 serialize_integer (m, e[i].prev, sizeof (e[i].prev));
498 }
499}
500
Dave Barachc3799992016-08-15 11:12:27 -0400501static void
502unserialize_vec_heap_elt (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700503{
Dave Barachc3799992016-08-15 11:12:27 -0400504 heap_elt_t *e = va_arg (*va, heap_elt_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700505 u32 i, n = va_arg (*va, u32);
506 for (i = 0; i < n; i++)
507 {
508 unserialize_integer (m, &e[i].offset, sizeof (e[i].offset));
509 unserialize_integer (m, &e[i].next, sizeof (e[i].next));
510 unserialize_integer (m, &e[i].prev, sizeof (e[i].prev));
511 }
512}
513
Dave Barachc3799992016-08-15 11:12:27 -0400514void
515serialize_heap (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700516{
Dave Barachc3799992016-08-15 11:12:27 -0400517 void *heap = va_arg (*va, void *);
518 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700519 u32 i, l;
Dave Barachc3799992016-08-15 11:12:27 -0400520 heap_header_t *h;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700521
522 l = vec_len (heap);
523 serialize_integer (m, l, sizeof (u32));
524 if (l == 0)
525 return;
526
527 h = heap_header (heap);
528
529#define foreach_serialize_heap_header_integer \
530 _ (head) _ (tail) _ (used_count) _ (max_len) _ (flags) _ (elt_bytes)
531
532#define _(f) serialize_integer (m, h->f, sizeof (h->f));
533 foreach_serialize_heap_header_integer;
534#undef _
535
536 serialize_integer (m, vec_len (h->free_lists), sizeof (u32));
537 for (i = 0; i < vec_len (h->free_lists); i++)
538 vec_serialize (m, h->free_lists[i], serialize_vec_32);
539
540 vec_serialize (m, h->elts, serialize_vec_heap_elt);
541 vec_serialize (m, h->small_free_elt_free_index, serialize_vec_32);
542 vec_serialize (m, h->free_elts, serialize_vec_32);
543
544 /* Serialize data in heap. */
545 {
Dave Barachc3799992016-08-15 11:12:27 -0400546 heap_elt_t *e, *end;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700547 e = h->elts + h->head;
548 end = h->elts + h->tail;
549 while (1)
550 {
Dave Barachc3799992016-08-15 11:12:27 -0400551 if (!heap_is_free (e))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700552 {
Dave Barachc3799992016-08-15 11:12:27 -0400553 void *v = heap + heap_offset (e) * h->elt_bytes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700554 u32 n = heap_elt_size (heap, e);
555 serialize (m, f, v, n);
556 }
557 if (e == end)
558 break;
559 e = heap_next (e);
560 }
561 }
562}
563
Dave Barachc3799992016-08-15 11:12:27 -0400564void
565unserialize_heap (serialize_main_t * m, va_list * va)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700566{
Dave Barachc3799992016-08-15 11:12:27 -0400567 void **result = va_arg (*va, void **);
568 serialize_function_t *f = va_arg (*va, serialize_function_t *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700569 u32 i, vl, fl;
570 heap_header_t h;
Dave Barachc3799992016-08-15 11:12:27 -0400571 void *heap;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700572
573 unserialize_integer (m, &vl, sizeof (u32));
574 if (vl == 0)
575 {
576 *result = 0;
577 return;
578 }
579
Dave Barachb7b92992018-10-17 10:38:51 -0400580 clib_memset (&h, 0, sizeof (h));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700581#define _(f) unserialize_integer (m, &h.f, sizeof (h.f));
582 foreach_serialize_heap_header_integer;
583#undef _
584
585 unserialize_integer (m, &fl, sizeof (u32));
586 vec_resize (h.free_lists, fl);
587
588 for (i = 0; i < vec_len (h.free_lists); i++)
589 vec_unserialize (m, &h.free_lists[i], unserialize_vec_32);
590
591 vec_unserialize (m, &h.elts, unserialize_vec_heap_elt);
592 vec_unserialize (m, &h.small_free_elt_free_index, unserialize_vec_32);
593 vec_unserialize (m, &h.free_elts, unserialize_vec_32);
594
595 /* Re-construct used elt bitmap. */
596 if (CLIB_DEBUG > 0)
597 {
Dave Barachc3799992016-08-15 11:12:27 -0400598 heap_elt_t *e;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700599 vec_foreach (e, h.elts)
Dave Barachc3799992016-08-15 11:12:27 -0400600 {
601 if (!heap_is_free (e))
602 h.used_elt_bitmap = clib_bitmap_ori (h.used_elt_bitmap, e - h.elts);
603 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700604 }
605
606 heap = *result = _heap_new (vl, h.elt_bytes);
607 heap_header (heap)[0] = h;
608
609 /* Unserialize data in heap. */
610 {
Dave Barachc3799992016-08-15 11:12:27 -0400611 heap_elt_t *e, *end;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700612 e = h.elts + h.head;
613 end = h.elts + h.tail;
614 while (1)
615 {
Dave Barachc3799992016-08-15 11:12:27 -0400616 if (!heap_is_free (e))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700617 {
Dave Barachc3799992016-08-15 11:12:27 -0400618 void *v = heap + heap_offset (e) * h.elt_bytes;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700619 u32 n = heap_elt_size (heap, e);
620 unserialize (m, f, v, n);
621 }
622 if (e == end)
623 break;
624 e = heap_next (e);
625 }
626 }
627}
628
Dave Barachc3799992016-08-15 11:12:27 -0400629void
630serialize_magic (serialize_main_t * m, void *magic, u32 magic_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700631{
Dave Barachc3799992016-08-15 11:12:27 -0400632 void *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700633 serialize_integer (m, magic_bytes, sizeof (magic_bytes));
634 p = serialize_get (m, magic_bytes);
Dave Barach178cf492018-11-13 16:34:13 -0500635 clib_memcpy_fast (p, magic, magic_bytes);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700636}
637
Dave Barachc3799992016-08-15 11:12:27 -0400638void
639unserialize_check_magic (serialize_main_t * m, void *magic, u32 magic_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700640{
641 u32 l;
Dave Barachc3799992016-08-15 11:12:27 -0400642 void *d;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700643
644 unserialize_integer (m, &l, sizeof (l));
645 if (l != magic_bytes)
646 {
647 bad:
648 serialize_error_return (m, "bad magic number");
649 }
650 d = serialize_get (m, magic_bytes);
651 if (memcmp (magic, d, magic_bytes))
652 goto bad;
653}
654
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200655__clib_export clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700656va_serialize (serialize_main_t * sm, va_list * va)
657{
Dave Barachc3799992016-08-15 11:12:27 -0400658 serialize_main_header_t *m = &sm->header;
659 serialize_function_t *f = va_arg (*va, serialize_function_t *);
660 clib_error_t *error = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700661
662 m->recursion_level += 1;
663 if (m->recursion_level == 1)
664 {
665 uword r = clib_setjmp (&m->error_longjmp, 0);
666 error = uword_to_pointer (r, clib_error_t *);
667 }
Dave Barachc3799992016-08-15 11:12:27 -0400668
669 if (!error)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700670 f (sm, va);
671
672 m->recursion_level -= 1;
673 return error;
674}
675
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200676__clib_export clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700677serialize (serialize_main_t * m, ...)
678{
Dave Barachc3799992016-08-15 11:12:27 -0400679 clib_error_t *error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700680 va_list va;
681
682 va_start (va, m);
683 error = va_serialize (m, &va);
684 va_end (va);
685 return error;
686}
687
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200688__clib_export clib_error_t *
Ed Warnickecb9cada2015-12-08 15:45:58 -0700689unserialize (serialize_main_t * m, ...)
690{
Dave Barachc3799992016-08-15 11:12:27 -0400691 clib_error_t *error;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700692 va_list va;
693
694 va_start (va, m);
695 error = va_serialize (m, &va);
696 va_end (va);
697 return error;
698}
699
Dave Barachc3799992016-08-15 11:12:27 -0400700static void *
701serialize_write_not_inline (serialize_main_header_t * m,
702 serialize_stream_t * s,
703 uword n_bytes_to_write, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700704{
705 uword cur_bi, n_left_b, n_left_o;
706
707 ASSERT (s->current_buffer_index <= s->n_buffer_bytes);
708 cur_bi = s->current_buffer_index;
709 n_left_b = s->n_buffer_bytes - cur_bi;
710 n_left_o = vec_len (s->overflow_buffer);
711
712 /* Prepend overflow buffer if present. */
Dave Barachc3799992016-08-15 11:12:27 -0400713 do
714 {
715 if (n_left_o > 0 && n_left_b > 0)
716 {
717 uword n = clib_min (n_left_b, n_left_o);
Dave Barach178cf492018-11-13 16:34:13 -0500718 clib_memcpy_fast (s->buffer + cur_bi, s->overflow_buffer, n);
Dave Barachc3799992016-08-15 11:12:27 -0400719 cur_bi += n;
720 n_left_b -= n;
721 n_left_o -= n;
722 if (n_left_o == 0)
Damjan Marion8bea5892022-04-04 22:40:45 +0200723 vec_set_len (s->overflow_buffer, 0);
Dave Barachc3799992016-08-15 11:12:27 -0400724 else
725 vec_delete (s->overflow_buffer, n, 0);
726 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700727
Dave Barachc3799992016-08-15 11:12:27 -0400728 /* Call data function when buffer is complete. Data function should
729 dispatch with current buffer and give us a new one to write more
730 data into. */
731 if (n_left_b == 0)
732 {
733 s->current_buffer_index = cur_bi;
734 m->data_function (m, s);
735 cur_bi = s->current_buffer_index;
736 n_left_b = s->n_buffer_bytes - cur_bi;
737 }
738 }
739 while (n_left_o > 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700740
741 if (n_left_o > 0 || n_left_b < n_bytes_to_write)
742 {
Dave Barachc3799992016-08-15 11:12:27 -0400743 u8 *r;
Dave Barach809eb662023-01-12 16:07:26 -0500744 s->current_buffer_index = cur_bi;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700745 vec_add2 (s->overflow_buffer, r, n_bytes_to_write);
746 return r;
747 }
748 else
749 {
750 s->current_buffer_index = cur_bi + n_bytes_to_write;
751 return s->buffer + cur_bi;
752 }
753}
754
Dave Barachc3799992016-08-15 11:12:27 -0400755static void *
756serialize_read_not_inline (serialize_main_header_t * m,
757 serialize_stream_t * s,
758 uword n_bytes_to_read, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700759{
760 uword cur_bi, cur_oi, n_left_b, n_left_o, n_left_to_read;
761
762 ASSERT (s->current_buffer_index <= s->n_buffer_bytes);
763
764 cur_bi = s->current_buffer_index;
765 cur_oi = s->current_overflow_index;
766
767 n_left_b = s->n_buffer_bytes - cur_bi;
768 n_left_o = vec_len (s->overflow_buffer) - cur_oi;
769
770 /* Read from overflow? */
771 if (n_left_o >= n_bytes_to_read)
772 {
773 s->current_overflow_index = cur_oi + n_bytes_to_read;
774 return vec_elt_at_index (s->overflow_buffer, cur_oi);
775 }
776
777 /* Reset overflow buffer. */
778 if (n_left_o == 0 && s->overflow_buffer)
779 {
780 s->current_overflow_index = 0;
Damjan Marion8bea5892022-04-04 22:40:45 +0200781 vec_set_len (s->overflow_buffer, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700782 }
783
784 n_left_to_read = n_bytes_to_read;
785 while (n_left_to_read > 0)
786 {
787 uword n;
788
789 /* If we don't have enough data between overflow and normal buffer
Dave Barachc3799992016-08-15 11:12:27 -0400790 call read function. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700791 if (n_left_o + n_left_b < n_bytes_to_read)
792 {
793 /* Save any left over buffer in overflow vector. */
794 if (n_left_b > 0)
795 {
796 vec_add (s->overflow_buffer, s->buffer + cur_bi, n_left_b);
797 n_left_o += n_left_b;
798 n_left_to_read -= n_left_b;
799 /* Advance buffer to end --- even if
Dave Barachc3799992016-08-15 11:12:27 -0400800 SERIALIZE_FLAG_NO_ADVANCE_CURRENT_BUFFER_INDEX is set. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700801 cur_bi = s->n_buffer_bytes;
802 n_left_b = 0;
803 }
804
805 if (m->data_function)
806 {
807 m->data_function (m, s);
808 cur_bi = s->current_buffer_index;
809 n_left_b = s->n_buffer_bytes - cur_bi;
810 }
811 }
812
813 /* For first time through loop return if we have enough data
Dave Barachc3799992016-08-15 11:12:27 -0400814 in normal buffer and overflow vector is empty. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700815 if (n_left_o == 0
Dave Barachc3799992016-08-15 11:12:27 -0400816 && n_left_to_read == n_bytes_to_read && n_left_b >= n_left_to_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700817 {
818 s->current_buffer_index = cur_bi + n_bytes_to_read;
819 return s->buffer + cur_bi;
820 }
821
Dave Barachc3799992016-08-15 11:12:27 -0400822 if (!m->data_function || serialize_stream_is_end_of_stream (s))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700823 {
824 /* This can happen for a peek at end of file.
825 Pad overflow buffer with 0s. */
826 vec_resize (s->overflow_buffer, n_left_to_read);
827 n_left_o += n_left_to_read;
828 n_left_to_read = 0;
829 }
830 else
831 {
832 /* Copy from buffer to overflow vector. */
833 n = clib_min (n_left_to_read, n_left_b);
834 vec_add (s->overflow_buffer, s->buffer + cur_bi, n);
835 cur_bi += n;
836 n_left_b -= n;
837 n_left_o += n;
838 n_left_to_read -= n;
839 }
840 }
Dave Barachc3799992016-08-15 11:12:27 -0400841
Ed Warnickecb9cada2015-12-08 15:45:58 -0700842 s->current_buffer_index = cur_bi;
843 s->current_overflow_index = cur_oi + n_bytes_to_read;
844 return vec_elt_at_index (s->overflow_buffer, cur_oi);
845}
846
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200847__clib_export void *
Dave Barachc3799992016-08-15 11:12:27 -0400848serialize_read_write_not_inline (serialize_main_header_t * m,
849 serialize_stream_t * s,
850 uword n_bytes, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700851{
Dave Barachc3799992016-08-15 11:12:27 -0400852 return (((flags & SERIALIZE_FLAG_IS_READ) ? serialize_read_not_inline :
853 serialize_write_not_inline) (m, s, n_bytes, flags));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700854}
855
Dave Barachc3799992016-08-15 11:12:27 -0400856static void
857serialize_read_write_close (serialize_main_header_t * m,
858 serialize_stream_t * s, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700859{
860 if (serialize_stream_is_end_of_stream (s))
861 return;
862
863 if (flags & SERIALIZE_FLAG_IS_WRITE)
864 /* "Write" 0 bytes to flush overflow vector. */
865 serialize_write_not_inline (m, s, /* n bytes */ 0, flags);
866
867 serialize_stream_set_end_of_stream (s);
868
869 /* Call it one last time to flush buffer and close. */
870 m->data_function (m, s);
871
872 vec_free (s->overflow_buffer);
873}
874
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200875__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400876serialize_close (serialize_main_t * m)
877{
878 serialize_read_write_close (&m->header, &m->stream,
879 SERIALIZE_FLAG_IS_WRITE);
880}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700881
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200882__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400883unserialize_close (serialize_main_t * m)
884{
885 serialize_read_write_close (&m->header, &m->stream, SERIALIZE_FLAG_IS_READ);
886}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700887
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200888__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400889serialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700890{
Dave Barachb7b92992018-10-17 10:38:51 -0400891 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700892 m->stream.buffer = data;
893 m->stream.n_buffer_bytes = n_data_bytes;
894}
895
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200896__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400897unserialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700898{
Dave Barachc3799992016-08-15 11:12:27 -0400899 serialize_open_data (m, data, n_data_bytes);
900}
901
902static void
903serialize_vector_write (serialize_main_header_t * m, serialize_stream_t * s)
904{
905 if (!serialize_stream_is_end_of_stream (s))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700906 {
907 /* Double buffer size. */
908 uword l = vec_len (s->buffer);
909 vec_resize (s->buffer, l > 0 ? l : 64);
910 s->n_buffer_bytes = vec_len (s->buffer);
911 }
912}
913
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200914__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400915serialize_open_vector (serialize_main_t * m, u8 * vector)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700916{
Dave Barachb7b92992018-10-17 10:38:51 -0400917 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700918 m->header.data_function = serialize_vector_write;
919 m->stream.buffer = vector;
920 m->stream.current_buffer_index = 0;
921 m->stream.n_buffer_bytes = vec_len (vector);
922}
Dave Barachc3799992016-08-15 11:12:27 -0400923
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200924__clib_export void *
Dave Barachc3799992016-08-15 11:12:27 -0400925serialize_close_vector (serialize_main_t * m)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700926{
Dave Barachc3799992016-08-15 11:12:27 -0400927 serialize_stream_t *s = &m->stream;
928 void *result;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700929
930 serialize_close (m); /* frees overflow buffer */
931
932 if (s->buffer)
Damjan Marion8bea5892022-04-04 22:40:45 +0200933 vec_set_len (s->buffer, s->current_buffer_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700934 result = s->buffer;
Dave Barachb7b92992018-10-17 10:38:51 -0400935 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700936 return result;
937}
Dave Barachc3799992016-08-15 11:12:27 -0400938
Damjan Marion4a251d02021-05-06 17:28:12 +0200939__clib_export void
940serialize_multiple_1 (serialize_main_t *m, void *data, uword data_stride,
941 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700942{
Dave Barachc3799992016-08-15 11:12:27 -0400943 u8 *d = data;
944 u8 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700945 uword n_left = n_data;
946
947 while (n_left >= 4)
948 {
949 p = serialize_get (m, 4 * sizeof (d[0]));
950 p[0] = d[0 * data_stride];
951 p[1] = d[1 * data_stride];
952 p[2] = d[2 * data_stride];
953 p[3] = d[3 * data_stride];
954 n_left -= 4;
955 d += 4 * data_stride;
956 }
957
958 if (n_left > 0)
959 {
960 p = serialize_get (m, n_left * sizeof (p[0]));
961 while (n_left > 0)
962 {
963 p[0] = d[0];
964 p += 1;
965 d += 1 * data_stride;
966 n_left -= 1;
967 }
968 }
969}
970
Damjan Marion4a251d02021-05-06 17:28:12 +0200971__clib_export void
972serialize_multiple_2 (serialize_main_t *m, void *data, uword data_stride,
973 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700974{
Dave Barachc3799992016-08-15 11:12:27 -0400975 void *d = data;
976 u16 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700977 uword n_left = n_data;
978
979 while (n_left >= 4)
980 {
981 p = serialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -0400982 clib_mem_unaligned (p + 0, u16) =
983 clib_host_to_net_mem_u16 (d + 0 * data_stride);
984 clib_mem_unaligned (p + 1, u16) =
985 clib_host_to_net_mem_u16 (d + 1 * data_stride);
986 clib_mem_unaligned (p + 2, u16) =
987 clib_host_to_net_mem_u16 (d + 2 * data_stride);
988 clib_mem_unaligned (p + 3, u16) =
989 clib_host_to_net_mem_u16 (d + 3 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700990 n_left -= 4;
991 d += 4 * data_stride;
992 }
993
994 if (n_left > 0)
995 {
996 p = serialize_get (m, n_left * sizeof (p[0]));
997 while (n_left > 0)
998 {
Dave Barachc3799992016-08-15 11:12:27 -0400999 clib_mem_unaligned (p + 0, u16) =
1000 clib_host_to_net_mem_u16 (d + 0 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001001 p += 1;
1002 d += 1 * data_stride;
1003 n_left -= 1;
1004 }
1005 }
1006}
1007
Damjan Marion4a251d02021-05-06 17:28:12 +02001008__clib_export void
1009serialize_multiple_4 (serialize_main_t *m, void *data, uword data_stride,
1010 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001011{
Dave Barachc3799992016-08-15 11:12:27 -04001012 void *d = data;
1013 u32 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001014 uword n_left = n_data;
1015
1016 while (n_left >= 4)
1017 {
1018 p = serialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -04001019 clib_mem_unaligned (p + 0, u32) =
1020 clib_host_to_net_mem_u32 (d + 0 * data_stride);
1021 clib_mem_unaligned (p + 1, u32) =
1022 clib_host_to_net_mem_u32 (d + 1 * data_stride);
1023 clib_mem_unaligned (p + 2, u32) =
1024 clib_host_to_net_mem_u32 (d + 2 * data_stride);
1025 clib_mem_unaligned (p + 3, u32) =
1026 clib_host_to_net_mem_u32 (d + 3 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001027 n_left -= 4;
1028 d += 4 * data_stride;
1029 }
1030
1031 if (n_left > 0)
1032 {
1033 p = serialize_get (m, n_left * sizeof (p[0]));
1034 while (n_left > 0)
1035 {
Dave Barachc3799992016-08-15 11:12:27 -04001036 clib_mem_unaligned (p + 0, u32) =
1037 clib_host_to_net_mem_u32 (d + 0 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001038 p += 1;
1039 d += 1 * data_stride;
1040 n_left -= 1;
1041 }
1042 }
1043}
1044
Damjan Marion4a251d02021-05-06 17:28:12 +02001045__clib_export void
1046unserialize_multiple_1 (serialize_main_t *m, void *data, uword data_stride,
1047 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001048{
Dave Barachc3799992016-08-15 11:12:27 -04001049 u8 *d = data;
1050 u8 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001051 uword n_left = n_data;
1052
1053 while (n_left >= 4)
1054 {
1055 p = unserialize_get (m, 4 * sizeof (d[0]));
1056 d[0 * data_stride] = p[0];
1057 d[1 * data_stride] = p[1];
1058 d[2 * data_stride] = p[2];
1059 d[3 * data_stride] = p[3];
1060 n_left -= 4;
1061 d += 4 * data_stride;
1062 }
1063
1064 if (n_left > 0)
1065 {
1066 p = unserialize_get (m, n_left * sizeof (p[0]));
1067 while (n_left > 0)
1068 {
1069 d[0] = p[0];
1070 p += 1;
1071 d += 1 * data_stride;
1072 n_left -= 1;
1073 }
1074 }
1075}
1076
Damjan Marion4a251d02021-05-06 17:28:12 +02001077__clib_export void
1078unserialize_multiple_2 (serialize_main_t *m, void *data, uword data_stride,
1079 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001080{
Dave Barachc3799992016-08-15 11:12:27 -04001081 void *d = data;
1082 u16 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001083 uword n_left = n_data;
1084
1085 while (n_left >= 4)
1086 {
1087 p = unserialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -04001088 clib_mem_unaligned (d + 0 * data_stride, u16) =
1089 clib_net_to_host_mem_u16 (p + 0);
1090 clib_mem_unaligned (d + 1 * data_stride, u16) =
1091 clib_net_to_host_mem_u16 (p + 1);
1092 clib_mem_unaligned (d + 2 * data_stride, u16) =
1093 clib_net_to_host_mem_u16 (p + 2);
1094 clib_mem_unaligned (d + 3 * data_stride, u16) =
1095 clib_net_to_host_mem_u16 (p + 3);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001096 n_left -= 4;
1097 d += 4 * data_stride;
1098 }
1099
1100 if (n_left > 0)
1101 {
1102 p = unserialize_get (m, n_left * sizeof (p[0]));
1103 while (n_left > 0)
1104 {
Dave Barachc3799992016-08-15 11:12:27 -04001105 clib_mem_unaligned (d + 0 * data_stride, u16) =
1106 clib_net_to_host_mem_u16 (p + 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001107 p += 1;
1108 d += 1 * data_stride;
1109 n_left -= 1;
1110 }
1111 }
1112}
1113
Damjan Marion4a251d02021-05-06 17:28:12 +02001114__clib_export void
1115unserialize_multiple_4 (serialize_main_t *m, void *data, uword data_stride,
1116 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001117{
Dave Barachc3799992016-08-15 11:12:27 -04001118 void *d = data;
1119 u32 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001120 uword n_left = n_data;
1121
1122 while (n_left >= 4)
1123 {
1124 p = unserialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -04001125 clib_mem_unaligned (d + 0 * data_stride, u32) =
1126 clib_net_to_host_mem_u32 (p + 0);
1127 clib_mem_unaligned (d + 1 * data_stride, u32) =
1128 clib_net_to_host_mem_u32 (p + 1);
1129 clib_mem_unaligned (d + 2 * data_stride, u32) =
1130 clib_net_to_host_mem_u32 (p + 2);
1131 clib_mem_unaligned (d + 3 * data_stride, u32) =
1132 clib_net_to_host_mem_u32 (p + 3);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001133 n_left -= 4;
1134 d += 4 * data_stride;
1135 }
1136
1137 if (n_left > 0)
1138 {
1139 p = unserialize_get (m, n_left * sizeof (p[0]));
1140 while (n_left > 0)
1141 {
Dave Barachc3799992016-08-15 11:12:27 -04001142 clib_mem_unaligned (d + 0 * data_stride, u32) =
1143 clib_net_to_host_mem_u32 (p + 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001144 p += 1;
1145 d += 1 * data_stride;
1146 n_left -= 1;
1147 }
1148 }
1149}
1150
1151#ifdef CLIB_UNIX
1152
1153#include <unistd.h>
1154#include <fcntl.h>
1155
Dave Barachc3799992016-08-15 11:12:27 -04001156static void
Dave Barach59b25652017-09-10 15:04:27 -04001157clib_file_write (serialize_main_header_t * m, serialize_stream_t * s)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001158{
1159 int fd, n;
1160
1161 fd = s->data_function_opaque;
1162 n = write (fd, s->buffer, s->current_buffer_index);
1163 if (n < 0)
1164 {
Dave Barachc3799992016-08-15 11:12:27 -04001165 if (!unix_error_is_fatal (errno))
Ed Warnickecb9cada2015-12-08 15:45:58 -07001166 n = 0;
1167 else
1168 serialize_error (m, clib_error_return_unix (0, "write"));
1169 }
1170 if (n == s->current_buffer_index)
Damjan Marion8bea5892022-04-04 22:40:45 +02001171 vec_set_len (s->buffer, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001172 else
1173 vec_delete (s->buffer, n, 0);
1174 s->current_buffer_index = vec_len (s->buffer);
1175}
1176
Dave Barachc3799992016-08-15 11:12:27 -04001177static void
Dave Barach59b25652017-09-10 15:04:27 -04001178clib_file_read (serialize_main_header_t * m, serialize_stream_t * s)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001179{
1180 int fd, n;
1181
1182 fd = s->data_function_opaque;
1183 n = read (fd, s->buffer, vec_len (s->buffer));
1184 if (n < 0)
1185 {
Dave Barachc3799992016-08-15 11:12:27 -04001186 if (!unix_error_is_fatal (errno))
Ed Warnickecb9cada2015-12-08 15:45:58 -07001187 n = 0;
1188 else
1189 serialize_error (m, clib_error_return_unix (0, "read"));
1190 }
1191 else if (n == 0)
1192 serialize_stream_set_end_of_stream (s);
1193 s->current_buffer_index = 0;
1194 s->n_buffer_bytes = n;
1195}
1196
1197static void
Dave Barach59b25652017-09-10 15:04:27 -04001198serialize_open_clib_file_descriptor_helper (serialize_main_t * m, int fd,
Dave Barachc3799992016-08-15 11:12:27 -04001199 uword is_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001200{
Dave Barachb7b92992018-10-17 10:38:51 -04001201 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001202 vec_resize (m->stream.buffer, 4096);
Dave Barachc3799992016-08-15 11:12:27 -04001203
1204 if (!is_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001205 {
1206 m->stream.n_buffer_bytes = vec_len (m->stream.buffer);
Damjan Marion8bea5892022-04-04 22:40:45 +02001207 vec_set_len (m->stream.buffer, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001208 }
1209
Dave Barach59b25652017-09-10 15:04:27 -04001210 m->header.data_function = is_read ? clib_file_read : clib_file_write;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001211 m->stream.data_function_opaque = fd;
1212}
1213
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001214__clib_export void
Dave Barach59b25652017-09-10 15:04:27 -04001215serialize_open_clib_file_descriptor (serialize_main_t * m, int fd)
Dave Barachc3799992016-08-15 11:12:27 -04001216{
Dave Barach59b25652017-09-10 15:04:27 -04001217 serialize_open_clib_file_descriptor_helper (m, fd, /* is_read */ 0);
Dave Barachc3799992016-08-15 11:12:27 -04001218}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001219
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001220__clib_export void
Dave Barach59b25652017-09-10 15:04:27 -04001221unserialize_open_clib_file_descriptor (serialize_main_t * m, int fd)
Dave Barachc3799992016-08-15 11:12:27 -04001222{
Dave Barach59b25652017-09-10 15:04:27 -04001223 serialize_open_clib_file_descriptor_helper (m, fd, /* is_read */ 1);
Dave Barachc3799992016-08-15 11:12:27 -04001224}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001225
1226static clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -04001227serialize_open_clib_file_helper (serialize_main_t * m, char *file,
Dave Barachc3799992016-08-15 11:12:27 -04001228 uword is_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001229{
1230 int fd, mode;
1231
1232 mode = is_read ? O_RDONLY : O_RDWR | O_CREAT | O_TRUNC;
1233 fd = open (file, mode, 0666);
1234 if (fd < 0)
1235 return clib_error_return_unix (0, "open `%s'", file);
1236
Dave Barach59b25652017-09-10 15:04:27 -04001237 serialize_open_clib_file_descriptor_helper (m, fd, is_read);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001238 return 0;
1239}
1240
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001241__clib_export clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -04001242serialize_open_clib_file (serialize_main_t * m, char *file)
Dave Barachc3799992016-08-15 11:12:27 -04001243{
Dave Barach59b25652017-09-10 15:04:27 -04001244 return serialize_open_clib_file_helper (m, file, /* is_read */ 0);
Dave Barachc3799992016-08-15 11:12:27 -04001245}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001246
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001247__clib_export clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -04001248unserialize_open_clib_file (serialize_main_t * m, char *file)
Dave Barachc3799992016-08-15 11:12:27 -04001249{
Dave Barach59b25652017-09-10 15:04:27 -04001250 return serialize_open_clib_file_helper (m, file, /* is_read */ 1);
Dave Barachc3799992016-08-15 11:12:27 -04001251}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001252
1253#endif /* CLIB_UNIX */
Dave Barachc3799992016-08-15 11:12:27 -04001254
1255/*
1256 * fd.io coding-style-patch-verification: ON
1257 *
1258 * Local Variables:
1259 * eval: (c-set-style "gnu")
1260 * End:
1261 */