void of_experimenter_error_msg_init(of_experimenter_error_msg_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_EXPERIMENTER_ERROR_MSG] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_EXPERIMENTER_ERROR_MSG] + of_object_extra_len[version][OF_EXPERIMENTER_ERROR_MSG]; } obj->version = version; obj->length = bytes; obj->object_id = OF_EXPERIMENTER_ERROR_MSG; /* Set up the object's function pointers */ obj->wire_type_set = of_experimenter_error_msg_push_wire_types; obj->wire_length_get = of_object_message_wire_length_get; obj->wire_length_set = of_object_message_wire_length_set; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
/** * Connect a child to a parent at the wire buffer level * * @param parent The top level object to bind to * @param child The sub-object connecting to the parent * @param offset The offset at which to attach the child RELATIVE * TO THE PARENT in the buffer * @param bytes The amount of the buffer dedicated to the child; see below * @param inc_ref_count Should the ref count of the parent be incremented * * This is used for 'get' accessors for composite types as well as * iterator functions for lists, both read (first/next) and write * (append_init, append_advance). * * Connect a child object to a parent by setting up the child's * wire_object to point to the parent's underlying buffer. The value * of the parameter bytes is important in determining how the child * is initialized: * @li If bytes <= 0, the length and type of the child are not modified; * no additional space is added to the buffer. * @li If bytes > 0, the current wire buffer is grown to * accomodate this many bytes. This is to support append operations. * * If an error is returned, future references to the child object * (until it is reinitialized) are undefined. */ static void object_child_attach(of_object_t *parent, of_object_t *child, int offset, int bytes) { of_wire_buffer_t *wbuf; /* Pointer to common wire buffer manager */ child->parent = parent; wbuf = parent->wbuf; /* Set up the child's wire buf to point to same as parent */ child->wbuf = wbuf; child->obj_offset = parent->obj_offset + offset; /* * bytes determines if this is a read or write setup. * If > 0, grow the buffer to accomodate the space * Otherwise do nothing */ if (bytes > 0) { /* Set internal length, request buffer space */ int tot_bytes; /* Total bytes to request for buffer if updated */ /* Set up space for the child in the parent's buffer */ tot_bytes = parent->obj_offset + offset + bytes; of_wire_buffer_grow(wbuf, tot_bytes); child->length = bytes; } /* if bytes == 0 don't do anything */ }
void of_list_meter_band_stats_init(of_list_meter_band_stats_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_LIST_METER_BAND_STATS] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_METER_BAND_STATS] + of_object_extra_len[version][OF_LIST_METER_BAND_STATS]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_METER_BAND_STATS; /* Set up the object's function pointers */ /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_bsn_controller_connection_init(of_bsn_controller_connection_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_BSN_CONTROLLER_CONNECTION] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_BSN_CONTROLLER_CONNECTION] + of_object_extra_len[version][OF_BSN_CONTROLLER_CONNECTION]; } obj->version = version; obj->length = bytes; obj->object_id = OF_BSN_CONTROLLER_CONNECTION; /* Set up the object's function pointers */ /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_experimenter_stats_header_init(of_experimenter_stats_header_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_EXPERIMENTER_STATS_HEADER] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_EXPERIMENTER_STATS_HEADER] + of_object_extra_len[version][OF_EXPERIMENTER_STATS_HEADER]; } obj->version = version; obj->length = bytes; obj->object_id = OF_EXPERIMENTER_STATS_HEADER; /* Set up the object's function pointers */ /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_bsn_gentable_desc_stats_entry_init(of_bsn_gentable_desc_stats_entry_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_BSN_GENTABLE_DESC_STATS_ENTRY] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_BSN_GENTABLE_DESC_STATS_ENTRY] + of_object_extra_len[version][OF_BSN_GENTABLE_DESC_STATS_ENTRY]; } obj->version = version; obj->length = bytes; obj->object_id = OF_BSN_GENTABLE_DESC_STATS_ENTRY; /* Set up the object's function pointers */ obj->wire_length_get = of_u16_len_wire_length_get; obj->wire_length_set = of_u16_len_wire_length_set; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_table_feature_prop_next_tables_init(of_table_feature_prop_next_tables_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_TABLE_FEATURE_PROP_NEXT_TABLES] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_TABLE_FEATURE_PROP_NEXT_TABLES] + of_object_extra_len[version][OF_TABLE_FEATURE_PROP_NEXT_TABLES]; } obj->version = version; obj->length = bytes; obj->object_id = OF_TABLE_FEATURE_PROP_NEXT_TABLES; /* Set up the object's function pointers */ obj->wire_type_set = of_table_feature_prop_next_tables_push_wire_types; obj->wire_length_set = of_tlv16_wire_length_set; obj->wire_length_get = of_tlv16_wire_length_get; obj->wire_type_get = of_table_feature_prop_wire_object_id_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_queue_stats_reply_init(of_queue_stats_reply_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_QUEUE_STATS_REPLY] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_QUEUE_STATS_REPLY] + of_object_extra_len[version][OF_QUEUE_STATS_REPLY]; } obj->version = version; obj->length = bytes; obj->object_id = OF_QUEUE_STATS_REPLY; /* Set up the object's function pointers */ obj->wire_type_set = of_queue_stats_reply_push_wire_types; obj->wire_length_get = of_object_message_wire_length_get; obj->wire_length_set = of_object_message_wire_length_set; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_oxm_bsn_l3_interface_class_id_init(of_oxm_bsn_l3_interface_class_id_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_OXM_BSN_L3_INTERFACE_CLASS_ID] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_OXM_BSN_L3_INTERFACE_CLASS_ID] + of_object_extra_len[version][OF_OXM_BSN_L3_INTERFACE_CLASS_ID]; } obj->version = version; obj->length = bytes; obj->object_id = OF_OXM_BSN_L3_INTERFACE_CLASS_ID; /* Set up the object's function pointers */ obj->wire_type_set = of_oxm_bsn_l3_interface_class_id_push_wire_types; obj->wire_length_get = of_oxm_wire_length_get; obj->wire_type_get = of_oxm_wire_object_id_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_list_queue_stats_entry_init(of_list_queue_stats_entry_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_LIST_QUEUE_STATS_ENTRY] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_QUEUE_STATS_ENTRY] + of_object_extra_len[version][OF_LIST_QUEUE_STATS_ENTRY]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_QUEUE_STATS_ENTRY; /* Set up the object's function pointers */ /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_get_config_request_init(of_get_config_request_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_GET_CONFIG_REQUEST] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_GET_CONFIG_REQUEST] + of_object_extra_len[version][OF_GET_CONFIG_REQUEST]; } obj->version = version; obj->length = bytes; obj->object_id = OF_GET_CONFIG_REQUEST; /* Set up the object's function pointers */ obj->wire_type_set = of_get_config_request_push_wire_types; obj->wire_length_get = of_object_message_wire_length_get; obj->wire_length_set = of_object_message_wire_length_set; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_list_table_feature_prop_init(of_list_table_feature_prop_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_LIST_TABLE_FEATURE_PROP] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_TABLE_FEATURE_PROP] + of_object_extra_len[version][OF_LIST_TABLE_FEATURE_PROP]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_TABLE_FEATURE_PROP; /* Set up the object's function pointers */ /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_bsn_vport_q_in_q_init(of_bsn_vport_q_in_q_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_BSN_VPORT_Q_IN_Q] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_BSN_VPORT_Q_IN_Q] + of_object_extra_len[version][OF_BSN_VPORT_Q_IN_Q]; } obj->version = version; obj->length = bytes; obj->object_id = OF_BSN_VPORT_Q_IN_Q; /* Set up the object's function pointers */ obj->wire_type_set = of_bsn_vport_q_in_q_push_wire_types; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_instruction_init(of_instruction_t *obj_p, of_version_t version, int bytes, int clean_wire) { of_instruction_header_t *obj; obj = &obj_p->header; /* Need instantiable subclass */ ASSERT(of_object_fixed_len[version][OF_INSTRUCTION] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_INSTRUCTION] + of_object_extra_len[version][OF_INSTRUCTION]; } obj->version = version; obj->length = bytes; obj->object_id = OF_INSTRUCTION; /* Set up the object's function pointers */ obj->wire_length_get = of_tlv16_wire_length_get; obj->wire_type_get = of_instruction_wire_object_id_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_instruction_id_goto_table_init(of_instruction_id_goto_table_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_INSTRUCTION_ID_GOTO_TABLE] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_INSTRUCTION_ID_GOTO_TABLE] + of_object_extra_len[version][OF_INSTRUCTION_ID_GOTO_TABLE]; } obj->version = version; obj->length = bytes; obj->object_id = OF_INSTRUCTION_ID_GOTO_TABLE; /* Set up the object's function pointers */ obj->wire_type_set = of_instruction_id_goto_table_push_wire_types; obj->wire_length_set = of_tlv16_wire_length_set; obj->wire_length_get = of_tlv16_wire_length_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_oxm_icmpv6_code_init(of_oxm_icmpv6_code_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_OXM_ICMPV6_CODE] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_OXM_ICMPV6_CODE] + of_object_extra_len[version][OF_OXM_ICMPV6_CODE]; } obj->version = version; obj->length = bytes; obj->object_id = OF_OXM_ICMPV6_CODE; /* Set up the object's function pointers */ obj->wire_type_set = of_oxm_icmpv6_code_push_wire_types; obj->wire_length_get = of_oxm_wire_length_get; obj->wire_type_get = of_oxm_wire_object_id_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_action_pop_pbb_init(of_action_pop_pbb_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_ACTION_POP_PBB] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_ACTION_POP_PBB] + of_object_extra_len[version][OF_ACTION_POP_PBB]; } obj->version = version; obj->length = bytes; obj->object_id = OF_ACTION_POP_PBB; /* Set up the object's function pointers */ obj->wire_type_set = of_action_pop_pbb_push_wire_types; obj->wire_length_set = of_tlv16_wire_length_set; obj->wire_length_get = of_tlv16_wire_length_get; obj->wire_type_get = of_action_wire_object_id_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
void of_bsn_tlv_tx_packets_init(of_bsn_tlv_tx_packets_t *obj, of_version_t version, int bytes, int clean_wire) { ASSERT(of_object_fixed_len[version][OF_BSN_TLV_TX_PACKETS] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_BSN_TLV_TX_PACKETS] + of_object_extra_len[version][OF_BSN_TLV_TX_PACKETS]; } obj->version = version; obj->length = bytes; obj->object_id = OF_BSN_TLV_TX_PACKETS; /* Set up the object's function pointers */ obj->wire_type_set = of_bsn_tlv_tx_packets_push_wire_types; obj->wire_length_set = of_tlv16_wire_length_set; obj->wire_length_get = of_tlv16_wire_length_get; obj->wire_type_get = of_bsn_tlv_wire_object_id_get; /* Grow the wire buffer */ if (obj->wire_object.wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->wire_object.obj_offset; of_wire_buffer_grow(obj->wire_object.wbuf, tot_bytes); } }
/** * Set data in an object of type of_packet_in. * @param obj Pointer to an object of type of_packet_in. * @param data The value to write into the object */ int WARN_UNUSED_RESULT of_packet_in_data_set( of_packet_in_t *obj, of_octets_t *data) { of_wire_buffer_t *wbuf; int offset = 0; /* Offset of value relative to the start obj */ int abs_offset; /* Offset of value relative to start of wbuf */ of_version_t ver; int cur_len = 0; /* Current length of object data */ int new_len, delta; /* For set, need new length and delta */ ASSERT(obj->object_id == OF_PACKET_IN); ver = obj->version; wbuf = OF_OBJECT_TO_WBUF(obj); ASSERT(wbuf != NULL); /* By version, determine offset and current length (where needed) */ switch (ver) { case OF_VERSION_1_0: offset = 18; cur_len = _END_LEN(obj, offset); break; case OF_VERSION_1_1: offset = 24; cur_len = _END_LEN(obj, offset); break; case OF_VERSION_1_2: case OF_VERSION_1_3: offset = _PACKET_IN_DATA_OFFSET(obj); cur_len = _END_LEN(obj, offset); break; default: ASSERT(0); } abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset); ASSERT(abs_offset >= 0); ASSERT(cur_len >= 0 && cur_len < 64 * 1024); new_len = data->bytes; of_wire_buffer_grow(wbuf, abs_offset + (new_len - cur_len)); of_wire_buffer_octets_data_set(wbuf, abs_offset, data, cur_len); /* Not scalar, update lengths if needed */ delta = new_len - cur_len; if (delta != 0) { /* Update parent(s) */ of_object_parent_length_update((of_object_t *)obj, delta); } OF_LENGTH_CHECK_ASSERT(obj); return OF_ERROR_NONE; }
void of_list_uint32_init(of_object_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_LIST_UINT32] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_UINT32]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_UINT32; /* Grow the wire buffer */ if (obj->wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->obj_offset; of_wire_buffer_grow(obj->wbuf, tot_bytes); } }
void of_list_bsn_gentable_entry_stats_entry_init(of_object_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_LIST_BSN_GENTABLE_ENTRY_STATS_ENTRY] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_BSN_GENTABLE_ENTRY_STATS_ENTRY]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_BSN_GENTABLE_ENTRY_STATS_ENTRY; /* Grow the wire buffer */ if (obj->wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->obj_offset; of_wire_buffer_grow(obj->wbuf, tot_bytes); } }
void of_wire_buffer_replace_data(of_wire_buffer_t *wbuf, int offset, int old_len, uint8_t *data, int new_len) { int bytes; uint8_t *src_ptr, *dst_ptr; int cur_bytes; ASSERT(wbuf != NULL); cur_bytes = wbuf->current_bytes; /* Doesn't make sense; mismatch in current buffer info */ ASSERT(old_len + offset <= wbuf->current_bytes); if (old_len < new_len) { of_wire_buffer_grow(wbuf, offset + new_len); } else { wbuf->current_bytes += (new_len - old_len); // may decrease size } if ((old_len + offset < cur_bytes) && (old_len != new_len)) { /* Need to move back of buffer */ src_ptr = &wbuf->buf[offset + old_len]; dst_ptr = &wbuf->buf[offset + new_len]; bytes = cur_bytes - (offset + old_len); MEMMOVE(dst_ptr, src_ptr, bytes); } dst_ptr = &wbuf->buf[offset]; MEMCPY(dst_ptr, data, new_len); ASSERT(wbuf->current_bytes == cur_bytes + (new_len - old_len)); }
void of_list_bucket_counter_init(of_list_bucket_counter_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_LIST_BUCKET_COUNTER] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_BUCKET_COUNTER] + of_object_extra_len[version][OF_LIST_BUCKET_COUNTER]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_BUCKET_COUNTER; /* Grow the wire buffer */ if (obj->wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->obj_offset; of_wire_buffer_grow(obj->wbuf, tot_bytes); } }
void of_list_bsn_flow_checksum_bucket_stats_entry_init(of_list_bsn_flow_checksum_bucket_stats_entry_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_LIST_BSN_FLOW_CHECKSUM_BUCKET_STATS_ENTRY] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_LIST_BSN_FLOW_CHECKSUM_BUCKET_STATS_ENTRY] + of_object_extra_len[version][OF_LIST_BSN_FLOW_CHECKSUM_BUCKET_STATS_ENTRY]; } obj->version = version; obj->length = bytes; obj->object_id = OF_LIST_BSN_FLOW_CHECKSUM_BUCKET_STATS_ENTRY; /* Grow the wire buffer */ if (obj->wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->obj_offset; of_wire_buffer_grow(obj->wbuf, tot_bytes); } }
void of_hello_elem_header_init(of_hello_elem_header_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_HELLO_ELEM_HEADER] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_HELLO_ELEM_HEADER] + of_object_extra_len[version][OF_HELLO_ELEM_HEADER]; } obj->version = version; obj->length = bytes; obj->object_id = OF_HELLO_ELEM_HEADER; /* Grow the wire buffer */ if (obj->wbuf != NULL) { int tot_bytes; tot_bytes = bytes + obj->obj_offset; of_wire_buffer_grow(obj->wbuf, tot_bytes); } }
/** * Generic atomic list append operation * @param list The list to which an item is being appended * @param item THe item to append to the list * * The contents of the item are copied to the end of the list. * Currently assumes the list is at the end of its parent. */ int of_list_append(of_object_t *list, of_object_t *item) { int new_len; new_len = list->length + item->length; if (!of_object_can_grow(list, new_len)) { return OF_ERROR_RESOURCE; } of_wire_buffer_grow(list->wbuf, OF_OBJECT_ABSOLUTE_OFFSET(list, new_len)); MEMCPY(OF_OBJECT_BUFFER_INDEX(list, list->length), OF_OBJECT_BUFFER_INDEX(item, 0), item->length); /* Update the list's length */ of_object_parent_length_update(list, item->length); OF_LENGTH_CHECK_ASSERT(list); return OF_ERROR_NONE; }
/** * Set actions in an object of type of_packet_out. * @param obj Pointer to an object of type of_packet_out. * @param actions Pointer to the child of type of_list_action_t. * * If the child's wire buffer is the same as the parent's, then * nothing is done as the changes have already been registered in the * parent. Otherwise, the data in the child's wire buffer is inserted * into the parent's and the appropriate lengths are updated. */ int WARN_UNUSED_RESULT of_packet_out_actions_set( of_packet_out_t *obj, of_list_action_t *actions) { of_wire_buffer_t *wbuf; int offset = 0; /* Offset of value relative to the start obj */ int abs_offset; /* Offset of value relative to start of wbuf */ of_version_t ver; int cur_len = 0; /* Current length of object data */ int new_len, delta; /* For set, need new length and delta */ ASSERT(obj->object_id == OF_PACKET_OUT); ver = obj->version; wbuf = OF_OBJECT_TO_WBUF(obj); ASSERT(wbuf != NULL); /* By version, determine offset and current length (where needed) */ switch (ver) { case OF_VERSION_1_0: offset = 16; cur_len = _PACKET_OUT_ACTION_LEN(obj); break; case OF_VERSION_1_1: case OF_VERSION_1_2: case OF_VERSION_1_3: offset = 24; cur_len = _PACKET_OUT_ACTION_LEN(obj); break; default: ASSERT(0); } abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset); ASSERT(abs_offset >= 0); ASSERT(cur_len >= 0 && cur_len < 64 * 1024); /* LOCI object type */ new_len = actions->length; /* If underlying buffer already shared; nothing to do */ if (obj->wire_object.wbuf == actions->wire_object.wbuf) { of_wire_buffer_grow(wbuf, abs_offset + new_len); /* Verify that the offsets are correct */ ASSERT(abs_offset == OF_OBJECT_ABSOLUTE_OFFSET(actions, 0)); /* ASSERT(new_len == cur_len); */ /* fixme: may fail for OXM lists */ return OF_ERROR_NONE; } /* Otherwise, replace existing object in data buffer */ of_wire_buffer_replace_data(wbuf, abs_offset, cur_len, OF_OBJECT_BUFFER_INDEX(actions, 0), new_len); /* Special case for setting action lengths */ _PACKET_OUT_ACTION_LEN_SET(obj, actions->length); /* Not scalar, update lengths if needed */ delta = new_len - cur_len; if (delta != 0) { /* Update parent(s) */ of_object_parent_length_update((of_object_t *)obj, delta); } OF_LENGTH_CHECK_ASSERT(obj); return OF_ERROR_NONE; }
/** * Set elements in an object of type of_hello. * @param obj Pointer to an object of type of_hello. * @param elements Pointer to the child of type of_list_hello_elem_t. * * If the child's wire buffer is the same as the parent's, then * nothing is done as the changes have already been registered in the * parent. Otherwise, the data in the child's wire buffer is inserted * into the parent's and the appropriate lengths are updated. */ int WARN_UNUSED_RESULT of_hello_elements_set( of_hello_t *obj, of_list_hello_elem_t *elements) { of_wire_buffer_t *wbuf; int offset = 0; /* Offset of value relative to the start obj */ int abs_offset; /* Offset of value relative to start of wbuf */ of_version_t ver; int cur_len = 0; /* Current length of object data */ int new_len, delta; /* For set, need new length and delta */ ASSERT(obj->object_id == OF_HELLO); ver = obj->version; wbuf = OF_OBJECT_TO_WBUF(obj); ASSERT(wbuf != NULL); /* By version, determine offset and current length (where needed) */ switch (ver) { case OF_VERSION_1_3: offset = 8; cur_len = _END_LEN(obj, offset); break; default: ASSERT(0); } abs_offset = OF_OBJECT_ABSOLUTE_OFFSET(obj, offset); ASSERT(abs_offset >= 0); ASSERT(cur_len >= 0 && cur_len < 64 * 1024); /* LOCI object type */ new_len = elements->length; /* If underlying buffer already shared; nothing to do */ if (obj->wire_object.wbuf == elements->wire_object.wbuf) { of_wire_buffer_grow(wbuf, abs_offset + new_len); /* Verify that the offsets are correct */ ASSERT(abs_offset == OF_OBJECT_ABSOLUTE_OFFSET(elements, 0)); /* ASSERT(new_len == cur_len); */ /* fixme: may fail for OXM lists */ return OF_ERROR_NONE; } /* Otherwise, replace existing object in data buffer */ of_wire_buffer_replace_data(wbuf, abs_offset, cur_len, OF_OBJECT_BUFFER_INDEX(elements, 0), new_len); /* @fixme Shouldn't this precede copying value's data to buffer? */ if (elements->wire_length_set != NULL) { elements->wire_length_set((of_object_t *)elements, elements->length); } /* Not scalar, update lengths if needed */ delta = new_len - cur_len; if (delta != 0) { /* Update parent(s) */ of_object_parent_length_update((of_object_t *)obj, delta); } OF_LENGTH_CHECK_ASSERT(obj); return OF_ERROR_NONE; }