Пример #1
0
/**
 * Set match in an object of type of_flow_modify.
 * @param obj Pointer to an object of type of_flow_modify.
 * @param match Pointer to the child of type of_match_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_flow_modify_match_set(
    of_flow_modify_t *obj,
    of_match_t *match)
{
    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 */
    of_octets_t match_octets; /* Serialized string for match */

    ASSERT(IS_FLOW_MOD_SUBTYPE(obj->object_id));
    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 = 8;
        cur_len = _WIRE_MATCH_PADDED_LEN(obj, offset);
        break;
    case OF_VERSION_1_1:
        offset = 48;
        cur_len = _WIRE_MATCH_PADDED_LEN(obj, offset);
        break;
    case OF_VERSION_1_2:
    case OF_VERSION_1_3:
        offset = 48;
        cur_len = _WIRE_MATCH_PADDED_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);

    /* Match object */
    OF_TRY(of_match_serialize(ver, match, &match_octets));
    new_len = match_octets.bytes;
    of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
        match_octets.data, new_len);
    /* Free match serialized octets */
    FREE(match_octets.data);

    /* 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;
}
Пример #2
0
static int
test_match_3(void)
{
    of_match_t match1;
    of_match_t match2;
    int value = 1;
    of_octets_t octets;
    of_object_storage_t storage;
    memset(&storage, 0, sizeof(storage));
    storage.obj.wbuf = &storage.wbuf;

    /* Serialize to version OF_VERSION_1_0 */
    TEST_ASSERT((value = of_match_populate(&match1, OF_VERSION_1_0, value)) > 0);
    TEST_ASSERT(of_match_serialize(OF_VERSION_1_0, &match1, &octets) ==
        OF_ERROR_NONE);
    storage.obj.wbuf->buf = octets.data;
    storage.obj.wbuf->alloc_bytes = octets.bytes;
    storage.obj.wbuf->current_bytes = octets.bytes;
    TEST_ASSERT(of_match_deserialize(OF_VERSION_1_0, &match2, &storage.obj, 0, octets.bytes) ==
        OF_ERROR_NONE);
    TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
    FREE(octets.data);

    /* Serialize to version OF_VERSION_1_1 */
    TEST_ASSERT((value = of_match_populate(&match1, OF_VERSION_1_1, value)) > 0);
    TEST_ASSERT(of_match_serialize(OF_VERSION_1_1, &match1, &octets) ==
        OF_ERROR_NONE);
    storage.obj.wbuf->buf = octets.data;
    storage.obj.wbuf->alloc_bytes = octets.bytes;
    storage.obj.wbuf->current_bytes = octets.bytes;
    TEST_ASSERT(of_match_deserialize(OF_VERSION_1_1, &match2, &storage.obj, 0, octets.bytes) ==
        OF_ERROR_NONE);
    TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
    FREE(octets.data);

    /* Serialize to version OF_VERSION_1_2 */
    TEST_ASSERT((value = of_match_populate(&match1, OF_VERSION_1_2, value)) > 0);
    TEST_ASSERT(of_match_serialize(OF_VERSION_1_2, &match1, &octets) ==
        OF_ERROR_NONE);
    storage.obj.wbuf->buf = octets.data;
    storage.obj.wbuf->alloc_bytes = octets.bytes;
    storage.obj.wbuf->current_bytes = octets.bytes;
    TEST_ASSERT(of_match_deserialize(OF_VERSION_1_2, &match2, &storage.obj, 0, octets.bytes) ==
        OF_ERROR_NONE);
    TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
    FREE(octets.data);

    /* Serialize to version OF_VERSION_1_3 */
    TEST_ASSERT((value = of_match_populate(&match1, OF_VERSION_1_3, value)) > 0);
    TEST_ASSERT(of_match_serialize(OF_VERSION_1_3, &match1, &octets) ==
        OF_ERROR_NONE);
    storage.obj.wbuf->buf = octets.data;
    storage.obj.wbuf->alloc_bytes = octets.bytes;
    storage.obj.wbuf->current_bytes = octets.bytes;
    TEST_ASSERT(of_match_deserialize(OF_VERSION_1_3, &match2, &storage.obj, 0, octets.bytes) ==
        OF_ERROR_NONE);
    TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
    FREE(octets.data);

    return TEST_PASS;
}