blob: 4736ac0b9e3c021591db57edf8196c82a880a492 [file] [log] [blame]
Rich Lanea06d0c32013-03-25 08:52:03 -07001:: # Copyright 2013, Big Switch Networks, Inc.
2:: #
3:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
4:: # the following special exception:
5:: #
6:: # LOXI Exception
7:: #
8:: # As a special exception to the terms of the EPL, you may distribute libraries
9:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
10:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
11:: # from the LoxiGen Libraries and the notice provided below is (i) included in
12:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
13:: # documentation for the LoxiGen Libraries, if distributed in binary form.
14:: #
15:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
16:: #
17:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
18:: # a copy of the EPL at:
19:: #
20:: # http://www.eclipse.org/legal/epl-v10.html
21:: #
22:: # Unless required by applicable law or agreed to in writing, software
23:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
24:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
25:: # EPL for the specific language governing permissions and limitations
26:: # under the EPL.
27::
Rich Laned983aa52013-06-13 11:48:37 -070028:: include('_copyright.c')
Rich Lanea06d0c32013-03-25 08:52:03 -070029
30#if !defined(_OF_WIRE_BUF_H_)
31#define _OF_WIRE_BUF_H_
32
33#include <string.h>
34#include <loci/loci_base.h>
35#include <loci/of_object.h>
36#include <loci/of_match.h>
37#include <loci/of_buffer.h>
38
39/****************************************************************
40 *
41 * Wire buffer declaration, constructor, data alloc, delete
42 *
43 ****************************************************************/
44
45/* Maximum length of an OpenFlow message. All wire buffers allocated for
46 * new objects (that don't come from a message) are this length to avoid
47 * needing to grow the buffers. */
48#define OF_WIRE_BUFFER_MAX_LENGTH 65535
49
50/**
51 * Buffer management structure
52 */
53typedef struct of_wire_buffer_s {
54 /** Pointer to a monolithic data buffer */
55 uint8_t *buf;
56
57 /** Length of buffer actually allocated */
58 int alloc_bytes;
59 /** Current extent actually used */
60 int current_bytes;
61 /** If not NULL, use this to dealloc buf */
62 of_buffer_free_f free;
63} of_wire_buffer_t;
64
65/**
66 * Decouples object from underlying wire buffer
67 *
68 * Called a 'slice' in some places.
69 */
70typedef struct of_wire_object_s {
71 /** A pointer to the underlying buffer's management structure. */
72 of_wire_buffer_t *wbuf;
73 /** The start offset for this object relative to the start of the
74 * underlying buffer */
75 int obj_offset;
76 /* Boolean, whether the object owns the wire buffer. */
77 char owned;
78} of_wire_object_t;
79
80#define WBUF_BUF(wbuf) (wbuf)->buf
81#define WBUF_ALLOC_BYTES(wbuf) (wbuf)->alloc_bytes
82#define WBUF_CURRENT_BYTES(wbuf) (wbuf)->current_bytes
83
84/**
85 * For read access, throw an error code if current buffer
86 * is not big enough.
87 * @param wbuf Pointer to an of_wire_buffer_t structure
88 * @param offset The extent of the buffer required
89 */
90#define OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset) \
Rich Lanee57f0432014-02-19 10:31:53 -080091 LOCI_ASSERT(((wbuf) != NULL) && (WBUF_BUF(wbuf) != NULL) && \
Rich Lanea06d0c32013-03-25 08:52:03 -070092 (offset > 0) && (WBUF_CURRENT_BYTES(wbuf) >= offset))
93
94/*
95 * Index a wire buffer
96 * Index a wire object (from obj_offset)
97 * Index a LOCI object
98 */
99
100/**
101 * Return a pointer to a particular offset in a wire buffer's data
102 * @param wbuf Pointer to an of_wire_buffer_t structure
103 * @param offset The location to reference
104 */
105#define OF_WIRE_BUFFER_INDEX(wbuf, offset) (&((WBUF_BUF(wbuf))[offset]))
106
107/**
108 * Return a pointer to a particular offset in the underlying buffer
109 * associated with a wire object
110 * @param wobj Pointer to an of_wire_object_t structure
111 * @param offset The location to reference relative to the start of the object
112 */
113#define OF_WIRE_OBJECT_INDEX(wobj, offset) \
114 OF_WIRE_BUFFER_INDEX((wobj)->wbuf, (offset) + (wobj)->obj_offset)
115
116/****************************************************************
117 * Object specific macros; of_object_t includes a wire_object
118 ****************************************************************/
119
120/**
121 * Return a pointer to a particular offset in the underlying buffer
122 * associated with a wire object
123 * @param obj Pointer to an of_object_t object
124 * @param offset The location to reference relative to the start of the object
125 */
126#define OF_OBJECT_BUFFER_INDEX(obj, offset) \
127 OF_WIRE_OBJECT_INDEX(&((obj)->wire_object), offset)
128
129/**
130 * Return the absolute offset as an integer from a object-relative offset
131 * @param obj Pointer to an of_wire_object_t structure
132 * @param offset The location to reference relative to the start of the object
133 */
134#define OF_OBJECT_ABSOLUTE_OFFSET(obj, offset) \
135 ((obj)->wire_object.obj_offset + offset)
136
137
138/**
139 * Map a generic object to the underlying wire buffer object (not the octets)
140 *
141 * Treat as private
142 */
143#define OF_OBJECT_TO_WBUF(obj) ((obj)->wire_object.wbuf)
144
145
146
147/**
148 * Minimum allocation size for wire buffer object
149 */
150#define OF_WIRE_BUFFER_MIN_ALLOC_BYTES 128
151
152/**
153 * Allocate a wire buffer object and the underlying data buffer.
154 * The wire buffer is initally empty (current_bytes == 0).
155 * @param a_bytes The number of bytes to allocate.
156 * @returns A wire buffer object if successful or NULL
157 */
158static inline of_wire_buffer_t *
159of_wire_buffer_new(int a_bytes)
160{
161 of_wire_buffer_t *wbuf;
162
163 wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
164 if (wbuf == NULL) {
165 return NULL;
166 }
167 MEMSET(wbuf, 0, sizeof(of_wire_buffer_t));
168
169 if (a_bytes < OF_WIRE_BUFFER_MIN_ALLOC_BYTES) {
170 a_bytes = OF_WIRE_BUFFER_MIN_ALLOC_BYTES;
171 }
172
173 if ((wbuf->buf = (uint8_t *)MALLOC(a_bytes)) == NULL) {
174 FREE(wbuf);
175 return NULL;
176 }
177 MEMSET(wbuf->buf, 0, a_bytes);
178 wbuf->current_bytes = 0;
179 wbuf->alloc_bytes = a_bytes;
180
181 return (of_wire_buffer_t *)wbuf;
182}
183
184/**
185 * Allocate a wire buffer object and bind it to an existing buffer.
186 * @param buf Existing buffer.
187 * @param bytes Size of buf.
188 * @param buf_free Function called to deallocate buf.
189 * @returns A wire buffer object if successful or NULL
190 */
191static inline of_wire_buffer_t *
192of_wire_buffer_new_bind(uint8_t *buf, int bytes, of_buffer_free_f buf_free)
193{
194 of_wire_buffer_t *wbuf;
195
196 wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
197 if (wbuf == NULL) {
198 return NULL;
199 }
200
201 wbuf->buf = buf;
202 wbuf->free = buf_free;
203 wbuf->current_bytes = bytes;
204 wbuf->alloc_bytes = bytes;
205
206 return (of_wire_buffer_t *)wbuf;
207}
208
209static inline void
210of_wire_buffer_free(of_wire_buffer_t *wbuf)
211{
212 if (wbuf == NULL) return;
213
214 if (wbuf->buf != NULL) {
215 if (wbuf->free != NULL) {
216 wbuf->free(wbuf->buf);
217 } else {
218 FREE(wbuf->buf);
219 }
220 }
221
222 FREE(wbuf);
223}
224
225static inline void
226of_wire_buffer_steal(of_wire_buffer_t *wbuf, uint8_t **buffer)
227{
228 *buffer = wbuf->buf;
229 /* Mark underlying data buffer as taken */
230 wbuf->buf = NULL;
231 of_wire_buffer_free(wbuf);
232}
233
234/**
235 * Increase the currently used length of the wire buffer.
236 * Will fail an assertion if the allocated length is not long enough.
237 *
238 * @param wbuf Pointer to the wire buffer structure
239 * @param bytes Total number of bytes buffer should grow to
240 */
241
242static inline void
243of_wire_buffer_grow(of_wire_buffer_t *wbuf, int bytes)
244{
Rich Lanee57f0432014-02-19 10:31:53 -0800245 LOCI_ASSERT(wbuf != NULL);
246 LOCI_ASSERT(wbuf->alloc_bytes >= bytes);
Rich Lanea06d0c32013-03-25 08:52:03 -0700247 if (bytes > wbuf->current_bytes) {
248 wbuf->current_bytes = bytes;
249 }
250}
251
252/* TBD */
253
254
255/**
256 * Get a uint8_t scalar from a wire buffer
257 * @param wbuf The pointer to the wire buffer structure
258 * @param offset Offset in the wire buffer
259 * @param value Pointer to where to put value
260 *
261 * The underlying buffer accessor funtions handle endian and alignment.
262 */
263
264static inline void
265of_wire_buffer_u8_get(of_wire_buffer_t *wbuf, int offset, uint8_t *value)
266{
267 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
268 buf_u8_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
269}
270
271/**
272 * Set a uint8_t scalar in a wire buffer
273 * @param wbuf The pointer to the wire buffer structure
274 * @param offset Offset in the wire buffer
275 * @param value The value to store
276 *
277 * The underlying buffer accessor funtions handle endian and alignment.
278 */
279
280static inline void
281of_wire_buffer_u8_set(of_wire_buffer_t *wbuf, int offset, uint8_t value)
282{
283 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
284 buf_u8_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
285}
286
287/**
288 * Get a uint16_t scalar from a wire buffer
289 * @param wbuf The pointer to the wire buffer structure
290 * @param offset Offset in the wire buffer
291 * @param value Pointer to where to put value
292 *
293 * The underlying buffer accessor funtions handle endian and alignment.
294 */
295
296static inline void
297of_wire_buffer_u16_get(of_wire_buffer_t *wbuf, int offset, uint16_t *value)
298{
299 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
300 buf_u16_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
301}
302
303/**
304 * Set a uint16_t scalar in a wire buffer
305 * @param wbuf The pointer to the wire buffer structure
306 * @param offset Offset in the wire buffer
307 * @param value The value to store
308 *
309 * The underlying buffer accessor funtions handle endian and alignment.
310 */
311
312static inline void
313of_wire_buffer_u16_set(of_wire_buffer_t *wbuf, int offset, uint16_t value)
314{
315 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
316 buf_u16_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
317}
318
319/**
320 * Get a uint32_t scalar from a wire buffer
321 * @param wbuf The pointer to the wire buffer structure
322 * @param offset Offset in the wire buffer
323 * @param value Pointer to where to put value
324 *
325 * The underlying buffer accessor funtions handle endian and alignment.
326 */
327
328static inline void
329of_wire_buffer_u32_get(of_wire_buffer_t *wbuf, int offset, uint32_t *value)
330{
331 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
332 buf_u32_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
333}
334
335/**
336 * Set a uint32_t scalar in a wire buffer
337 * @param wbuf The pointer to the wire buffer structure
338 * @param offset Offset in the wire buffer
339 * @param value The value to store
340 *
341 * The underlying buffer accessor funtions handle endian and alignment.
342 */
343
344static inline void
345of_wire_buffer_u32_set(of_wire_buffer_t *wbuf, int offset, uint32_t value)
346{
347 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
348 buf_u32_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
349}
350
Andreas Wundsamb566a162013-07-18 19:30:23 -0700351
352/**
353 * Get a uint32_t scalar from a wire buffer
354 * @param wbuf The pointer to the wire buffer structure
355 * @param offset Offset in the wire buffer
356 * @param value Pointer to where to put value
357 *
358 * The underlying buffer accessor funtions handle endian and alignment.
359 */
360
361static inline void
362of_wire_buffer_ipv4_get(of_wire_buffer_t *wbuf, int offset, of_ipv4_t *value)
363{
364 of_wire_buffer_u32_get(wbuf, offset, value);
365}
366
367/**
368 * Set a ipv4 (uint32_t) scalar in a wire buffer
369 * @param wbuf The pointer to the wire buffer structure
370 * @param offset Offset in the wire buffer
371 * @param value The value to store
372 *
373 * The underlying buffer accessor funtions handle endian and alignment.
374 */
375
376static inline void
377of_wire_buffer_ipv4_set(of_wire_buffer_t *wbuf, int offset, of_ipv4_t value)
378{
379 of_wire_buffer_u32_set(wbuf, offset, value);
380}
381
382
Rich Lanea06d0c32013-03-25 08:52:03 -0700383/**
384 * Get a uint64_t scalar from a wire buffer
385 * @param wbuf The pointer to the wire buffer structure
386 * @param offset Offset in the wire buffer
387 * @param value Pointer to where to put value
388 *
389 * The underlying buffer accessor funtions handle endian and alignment.
390 */
391
392static inline void
393of_wire_buffer_u64_get(of_wire_buffer_t *wbuf, int offset, uint64_t *value)
394{
395 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
396 buf_u64_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
397}
398
399/**
400 * Set a uint64_t scalar in a wire buffer
401 * @param wbuf The pointer to the wire buffer structure
402 * @param offset Offset in the wire buffer
403 * @param value The value to store
404 *
405 * The underlying buffer accessor funtions handle endian and alignment.
406 */
407
408static inline void
409of_wire_buffer_u64_set(of_wire_buffer_t *wbuf, int offset, uint64_t value)
410{
411 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
412 buf_u64_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
413}
414
415/**
416 * Get a generic OF match structure from a wire buffer
417 * @param wbuf The pointer to the wire buffer structure
418 * @param offset Offset in the wire buffer
419 * @param value Pointer to the structure to update
420 *
421 * NOT IMPLEMENTED.
422 *
423 */
424
425static inline void
426of_wire_buffer_match_get(int version, of_wire_buffer_t *wbuf, int offset,
427 of_match_t *value)
428{
Rich Lanee57f0432014-02-19 10:31:53 -0800429 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700430}
431
432/**
433 * Set a generic OF match structure in a wire buffer
434 * @param wbuf The pointer to the wire buffer structure
435 * @param offset Offset in the wire buffer
436 * @param value Pointer to the structure to store
437 *
438 * NOT IMPLEMENTED.
439 *
440 */
441
442static inline void
443of_wire_buffer_match_set(int version, of_wire_buffer_t *wbuf, int offset,
444 of_match_t *value)
445{
Rich Lanee57f0432014-02-19 10:31:53 -0800446 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700447}
448
449/**
450 * Get a port description object from a wire buffer
451 * @param wbuf The pointer to the wire buffer structure
452 * @param offset Offset in the wire buffer
453 * @param value Pointer to the structure to fill out
454 *
455 * NOT IMPLEMENTED.
456 *
457 * @fixme Where should this go?
458 */
459
460static inline void
461of_wire_buffer_of_port_desc_get(int version, of_wire_buffer_t *wbuf, int offset,
462 void *value)
463{
Rich Lanee57f0432014-02-19 10:31:53 -0800464 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700465}
466
467/**
468 * Set a port description object in a wire buffer
469 * @param wbuf The pointer to the wire buffer structure
470 * @param offset Offset in the wire buffer
471 * @param value Pointer to the structure to fill out
472 *
473 * NOT IMPLEMENTED.
474 *
475 * @fixme Where should this go?
476 */
477
478static inline void
479of_wire_buffer_of_port_desc_set(int version, of_wire_buffer_t *wbuf, int offset,
480 void *value)
481{
Rich Lanee57f0432014-02-19 10:31:53 -0800482 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700483}
484
485/**
486 * Get a port number scalar from a wire buffer
487 * @param wbuf The pointer to the wire buffer structure
488 * @param offset Offset in the wire buffer
489 * @param value Pointer to where to put value
490 *
491 * Port numbers are version specific.
492 */
493
494static inline void
495of_wire_buffer_port_no_get(int version, of_wire_buffer_t *wbuf, int offset,
496 of_port_no_t *value)
497{
498 uint16_t v16;
499 uint32_t v32;
500
501 switch (version) {
502 case OF_VERSION_1_0:
503 of_wire_buffer_u16_get(wbuf, offset, &v16);
504 *value = v16;
505 break;
506 case OF_VERSION_1_1:
507 case OF_VERSION_1_2:
508 case OF_VERSION_1_3:
509 of_wire_buffer_u32_get(wbuf, offset, &v32);
510 *value = v32;
511 break;
512 default:
Rich Lanee57f0432014-02-19 10:31:53 -0800513 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700514 }
515}
516
517/**
518 * Set a port number scalar from a wire buffer
519 * @param wbuf The pointer to the wire buffer structure
520 * @param offset Offset in the wire buffer
521 * @param value The value to store in the buffer
522 *
523 * Port numbers are version specific.
524 */
525
526static inline void
527of_wire_buffer_port_no_set(int version, of_wire_buffer_t *wbuf, int offset,
528 of_port_no_t value)
529{
530
531 switch (version) {
532 case OF_VERSION_1_0:
533 of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
534 break;
535 case OF_VERSION_1_1:
536 case OF_VERSION_1_2:
537 case OF_VERSION_1_3:
538 of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
539 break;
540 default:
Rich Lanee57f0432014-02-19 10:31:53 -0800541 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700542 }
543}
544
545/**
546 * Get a flow mod command value from a wire buffer
547 * @param wbuf The pointer to the wire buffer structure
548 * @param offset Offset in the wire buffer
549 * @param value Pointer to where to put value
550 */
551
552static inline void
553of_wire_buffer_fm_cmd_get(int version, of_wire_buffer_t *wbuf, int offset,
554 of_fm_cmd_t *value)
555{
556 uint16_t v16;
557 uint8_t v8;
558
559 switch (version) {
560 case OF_VERSION_1_0:
561 of_wire_buffer_u16_get(wbuf, offset, &v16);
562 *value = v16;
563 break;
564 case OF_VERSION_1_1:
565 case OF_VERSION_1_2:
566 case OF_VERSION_1_3:
567 of_wire_buffer_u8_get(wbuf, offset, &v8);
568 *value = v8;
569 break;
570 default:
Rich Lanee57f0432014-02-19 10:31:53 -0800571 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700572 }
573}
574
575/**
576 * Set a flow mod command value in a wire buffer
577 * @param wbuf The pointer to the wire buffer structure
578 * @param offset Offset in the wire buffer
579 * @param value The value to store
580 */
581
582static inline void
583of_wire_buffer_fm_cmd_set(int version, of_wire_buffer_t *wbuf, int offset,
584 of_fm_cmd_t value)
585{
586 switch (version) {
587 case OF_VERSION_1_0:
588 of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
589 break;
590 case OF_VERSION_1_1:
591 case OF_VERSION_1_2:
592 case OF_VERSION_1_3:
593 of_wire_buffer_u8_set(wbuf, offset, (uint8_t)value);
594 break;
595 default:
Rich Lanee57f0432014-02-19 10:31:53 -0800596 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700597 }
598}
599
600/**
601 * Get a wild card bitmap value from a wire buffer
602 * @param wbuf The pointer to the wire buffer structure
603 * @param offset Offset in the wire buffer
604 * @param value Pointer to where to store the value
605 */
606
607static inline void
608of_wire_buffer_wc_bmap_get(int version, of_wire_buffer_t *wbuf, int offset,
609 of_wc_bmap_t *value)
610{
611 uint32_t v32;
612 uint64_t v64;
613
614 switch (version) {
615 case OF_VERSION_1_0:
616 case OF_VERSION_1_1:
617 of_wire_buffer_u32_get(wbuf, offset, &v32);
618 *value = v32;
619 break;
620 case OF_VERSION_1_2:
621 case OF_VERSION_1_3:
622 of_wire_buffer_u64_get(wbuf, offset, &v64);
623 *value = v64;
624 break;
625 default:
Rich Lanee57f0432014-02-19 10:31:53 -0800626 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700627 }
628}
629
630/**
631 * Set a wild card bitmap value in a wire buffer
632 * @param wbuf The pointer to the wire buffer structure
633 * @param offset Offset in the wire buffer
634 * @param value The value to store
635 */
636
637static inline void
638of_wire_buffer_wc_bmap_set(int version, of_wire_buffer_t *wbuf, int offset,
639 of_wc_bmap_t value)
640{
641 switch (version) {
642 case OF_VERSION_1_0:
643 case OF_VERSION_1_1:
644 of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
645 break;
646 case OF_VERSION_1_2:
647 case OF_VERSION_1_3:
648 of_wire_buffer_u64_set(wbuf, offset, (uint64_t)value);
649 break;
650 default:
Rich Lanee57f0432014-02-19 10:31:53 -0800651 LOCI_ASSERT(0);
Rich Lanea06d0c32013-03-25 08:52:03 -0700652 }
653}
654
655/* match bitmap and wildcard bitmaps followed the same pattern */
656#define of_wire_buffer_match_bmap_get of_wire_buffer_wc_bmap_get
657#define of_wire_buffer_match_bmap_set of_wire_buffer_wc_bmap_set
658
659/* Derived functions, mostly for fixed length name strings */
660#define of_wire_buffer_char_get of_wire_buffer_u8_get
661#define of_wire_buffer_char_set of_wire_buffer_u8_set
662
663
664/**
665 * Get an octet object from a wire buffer
666 * @param wbuf The pointer to the wire buffer structure
667 * @param offset Offset in the wire buffer
668 * @param value Pointer to where to put value
669 *
670 * of_octets_t is treated specially as the high level functions pass around
671 * pointers for "get" operators.
672 *
673 * Important: The length of data to copy is stored in the value->bytes
674 * variable.
675 */
676
677static inline void
678of_wire_buffer_octets_data_get(of_wire_buffer_t *wbuf, int offset,
679 of_octets_t *value)
680{
681 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
682 buf_octets_get(OF_WIRE_BUFFER_INDEX(wbuf, offset),
683 OF_OCTETS_POINTER_GET(value),
684 OF_OCTETS_BYTES_GET(value));
685}
686
687/**
688 * Set an octet object in a wire buffer
689 * @param wbuf The pointer to the wire buffer structure
690 * @param offset Offset in the wire buffer
691 * @param value Pointer to the octet stream to store
692 * @param cur_len Current length of data in the buffer
693 *
694 * of_octets_t is treated specially as the high level functions pass around
695 * pointers for "get" operators.
696 *
697 * @fixme Need to take into account cur_len
698 */
699
700static inline void
701of_wire_buffer_octets_data_set(of_wire_buffer_t *wbuf, int offset,
702 of_octets_t *value, int cur_len)
703{
704 // FIXME need to adjust length of octets member in buffer
Rich Lanee57f0432014-02-19 10:31:53 -0800705 LOCI_ASSERT(cur_len == 0 || cur_len == value->bytes);
Rich Lanea06d0c32013-03-25 08:52:03 -0700706
707 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
708 buf_octets_set(OF_WIRE_BUFFER_INDEX(wbuf, offset),
709 OF_OCTETS_POINTER_GET(value),
710 OF_OCTETS_BYTES_GET(value));
711}
712
713static inline void
714_wbuf_octets_set(of_wire_buffer_t *wbuf, int offset, uint8_t *src, int bytes) {
715 of_octets_t octets;
716 OF_OCTETS_POINTER_SET(&octets, src);
717 OF_OCTETS_BYTES_SET(&octets, bytes);
718 of_wire_buffer_octets_data_set(wbuf, offset, &octets, bytes);
719}
720
721static inline void
722_wbuf_octets_get(of_wire_buffer_t *wbuf, int offset, uint8_t *dst, int bytes) {
723 of_octets_t octets;
724 OF_OCTETS_POINTER_SET(&octets, dst);
725 OF_OCTETS_BYTES_SET(&octets, bytes);
726 of_wire_buffer_octets_data_get(wbuf, offset, &octets);
727}
728
729
730/**
731 * Get a MAC address from a wire buffer
732 * @param wbuf The pointer to the wire buffer structure
733 * @param offset Offset in the wire buffer
734 * @param mac Pointer to the mac address location
735 *
736 * Uses the octets function.
737 */
738
739#define of_wire_buffer_mac_get(buf, offset, mac) \
740 _wbuf_octets_get(buf, offset, (uint8_t *)mac, 6)
741
742/**
743 * Set a MAC address in a wire buffer
744 * @param wbuf The pointer to the wire buffer structure
745 * @param offset Offset in the wire buffer
746 * @param mac The variable holding the mac address to store
747 *
748 * Uses the octets function.
749 */
750
751#define of_wire_buffer_mac_set(buf, offset, mac) \
752 _wbuf_octets_set(buf, offset, (uint8_t *)&mac, 6)
753
754
755/**
756 * Get a port name string from a wire buffer
757 * @param wbuf The pointer to the wire buffer structure
758 * @param offset Offset in the wire buffer
759 * @param mac The mac address
760 *
761 * Uses the octets function.
762 */
763#define of_wire_buffer_port_name_get(buf, offset, portname) \
764 _wbuf_octets_get(buf, offset, (uint8_t *)portname, \
765 OF_MAX_PORT_NAME_LEN)
766
767/**
768 * Set a port name address in a wire buffer
769 * @param wbuf The pointer to the wire buffer structure
770 * @param offset Offset in the wire buffer
771 * @param portname Where to store the port name
772 *
773 * Uses the octets function.
774 */
775
776#define of_wire_buffer_port_name_set(buf, offset, portname) \
777 _wbuf_octets_set(buf, offset, (uint8_t *)portname, \
778 OF_MAX_PORT_NAME_LEN)
779
780
781/**
782 * Get a table name string from a wire buffer
783 * @param wbuf The pointer to the wire buffer structure
784 * @param offset Offset in the wire buffer
785 * @param portname The port name
786 *
787 * Uses the octets function.
788 */
789
790#define of_wire_buffer_tab_name_get(buf, offset, tabname) \
791 _wbuf_octets_get(buf, offset, (uint8_t *)tabname, \
792 OF_MAX_TABLE_NAME_LEN)
793
794/**
795 * Set a table name address in a wire buffer
796 * @param wbuf The pointer to the wire buffer structure
797 * @param offset Offset in the wire buffer
798 * @param mac Where to store the table name
799 *
800 * Uses the octets function.
801 */
802
803#define of_wire_buffer_tab_name_set(buf, offset, tabname) \
804 _wbuf_octets_set(buf, offset, (uint8_t *)tabname, \
805 OF_MAX_TABLE_NAME_LEN)
806
807/**
808 * Get a description string from a wire buffer
809 * @param wbuf The pointer to the wire buffer structure
810 * @param offset Offset in the wire buffer
811 * @param desc Where to store the description string
812 *
813 * Uses the octets function.
814 */
815
816#define of_wire_buffer_desc_str_get(buf, offset, desc) \
817 _wbuf_octets_get(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)
818
819/**
820 * Set a description string in a wire buffer
821 * @param wbuf The pointer to the wire buffer structure
822 * @param offset Offset in the wire buffer
823 * @param desc The description string
824 *
825 * Uses the octets function.
826 */
827
828#define of_wire_buffer_desc_str_set(buf, offset, desc) \
829 _wbuf_octets_set(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)
830
831/**
832 * Get a serial number string from a wire buffer
833 * @param wbuf The pointer to the wire buffer structure
834 * @param offset Offset in the wire buffer
835 * @param sernum Where to store the serial number string
836 *
837 * Uses the octets function.
838 */
839
840#define of_wire_buffer_ser_num_get(buf, offset, sernum) \
841 _wbuf_octets_get(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)
842
843/**
844 * Set a serial number string in a wire buffer
845 * @param wbuf The pointer to the wire buffer structure
846 * @param offset Offset in the wire buffer
847 * @param desc The serial number string
848 *
849 * Uses the octets function.
850 */
851
852#define of_wire_buffer_ser_num_set(buf, offset, sernum) \
853 _wbuf_octets_set(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)
854
855/**
856 * Get an ipv6 address from a wire buffer
857 * @param wbuf The pointer to the wire buffer structure
858 * @param offset Offset in the wire buffer
859 * @param addr Pointer to where to store the ipv6 address
860 *
861 * Uses the octets function.
862 */
863
864#define of_wire_buffer_ipv6_get(buf, offset, addr) \
865 _wbuf_octets_get(buf, offset, (uint8_t *)addr, sizeof(of_ipv6_t))
866
867/**
868 * Set an ipv6 address in a wire buffer
869 * @param wbuf The pointer to the wire buffer structure
870 * @param offset Offset in the wire buffer
871 * @param addr The variable holding ipv6 address to store
872 *
873 * Uses the octets function.
874 */
875
876#define of_wire_buffer_ipv6_set(buf, offset, addr) \
877 _wbuf_octets_set(buf, offset, (uint8_t *)&addr, sizeof(of_ipv6_t))
878
Rich Lane3b2fd832013-09-24 13:44:08 -0700879/**
880 * Get an bitmap_128 address from a wire buffer
881 * @param wbuf The pointer to the wire buffer structure
882 * @param offset Offset in the wire buffer
883 * @param addr Pointer to where to store the bitmap_128 address
884 *
885 * Uses the octets function.
886 */
887
888#define of_wire_buffer_bitmap_128_get(buf, offset, addr) \
889 (of_wire_buffer_u64_get(buf, offset, &addr->hi), of_wire_buffer_u64_get(buf, offset+8, &addr->lo))
890
891/**
892 * Set an bitmap_128 address in a wire buffer
893 * @param wbuf The pointer to the wire buffer structure
894 * @param offset Offset in the wire buffer
895 * @param addr The variable holding bitmap_128 address to store
896 *
897 * Uses the octets function.
898 */
899
900#define of_wire_buffer_bitmap_128_set(buf, offset, addr) \
901 (of_wire_buffer_u64_set(buf, offset, addr.hi), of_wire_buffer_u64_set(buf, offset+8, addr.lo))
902
Rich Lanefab0c822013-12-30 11:46:48 -0800903/**
904 * Get a checksum_128 from a wire buffer
905 * @param wbuf The pointer to the wire buffer structure
906 * @param offset Offset in the wire buffer
907 * @param checksum Pointer to where to store the checksum_128
908 */
909
910#define of_wire_buffer_checksum_128_get(buf, offset, checksum) \
911 (of_wire_buffer_u64_get(buf, offset, &checksum->hi), of_wire_buffer_u64_get(buf, offset+8, &checksum->lo))
912
913/**
914 * Set a checksum_128 in a wire buffer
915 * @param wbuf The pointer to the wire buffer structure
916 * @param offset Offset in the wire buffer
917 * @param checksum The variable holding checksum_128 to store
918 */
919
920#define of_wire_buffer_checksum_128_set(buf, offset, checksum) \
921 (of_wire_buffer_u64_set(buf, offset, checksum.hi), of_wire_buffer_u64_set(buf, offset+8, checksum.lo))
922
Rich Lanea06d0c32013-03-25 08:52:03 -0700923/* Relocate data from start offset to the end of the buffer to a new position */
924static inline void
925of_wire_buffer_move_end(of_wire_buffer_t *wbuf, int start_offset, int new_offset)
926{
927 int bytes;
928 int new_length;
929
930 if (new_offset > start_offset) {
931 bytes = new_offset - start_offset;
932 new_length = wbuf->alloc_bytes + bytes;
933 OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, new_length);
934 } else {
935 bytes = start_offset - new_offset;
936 new_length = wbuf->alloc_bytes - bytes;
937 }
938
939 MEMMOVE(&wbuf->buf[new_offset], &wbuf->buf[start_offset], bytes);
940 wbuf->alloc_bytes = new_length;
941}
942
943/* Given a wire buffer object and the offset of the start of an of_match struct,
944 * return its total length in the buffer
945 */
946static inline int
947of_match_bytes(of_wire_buffer_t *wbuf, int offset) {
948 uint16_t len;
949 of_wire_buffer_u16_get(wbuf, offset + 2, &len);
950 return OF_MATCH_BYTES(len);
951}
952
953extern void
954of_wire_buffer_replace_data(of_wire_buffer_t *wbuf,
955 int offset,
956 int old_len,
957 uint8_t *data,
958 int new_len);
959
960#endif /* _OF_WIRE_BUF_H_ */