Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2016 Nicira, Inc.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at:
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include <config.h>
18 : : #include "openvswitch/ofpbuf.h"
19 : : #include <stdlib.h>
20 : : #include <string.h>
21 : : #include "openvswitch/dynamic-string.h"
22 : : #include "netdev-dpdk.h"
23 : : #include "util.h"
24 : :
25 : : static void
26 : 1719884 : ofpbuf_init__(struct ofpbuf *b, size_t allocated, enum ofpbuf_source source)
27 : : {
28 : 1719884 : b->allocated = allocated;
29 : 1719884 : b->source = source;
30 : 1719884 : b->header = NULL;
31 : 1719884 : b->msg = NULL;
32 : 1719884 : ovs_list_poison(&b->list_node);
33 : 1719878 : }
34 : :
35 : : static void
36 : 1719893 : ofpbuf_use__(struct ofpbuf *b, void *base, size_t allocated, size_t size,
37 : : enum ofpbuf_source source)
38 : : {
39 : 1719893 : b->base = base;
40 : 1719893 : b->data = base;
41 : 1719893 : b->size = size;
42 : :
43 : 1719893 : ofpbuf_init__(b, allocated, source);
44 : 1719877 : }
45 : :
46 : : /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of
47 : : * memory starting at 'base'. 'base' should be the first byte of a region
48 : : * obtained from malloc(). It will be freed (with free()) if 'b' is resized or
49 : : * freed. */
50 : : static void
51 : 325743 : ofpbuf_use(struct ofpbuf *b, void *base, size_t allocated)
52 : : {
53 : 325743 : ofpbuf_use__(b, base, allocated, 0, OFPBUF_MALLOC);
54 : 325743 : }
55 : :
56 : : /* Converts ds into ofpbuf 'b'. 'b' contains the 'ds->allocated' bytes of
57 : : * memory starting at 'ds->string'. 'ds' should not be modified any more.
58 : : * The memory allocated for 'ds' will be freed (with free()) if 'b' is
59 : : * resized or freed. */
60 : : void
61 : 94326 : ofpbuf_use_ds(struct ofpbuf *b, const struct ds *ds)
62 : : {
63 : 94326 : ofpbuf_use__(b, ds->string, ds->allocated + 1, ds->length, OFPBUF_MALLOC);
64 : 94326 : }
65 : :
66 : : /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of
67 : : * memory starting at 'base'. 'base' should point to a buffer on the stack.
68 : : * (Nothing actually relies on 'base' being allocated on the stack. It could
69 : : * be static or malloc()'d memory. But stack space is the most common use
70 : : * case.)
71 : : *
72 : : * 'base' should be appropriately aligned. Using an array of uint32_t or
73 : : * uint64_t for the buffer is a reasonable way to ensure appropriate alignment
74 : : * for 32- or 64-bit data.
75 : : *
76 : : * An ofpbuf operation that requires reallocating data will assert-fail if this
77 : : * function was used to initialize it. Thus, one need not call ofpbuf_uninit()
78 : : * on an ofpbuf initialized by this function (though doing so is harmless),
79 : : * because it is guaranteed that 'b' does not own any heap-allocated memory. */
80 : : void
81 : 376459 : ofpbuf_use_stack(struct ofpbuf *b, void *base, size_t allocated)
82 : : {
83 : 376459 : ofpbuf_use__(b, base, allocated, 0, OFPBUF_STACK);
84 : 376459 : }
85 : :
86 : : /* Initializes 'b' as an empty ofpbuf that contains the 'allocated' bytes of
87 : : * memory starting at 'base'. 'base' should point to a buffer on the stack.
88 : : * (Nothing actually relies on 'base' being allocated on the stack. It could
89 : : * be static or malloc()'d memory. But stack space is the most common use
90 : : * case.)
91 : : *
92 : : * 'base' should be appropriately aligned. Using an array of uint32_t or
93 : : * uint64_t for the buffer is a reasonable way to ensure appropriate alignment
94 : : * for 32- or 64-bit data.
95 : : *
96 : : * An ofpbuf operation that requires reallocating data will copy the provided
97 : : * buffer into a malloc()'d buffer. Thus, it is wise to call ofpbuf_uninit()
98 : : * on an ofpbuf initialized by this function, so that if it expanded into the
99 : : * heap, that memory is freed. */
100 : : void
101 : 780778 : ofpbuf_use_stub(struct ofpbuf *b, void *base, size_t allocated)
102 : : {
103 : 780778 : ofpbuf_use__(b, base, allocated, 0, OFPBUF_STUB);
104 : 780777 : }
105 : :
106 : : /* Initializes 'b' as an ofpbuf whose data starts at 'data' and continues for
107 : : * 'size' bytes. This is appropriate for an ofpbuf that will be used to
108 : : * inspect existing data, without moving it around or reallocating it, and
109 : : * generally without modifying it at all.
110 : : *
111 : : * An ofpbuf operation that requires reallocating data will assert-fail if this
112 : : * function was used to initialize it. */
113 : : void
114 : 142591 : ofpbuf_use_const(struct ofpbuf *b, const void *data, size_t size)
115 : : {
116 : 142591 : ofpbuf_use__(b, CONST_CAST(void *, data), size, size, OFPBUF_STACK);
117 : 142591 : }
118 : :
119 : : /* Initializes 'b' as an empty ofpbuf with an initial capacity of 'size'
120 : : * bytes. */
121 : : void
122 : 325743 : ofpbuf_init(struct ofpbuf *b, size_t size)
123 : : {
124 [ + + ]: 325743 : ofpbuf_use(b, size ? xmalloc(size) : NULL, size);
125 : 325743 : }
126 : :
127 : : /* Frees memory that 'b' points to. */
128 : : void
129 : 18310296 : ofpbuf_uninit(struct ofpbuf *b)
130 : : {
131 [ + + ]: 18310296 : if (b) {
132 [ + + ]: 18307165 : if (b->source == OFPBUF_MALLOC) {
133 : 458043 : free(b->base);
134 : : }
135 : : }
136 : 18310296 : }
137 : :
138 : : /* Frees memory that 'b' points to and allocates a new ofpbuf */
139 : : void
140 : 0 : ofpbuf_reinit(struct ofpbuf *b, size_t size)
141 : : {
142 : 0 : ofpbuf_uninit(b);
143 : 0 : ofpbuf_init(b, size);
144 : 0 : }
145 : :
146 : : /* Creates and returns a new ofpbuf with an initial capacity of 'size'
147 : : * bytes. */
148 : : struct ofpbuf *
149 : 190277 : ofpbuf_new(size_t size)
150 : : {
151 : 190277 : struct ofpbuf *b = xmalloc(sizeof *b);
152 : 190277 : ofpbuf_init(b, size);
153 : 190277 : return b;
154 : : }
155 : :
156 : : /* Creates and returns a new ofpbuf with an initial capacity of 'size +
157 : : * headroom' bytes, reserving the first 'headroom' bytes as headroom. */
158 : : struct ofpbuf *
159 : 7412 : ofpbuf_new_with_headroom(size_t size, size_t headroom)
160 : : {
161 : 7412 : struct ofpbuf *b = ofpbuf_new(size + headroom);
162 : 7412 : ofpbuf_reserve(b, headroom);
163 : 7412 : return b;
164 : : }
165 : :
166 : : /* Creates and returns a new ofpbuf that initially contains a copy of the
167 : : * 'buffer->size' bytes of data starting at 'buffer->data' with no headroom or
168 : : * tailroom. */
169 : : struct ofpbuf *
170 : 7173 : ofpbuf_clone(const struct ofpbuf *buffer)
171 : : {
172 : 7173 : return ofpbuf_clone_with_headroom(buffer, 0);
173 : : }
174 : :
175 : : /* Creates and returns a new ofpbuf whose data are copied from 'buffer'. The
176 : : * returned ofpbuf will additionally have 'headroom' bytes of headroom. */
177 : : struct ofpbuf *
178 : 7173 : ofpbuf_clone_with_headroom(const struct ofpbuf *b, size_t headroom)
179 : : {
180 : : struct ofpbuf *new_buffer;
181 : :
182 : 7173 : new_buffer = ofpbuf_clone_data_with_headroom(b->data, b->size, headroom);
183 [ - + ]: 7173 : if (b->header) {
184 : 0 : ptrdiff_t header_offset = (char *) b->header - (char *) b->data;
185 : :
186 : 0 : new_buffer->header = (char *) new_buffer->data + header_offset;
187 : : }
188 [ - + ]: 7173 : if (b->msg) {
189 : 0 : ptrdiff_t msg_offset = (char *) b->msg - (char *) b->data;
190 : :
191 : 0 : new_buffer->msg = (char *) new_buffer->data + msg_offset;
192 : : }
193 : :
194 : 7173 : return new_buffer;
195 : : }
196 : :
197 : : /* Creates and returns a new ofpbuf that initially contains a copy of the
198 : : * 'size' bytes of data starting at 'data' with no headroom or tailroom. */
199 : : struct ofpbuf *
200 : 239 : ofpbuf_clone_data(const void *data, size_t size)
201 : : {
202 : 239 : return ofpbuf_clone_data_with_headroom(data, size, 0);
203 : : }
204 : :
205 : : /* Creates and returns a new ofpbuf that initially contains 'headroom' bytes of
206 : : * headroom followed by a copy of the 'size' bytes of data starting at
207 : : * 'data'. */
208 : : struct ofpbuf *
209 : 7412 : ofpbuf_clone_data_with_headroom(const void *data, size_t size, size_t headroom)
210 : : {
211 : 7412 : struct ofpbuf *b = ofpbuf_new_with_headroom(size, headroom);
212 : 7412 : ofpbuf_put(b, data, size);
213 : 7412 : return b;
214 : : }
215 : :
216 : : static void
217 : 85544 : ofpbuf_copy__(struct ofpbuf *b, uint8_t *new_base,
218 : : size_t new_headroom, size_t new_tailroom)
219 : : {
220 : 85544 : const uint8_t *old_base = b->base;
221 : 85544 : size_t old_headroom = ofpbuf_headroom(b);
222 : 85544 : size_t old_tailroom = ofpbuf_tailroom(b);
223 : 85544 : size_t copy_headroom = MIN(old_headroom, new_headroom);
224 : 85544 : size_t copy_tailroom = MIN(old_tailroom, new_tailroom);
225 : :
226 : 171088 : memcpy(&new_base[new_headroom - copy_headroom],
227 : 85544 : &old_base[old_headroom - copy_headroom],
228 : 85544 : copy_headroom + b->size + copy_tailroom);
229 : 85544 : }
230 : :
231 : : /* Reallocates 'b' so that it has exactly 'new_headroom' and 'new_tailroom'
232 : : * bytes of headroom and tailroom, respectively. */
233 : : static void
234 : 537034 : ofpbuf_resize__(struct ofpbuf *b, size_t new_headroom, size_t new_tailroom)
235 : : {
236 : : void *new_base, *new_data;
237 : : size_t new_allocated;
238 : :
239 : 537034 : new_allocated = new_headroom + b->size + new_tailroom;
240 : :
241 [ + - + - ]: 537034 : switch (b->source) {
242 : : case OFPBUF_MALLOC:
243 [ + + ]: 452759 : if (new_headroom == ofpbuf_headroom(b)) {
244 : 451490 : new_base = xrealloc(b->base, new_allocated);
245 : : } else {
246 : 1269 : new_base = xmalloc(new_allocated);
247 : 1269 : ofpbuf_copy__(b, new_base, new_headroom, new_tailroom);
248 : 1269 : free(b->base);
249 : : }
250 : 452759 : break;
251 : :
252 : : case OFPBUF_STACK:
253 : 0 : OVS_NOT_REACHED();
254 : :
255 : : case OFPBUF_STUB:
256 : 84275 : b->source = OFPBUF_MALLOC;
257 : 84275 : new_base = xmalloc(new_allocated);
258 : 84275 : ofpbuf_copy__(b, new_base, new_headroom, new_tailroom);
259 : 84275 : break;
260 : :
261 : : default:
262 : 0 : OVS_NOT_REACHED();
263 : : }
264 : :
265 : 537034 : b->allocated = new_allocated;
266 : 537034 : b->base = new_base;
267 : :
268 : 537034 : new_data = (char *) new_base + new_headroom;
269 [ + + ]: 537034 : if (b->data != new_data) {
270 [ + + ]: 257438 : if (b->header) {
271 : 147111 : ptrdiff_t header_offset = (char *) b->header - (char *) b->data;
272 : :
273 : 147111 : b->header = (char *) new_data + header_offset;
274 : : }
275 [ + + ]: 257438 : if (b->msg) {
276 : 1000 : ptrdiff_t msg_offset = (char *) b->msg - (char *) b->data;
277 : :
278 : 1000 : b->msg = (char *) new_data + msg_offset;
279 : : }
280 : 257438 : b->data = new_data;
281 : : }
282 : 537034 : }
283 : :
284 : : /* Ensures that 'b' has room for at least 'size' bytes at its tail end,
285 : : * reallocating and copying its data if necessary. Its headroom, if any, is
286 : : * preserved. */
287 : : void
288 : 9701214 : ofpbuf_prealloc_tailroom(struct ofpbuf *b, size_t size)
289 : : {
290 [ + + ]: 9701214 : if (size > ofpbuf_tailroom(b)) {
291 : 535765 : ofpbuf_resize__(b, ofpbuf_headroom(b), MAX(size, 64));
292 : : }
293 : 9701207 : }
294 : :
295 : : /* Ensures that 'b' has room for at least 'size' bytes at its head,
296 : : * reallocating and copying its data if necessary. Its tailroom, if any, is
297 : : * preserved. */
298 : : void
299 : 50821 : ofpbuf_prealloc_headroom(struct ofpbuf *b, size_t size)
300 : : {
301 [ + + ]: 50821 : if (size > ofpbuf_headroom(b)) {
302 : 1269 : ofpbuf_resize__(b, MAX(size, 64), ofpbuf_tailroom(b));
303 : : }
304 : 50821 : }
305 : :
306 : : /* Trims the size of 'b' to fit its actual content, reducing its headroom and
307 : : * tailroom to 0, if any.
308 : : *
309 : : * Buffers not obtained from malloc() are not resized, since that wouldn't save
310 : : * any memory.
311 : : *
312 : : * Caller needs to updates 'b->header' and 'b->msg' so that they point to the
313 : : * same locations in the data. (If they pointed into the tailroom or headroom
314 : : * then they become invalid.)
315 : : *
316 : : */
317 : : void
318 : 0 : ofpbuf_trim(struct ofpbuf *b)
319 : : {
320 [ # # ]: 0 : if (b->source == OFPBUF_MALLOC
321 [ # # ][ # # ]: 0 : && (ofpbuf_headroom(b) || ofpbuf_tailroom(b))) {
322 : 0 : ofpbuf_resize__(b, 0, 0);
323 : : }
324 : 0 : }
325 : :
326 : : /* If 'b' is shorter than 'length' bytes, pads its tail out with zeros to that
327 : : * length. */
328 : : void
329 : 1117772 : ofpbuf_padto(struct ofpbuf *b, size_t length)
330 : : {
331 [ + + ]: 1117772 : if (b->size < length) {
332 : 446165 : ofpbuf_put_zeros(b, length - b->size);
333 : : }
334 : 1117772 : }
335 : :
336 : : /* Shifts all of the data within the allocated space in 'b' by 'delta' bytes.
337 : : * For example, a 'delta' of 1 would cause each byte of data to move one byte
338 : : * forward (from address 'p' to 'p+1'), and a 'delta' of -1 would cause each
339 : : * byte to move one byte backward (from 'p' to 'p-1').
340 : : *
341 : : * If used, user must make sure the 'header' and 'msg' pointers are updated
342 : : * after shifting.
343 : : */
344 : : void
345 : 0 : ofpbuf_shift(struct ofpbuf *b, int delta)
346 : : {
347 [ # # ][ # # ]: 0 : ovs_assert(delta > 0 ? delta <= ofpbuf_tailroom(b)
[ # # ][ # # ]
348 : : : delta < 0 ? -delta <= ofpbuf_headroom(b)
349 : : : true);
350 : :
351 [ # # ]: 0 : if (delta != 0) {
352 : 0 : char *dst = (char *) b->data + delta;
353 : 0 : memmove(dst, b->data, b->size);
354 : 0 : b->data = dst;
355 : : }
356 : 0 : }
357 : :
358 : : /* Appends 'size' bytes of data to the tail end of 'b', reallocating and
359 : : * copying its data if necessary. Returns a pointer to the first byte of the
360 : : * new data, which is left uninitialized. */
361 : : void *
362 : 9251486 : ofpbuf_put_uninit(struct ofpbuf *b, size_t size)
363 : : {
364 : : void *p;
365 : 9251486 : ofpbuf_prealloc_tailroom(b, size);
366 : 9251484 : p = ofpbuf_tail(b);
367 : 9251482 : b->size += size;
368 : 9251482 : return p;
369 : : }
370 : :
371 : : /* Appends 'size' zeroed bytes to the tail end of 'b'. Data in 'b' is
372 : : * reallocated and copied if necessary. Returns a pointer to the first byte of
373 : : * the data's location in the ofpbuf. */
374 : : void *
375 : 2997512 : ofpbuf_put_zeros(struct ofpbuf *b, size_t size)
376 : : {
377 : 2997512 : void *dst = ofpbuf_put_uninit(b, size);
378 : 2997511 : memset(dst, 0, size);
379 : 2997511 : return dst;
380 : : }
381 : :
382 : : /* Appends the 'size' bytes of data in 'p' to the tail end of 'b'. Data in 'b'
383 : : * is reallocated and copied if necessary. Returns a pointer to the first
384 : : * byte of the data's location in the ofpbuf. */
385 : : void *
386 : 1233505 : ofpbuf_put(struct ofpbuf *b, const void *p, size_t size)
387 : : {
388 : 1233505 : void *dst = ofpbuf_put_uninit(b, size);
389 : 1233505 : memcpy(dst, p, size);
390 : 1233505 : return dst;
391 : : }
392 : :
393 : : /* Parses as many pairs of hex digits as possible (possibly separated by spaces
394 : : * or periods) from the beginning of 's', appending bytes for their values to
395 : : * 'b'. Returns the first character of 's' that is not the first of a pair of
396 : : * hex digits. If 'n' is nonnull, stores the number of bytes added to 'b' in
397 : : * '*n'. */
398 : : char *
399 : 1934 : ofpbuf_put_hex(struct ofpbuf *b, const char *s, size_t *n)
400 : : {
401 : 1934 : size_t initial_size = b->size;
402 : : for (;;) {
403 : : uint8_t byte;
404 : : bool ok;
405 : :
406 : 71332 : s += strspn(s, " .\t\r\n");
407 : 71332 : byte = hexits_value(s, 2, &ok);
408 [ + + ]: 71332 : if (!ok) {
409 [ + + ]: 1934 : if (n) {
410 : 1064 : *n = b->size - initial_size;
411 : : }
412 : 1934 : return CONST_CAST(char *, s);
413 : : }
414 : :
415 : 69398 : ofpbuf_put(b, &byte, 1);
416 : 69398 : s += 2;
417 : 69398 : }
418 : : }
419 : :
420 : : /* Reserves 'size' bytes of headroom so that they can be later allocated with
421 : : * ofpbuf_push_uninit() without reallocating the ofpbuf. */
422 : : void
423 : 92041 : ofpbuf_reserve(struct ofpbuf *b, size_t size)
424 : : {
425 [ - + ]: 92041 : ovs_assert(!b->size);
426 : 92041 : ofpbuf_prealloc_tailroom(b, size);
427 : 92041 : b->data = (char*)b->data + size;
428 : 92041 : }
429 : :
430 : : /* Prefixes 'size' bytes to the head end of 'b', reallocating and copying its
431 : : * data if necessary. Returns a pointer to the first byte of the data's
432 : : * location in the ofpbuf. The new data is left uninitialized. */
433 : : void *
434 : 50820 : ofpbuf_push_uninit(struct ofpbuf *b, size_t size)
435 : : {
436 : 50820 : ofpbuf_prealloc_headroom(b, size);
437 : 50820 : b->data = (char*)b->data - size;
438 : 50820 : b->size += size;
439 : 50820 : return b->data;
440 : : }
441 : :
442 : : /* Prefixes 'size' zeroed bytes to the head end of 'b', reallocating and
443 : : * copying its data if necessary. Returns a pointer to the first byte of the
444 : : * data's location in the ofpbuf. */
445 : : void *
446 : 0 : ofpbuf_push_zeros(struct ofpbuf *b, size_t size)
447 : : {
448 : 0 : void *dst = ofpbuf_push_uninit(b, size);
449 : 0 : memset(dst, 0, size);
450 : 0 : return dst;
451 : : }
452 : :
453 : : /* Copies the 'size' bytes starting at 'p' to the head end of 'b', reallocating
454 : : * and copying its data if necessary. Returns a pointer to the first byte of
455 : : * the data's location in the ofpbuf. */
456 : : void *
457 : 1268 : ofpbuf_push(struct ofpbuf *b, const void *p, size_t size)
458 : : {
459 : 1268 : void *dst = ofpbuf_push_uninit(b, size);
460 : 1268 : memcpy(dst, p, size);
461 : 1268 : return dst;
462 : : }
463 : :
464 : : /* Returns the data in 'b' as a block of malloc()'d memory and frees the buffer
465 : : * within 'b'. (If 'b' itself was dynamically allocated, e.g. with
466 : : * ofpbuf_new(), then it should still be freed with, e.g., ofpbuf_delete().) */
467 : : void *
468 : 42550 : ofpbuf_steal_data(struct ofpbuf *b)
469 : : {
470 : : void *p;
471 : :
472 [ + + ][ + - ]: 42550 : if (b->source == OFPBUF_MALLOC && b->data == b->base) {
473 : 40157 : p = b->data;
474 : : } else {
475 : 2393 : p = xmemdup(b->data, b->size);
476 [ - + ]: 2393 : if (b->source == OFPBUF_MALLOC) {
477 : 0 : free(b->base);
478 : : }
479 : : }
480 : 42550 : b->base = NULL;
481 : 42550 : b->data = NULL;
482 : 42550 : b->header = NULL;
483 : 42550 : b->msg = NULL;
484 : 42550 : return p;
485 : : }
486 : :
487 : : /* Returns a string that describes some of 'b''s metadata plus a hex dump of up
488 : : * to 'maxbytes' from the start of the buffer. */
489 : : char *
490 : 0 : ofpbuf_to_string(const struct ofpbuf *b, size_t maxbytes)
491 : : {
492 : : struct ds s;
493 : :
494 : 0 : ds_init(&s);
495 : 0 : ds_put_format(&s, "size=%"PRIu32", allocated=%"PRIu32", head=%"PRIuSIZE", tail=%"PRIuSIZE"\n",
496 : : b->size, b->allocated,
497 : : ofpbuf_headroom(b), ofpbuf_tailroom(b));
498 : 0 : ds_put_hex_dump(&s, b->data, MIN(b->size, maxbytes), 0, false);
499 : 0 : return ds_cstr(&s);
500 : : }
501 : :
502 : : /* Removes each of the "struct ofpbuf"s on 'list' from the list and frees
503 : : * them. */
504 : : void
505 : 65140 : ofpbuf_list_delete(struct ovs_list *list)
506 : : {
507 : : struct ofpbuf *b;
508 : :
509 [ + + ]: 65916 : LIST_FOR_EACH_POP (b, list_node, list) {
510 : 776 : ofpbuf_delete(b);
511 : : }
512 : 65140 : }
|