blob: f5c00649627853c9436f8019f4cfb7b41974e6b7 [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;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700744 vec_add2 (s->overflow_buffer, r, n_bytes_to_write);
745 return r;
746 }
747 else
748 {
749 s->current_buffer_index = cur_bi + n_bytes_to_write;
750 return s->buffer + cur_bi;
751 }
752}
753
Dave Barachc3799992016-08-15 11:12:27 -0400754static void *
755serialize_read_not_inline (serialize_main_header_t * m,
756 serialize_stream_t * s,
757 uword n_bytes_to_read, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700758{
759 uword cur_bi, cur_oi, n_left_b, n_left_o, n_left_to_read;
760
761 ASSERT (s->current_buffer_index <= s->n_buffer_bytes);
762
763 cur_bi = s->current_buffer_index;
764 cur_oi = s->current_overflow_index;
765
766 n_left_b = s->n_buffer_bytes - cur_bi;
767 n_left_o = vec_len (s->overflow_buffer) - cur_oi;
768
769 /* Read from overflow? */
770 if (n_left_o >= n_bytes_to_read)
771 {
772 s->current_overflow_index = cur_oi + n_bytes_to_read;
773 return vec_elt_at_index (s->overflow_buffer, cur_oi);
774 }
775
776 /* Reset overflow buffer. */
777 if (n_left_o == 0 && s->overflow_buffer)
778 {
779 s->current_overflow_index = 0;
Damjan Marion8bea5892022-04-04 22:40:45 +0200780 vec_set_len (s->overflow_buffer, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700781 }
782
783 n_left_to_read = n_bytes_to_read;
784 while (n_left_to_read > 0)
785 {
786 uword n;
787
788 /* If we don't have enough data between overflow and normal buffer
Dave Barachc3799992016-08-15 11:12:27 -0400789 call read function. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700790 if (n_left_o + n_left_b < n_bytes_to_read)
791 {
792 /* Save any left over buffer in overflow vector. */
793 if (n_left_b > 0)
794 {
795 vec_add (s->overflow_buffer, s->buffer + cur_bi, n_left_b);
796 n_left_o += n_left_b;
797 n_left_to_read -= n_left_b;
798 /* Advance buffer to end --- even if
Dave Barachc3799992016-08-15 11:12:27 -0400799 SERIALIZE_FLAG_NO_ADVANCE_CURRENT_BUFFER_INDEX is set. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700800 cur_bi = s->n_buffer_bytes;
801 n_left_b = 0;
802 }
803
804 if (m->data_function)
805 {
806 m->data_function (m, s);
807 cur_bi = s->current_buffer_index;
808 n_left_b = s->n_buffer_bytes - cur_bi;
809 }
810 }
811
812 /* For first time through loop return if we have enough data
Dave Barachc3799992016-08-15 11:12:27 -0400813 in normal buffer and overflow vector is empty. */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700814 if (n_left_o == 0
Dave Barachc3799992016-08-15 11:12:27 -0400815 && n_left_to_read == n_bytes_to_read && n_left_b >= n_left_to_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700816 {
817 s->current_buffer_index = cur_bi + n_bytes_to_read;
818 return s->buffer + cur_bi;
819 }
820
Dave Barachc3799992016-08-15 11:12:27 -0400821 if (!m->data_function || serialize_stream_is_end_of_stream (s))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700822 {
823 /* This can happen for a peek at end of file.
824 Pad overflow buffer with 0s. */
825 vec_resize (s->overflow_buffer, n_left_to_read);
826 n_left_o += n_left_to_read;
827 n_left_to_read = 0;
828 }
829 else
830 {
831 /* Copy from buffer to overflow vector. */
832 n = clib_min (n_left_to_read, n_left_b);
833 vec_add (s->overflow_buffer, s->buffer + cur_bi, n);
834 cur_bi += n;
835 n_left_b -= n;
836 n_left_o += n;
837 n_left_to_read -= n;
838 }
839 }
Dave Barachc3799992016-08-15 11:12:27 -0400840
Ed Warnickecb9cada2015-12-08 15:45:58 -0700841 s->current_buffer_index = cur_bi;
842 s->current_overflow_index = cur_oi + n_bytes_to_read;
843 return vec_elt_at_index (s->overflow_buffer, cur_oi);
844}
845
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200846__clib_export void *
Dave Barachc3799992016-08-15 11:12:27 -0400847serialize_read_write_not_inline (serialize_main_header_t * m,
848 serialize_stream_t * s,
849 uword n_bytes, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700850{
Dave Barachc3799992016-08-15 11:12:27 -0400851 return (((flags & SERIALIZE_FLAG_IS_READ) ? serialize_read_not_inline :
852 serialize_write_not_inline) (m, s, n_bytes, flags));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700853}
854
Dave Barachc3799992016-08-15 11:12:27 -0400855static void
856serialize_read_write_close (serialize_main_header_t * m,
857 serialize_stream_t * s, uword flags)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700858{
859 if (serialize_stream_is_end_of_stream (s))
860 return;
861
862 if (flags & SERIALIZE_FLAG_IS_WRITE)
863 /* "Write" 0 bytes to flush overflow vector. */
864 serialize_write_not_inline (m, s, /* n bytes */ 0, flags);
865
866 serialize_stream_set_end_of_stream (s);
867
868 /* Call it one last time to flush buffer and close. */
869 m->data_function (m, s);
870
871 vec_free (s->overflow_buffer);
872}
873
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200874__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400875serialize_close (serialize_main_t * m)
876{
877 serialize_read_write_close (&m->header, &m->stream,
878 SERIALIZE_FLAG_IS_WRITE);
879}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700880
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200881__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400882unserialize_close (serialize_main_t * m)
883{
884 serialize_read_write_close (&m->header, &m->stream, SERIALIZE_FLAG_IS_READ);
885}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700886
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200887__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400888serialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700889{
Dave Barachb7b92992018-10-17 10:38:51 -0400890 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700891 m->stream.buffer = data;
892 m->stream.n_buffer_bytes = n_data_bytes;
893}
894
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200895__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400896unserialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700897{
Dave Barachc3799992016-08-15 11:12:27 -0400898 serialize_open_data (m, data, n_data_bytes);
899}
900
901static void
902serialize_vector_write (serialize_main_header_t * m, serialize_stream_t * s)
903{
904 if (!serialize_stream_is_end_of_stream (s))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700905 {
906 /* Double buffer size. */
907 uword l = vec_len (s->buffer);
908 vec_resize (s->buffer, l > 0 ? l : 64);
909 s->n_buffer_bytes = vec_len (s->buffer);
910 }
911}
912
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200913__clib_export void
Dave Barachc3799992016-08-15 11:12:27 -0400914serialize_open_vector (serialize_main_t * m, u8 * vector)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700915{
Dave Barachb7b92992018-10-17 10:38:51 -0400916 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700917 m->header.data_function = serialize_vector_write;
918 m->stream.buffer = vector;
919 m->stream.current_buffer_index = 0;
920 m->stream.n_buffer_bytes = vec_len (vector);
921}
Dave Barachc3799992016-08-15 11:12:27 -0400922
Damjan Mariondae1c7e2020-10-17 13:32:25 +0200923__clib_export void *
Dave Barachc3799992016-08-15 11:12:27 -0400924serialize_close_vector (serialize_main_t * m)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700925{
Dave Barachc3799992016-08-15 11:12:27 -0400926 serialize_stream_t *s = &m->stream;
927 void *result;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700928
929 serialize_close (m); /* frees overflow buffer */
930
931 if (s->buffer)
Damjan Marion8bea5892022-04-04 22:40:45 +0200932 vec_set_len (s->buffer, s->current_buffer_index);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700933 result = s->buffer;
Dave Barachb7b92992018-10-17 10:38:51 -0400934 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700935 return result;
936}
Dave Barachc3799992016-08-15 11:12:27 -0400937
Damjan Marion4a251d02021-05-06 17:28:12 +0200938__clib_export void
939serialize_multiple_1 (serialize_main_t *m, void *data, uword data_stride,
940 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700941{
Dave Barachc3799992016-08-15 11:12:27 -0400942 u8 *d = data;
943 u8 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700944 uword n_left = n_data;
945
946 while (n_left >= 4)
947 {
948 p = serialize_get (m, 4 * sizeof (d[0]));
949 p[0] = d[0 * data_stride];
950 p[1] = d[1 * data_stride];
951 p[2] = d[2 * data_stride];
952 p[3] = d[3 * data_stride];
953 n_left -= 4;
954 d += 4 * data_stride;
955 }
956
957 if (n_left > 0)
958 {
959 p = serialize_get (m, n_left * sizeof (p[0]));
960 while (n_left > 0)
961 {
962 p[0] = d[0];
963 p += 1;
964 d += 1 * data_stride;
965 n_left -= 1;
966 }
967 }
968}
969
Damjan Marion4a251d02021-05-06 17:28:12 +0200970__clib_export void
971serialize_multiple_2 (serialize_main_t *m, void *data, uword data_stride,
972 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700973{
Dave Barachc3799992016-08-15 11:12:27 -0400974 void *d = data;
975 u16 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700976 uword n_left = n_data;
977
978 while (n_left >= 4)
979 {
980 p = serialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -0400981 clib_mem_unaligned (p + 0, u16) =
982 clib_host_to_net_mem_u16 (d + 0 * data_stride);
983 clib_mem_unaligned (p + 1, u16) =
984 clib_host_to_net_mem_u16 (d + 1 * data_stride);
985 clib_mem_unaligned (p + 2, u16) =
986 clib_host_to_net_mem_u16 (d + 2 * data_stride);
987 clib_mem_unaligned (p + 3, u16) =
988 clib_host_to_net_mem_u16 (d + 3 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700989 n_left -= 4;
990 d += 4 * data_stride;
991 }
992
993 if (n_left > 0)
994 {
995 p = serialize_get (m, n_left * sizeof (p[0]));
996 while (n_left > 0)
997 {
Dave Barachc3799992016-08-15 11:12:27 -0400998 clib_mem_unaligned (p + 0, u16) =
999 clib_host_to_net_mem_u16 (d + 0 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001000 p += 1;
1001 d += 1 * data_stride;
1002 n_left -= 1;
1003 }
1004 }
1005}
1006
Damjan Marion4a251d02021-05-06 17:28:12 +02001007__clib_export void
1008serialize_multiple_4 (serialize_main_t *m, void *data, uword data_stride,
1009 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001010{
Dave Barachc3799992016-08-15 11:12:27 -04001011 void *d = data;
1012 u32 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001013 uword n_left = n_data;
1014
1015 while (n_left >= 4)
1016 {
1017 p = serialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -04001018 clib_mem_unaligned (p + 0, u32) =
1019 clib_host_to_net_mem_u32 (d + 0 * data_stride);
1020 clib_mem_unaligned (p + 1, u32) =
1021 clib_host_to_net_mem_u32 (d + 1 * data_stride);
1022 clib_mem_unaligned (p + 2, u32) =
1023 clib_host_to_net_mem_u32 (d + 2 * data_stride);
1024 clib_mem_unaligned (p + 3, u32) =
1025 clib_host_to_net_mem_u32 (d + 3 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001026 n_left -= 4;
1027 d += 4 * data_stride;
1028 }
1029
1030 if (n_left > 0)
1031 {
1032 p = serialize_get (m, n_left * sizeof (p[0]));
1033 while (n_left > 0)
1034 {
Dave Barachc3799992016-08-15 11:12:27 -04001035 clib_mem_unaligned (p + 0, u32) =
1036 clib_host_to_net_mem_u32 (d + 0 * data_stride);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001037 p += 1;
1038 d += 1 * data_stride;
1039 n_left -= 1;
1040 }
1041 }
1042}
1043
Damjan Marion4a251d02021-05-06 17:28:12 +02001044__clib_export void
1045unserialize_multiple_1 (serialize_main_t *m, void *data, uword data_stride,
1046 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001047{
Dave Barachc3799992016-08-15 11:12:27 -04001048 u8 *d = data;
1049 u8 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001050 uword n_left = n_data;
1051
1052 while (n_left >= 4)
1053 {
1054 p = unserialize_get (m, 4 * sizeof (d[0]));
1055 d[0 * data_stride] = p[0];
1056 d[1 * data_stride] = p[1];
1057 d[2 * data_stride] = p[2];
1058 d[3 * data_stride] = p[3];
1059 n_left -= 4;
1060 d += 4 * data_stride;
1061 }
1062
1063 if (n_left > 0)
1064 {
1065 p = unserialize_get (m, n_left * sizeof (p[0]));
1066 while (n_left > 0)
1067 {
1068 d[0] = p[0];
1069 p += 1;
1070 d += 1 * data_stride;
1071 n_left -= 1;
1072 }
1073 }
1074}
1075
Damjan Marion4a251d02021-05-06 17:28:12 +02001076__clib_export void
1077unserialize_multiple_2 (serialize_main_t *m, void *data, uword data_stride,
1078 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001079{
Dave Barachc3799992016-08-15 11:12:27 -04001080 void *d = data;
1081 u16 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001082 uword n_left = n_data;
1083
1084 while (n_left >= 4)
1085 {
1086 p = unserialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -04001087 clib_mem_unaligned (d + 0 * data_stride, u16) =
1088 clib_net_to_host_mem_u16 (p + 0);
1089 clib_mem_unaligned (d + 1 * data_stride, u16) =
1090 clib_net_to_host_mem_u16 (p + 1);
1091 clib_mem_unaligned (d + 2 * data_stride, u16) =
1092 clib_net_to_host_mem_u16 (p + 2);
1093 clib_mem_unaligned (d + 3 * data_stride, u16) =
1094 clib_net_to_host_mem_u16 (p + 3);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001095 n_left -= 4;
1096 d += 4 * data_stride;
1097 }
1098
1099 if (n_left > 0)
1100 {
1101 p = unserialize_get (m, n_left * sizeof (p[0]));
1102 while (n_left > 0)
1103 {
Dave Barachc3799992016-08-15 11:12:27 -04001104 clib_mem_unaligned (d + 0 * data_stride, u16) =
1105 clib_net_to_host_mem_u16 (p + 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001106 p += 1;
1107 d += 1 * data_stride;
1108 n_left -= 1;
1109 }
1110 }
1111}
1112
Damjan Marion4a251d02021-05-06 17:28:12 +02001113__clib_export void
1114unserialize_multiple_4 (serialize_main_t *m, void *data, uword data_stride,
1115 uword n_data)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001116{
Dave Barachc3799992016-08-15 11:12:27 -04001117 void *d = data;
1118 u32 *p;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001119 uword n_left = n_data;
1120
1121 while (n_left >= 4)
1122 {
1123 p = unserialize_get (m, 4 * sizeof (p[0]));
Dave Barachc3799992016-08-15 11:12:27 -04001124 clib_mem_unaligned (d + 0 * data_stride, u32) =
1125 clib_net_to_host_mem_u32 (p + 0);
1126 clib_mem_unaligned (d + 1 * data_stride, u32) =
1127 clib_net_to_host_mem_u32 (p + 1);
1128 clib_mem_unaligned (d + 2 * data_stride, u32) =
1129 clib_net_to_host_mem_u32 (p + 2);
1130 clib_mem_unaligned (d + 3 * data_stride, u32) =
1131 clib_net_to_host_mem_u32 (p + 3);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001132 n_left -= 4;
1133 d += 4 * data_stride;
1134 }
1135
1136 if (n_left > 0)
1137 {
1138 p = unserialize_get (m, n_left * sizeof (p[0]));
1139 while (n_left > 0)
1140 {
Dave Barachc3799992016-08-15 11:12:27 -04001141 clib_mem_unaligned (d + 0 * data_stride, u32) =
1142 clib_net_to_host_mem_u32 (p + 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001143 p += 1;
1144 d += 1 * data_stride;
1145 n_left -= 1;
1146 }
1147 }
1148}
1149
1150#ifdef CLIB_UNIX
1151
1152#include <unistd.h>
1153#include <fcntl.h>
1154
Dave Barachc3799992016-08-15 11:12:27 -04001155static void
Dave Barach59b25652017-09-10 15:04:27 -04001156clib_file_write (serialize_main_header_t * m, serialize_stream_t * s)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001157{
1158 int fd, n;
1159
1160 fd = s->data_function_opaque;
1161 n = write (fd, s->buffer, s->current_buffer_index);
1162 if (n < 0)
1163 {
Dave Barachc3799992016-08-15 11:12:27 -04001164 if (!unix_error_is_fatal (errno))
Ed Warnickecb9cada2015-12-08 15:45:58 -07001165 n = 0;
1166 else
1167 serialize_error (m, clib_error_return_unix (0, "write"));
1168 }
1169 if (n == s->current_buffer_index)
Damjan Marion8bea5892022-04-04 22:40:45 +02001170 vec_set_len (s->buffer, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001171 else
1172 vec_delete (s->buffer, n, 0);
1173 s->current_buffer_index = vec_len (s->buffer);
1174}
1175
Dave Barachc3799992016-08-15 11:12:27 -04001176static void
Dave Barach59b25652017-09-10 15:04:27 -04001177clib_file_read (serialize_main_header_t * m, serialize_stream_t * s)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001178{
1179 int fd, n;
1180
1181 fd = s->data_function_opaque;
1182 n = read (fd, s->buffer, vec_len (s->buffer));
1183 if (n < 0)
1184 {
Dave Barachc3799992016-08-15 11:12:27 -04001185 if (!unix_error_is_fatal (errno))
Ed Warnickecb9cada2015-12-08 15:45:58 -07001186 n = 0;
1187 else
1188 serialize_error (m, clib_error_return_unix (0, "read"));
1189 }
1190 else if (n == 0)
1191 serialize_stream_set_end_of_stream (s);
1192 s->current_buffer_index = 0;
1193 s->n_buffer_bytes = n;
1194}
1195
1196static void
Dave Barach59b25652017-09-10 15:04:27 -04001197serialize_open_clib_file_descriptor_helper (serialize_main_t * m, int fd,
Dave Barachc3799992016-08-15 11:12:27 -04001198 uword is_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001199{
Dave Barachb7b92992018-10-17 10:38:51 -04001200 clib_memset (m, 0, sizeof (m[0]));
Ed Warnickecb9cada2015-12-08 15:45:58 -07001201 vec_resize (m->stream.buffer, 4096);
Dave Barachc3799992016-08-15 11:12:27 -04001202
1203 if (!is_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001204 {
1205 m->stream.n_buffer_bytes = vec_len (m->stream.buffer);
Damjan Marion8bea5892022-04-04 22:40:45 +02001206 vec_set_len (m->stream.buffer, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001207 }
1208
Dave Barach59b25652017-09-10 15:04:27 -04001209 m->header.data_function = is_read ? clib_file_read : clib_file_write;
Ed Warnickecb9cada2015-12-08 15:45:58 -07001210 m->stream.data_function_opaque = fd;
1211}
1212
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001213__clib_export void
Dave Barach59b25652017-09-10 15:04:27 -04001214serialize_open_clib_file_descriptor (serialize_main_t * m, int fd)
Dave Barachc3799992016-08-15 11:12:27 -04001215{
Dave Barach59b25652017-09-10 15:04:27 -04001216 serialize_open_clib_file_descriptor_helper (m, fd, /* is_read */ 0);
Dave Barachc3799992016-08-15 11:12:27 -04001217}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001218
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001219__clib_export void
Dave Barach59b25652017-09-10 15:04:27 -04001220unserialize_open_clib_file_descriptor (serialize_main_t * m, int fd)
Dave Barachc3799992016-08-15 11:12:27 -04001221{
Dave Barach59b25652017-09-10 15:04:27 -04001222 serialize_open_clib_file_descriptor_helper (m, fd, /* is_read */ 1);
Dave Barachc3799992016-08-15 11:12:27 -04001223}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001224
1225static clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -04001226serialize_open_clib_file_helper (serialize_main_t * m, char *file,
Dave Barachc3799992016-08-15 11:12:27 -04001227 uword is_read)
Ed Warnickecb9cada2015-12-08 15:45:58 -07001228{
1229 int fd, mode;
1230
1231 mode = is_read ? O_RDONLY : O_RDWR | O_CREAT | O_TRUNC;
1232 fd = open (file, mode, 0666);
1233 if (fd < 0)
1234 return clib_error_return_unix (0, "open `%s'", file);
1235
Dave Barach59b25652017-09-10 15:04:27 -04001236 serialize_open_clib_file_descriptor_helper (m, fd, is_read);
Ed Warnickecb9cada2015-12-08 15:45:58 -07001237 return 0;
1238}
1239
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001240__clib_export clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -04001241serialize_open_clib_file (serialize_main_t * m, char *file)
Dave Barachc3799992016-08-15 11:12:27 -04001242{
Dave Barach59b25652017-09-10 15:04:27 -04001243 return serialize_open_clib_file_helper (m, file, /* is_read */ 0);
Dave Barachc3799992016-08-15 11:12:27 -04001244}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001245
Damjan Mariondae1c7e2020-10-17 13:32:25 +02001246__clib_export clib_error_t *
Dave Barach59b25652017-09-10 15:04:27 -04001247unserialize_open_clib_file (serialize_main_t * m, char *file)
Dave Barachc3799992016-08-15 11:12:27 -04001248{
Dave Barach59b25652017-09-10 15:04:27 -04001249 return serialize_open_clib_file_helper (m, file, /* is_read */ 1);
Dave Barachc3799992016-08-15 11:12:27 -04001250}
Ed Warnickecb9cada2015-12-08 15:45:58 -07001251
1252#endif /* CLIB_UNIX */
Dave Barachc3799992016-08-15 11:12:27 -04001253
1254/*
1255 * fd.io coding-style-patch-verification: ON
1256 *
1257 * Local Variables:
1258 * eval: (c-set-style "gnu")
1259 * End:
1260 */