blob: 3fcf024ba30cbfa649a81335effdc6c9a310d490 [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')
/****************************************************************
*
* Functions related to mapping wire values to object types
* and lengths
*
****************************************************************/
#include <loci/loci.h>
#include <loci/of_message.h>
${legacy_code}
/****************************************************************
* Top level OpenFlow message length functions
****************************************************************/
/**
* Get the length of a message object as reported on the wire
* @param obj The object to check
* @param bytes (out) Where the length is stored
* @returns OF_ERROR_ code
*/
void
of_object_message_wire_length_get(of_object_t *obj, int *bytes)
{
LOCI_ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
// LOCI_ASSERT(obj is message)
*bytes = of_message_length_get(OF_OBJECT_TO_MESSAGE(obj));
}
/**
* Set the length of a message object as reported on the wire
* @param obj The object to check
* @param bytes The new length of the object
* @returns OF_ERROR_ code
*/
void
of_object_message_wire_length_set(of_object_t *obj, int bytes)
{
LOCI_ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
// LOCI_ASSERT(obj is message)
of_message_length_set(OF_OBJECT_TO_MESSAGE(obj), bytes);
}
/****************************************************************
* TLV16 type/length functions
****************************************************************/
/**
* Many objects are TLVs and use uint16 for the type and length values
* stored on the wire at the beginning of the buffer.
*/
#define TLV16_WIRE_TYPE_OFFSET 0
#define TLV16_WIRE_LENGTH_OFFSET 2
/**
* Get the length field from the wire for a standard TLV
* object that uses uint16 for both type and length.
* @param obj The object being referenced
* @param bytes (out) Where to store the length
*/
void
of_tlv16_wire_length_get(of_object_t *obj, int *bytes)
{
uint16_t val16;
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_get(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_LENGTH_OFFSET), &val16);
*bytes = val16;
}
/**
* Set the length field in the wire buffer for a standard TLV
* object that uses uint16 for both type and length.
* @param obj The object being referenced
* @param bytes The length value to use
*/
void
of_tlv16_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, TLV16_WIRE_LENGTH_OFFSET), bytes);
}
/****************************************************************
* OXM type/length functions.
****************************************************************/
/* Where does the OXM type-length header lie in the buffer */
#define OXM_HDR_OFFSET 0
/**
* Get the OXM header (type-length fields) from the wire buffer
* associated with an OXM object
*
* Will return if error; set hdr to the OXM header
*/
#define _GET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
wbuf = OF_OBJECT_TO_WBUF(obj); \
LOCI_ASSERT(wbuf != NULL); \
of_wire_buffer_u32_get(wbuf, \
OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
} while (0)
#define _SET_OXM_TYPE_LEN(obj, tl_p, wbuf) do { \
wbuf = OF_OBJECT_TO_WBUF(obj); \
LOCI_ASSERT(wbuf != NULL); \
of_wire_buffer_u32_set(wbuf, \
OF_OBJECT_ABSOLUTE_OFFSET(obj, OXM_HDR_OFFSET), (tl_p)); \
} while (0)
/**
* Get the length of an OXM object from the wire buffer
* @param obj The object whose wire buffer is an OXM type
* @param bytes (out) Where length is stored
*/
void
of_oxm_wire_length_get(of_object_t *obj, int *bytes)
{
uint32_t type_len;
of_wire_buffer_t *wbuf;
_GET_OXM_TYPE_LEN(obj, &type_len, wbuf);
*bytes = OF_OXM_LENGTH_GET(type_len);
}
#define OF_U16_LEN_LENGTH_OFFSET 0
/**
* Get the wire length for an object with a uint16 length as first member
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*/
void
of_u16_len_wire_length_get(of_object_t *obj, int *bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
uint16_t u16;
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_get(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
&u16);
*bytes = u16;
}
/**
* Set the wire length for an object with a uint16 length as first member
* @param obj The object being referenced
* @param bytes The length of the object
*/
void
of_u16_len_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
/* LOCI_ASSERT(obj is u16-len entry) */
of_wire_buffer_u16_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_U16_LEN_LENGTH_OFFSET),
bytes);
}
#define OF_PACKET_QUEUE_LENGTH_OFFSET(ver) \
(((ver) >= OF_VERSION_1_2) ? 8 : 4)
/**
* Get the wire length for a packet queue object
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*
* The length is a uint16 at the offset indicated above
*/
void
of_packet_queue_wire_length_get(of_object_t *obj, int *bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
uint16_t u16;
int offset;
LOCI_ASSERT(wbuf != NULL);
/* LOCI_ASSERT(obj is packet queue obj) */
offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
&u16);
*bytes = u16;
}
/**
* Set the wire length for a 1.2 packet queue object
* @param obj The object being referenced
* @param bytes The length of the object
*
* The length is a uint16 at the offset indicated above
*/
void
of_packet_queue_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
int offset;
LOCI_ASSERT(wbuf != NULL);
/* LOCI_ASSERT(obj is packet queue obj) */
offset = OF_PACKET_QUEUE_LENGTH_OFFSET(obj->version);
of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, offset),
bytes);
}
/**
* Get the wire length for a meter band stats list
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*
* Must a meter_stats object as a parent
*/
void
of_list_meter_band_stats_wire_length_get(of_object_t *obj, int *bytes)
{
LOCI_ASSERT(obj->parent != NULL);
LOCI_ASSERT(obj->parent->object_id == OF_METER_STATS);
/* We're counting on the parent being properly initialized already.
* The length is stored in a uint16 at offset 4 of the parent.
*/
*bytes = obj->parent->length - OF_OBJECT_FIXED_LENGTH(obj->parent);
}
#define OF_METER_STATS_LENGTH_OFFSET 4
/**
* Get/set the wire length for a meter stats object
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*
* It's almost a TLV....
*/
void
of_meter_stats_wire_length_get(of_object_t *obj, int *bytes)
{
uint16_t val16;
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_get(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET),
&val16);
*bytes = val16;
}
void
of_meter_stats_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_set(wbuf,
OF_OBJECT_ABSOLUTE_OFFSET(obj, OF_METER_STATS_LENGTH_OFFSET), bytes);
}
/**
* Get the wire length for a port desc object
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*
* The length is only present for OF 1.4+.
*/
void
of_port_desc_wire_length_get(of_object_t *obj, int *bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
uint16_t u16;
LOCI_ASSERT(wbuf != NULL);
if (obj->version >= OF_VERSION_1_4) {
of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
&u16);
*bytes = u16;
} else {
*bytes = OF_OBJECT_FIXED_LENGTH(obj);
}
}
/**
* Set the wire length for a port desc object
* @param obj The object being referenced
* @param bytes The length of the object
*
* The length is only present for OF 1.4+.
*/
void
of_port_desc_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
if (obj->version >= OF_VERSION_1_4) {
of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 4),
bytes);
} else {
LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
}
}
/**
* Get the wire length for a port stats_entry object
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*
* The length is only present for OF 1.4+.
*/
void
of_port_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
uint16_t u16;
LOCI_ASSERT(wbuf != NULL);
if (obj->version >= OF_VERSION_1_4) {
of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
&u16);
*bytes = u16;
} else {
*bytes = OF_OBJECT_FIXED_LENGTH(obj);
}
}
/**
* Set the wire length for a port stats_entry object
* @param obj The object being referenced
* @param bytes The length of the object
*
* The length is only present for OF 1.4+.
*/
void
of_port_stats_entry_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
if (obj->version >= OF_VERSION_1_4) {
of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
bytes);
} else {
LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
}
}
/**
* Get the wire length for a queue stats_entry object
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*
* The length is only present for OF 1.4+.
*/
void
of_queue_stats_entry_wire_length_get(of_object_t *obj, int *bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
uint16_t u16;
LOCI_ASSERT(wbuf != NULL);
if (obj->version >= OF_VERSION_1_4) {
of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
&u16);
*bytes = u16;
} else {
*bytes = OF_OBJECT_FIXED_LENGTH(obj);
}
}
/**
* Set the wire length for a queue stats_entry object
* @param obj The object being referenced
* @param bytes The length of the object
*
* The length is only present for OF 1.4+.
*/
void
of_queue_stats_entry_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
if (obj->version >= OF_VERSION_1_4) {
of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 0),
bytes);
} else {
LOCI_ASSERT(obj->length == OF_OBJECT_FIXED_LENGTH(obj));
}
}
/**
* Get the wire length for a queue_desc object
* @param obj The object being referenced
* @param bytes Pointer to location to store length
*/
void
of_queue_desc_wire_length_get(of_object_t *obj, int *bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
uint16_t u16;
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_get(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 8), &u16);
*bytes = u16;
}
/**
* Set the wire length for a queue_desc object
* @param obj The object being referenced
* @param bytes The length of the object
*/
void
of_queue_desc_wire_length_set(of_object_t *obj, int bytes)
{
of_wire_buffer_t *wbuf = OF_OBJECT_TO_WBUF(obj);
LOCI_ASSERT(wbuf != NULL);
of_wire_buffer_u16_set(wbuf, OF_OBJECT_ABSOLUTE_OFFSET(obj, 8), bytes);
}