blob: 5f63d29fe711c65392560fad16e236e498a89f75 [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')
#include <loci/loci.h>
#include <loci/of_object.h>
#include "loci_log.h"
#include "loci_int.h"
/* Flow stats entry setup for all versions */
static int
flow_stats_entry_setup_from_flow_add_common(of_flow_stats_entry_t *obj,
of_flow_add_t *flow_add,
of_object_t *effects,
int entry_match_offset,
int add_match_offset)
{
int entry_len, add_len;
of_wire_buffer_t *wbuf;
int abs_offset;
int delta;
uint16_t val16;
uint64_t cookie;
of_octets_t match_octets;
/* Transfer the match underlying object from add to stats entry */
wbuf = OF_OBJECT_TO_WBUF(obj);
entry_len = _WIRE_MATCH_PADDED_LEN(obj, entry_match_offset);
add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);
match_octets.bytes = add_len;
match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);
/* Copy data into flow entry */
abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, entry_match_offset);
of_wire_buffer_replace_data(wbuf, abs_offset, entry_len,
match_octets.data, add_len);
/* Not scalar, update lengths if needed */
delta = add_len - entry_len;
if (delta != 0) {
/* Update parent(s) */
of_object_parent_length_update((of_object_t *)obj, delta);
}
of_flow_add_cookie_get(flow_add, &cookie);
of_flow_stats_entry_cookie_set(obj, cookie);
of_flow_add_priority_get(flow_add, &val16);
of_flow_stats_entry_priority_set(obj, val16);
of_flow_add_idle_timeout_get(flow_add, &val16);
of_flow_stats_entry_idle_timeout_set(obj, val16);
of_flow_add_hard_timeout_get(flow_add, &val16);
of_flow_stats_entry_hard_timeout_set(obj, val16);
/* Effects may come from different places */
if (effects != NULL) {
if (obj->version == OF_VERSION_1_0) {
OF_TRY(of_flow_stats_entry_actions_set(obj,
(of_list_action_t *)effects));
} else {
OF_TRY(of_flow_stats_entry_instructions_set(obj,
(of_list_instruction_t *)effects));
}
} else {
if (obj->version == OF_VERSION_1_0) {
of_list_action_t actions;
of_flow_add_actions_bind(flow_add, &actions);
OF_TRY(of_flow_stats_entry_actions_set(obj, &actions));
} else {
of_list_instruction_t instructions;
of_flow_add_instructions_bind(flow_add, &instructions);
OF_TRY(of_flow_stats_entry_instructions_set(obj, &instructions));
}
}
return OF_ERROR_NONE;
}
/* Flow removed setup for all versions */
static int
flow_removed_setup_from_flow_add_common(of_flow_removed_t *obj,
of_flow_add_t *flow_add,
int removed_match_offset,
int add_match_offset)
{
int add_len, removed_len;
of_wire_buffer_t *wbuf;
int abs_offset;
int delta;
uint16_t val16;
uint64_t cookie;
of_octets_t match_octets;
/* Transfer the match underlying object from add to removed obj */
wbuf = OF_OBJECT_TO_WBUF(obj);
removed_len = _WIRE_MATCH_PADDED_LEN(obj, removed_match_offset);
add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);
match_octets.bytes = add_len;
match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);
/* Copy data into flow removed */
abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, removed_match_offset);
of_wire_buffer_replace_data(wbuf, abs_offset, removed_len,
match_octets.data, add_len);
/* Not scalar, update lengths if needed */
delta = add_len - removed_len;
if (delta != 0) {
/* Update parent(s) */
of_object_parent_length_update((of_object_t *)obj, delta);
}
of_flow_add_cookie_get(flow_add, &cookie);
of_flow_removed_cookie_set(obj, cookie);
of_flow_add_priority_get(flow_add, &val16);
of_flow_removed_priority_set(obj, val16);
of_flow_add_idle_timeout_get(flow_add, &val16);
of_flow_removed_idle_timeout_set(obj, val16);
if (obj->version >= OF_VERSION_1_2) {
of_flow_add_hard_timeout_get(flow_add, &val16);
of_flow_removed_hard_timeout_set(obj, val16);
}
return OF_ERROR_NONE;
}
/* Set up a flow removed message from the original add */
int
of_flow_removed_setup_from_flow_add(of_flow_removed_t *obj,
of_flow_add_t *flow_add)
{
switch (obj->version) {
case OF_VERSION_1_0:
return flow_removed_setup_from_flow_add_common(obj, flow_add,
8, 8);
break;
case OF_VERSION_1_1:
case OF_VERSION_1_2:
case OF_VERSION_1_3:
return flow_removed_setup_from_flow_add_common(obj, flow_add,
48, 48);
break;
default:
return OF_ERROR_VERSION;
break;
}
return OF_ERROR_NONE;
}
/* Set up a packet in message from the original add */
int
of_packet_in_setup_from_flow_add(of_packet_in_t *obj,
of_flow_add_t *flow_add)
{
int add_len, pkt_in_len;
of_wire_buffer_t *wbuf;
int abs_offset;
int delta;
const int pkt_in_match_offset = 16;
const int add_match_offset = 48;
of_octets_t match_octets;
if (obj->version < OF_VERSION_1_2) {
/* Nothing to be done before OF 1.2 */
return OF_ERROR_NONE;
}
/* Transfer match struct from flow add to packet in object */
wbuf = OF_OBJECT_TO_WBUF(obj);
pkt_in_len = _WIRE_MATCH_PADDED_LEN(obj, pkt_in_match_offset);
add_len = _WIRE_MATCH_PADDED_LEN(flow_add, add_match_offset);
match_octets.bytes = add_len;
match_octets.data = OF_OBJECT_BUFFER_INDEX(flow_add, add_match_offset);
/* Copy data into pkt_in msg */
abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, pkt_in_match_offset);
of_wire_buffer_replace_data(wbuf, abs_offset, pkt_in_len,
match_octets.data, add_len);
/* Not scalar, update lengths if needed */
delta = add_len - pkt_in_len;
if (delta != 0) {
/* Update parent(s) */
of_object_parent_length_update((of_object_t *)obj, delta);
}
return OF_ERROR_NONE;
}
/* Set up a stats entry from the original add */
int
of_flow_stats_entry_setup_from_flow_add(of_flow_stats_entry_t *obj,
of_flow_add_t *flow_add,
of_object_t *effects)
{
switch (obj->version) {
case OF_VERSION_1_0:
return flow_stats_entry_setup_from_flow_add_common(obj, flow_add,
effects, 4, 8);
break;
case OF_VERSION_1_1:
case OF_VERSION_1_2:
case OF_VERSION_1_3:
return flow_stats_entry_setup_from_flow_add_common(obj, flow_add,
effects, 48, 48);
break;
default:
return OF_ERROR_VERSION;
}
return OF_ERROR_NONE;
}