blob: 9ade2c42d53abeed15bf492af246ba2cf23c3b7b [file] [log] [blame]
:: # Copyright 2013, Big Switch Networks, Inc.
:: #
:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
:: # the following special exception:
:: #
:: # LOXI Exception
:: #
:: # As a special exception to the terms of the EPL, you may distribute libraries
:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
:: # from the LoxiGen Libraries and the notice provided below is (i) included in
:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
:: # documentation for the LoxiGen Libraries, if distributed in binary form.
:: #
:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
:: #
:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
:: # a copy of the EPL at:
:: #
:: # http://www.eclipse.org/legal/epl-v10.html
:: #
:: # Unless required by applicable law or agreed to in writing, software
:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
:: # EPL for the specific language governing permissions and limitations
:: # under the EPL.
::
:: include('_copyright.c')
#if !defined(_OF_WIRE_BUF_H_)
#define _OF_WIRE_BUF_H_
#include <string.h>
#include <loci/loci_base.h>
#include <loci/of_object.h>
#include <loci/of_match.h>
#include <loci/of_buffer.h>
/****************************************************************
*
* Wire buffer declaration, constructor, data alloc, delete
*
****************************************************************/
/* Maximum length of an OpenFlow message. All wire buffers allocated for
* new objects (that don't come from a message) are this length to avoid
* needing to grow the buffers. */
#define OF_WIRE_BUFFER_MAX_LENGTH 65535
/**
* Buffer management structure
*/
typedef struct of_wire_buffer_s {
/** Pointer to a monolithic data buffer */
uint8_t *buf;
/** Length of buffer actually allocated */
int alloc_bytes;
/** Current extent actually used */
int current_bytes;
/** If not NULL, use this to dealloc buf */
of_buffer_free_f free;
} of_wire_buffer_t;
#define WBUF_BUF(wbuf) (wbuf)->buf
#define WBUF_ALLOC_BYTES(wbuf) (wbuf)->alloc_bytes
#define WBUF_CURRENT_BYTES(wbuf) (wbuf)->current_bytes
/**
* For read access, throw an error code if current buffer
* is not big enough.
* @param wbuf Pointer to an of_wire_buffer_t structure
* @param offset The extent of the buffer required
*/
#define OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset) \
LOCI_ASSERT(((wbuf) != NULL) && (WBUF_BUF(wbuf) != NULL) && \
(offset > 0) && (WBUF_CURRENT_BYTES(wbuf) >= offset))
/*
* Index a wire buffer
* Index a wire object (from obj_offset)
* Index a LOCI object
*/
/**
* Return a pointer to a particular offset in a wire buffer's data
* @param wbuf Pointer to an of_wire_buffer_t structure
* @param offset The location to reference
*/
#define OF_WIRE_BUFFER_INDEX(wbuf, offset) (&((WBUF_BUF(wbuf))[offset]))
/****************************************************************
* Object specific macros; of_object_t includes a wire_object
****************************************************************/
/**
* Return a pointer to a particular offset in the underlying buffer
* associated with a wire object
* @param obj Pointer to an of_object_t object
* @param offset The location to reference relative to the start of the object
*/
#define OF_OBJECT_BUFFER_INDEX(obj, offset) \
OF_WIRE_BUFFER_INDEX((obj)->wbuf, (obj)->obj_offset + offset)
/**
* Return the absolute offset as an integer from a object-relative offset
* @param obj Pointer to an of_wire_object_t structure
* @param offset The location to reference relative to the start of the object
*/
#define OF_OBJECT_ABSOLUTE_OFFSET(obj, offset) \
((obj)->obj_offset + offset)
/**
* Map a generic object to the underlying wire buffer object (not the octets)
*
* Treat as private
*/
#define OF_OBJECT_TO_WBUF(obj) ((obj)->wbuf)
/**
* Allocate a wire buffer object and the underlying data buffer.
* The wire buffer is initally empty (current_bytes == 0).
* @param a_bytes The number of bytes to allocate.
* @returns A wire buffer object if successful or NULL
*/
static inline of_wire_buffer_t *
of_wire_buffer_new(int a_bytes)
{
of_wire_buffer_t *wbuf;
wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
if (wbuf == NULL) {
return NULL;
}
MEMSET(wbuf, 0, sizeof(of_wire_buffer_t));
if ((wbuf->buf = (uint8_t *)MALLOC(a_bytes)) == NULL) {
FREE(wbuf);
return NULL;
}
wbuf->current_bytes = 0;
wbuf->alloc_bytes = a_bytes;
return (of_wire_buffer_t *)wbuf;
}
/**
* Allocate a wire buffer object and bind it to an existing buffer.
* @param buf Existing buffer.
* @param bytes Size of buf.
* @param buf_free Function called to deallocate buf.
* @returns A wire buffer object if successful or NULL
*/
static inline of_wire_buffer_t *
of_wire_buffer_new_bind(uint8_t *buf, int bytes, of_buffer_free_f buf_free)
{
of_wire_buffer_t *wbuf;
wbuf = (of_wire_buffer_t *)MALLOC(sizeof(of_wire_buffer_t));
if (wbuf == NULL) {
return NULL;
}
wbuf->buf = buf;
wbuf->free = buf_free;
wbuf->current_bytes = bytes;
wbuf->alloc_bytes = bytes;
return (of_wire_buffer_t *)wbuf;
}
static inline void
of_wire_buffer_free(of_wire_buffer_t *wbuf)
{
if (wbuf == NULL) return;
if (wbuf->buf != NULL) {
if (wbuf->free != NULL) {
wbuf->free(wbuf->buf);
} else {
FREE(wbuf->buf);
}
}
FREE(wbuf);
}
static inline void
of_wire_buffer_steal(of_wire_buffer_t *wbuf, uint8_t **buffer)
{
*buffer = wbuf->buf;
/* Mark underlying data buffer as taken */
wbuf->buf = NULL;
of_wire_buffer_free(wbuf);
}
/**
* Increase the currently used length of the wire buffer.
* Will fail an assertion if the allocated length is not long enough.
*
* @param wbuf Pointer to the wire buffer structure
* @param bytes Total number of bytes buffer should grow to
*/
static inline void
of_wire_buffer_grow(of_wire_buffer_t *wbuf, int bytes)
{
LOCI_ASSERT(wbuf != NULL);
LOCI_ASSERT(wbuf->alloc_bytes >= bytes);
if (bytes > wbuf->current_bytes) {
MEMSET(wbuf->buf + wbuf->current_bytes, 0, bytes - wbuf->current_bytes);
wbuf->current_bytes = bytes;
}
}
/* TBD */
/**
* Get a uint8_t scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u8_get(of_wire_buffer_t *wbuf, int offset, uint8_t *value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
buf_u8_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Set a uint8_t scalar in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u8_set(of_wire_buffer_t *wbuf, int offset, uint8_t value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint8_t));
buf_u8_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Get a uint16_t scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u16_get(of_wire_buffer_t *wbuf, int offset, uint16_t *value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
buf_u16_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Set a uint16_t scalar in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u16_set(of_wire_buffer_t *wbuf, int offset, uint16_t value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint16_t));
buf_u16_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Get a uint32_t scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u32_get(of_wire_buffer_t *wbuf, int offset, uint32_t *value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
buf_u32_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Set a uint32_t scalar in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u32_set(of_wire_buffer_t *wbuf, int offset, uint32_t value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint32_t));
buf_u32_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Get a uint32_t scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_ipv4_get(of_wire_buffer_t *wbuf, int offset, of_ipv4_t *value)
{
of_wire_buffer_u32_get(wbuf, offset, value);
}
/**
* Set a ipv4 (uint32_t) scalar in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_ipv4_set(of_wire_buffer_t *wbuf, int offset, of_ipv4_t value)
{
of_wire_buffer_u32_set(wbuf, offset, value);
}
/**
* Get a uint64_t scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u64_get(of_wire_buffer_t *wbuf, int offset, uint64_t *value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
buf_u64_get(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Set a uint64_t scalar in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_u64_set(of_wire_buffer_t *wbuf, int offset, uint64_t value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(uint64_t));
buf_u64_set(OF_WIRE_BUFFER_INDEX(wbuf, offset), value);
}
/**
* Get a generic OF match structure from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to the structure to update
*
* NOT IMPLEMENTED.
*
*/
static inline void
of_wire_buffer_match_get(int version, of_wire_buffer_t *wbuf, int offset,
of_match_t *value)
{
LOCI_ASSERT(0);
}
/**
* Set a generic OF match structure in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to the structure to store
*
* NOT IMPLEMENTED.
*
*/
static inline void
of_wire_buffer_match_set(int version, of_wire_buffer_t *wbuf, int offset,
of_match_t *value)
{
LOCI_ASSERT(0);
}
/**
* Get a port description object from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to the structure to fill out
*
* NOT IMPLEMENTED.
*
* @fixme Where should this go?
*/
static inline void
of_wire_buffer_of_port_desc_get(int version, of_wire_buffer_t *wbuf, int offset,
void *value)
{
LOCI_ASSERT(0);
}
/**
* Set a port description object in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to the structure to fill out
*
* NOT IMPLEMENTED.
*
* @fixme Where should this go?
*/
static inline void
of_wire_buffer_of_port_desc_set(int version, of_wire_buffer_t *wbuf, int offset,
void *value)
{
LOCI_ASSERT(0);
}
/**
* Get a port number scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* Port numbers are version specific.
*/
static inline void
of_wire_buffer_port_no_get(int version, of_wire_buffer_t *wbuf, int offset,
of_port_no_t *value)
{
uint16_t v16;
uint32_t v32;
switch (version) {
case OF_VERSION_1_0:
of_wire_buffer_u16_get(wbuf, offset, &v16);
*value = v16;
break;
default:
of_wire_buffer_u32_get(wbuf, offset, &v32);
*value = v32;
break;
}
}
/**
* Set a port number scalar from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store in the buffer
*
* Port numbers are version specific.
*/
static inline void
of_wire_buffer_port_no_set(int version, of_wire_buffer_t *wbuf, int offset,
of_port_no_t value)
{
switch (version) {
case OF_VERSION_1_0:
of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
break;
default:
of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
break;
}
}
/**
* Get a flow mod command value from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*/
static inline void
of_wire_buffer_fm_cmd_get(int version, of_wire_buffer_t *wbuf, int offset,
of_fm_cmd_t *value)
{
uint16_t v16;
uint8_t v8;
switch (version) {
case OF_VERSION_1_0:
of_wire_buffer_u16_get(wbuf, offset, &v16);
*value = v16;
break;
default:
of_wire_buffer_u8_get(wbuf, offset, &v8);
*value = v8;
break;
}
}
/**
* Set a flow mod command value in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*/
static inline void
of_wire_buffer_fm_cmd_set(int version, of_wire_buffer_t *wbuf, int offset,
of_fm_cmd_t value)
{
switch (version) {
case OF_VERSION_1_0:
of_wire_buffer_u16_set(wbuf, offset, (uint16_t)value);
break;
default:
of_wire_buffer_u8_set(wbuf, offset, (uint8_t)value);
break;
}
}
/**
* Get a wild card bitmap value from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to store the value
*/
static inline void
of_wire_buffer_wc_bmap_get(int version, of_wire_buffer_t *wbuf, int offset,
of_wc_bmap_t *value)
{
uint32_t v32;
uint64_t v64;
switch (version) {
case OF_VERSION_1_0:
case OF_VERSION_1_1:
of_wire_buffer_u32_get(wbuf, offset, &v32);
*value = v32;
break;
default:
of_wire_buffer_u64_get(wbuf, offset, &v64);
*value = v64;
break;
}
}
/**
* Set a wild card bitmap value in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*/
static inline void
of_wire_buffer_wc_bmap_set(int version, of_wire_buffer_t *wbuf, int offset,
of_wc_bmap_t value)
{
switch (version) {
case OF_VERSION_1_0:
case OF_VERSION_1_1:
of_wire_buffer_u32_set(wbuf, offset, (uint32_t)value);
break;
default:
of_wire_buffer_u64_set(wbuf, offset, (uint64_t)value);
break;
}
}
/* match bitmap and wildcard bitmaps followed the same pattern */
#define of_wire_buffer_match_bmap_get of_wire_buffer_wc_bmap_get
#define of_wire_buffer_match_bmap_set of_wire_buffer_wc_bmap_set
/* Derived functions, mostly for fixed length name strings */
#define of_wire_buffer_char_get of_wire_buffer_u8_get
#define of_wire_buffer_char_set of_wire_buffer_u8_set
/**
* Get an octet object from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* of_octets_t is treated specially as the high level functions pass around
* pointers for "get" operators.
*
* Important: The length of data to copy is stored in the value->bytes
* variable.
*/
static inline void
of_wire_buffer_octets_data_get(of_wire_buffer_t *wbuf, int offset,
of_octets_t *value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
buf_octets_get(OF_WIRE_BUFFER_INDEX(wbuf, offset),
OF_OCTETS_POINTER_GET(value),
OF_OCTETS_BYTES_GET(value));
}
/**
* Set an octet object in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to the octet stream to store
* @param cur_len Current length of data in the buffer
*
* of_octets_t is treated specially as the high level functions pass around
* pointers for "get" operators.
*
* @fixme Need to take into account cur_len
*/
static inline void
of_wire_buffer_octets_data_set(of_wire_buffer_t *wbuf, int offset,
of_octets_t *value, int cur_len)
{
// FIXME need to adjust length of octets member in buffer
LOCI_ASSERT(cur_len == 0 || cur_len == value->bytes);
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + OF_OCTETS_BYTES_GET(value));
buf_octets_set(OF_WIRE_BUFFER_INDEX(wbuf, offset),
OF_OCTETS_POINTER_GET(value),
OF_OCTETS_BYTES_GET(value));
}
static inline void
_wbuf_octets_set(of_wire_buffer_t *wbuf, int offset, uint8_t *src, int bytes) {
of_octets_t octets;
OF_OCTETS_POINTER_SET(&octets, src);
OF_OCTETS_BYTES_SET(&octets, bytes);
of_wire_buffer_octets_data_set(wbuf, offset, &octets, bytes);
}
static inline void
_wbuf_octets_get(of_wire_buffer_t *wbuf, int offset, uint8_t *dst, int bytes) {
of_octets_t octets;
OF_OCTETS_POINTER_SET(&octets, dst);
OF_OCTETS_BYTES_SET(&octets, bytes);
of_wire_buffer_octets_data_get(wbuf, offset, &octets);
}
/**
* Get a MAC address from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param mac Pointer to the mac address location
*
* Uses the octets function.
*/
#define of_wire_buffer_mac_get(buf, offset, mac) \
_wbuf_octets_get(buf, offset, (uint8_t *)mac, 6)
/**
* Set a MAC address in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param mac The variable holding the mac address to store
*
* Uses the octets function.
*/
#define of_wire_buffer_mac_set(buf, offset, mac) \
_wbuf_octets_set(buf, offset, (uint8_t *)&mac, 6)
/**
* Get a port name string from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param mac The mac address
*
* Uses the octets function.
*/
#define of_wire_buffer_port_name_get(buf, offset, portname) \
_wbuf_octets_get(buf, offset, (uint8_t *)portname, \
OF_MAX_PORT_NAME_LEN)
/**
* Set a port name address in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param portname Where to store the port name
*
* Uses the octets function.
*/
#define of_wire_buffer_port_name_set(buf, offset, portname) \
_wbuf_octets_set(buf, offset, (uint8_t *)portname, \
OF_MAX_PORT_NAME_LEN)
/**
* Get a table name string from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param portname The port name
*
* Uses the octets function.
*/
#define of_wire_buffer_tab_name_get(buf, offset, tabname) \
_wbuf_octets_get(buf, offset, (uint8_t *)tabname, \
OF_MAX_TABLE_NAME_LEN)
/**
* Set a table name address in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param mac Where to store the table name
*
* Uses the octets function.
*/
#define of_wire_buffer_tab_name_set(buf, offset, tabname) \
_wbuf_octets_set(buf, offset, (uint8_t *)tabname, \
OF_MAX_TABLE_NAME_LEN)
/**
* Get a description string from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param desc Where to store the description string
*
* Uses the octets function.
*/
#define of_wire_buffer_desc_str_get(buf, offset, desc) \
_wbuf_octets_get(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)
/**
* Set a description string in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param desc The description string
*
* Uses the octets function.
*/
#define of_wire_buffer_desc_str_set(buf, offset, desc) \
_wbuf_octets_set(buf, offset, (uint8_t *)desc, OF_DESC_STR_LEN)
/**
* Get a serial number string from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param sernum Where to store the serial number string
*
* Uses the octets function.
*/
#define of_wire_buffer_ser_num_get(buf, offset, sernum) \
_wbuf_octets_get(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)
/**
* Set a serial number string in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param desc The serial number string
*
* Uses the octets function.
*/
#define of_wire_buffer_ser_num_set(buf, offset, sernum) \
_wbuf_octets_set(buf, offset, (uint8_t *)sernum, OF_SERIAL_NUM_LEN)
/**
* Get a str64 string from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param s The string
*
* Uses the octets function.
*/
#define of_wire_buffer_str64_get(buf, offset, s) \
_wbuf_octets_get(buf, offset, (uint8_t *)s, 64)
/**
* Set a str64 string in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param s Where to store the str64
*
* Uses the octets function.
*/
#define of_wire_buffer_str64_set(buf, offset, s) \
_wbuf_octets_set(buf, offset, (uint8_t *)s, 64)
/**
* Get an ipv6 address from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param addr Pointer to where to store the ipv6 address
*
* Uses the octets function.
*/
#define of_wire_buffer_ipv6_get(buf, offset, addr) \
_wbuf_octets_get(buf, offset, (uint8_t *)addr, sizeof(of_ipv6_t))
/**
* Set an ipv6 address in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param addr The variable holding ipv6 address to store
*
* Uses the octets function.
*/
#define of_wire_buffer_ipv6_set(buf, offset, addr) \
_wbuf_octets_set(buf, offset, (uint8_t *)&addr, sizeof(of_ipv6_t))
/**
* Get an bitmap_128 address from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param addr Pointer to where to store the bitmap_128 address
*
* Uses the octets function.
*/
#define of_wire_buffer_bitmap_128_get(buf, offset, addr) \
(of_wire_buffer_u64_get(buf, offset, &addr->hi), of_wire_buffer_u64_get(buf, offset+8, &addr->lo))
/**
* Set an bitmap_128 address in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param addr The variable holding bitmap_128 address to store
*
* Uses the octets function.
*/
#define of_wire_buffer_bitmap_128_set(buf, offset, addr) \
(of_wire_buffer_u64_set(buf, offset, addr.hi), of_wire_buffer_u64_set(buf, offset+8, addr.lo))
/**
* Get a checksum_128 from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param checksum Pointer to where to store the checksum_128
*/
#define of_wire_buffer_checksum_128_get(buf, offset, checksum) \
(of_wire_buffer_u64_get(buf, offset, &checksum->hi), of_wire_buffer_u64_get(buf, offset+8, &checksum->lo))
/**
* Set a checksum_128 in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param checksum The variable holding checksum_128 to store
*/
#define of_wire_buffer_checksum_128_set(buf, offset, checksum) \
(of_wire_buffer_u64_set(buf, offset, checksum.hi), of_wire_buffer_u64_set(buf, offset+8, checksum.lo))
/**
* Get a bitmap_512 from a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value Pointer to where to put value
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_bitmap_512_get(of_wire_buffer_t *wbuf, int offset, of_bitmap_512_t *value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(of_bitmap_512_t));
int i;
for (i = 0; i < 8; i++) {
buf_u64_get(OF_WIRE_BUFFER_INDEX(wbuf, offset+i*8), &value->words[i]);
}
}
/**
* Set a bitmap_512 in a wire buffer
* @param wbuf The pointer to the wire buffer structure
* @param offset Offset in the wire buffer
* @param value The value to store
*
* The underlying buffer accessor funtions handle endian and alignment.
*/
static inline void
of_wire_buffer_bitmap_512_set(of_wire_buffer_t *wbuf, int offset, of_bitmap_512_t value)
{
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, offset + (int) sizeof(of_bitmap_512_t));
int i;
for (i = 0; i < 8; i++) {
buf_u64_set(OF_WIRE_BUFFER_INDEX(wbuf, offset+i*8), value.words[i]);
}
}
/* Relocate data from start offset to the end of the buffer to a new position */
static inline void
of_wire_buffer_move_end(of_wire_buffer_t *wbuf, int start_offset, int new_offset)
{
int bytes;
int new_length;
if (new_offset > start_offset) {
bytes = new_offset - start_offset;
new_length = wbuf->alloc_bytes + bytes;
OF_WIRE_BUFFER_ACCESS_CHECK(wbuf, new_length);
} else {
bytes = start_offset - new_offset;
new_length = wbuf->alloc_bytes - bytes;
}
MEMMOVE(&wbuf->buf[new_offset], &wbuf->buf[start_offset], bytes);
wbuf->alloc_bytes = new_length;
}
/* Given a wire buffer object and the offset of the start of an of_match struct,
* return its total length in the buffer
*/
static inline int
of_match_bytes(of_wire_buffer_t *wbuf, int offset) {
uint16_t len;
of_wire_buffer_u16_get(wbuf, offset + 2, &len);
return OF_MATCH_BYTES(len);
}
extern void
of_wire_buffer_replace_data(of_wire_buffer_t *wbuf,
int offset,
int old_len,
uint8_t *data,
int new_len);
#endif /* _OF_WIRE_BUF_H_ */