Ejemplo n.º 1
0
:: import of_g
:: from loxi_utils import loxi_utils
:: from loxi_front_end import type_maps

/**
 * Test message validator
 *
 * Run the message validator on corrupt messages to ensure it catches them.
 */

#include "loci_log.h"

#include <locitest/test_common.h>
#include <loci/loci_validator.h>

static int
test_validate_fixed_length(void)
{
    of_table_stats_request_t *obj = of_table_stats_request_new(OF_VERSION_1_0);
    of_message_t msg = OF_OBJECT_TO_MESSAGE(obj);

    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == 0);

    of_message_length_set(msg, of_message_length_get(msg) - 1);
    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == -1);

    of_table_stats_request_delete(obj);
    return TEST_PASS;
}
Ejemplo n.º 2
0
static int
test_validate_tlv16_list(void)
{
    of_flow_modify_t *obj = of_flow_modify_new(OF_VERSION_1_0);
    of_list_action_t list;
    of_action_set_tp_dst_t element1;
    of_action_output_t element2;
    of_message_t msg; 
    of_flow_modify_actions_bind(obj, &list);
    of_action_set_tp_dst_init(&element1, OF_VERSION_1_0, -1, 1);
    of_list_action_append_bind(&list, (of_action_t *)&element1);
    of_action_output_init(&element2, OF_VERSION_1_0, -1, 1);
    of_list_action_append_bind(&list, (of_action_t *)&element2);
    msg = OF_OBJECT_TO_MESSAGE(obj);

    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == 0);

    of_message_length_set(msg, of_message_length_get(msg) - 1);
    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == -1);

    of_message_length_set(msg, of_message_length_get(msg) + 2);
    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == -1);

    of_flow_modify_delete(obj);
    return TEST_PASS;
}
Ejemplo n.º 3
0
static int
test_validate_fixed_length(void)
{
    of_table_stats_request_t *obj = of_table_stats_request_new(OF_VERSION_1_0);
    of_message_t msg = OF_OBJECT_TO_MESSAGE(obj);

    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == 0);

    of_message_length_set(msg, of_message_length_get(msg) - 1);
    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == -1);

    of_table_stats_request_delete(obj);
    return TEST_PASS;
}
Ejemplo n.º 4
0
of_hello_t *
of_hello_new_from_message(of_message_t msg)
{
    of_hello_t *obj = NULL;
    of_version_t version;
    int length;

    if (msg == NULL) return NULL;

    version = of_message_version_get(msg);
    if (!OF_VERSION_OKAY(version)) return NULL;

    length = of_message_length_get(msg);

    if ((obj = (of_hello_t *)of_object_new(-1)) == NULL) {
        return NULL;
    }

    of_hello_init(obj, version, 0, 0);

    if ((of_object_buffer_bind((of_object_t *)obj, OF_MESSAGE_TO_BUFFER(msg),
                               length, OF_MESSAGE_FREE_FUNCTION)) < 0) {
       FREE(obj);
       return NULL;
    }
    obj->length = length;
    obj->version = version;

    return obj;
}
Ejemplo n.º 5
0
/**
 * 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)
{
    ASSERT(OF_OBJECT_TO_WBUF(obj) != NULL);
    // ASSERT(obj is message)
    *bytes = of_message_length_get(OF_OBJECT_TO_MESSAGE(obj));
}
Ejemplo n.º 6
0
void
ind_cxn_bundle_add_handle(connection_t *cxn, of_object_t *obj)
{
    uint32_t bundle_id;
    uint16_t flags;
    of_octets_t data;

    of_bundle_add_msg_bundle_id_get(obj, &bundle_id);
    of_bundle_add_msg_flags_get(obj, &flags);
    of_bundle_add_msg_data_get(obj, &data);

    bundle_t *bundle = find_bundle(cxn, bundle_id);
    if (bundle == NULL) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_BAD_ID);
        return;
    }

    /* Validate length */
    if (data.bytes < OF_MESSAGE_HEADER_LENGTH || data.bytes != of_message_length_get(data.data)) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_MSG_BAD_LEN);
        AIM_LOG_WARN("Inconsistent bundled message length", bundle->id);
        return;
    }

    /* Limit number of messages in the bundle */
    if (bundle->count >= OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_MSGS) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_MSG_TOO_MANY);
        AIM_LOG_WARN("Exceeded maximum number (%u) of messages in bundle %u", OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_MSGS, bundle->id);
        return;
    }

    /* Limit amount of memory used by the bundle */
    if ((bundle->bytes + data.bytes) > OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_BYTES) {
        indigo_cxn_send_error_reply(
            cxn->cxn_id, obj,
            OF_ERROR_TYPE_BUNDLE_FAILED,
            OFPBFC_MSG_TOO_MANY);
        AIM_LOG_WARN("Exceeded maximum size (%u bytes) of messages in bundle %u", OFCONNECTIONMANAGER_CONFIG_MAX_BUNDLE_BYTES, bundle->id);
        return;
    }

    if (bundle->count == bundle->allocated) {
        /* Resize array */
        uint32_t new_allocated = (bundle->allocated == 0 ? 1 : bundle->allocated * 2);
        bundle->msgs = aim_realloc(bundle->msgs, sizeof(*bundle->msgs) * new_allocated);
        bundle->allocated = new_allocated;
    }

    bundle->msgs[bundle->count++] = aim_memdup(data.data, data.bytes);
    bundle->bytes += data.bytes;
}
Ejemplo n.º 7
0
static int
test_validate_fixed_length_list(void)
{
    of_table_stats_reply_t *obj = of_table_stats_reply_new(OF_VERSION_1_0);
    of_list_table_stats_entry_t list;
    of_table_stats_entry_t element;
    of_message_t msg; 
    of_table_stats_reply_entries_bind(obj, &list);
    of_table_stats_entry_init(&element, OF_VERSION_1_0, -1, 1);
    of_list_table_stats_entry_append_bind(&list, &element);
    of_list_table_stats_entry_append_bind(&list, &element);
    msg = OF_OBJECT_TO_MESSAGE(obj);

    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == 0);

    of_message_length_set(msg, of_message_length_get(msg) - 1);
    TEST_ASSERT(of_validate_message(msg, of_message_length_get(msg)) == -1);

    of_table_stats_reply_delete(obj);
    return TEST_PASS;
}
SwitchConnectionUtil::HandshakeResult SwitchConnectionUtil::attemptHandshake(
        std::shared_ptr<Poco::Net::SocketStream> socket,
        const of_version_t openFlowVersion) {

    uint8_t* receiveBuffer = new uint8_t[65536];
    bool ioSuccess;

    // Do handshake - send an OpenFlow hello message to the switch
    of_hello_t* hello = of_hello_new(openFlowVersion);
    ioSuccess = SwitchConnectionUtil::writeOpenFlowToSocket(*socket, hello);
    of_hello_delete(hello);

    if (ioSuccess) {
        socket->flush();
        ioSuccess = socket->good();
    }

    if (!ioSuccess) {
        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::HELLO_FAILED, OF_VERSION_UNKNOWN, 0);
    }

    ioSuccess = SwitchConnectionUtil::parseOpenFlowFromSocketToBuffer(receiveBuffer, *socket);

    if (!ioSuccess) {
        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::HELLO_FAILED, OF_VERSION_UNKNOWN, 0);
    }

    if (of_message_type_get(receiveBuffer) != OF_OBJ_TYPE_HELLO) {
        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::HELLO_FAILED, OF_VERSION_UNKNOWN, 0);
    }

    of_version_t switchVersion = of_message_version_get(receiveBuffer);

    if (switchVersion != openFlowVersion) {
        // send ERROR message to switch
        of_hello_failed_error_msg_t* errorMsg = of_hello_failed_error_msg_new(openFlowVersion);
        SwitchConnectionUtil::writeOpenFlowToSocket(*socket, errorMsg);
        of_hello_failed_error_msg_delete(errorMsg);

        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::WRONG_OPENFLOW_VERSION, switchVersion, 0);
    }

    // now we send a feature request so we know the Switch id (DPID) of the switch that just connected.
    of_features_request_t* featReq = of_features_request_new(openFlowVersion);
    ioSuccess = SwitchConnectionUtil::writeOpenFlowToSocket(*socket, featReq);
    of_features_request_delete(featReq);

    if (ioSuccess) {
        socket->flush();
        ioSuccess = socket->good();
    }

    if (!ioSuccess) {
        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::FEATURE_REQUEST_FAILED, switchVersion, 0);
    }


    // receive featureReply
    ioSuccess = SwitchConnectionUtil::parseOpenFlowFromSocketToBuffer(receiveBuffer, *socket);

    if (!ioSuccess) {
        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::FEATURE_REQUEST_FAILED, switchVersion, 0);
    }


    if (of_message_type_get(receiveBuffer) != OF_OBJ_TYPE_FEATURES_REPLY) {
        delete[]  receiveBuffer;
        return HandshakeResult(HandshakeResult::FEATURE_REQUEST_FAILED, switchVersion, 0);
    }

    uint64_t switchId;
    of_features_reply_t* featRep = of_object_new_from_message(receiveBuffer, of_message_length_get(receiveBuffer));
    of_features_reply_datapath_id_get(featRep, &switchId);
    of_object_wire_buffer_steal(featRep, &receiveBuffer);
    of_features_reply_delete(featRep);

    delete[]  receiveBuffer;
    return HandshakeResult(HandshakeResult::SUCCESS, switchVersion, switchId);
}
Ejemplo n.º 9
0
static of_object_t *
parse_message(uint8_t *data, of_object_storage_t *storage)
{
    int len = of_message_length_get(data);
    return of_object_new_from_message_preallocated(storage, data, len);
}