Пример #1
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;
}
Пример #2
0
of_object_t *
of_object_new_from_message_preallocated(of_object_storage_t *storage,
                                        uint8_t *buf, int len)
{
    of_object_t *obj = &storage->obj;
    of_wire_buffer_t *wbuf = &storage->wbuf;
    of_message_t msg = buf;
    of_version_t version;
    of_object_id_t object_id;

    memset(storage, 0, sizeof(*storage));

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

    if (of_validate_message(msg, len) != 0) {
        LOCI_LOG_ERROR("message validation failed\n");
        return NULL;
    }

    obj->version = version;
    obj->wbuf = wbuf;
    wbuf->buf = msg;
    wbuf->alloc_bytes = len;
    wbuf->current_bytes = len;

    of_header_wire_object_id_get(obj, &object_id);
    of_object_init_map[object_id](obj, version, len, 0);

    return obj;
}
Пример #3
0
of_object_t *
of_object_new_from_message(of_message_t msg, int len)
{
    of_object_id_t object_id;
    of_object_t *obj;
    of_version_t version;

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

    if (of_validate_message(msg, len) != 0) {
        LOCI_LOG_ERROR("message validation failed\n");
        return NULL;
    }

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

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

    of_header_wire_object_id_get(obj, &object_id);
    of_object_init_map[object_id](obj, version, len, 0);

    return obj;
}
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);
}