FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
serialize.h
Go to the documentation of this file.
1 /*
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 #ifndef included_clib_serialize_h
39 #define included_clib_serialize_h
40 
41 #include <stdarg.h>
42 #include <vppinfra/byte_order.h>
43 #include <vppinfra/types.h>
44 #include <vppinfra/vec.h>
45 #include <vppinfra/longjmp.h>
46 
48 struct serialize_stream_t;
49 
51  struct serialize_stream_t * s);
52 
53 typedef struct serialize_stream_t
54 {
55  /* Current data buffer being serialized/unserialized. */
57 
58  /* Size of buffer in bytes. */
60 
61  /* Current index into buffer. */
63 
64  /* Overflow buffer for when there is not enough room at the end of
65  buffer to hold serialized/unserialized data. */
67 
68  /* Current index in overflow buffer for reads. */
70 
72 #define SERIALIZE_END_OF_STREAM (1 << 0)
73 
75 
76  u32 opaque[64 - 4 * sizeof (u32) - 1 * sizeof (uword) -
77  2 * sizeof (void *)];
79 
80 always_inline void
82 {
84 }
85 
88 {
89  return (s->flags & SERIALIZE_END_OF_STREAM) != 0;
90 }
91 
93 {
95 
96  /* Data callback function and opaque data. */
98 
99  /* Error if signaled by data function. */
101 
102  /* Exit unwind point if error occurs. */
105 
106 always_inline void
108 {
110 }
111 
112 #define serialize_error_return(m,args...) \
113  serialize_error (&(m)->header, clib_error_return (0, args))
114 
116  serialize_stream_t * s,
118 
119 #define SERIALIZE_FLAG_IS_READ (1 << 0)
120 #define SERIALIZE_FLAG_IS_WRITE (1 << 1)
121 
122 always_inline void *
124  serialize_stream_t * s,
126 {
127  uword i, j, l;
128 
129  l = vec_len (s->overflow_buffer);
130  i = s->current_buffer_index;
131  j = i + n_bytes;
132  s->current_buffer_index = j;
133  if (l == 0 && j <= s->n_buffer_bytes)
134  {
135  return s->buffer + i;
136  }
137  else
138  {
139  s->current_buffer_index = i;
140  return serialize_read_write_not_inline (header, s, n_bytes, flags);
141  }
142 }
143 
144 typedef struct
145 {
149 
150 always_inline void
152 {
154 }
155 
158 {
160 }
161 
162 typedef struct
163 {
167 
168 typedef void (serialize_function_t) (serialize_main_t * m, va_list * va);
169 
170 always_inline void *
172 {
175 }
176 
177 always_inline void *
179 {
182 }
183 
184 always_inline void
186 {
187  u8 *p = serialize_get (m, n_bytes);
188  if (n_bytes == 1)
189  p[0] = x;
190  else if (n_bytes == 2)
191  clib_mem_unaligned (p, u16) = clib_host_to_net_u16 (x);
192  else if (n_bytes == 4)
193  clib_mem_unaligned (p, u32) = clib_host_to_net_u32 (x);
194  else if (n_bytes == 8)
195  clib_mem_unaligned (p, u64) = clib_host_to_net_u64 (x);
196  else
197  ASSERT (0);
198 }
199 
200 always_inline void
202 {
203  u8 *p = unserialize_get (m, n_bytes);
204  if (n_bytes == 1)
205  *(u8 *) x = p[0];
206  else if (n_bytes == 2)
207  *(u16 *) x = clib_net_to_host_unaligned_mem_u16 ((u16 *) p);
208  else if (n_bytes == 4)
209  *(u32 *) x = clib_net_to_host_unaligned_mem_u32 ((u32 *) p);
210  else if (n_bytes == 8)
211  *(u64 *) x = clib_net_to_host_unaligned_mem_u64 ((u64 *) p);
212  else
213  ASSERT (0);
214 }
215 
216 /* As above but tries to be more compact. */
217 always_inline void
219 {
220  u64 r = x;
221  u8 *p;
222 
223  /* Low bit set means it fits into 1 byte. */
224  if (r < (1 << 7))
225  {
226  p = serialize_get (m, 1);
227  p[0] = 1 + 2 * r;
228  return;
229  }
230 
231  /* Low 2 bits 1 0 means it fits into 2 bytes. */
232  r -= (1 << 7);
233  if (r < (1 << 14))
234  {
235  p = serialize_get (m, 2);
236  clib_mem_unaligned (p, u16) = clib_host_to_little_u16 (4 * r + 2);
237  return;
238  }
239 
240  r -= (1 << 14);
241  if (r < (1 << 29))
242  {
243  p = serialize_get (m, 4);
244  clib_mem_unaligned (p, u32) = clib_host_to_little_u32 (8 * r + 4);
245  return;
246  }
247 
248  p = serialize_get (m, 9);
249  p[0] = 0; /* Only low 3 bits are used. */
250  clib_mem_unaligned (p + 1, u64) = clib_host_to_little_u64 (x);
251 }
252 
255 {
256  u8 *p = unserialize_get (m, 1);
257  u64 r;
258  u32 y = p[0];
259 
260  if (y & 1)
261  return y / 2;
262 
263  r = 1 << 7;
264  if (y & 2)
265  {
266  p = unserialize_get (m, 1);
267  r += (y / 4) + (p[0] << 6);
268  return r;
269  }
270 
271  r += 1 << 14;
272  if (y & 4)
273  {
274  p = unserialize_get (m, 3);
275  r += ((y / 8)
276  + (p[0] << (5 + 8 * 0))
277  + (p[1] << (5 + 8 * 1)) + (p[2] << (5 + 8 * 2)));
278  return r;
279  }
280 
281  p = unserialize_get (m, 8);
282  r = clib_mem_unaligned (p, u64);
283  r = clib_little_to_host_u64 (r);
284 
285  return r;
286 }
287 
288 always_inline void
290 {
291  u64 u = s < 0 ? -(2 * s + 1) : 2 * s;
293 }
294 
297 {
299  i64 s = u / 2;
300  return (u & 1) ? -s : s;
301 }
302 
303 void
305  void *data, uword data_stride, uword n_data);
306 void
308  void *data, uword data_stride, uword n_data);
309 void
311  void *data, uword data_stride, uword n_data);
312 
313 void
315  void *data, uword data_stride, uword n_data);
316 void
318  void *data, uword data_stride, uword n_data);
319 void
321  void *data, uword data_stride, uword n_data);
322 
323 always_inline void
325  void *data,
326  uword n_data_bytes, uword data_stride, uword n_data)
327 {
328  if (n_data_bytes == 1)
329  serialize_multiple_1 (m, data, data_stride, n_data);
330  else if (n_data_bytes == 2)
331  serialize_multiple_2 (m, data, data_stride, n_data);
332  else if (n_data_bytes == 4)
333  serialize_multiple_4 (m, data, data_stride, n_data);
334  else
335  ASSERT (0);
336 }
337 
338 always_inline void
340  void *data,
341  uword n_data_bytes, uword data_stride, uword n_data)
342 {
343  if (n_data_bytes == 1)
344  unserialize_multiple_1 (m, data, data_stride, n_data);
345  else if (n_data_bytes == 2)
346  unserialize_multiple_2 (m, data, data_stride, n_data);
347  else if (n_data_bytes == 4)
348  unserialize_multiple_4 (m, data, data_stride, n_data);
349  else
350  ASSERT (0);
351 }
352 
353 /* Basic types. */
360 
361 /* Basic vector types. */
366 
367 /* Serialize generic vectors. */
370 
371 #define vec_serialize(m,v,f) \
372  serialize ((m), serialize_vector, (v), sizeof ((v)[0]), (f))
373 
374 #define vec_unserialize(m,v,f) \
375  unserialize ((m), unserialize_vector, (v), sizeof ((*(v))[0]), (f))
376 
377 #define vec_unserialize_aligned(m,v,f) \
378  unserialize ((m), unserialize_aligned_vector, (v), sizeof ((*(v))[0]), (f))
379 
380 /* Serialize pools. */
383 
384 #define pool_serialize(m,v,f) \
385  serialize ((m), serialize_pool, (v), sizeof ((v)[0]), (f))
386 
387 #define pool_unserialize(m,v,f) \
388  unserialize ((m), unserialize_pool, (v), sizeof ((*(v))[0]), (f))
389 
390 #define pool_unserialize_aligned(m,v,a,f) \
391  unserialize ((m), unserialize_aligned_pool, (v), sizeof ((*(v))[0]), (a), (f))
392 
393 /* Serialize heaps. */
395 
398 
399 void serialize_cstring (serialize_main_t * m, char *string);
400 void unserialize_cstring (serialize_main_t * m, char **string);
401 
404 
406  uword n_data_bytes);
408  uword n_data_bytes);
409 
410 /* Starts serialization with expanding vector as buffer. */
411 void serialize_open_vector (serialize_main_t * m, u8 * vector);
412 
413 /* Serialization is done: returns vector buffer to caller. */
415 
416 void unserialize_open_vector (serialize_main_t * m, u8 * vector);
417 
418 #ifdef CLIB_UNIX
421 
424 #endif /* CLIB_UNIX */
425 
426 /* Main routines. */
429 clib_error_t *va_serialize (serialize_main_t * m, va_list * va);
430 
431 void serialize_magic (serialize_main_t * m, void *magic, u32 magic_bytes);
432 void unserialize_check_magic (serialize_main_t * m, void *magic,
433  u32 magic_bytes);
434 
435 #endif /* included_clib_serialize_h */
436 
437 /*
438  * fd.io coding-style-patch-verification: ON
439  *
440  * Local Variables:
441  * eval: (c-set-style "gnu")
442  * End:
443  */
serialize_main_header_t
Definition: serialize.h:92
serialize_vec_8
serialize_function_t serialize_vec_8
Definition: serialize.h:362
unserialize_multiple_4
void unserialize_multiple_4(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1109
unserialize_heap
serialize_function_t unserialize_heap
Definition: serialize.h:394
unserialize_vec_64
serialize_function_t unserialize_vec_64
Definition: serialize.h:365
serialize_stream_t::buffer
u8 * buffer
Definition: serialize.h:56
serialize_vec_64
serialize_function_t serialize_vec_64
Definition: serialize.h:365
unserialize_check_magic
void unserialize_check_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
Definition: serialize.c:634
serialize_open_clib_file_descriptor
void serialize_open_clib_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1209
serialize_integer
static void serialize_integer(serialize_main_t *m, u64 x, u32 n_bytes)
Definition: serialize.h:185
unserialize_aligned_vector
serialize_function_t unserialize_aligned_vector
Definition: serialize.h:369
serialize_data_function_t
void() serialize_data_function_t(struct serialize_main_header_t *h, struct serialize_stream_t *s)
Definition: serialize.h:50
serialize_stream_t
struct serialize_stream_t serialize_stream_t
unserialize_vec_8
serialize_function_t unserialize_vec_8
Definition: serialize.h:362
serialize_main_header_t::recursion_level
u32 recursion_level
Definition: serialize.h:94
serialize_main_t::header
serialize_main_header_t header
Definition: serialize.h:146
serialize_close
void serialize_close(serialize_main_t *m)
Definition: serialize.c:870
serialize_8
serialize_function_t serialize_8
Definition: serialize.h:357
serialize_stream_t::flags
u32 flags
Definition: serialize.h:71
serialize_vector
serialize_function_t serialize_vector
Definition: serialize.h:368
unserialize_open_vector
void unserialize_open_vector(serialize_main_t *m, u8 *vector)
serialize_multiple_2
void serialize_multiple_2(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:966
types.h
unserialize
clib_error_t * unserialize(serialize_main_t *m,...)
Definition: serialize.c:684
unserialize_vec_16
serialize_function_t unserialize_vec_16
Definition: serialize.h:363
pointer_to_uword
static uword pointer_to_uword(const void *p)
Definition: types.h:131
serialize_stream_set_end_of_stream
static void serialize_stream_set_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:81
serialize_multiple
static void serialize_multiple(serialize_main_t *m, void *data, uword n_data_bytes, uword data_stride, uword n_data)
Definition: serialize.h:324
serialize_multiple_main_t
Definition: serialize.h:162
serialize_open_vector
void serialize_open_vector(serialize_main_t *m, u8 *vector)
Definition: serialize.c:909
serialize_stream_is_end_of_stream
static uword serialize_stream_is_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:87
serialize_function_t
void() serialize_function_t(serialize_main_t *m, va_list *va)
Definition: serialize.h:168
unserialize_multiple
static void unserialize_multiple(serialize_main_t *m, void *data, uword n_data_bytes, uword data_stride, uword n_data)
Definition: serialize.h:339
serialize_stream_t::current_buffer_index
u32 current_buffer_index
Definition: serialize.h:62
u16
unsigned short u16
Definition: types.h:57
byte_order.h
SERIALIZE_FLAG_IS_WRITE
#define SERIALIZE_FLAG_IS_WRITE
Definition: serialize.h:120
unserialize_f32
serialize_function_t unserialize_f32
Definition: serialize.h:359
unserialize_get
static void * unserialize_get(serialize_main_t *m, uword n_bytes)
Definition: serialize.h:171
unserialize_multiple_1
void unserialize_multiple_1(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1040
serialize_open_data
void serialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:883
serialize_bitmap
void serialize_bitmap(serialize_main_t *m, uword *b)
Definition: serialize.c:359
serialize_main_t
Definition: serialize.h:144
unserialize_close
void unserialize_close(serialize_main_t *m)
Definition: serialize.c:877
va_serialize
clib_error_t * va_serialize(serialize_main_t *m, va_list *va)
Definition: serialize.c:651
r
vnet_hw_if_output_node_runtime_t * r
Definition: interface_output.c:1071
serialize_multiple_main_t::streams
serialize_stream_t * streams
Definition: serialize.h:165
unserialize_16
serialize_function_t unserialize_16
Definition: serialize.h:356
serialize_error
static void serialize_error(serialize_main_header_t *m, clib_error_t *error)
Definition: serialize.h:107
serialize_magic
void serialize_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
Definition: serialize.c:625
h
h
Definition: flowhash_template.h:372
error
Definition: cJSON.c:88
i64
signed long i64
Definition: types.h:78
unserialize_cstring
void unserialize_cstring(serialize_main_t *m, char **string)
Definition: serialize.c:178
longjmp.h
clib_longjmp
void clib_longjmp(clib_longjmp_t *save, uword return_value)
unserialize_multiple_2
void unserialize_multiple_2(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1072
unserialize_64
serialize_function_t unserialize_64
Definition: serialize.h:354
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
serialize_f32
serialize_function_t serialize_f32
Definition: serialize.h:359
serialize_set_end_of_stream
static void serialize_set_end_of_stream(serialize_main_t *m)
Definition: serialize.h:151
SERIALIZE_FLAG_IS_READ
#define SERIALIZE_FLAG_IS_READ
Definition: serialize.h:119
serialize_main_header_t::error
clib_error_t * error
Definition: serialize.h:100
serialize_likely_small_unsigned_integer
static void serialize_likely_small_unsigned_integer(serialize_main_t *m, u64 x)
Definition: serialize.h:218
serialize_multiple_4
void serialize_multiple_4(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1003
unserialize_integer
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
Definition: serialize.h:201
serialize_vec_32
serialize_function_t serialize_vec_32
Definition: serialize.h:364
uword
u64 uword
Definition: types.h:112
serialize_heap
serialize_function_t serialize_heap
Definition: serialize.h:394
clib_mem_unaligned
#define clib_mem_unaligned(pointer, type)
Definition: types.h:155
serialize_stream_t::n_buffer_bytes
u32 n_buffer_bytes
Definition: serialize.h:59
serialize_open_clib_file
clib_error_t * serialize_open_clib_file(serialize_main_t *m, char *file)
Definition: serialize.c:1236
serialize_stream_t::current_overflow_index
u32 current_overflow_index
Definition: serialize.h:69
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
serialize_main_t::stream
serialize_stream_t stream
Definition: serialize.h:147
unserialize_likely_small_signed_integer
static i64 unserialize_likely_small_signed_integer(serialize_main_t *m)
Definition: serialize.h:296
serialize_f64
serialize_function_t serialize_f64
Definition: serialize.h:358
serialize
clib_error_t * serialize(serialize_main_t *m,...)
Definition: serialize.c:672
unserialize_aligned_pool
serialize_function_t unserialize_aligned_pool
Definition: serialize.h:382
data
u8 data[128]
Definition: ipsec_types.api:92
unserialize_bitmap
uword * unserialize_bitmap(serialize_main_t *m)
Definition: serialize.c:377
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
serialize_stream_t::data_function_opaque
uword data_function_opaque
Definition: serialize.h:74
u64
unsigned long u64
Definition: types.h:89
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
serialize_is_end_of_stream
static uword serialize_is_end_of_stream(serialize_main_t *m)
Definition: serialize.h:157
u32
unsigned int u32
Definition: types.h:88
serialize_main_header_t::error_longjmp
clib_longjmp_t error_longjmp
Definition: serialize.h:103
n_bytes
u32 n_bytes
Definition: interface_output.c:401
unserialize_open_data
void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:891
unserialize_8
serialize_function_t unserialize_8
Definition: serialize.h:357
unserialize_vec_32
serialize_function_t unserialize_vec_32
Definition: serialize.h:364
vec.h
unserialize_open_clib_file
clib_error_t * unserialize_open_clib_file(serialize_main_t *m, char *file)
Definition: serialize.c:1242
SERIALIZE_END_OF_STREAM
#define SERIALIZE_END_OF_STREAM
Definition: serialize.h:72
serialize_multiple_main_t::header
serialize_main_header_t header
Definition: serialize.h:164
serialize_likely_small_signed_integer
static void serialize_likely_small_signed_integer(serialize_main_t *m, i64 s)
Definition: serialize.h:289
b
vlib_buffer_t ** b
Definition: nat44_ei_out2in.c:717
u8
unsigned char u8
Definition: types.h:56
serialize_64
serialize_function_t serialize_64
Definition: serialize.h:354
clib_error_t
Definition: clib_error.h:21
serialize_stream_t::overflow_buffer
u8 * overflow_buffer
Definition: serialize.h:66
unserialize_32
serialize_function_t unserialize_32
Definition: serialize.h:355
serialize_stream_read_write
static void * serialize_stream_read_write(serialize_main_header_t *header, serialize_stream_t *s, uword n_bytes, uword flags)
Definition: serialize.h:123
serialize_stream_t::opaque
u32 opaque[64 - 4 *sizeof(u32) - 1 *sizeof(uword) - 2 *sizeof(void *)]
Definition: serialize.h:77
unserialize_likely_small_unsigned_integer
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
Definition: serialize.h:254
serialize_vec_16
serialize_function_t serialize_vec_16
Definition: serialize.h:363
serialize_32
serialize_function_t serialize_32
Definition: serialize.h:355
serialize_read_write_not_inline
void * serialize_read_write_not_inline(serialize_main_header_t *m, serialize_stream_t *s, uword n_bytes, uword flags)
Definition: serialize.c:842
serialize_cstring
void serialize_cstring(serialize_main_t *m, char *string)
Definition: serialize.c:164
serialize_main_header_t::data_function
serialize_data_function_t * data_function
Definition: serialize.h:97
unserialize_vector
serialize_function_t unserialize_vector
Definition: serialize.h:368
serialize_16
serialize_function_t serialize_16
Definition: serialize.h:356
serialize_main_header_t
struct serialize_main_header_t serialize_main_header_t
serialize_get
static void * serialize_get(serialize_main_t *m, uword n_bytes)
Definition: serialize.h:178
unserialize_open_clib_file_descriptor
void unserialize_open_clib_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1215
serialize_stream_t
Definition: serialize.h:53
serialize_close_vector
void * serialize_close_vector(serialize_main_t *m)
Definition: serialize.c:919
unserialize_f64
serialize_function_t unserialize_f64
Definition: serialize.h:358
serialize_multiple_1
void serialize_multiple_1(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:934
unserialize_pool
serialize_function_t unserialize_pool
Definition: serialize.h:381
serialize_pool
serialize_function_t serialize_pool
Definition: serialize.h:381
clib_longjmp_t
Definition: longjmp.h:102
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105