/** * Iteratively update parent lengths thru hierarchy * @param obj The object whose length is being updated * @param delta The difference between the current and new lengths * * Note that this includes updating the object itself. It will * iterate thru parents. * * Assumes delta > 0. */ void of_object_parent_length_update(of_object_t *obj, int delta) { #ifndef NDEBUG int count = 0; of_wire_buffer_t *wbuf; /* For debug asserts only */ #endif while (obj != NULL) { LOCI_ASSERT(count++ < _MAX_PARENT_ITERATIONS); obj->length += delta; of_object_wire_length_set(obj, obj->length); #ifndef NDEBUG wbuf = obj->wbuf; #endif /* Asserts for wire length checking */ LOCI_ASSERT(obj->length + obj->obj_offset <= WBUF_CURRENT_BYTES(wbuf)); if (obj->parent == NULL) { LOCI_ASSERT(obj->length + obj->obj_offset == WBUF_CURRENT_BYTES(wbuf)); } obj = obj->parent; } }
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_table_feature_prop_header_init(of_table_feature_prop_header_t *obj, of_version_t version, int bytes, int clean_wire) { LOCI_ASSERT(of_object_fixed_len[version][OF_TABLE_FEATURE_PROP_HEADER] >= 0); if (clean_wire) { MEMSET(obj, 0, sizeof(*obj)); } if (bytes < 0) { bytes = of_object_fixed_len[version][OF_TABLE_FEATURE_PROP_HEADER] + of_object_extra_len[version][OF_TABLE_FEATURE_PROP_HEADER]; } obj->version = version; obj->length = bytes; obj->object_id = OF_TABLE_FEATURE_PROP_HEADER; /* Set up the object's function pointers */ 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_object_wire_buffer_steal(of_object_t *obj, uint8_t **buffer) { LOCI_ASSERT(obj != NULL); of_wire_buffer_steal(obj->wbuf, buffer); obj->wbuf = NULL; }
int of_object_buffer_bind(of_object_t *obj, uint8_t *buf, int bytes, of_buffer_free_f buf_free) { of_wire_buffer_t *wbuf; LOCI_ASSERT(buf != NULL); LOCI_ASSERT(bytes > 0); wbuf = of_wire_buffer_new_bind(buf, bytes, buf_free); if (wbuf == NULL) { return OF_ERROR_RESOURCE; } obj->wbuf = wbuf; obj->obj_offset = 0; obj->length = bytes; return OF_ERROR_NONE; }
/** * Generic list next function * @param parent The parent; must be a list object * @param child The child object; must be of type list element * @return OF_ERROR_RANGE if at end of list * @return OF_ERROR_ * * Advances the child to point to the subsequent element in the list. * The wire buffer object must not have been modified since the * previous call to _first or _next. * * @note TREAT AS PRIVATE * Does not fully initialized object */ int of_list_next(of_object_t *parent, of_object_t *child) { int offset; LOCI_ASSERT(child->length > 0); /* Get offset of parent */ if (of_list_is_last(parent, child)) { return OF_ERROR_RANGE; /* We were on the last object */ } /* Offset is relative to parent start */ offset = (child->obj_offset - parent->obj_offset) + child->length; object_child_attach(parent, child, offset, 0); 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_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); } }
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); } }