Exemplo n.º 1
0
/* Try connecting and sending a hello packet that has a bad version, which
 * should fail with EPROTO. */
static void
test_send_invalid_version_hello(int argc OVS_UNUSED, char *argv[])
{
    const char *type = argv[1];
    struct ofpbuf *hello;

    hello = ofpraw_alloc_xid(OFPRAW_OFPT_HELLO, OFP13_VERSION,
                             htonl(0x12345678), 0);
    ((struct ofp_header *) ofpbuf_data(hello))->version = 0;
    test_send_hello(type, ofpbuf_data(hello), ofpbuf_size(hello), EPROTO);
    ofpbuf_delete(hello);
}
Exemplo n.º 2
0
/* Try connecting and sending an extra-long hello, which should succeed (since
 * the specification says that implementations must accept and ignore extra
 * data). */
static void
test_send_long_hello(struct ovs_cmdl_context *ctx)
{
    const char *type = ctx->argv[1];
    struct ofpbuf *hello;
    enum { EXTRA_BYTES = 8 };

    hello = ofpraw_alloc_xid(OFPRAW_OFPT_HELLO, OFP13_VERSION,
                             htonl(0x12345678), EXTRA_BYTES);
    ofpbuf_put_zeros(hello, EXTRA_BYTES);
    ofpmsg_update_length(hello);
    test_send_hello(type, hello->data, hello->size, 0);
    ofpbuf_delete(hello);
}
Exemplo n.º 3
0
/* Try connecting and sending an extra-long hello, which should succeed (since
 * the specification says that implementations must accept and ignore extra
 * data). */
static void
test_send_long_hello(int argc OVS_UNUSED, char *argv[])
{
    const char *type = argv[1];
    struct ofpbuf *hello;
    enum { EXTRA_BYTES = 8 };

    hello = ofpraw_alloc_xid(OFPRAW_OFPT_HELLO, OFP13_VERSION,
                             htonl(0x12345678), EXTRA_BYTES);
    ofpbuf_put_zeros(hello, EXTRA_BYTES);
    ofpmsg_update_length(hello);
    test_send_hello(type, ofpbuf_data(hello), ofpbuf_size(hello), 0);
    ofpbuf_delete(hello);
}
Exemplo n.º 4
0
struct ofpbuf *
ofputil_encode_bundle_add(enum ofp_version ofp_version,
                          struct ofputil_bundle_add_msg *msg)
{
    struct ofpbuf *request;
    struct ofp14_bundle_ctrl_msg *m;

    /* Must use the same xid as the embedded message. */
    request = ofpraw_alloc_xid(ofp_version == OFP13_VERSION
                               ? OFPRAW_ONFT13_BUNDLE_ADD_MESSAGE
                               : OFPRAW_OFPT14_BUNDLE_ADD_MESSAGE, ofp_version,
                               msg->msg->xid, ntohs(msg->msg->length));
    m = ofpbuf_put_zeros(request, sizeof *m);

    m->bundle_id = htonl(msg->bundle_id);
    m->flags = htons(msg->flags);
    ofpbuf_put(request, msg->msg, ntohs(msg->msg->length));

    ofpmsg_update_length(request);
    return request;
}
Exemplo n.º 5
0
static struct ofpbuf *
ofperr_encode_msg__(enum ofperr error, enum ofp_version ofp_version,
                    ovs_be32 xid, const void *data, size_t data_len)
{
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
    const struct ofperr_domain *domain;
    const struct triplet *triplet;
    struct ofp_error_msg *oem;
    struct ofpbuf *buf;

    /* Get the error domain for 'ofp_version', or fall back to OF1.0. */
    domain = ofperr_domain_from_version(ofp_version);
    if (!domain) {
        VLOG_ERR_RL(&rl, "cannot encode error for unknown OpenFlow "
                    "version 0x%02x", ofp_version);
        domain = &ofperr_of10;
    }

    /* Make sure 'error' is valid in 'domain', or use a fallback error. */
    if (!ofperr_is_valid(error)) {
        /* 'error' seems likely to be a system errno value. */
        VLOG_ERR_RL(&rl, "invalid OpenFlow error code %d (%s)",
                    error, ovs_strerror(error));
        error = OFPERR_NXBRC_UNENCODABLE_ERROR;
    } else if (domain->errors[error - OFPERR_OFS].code < 0) {
        VLOG_ERR_RL(&rl, "cannot encode %s for %s",
                    ofperr_get_name(error), domain->name);
        error = OFPERR_NXBRC_UNENCODABLE_ERROR;
    }

    triplet = ofperr_get_triplet__(error, domain);
    if (!triplet->vendor) {
        buf = ofpraw_alloc_xid(OFPRAW_OFPT_ERROR, domain->version, xid,
                               sizeof *oem + data_len);

        oem = ofpbuf_put_uninit(buf, sizeof *oem);
        oem->type = htons(triplet->type);
        oem->code = htons(triplet->code);
    } else if (ofp_version <= OFP11_VERSION) {
        struct nx_vendor_error *nve;

        buf = ofpraw_alloc_xid(OFPRAW_OFPT_ERROR, domain->version, xid,
                               sizeof *oem + sizeof *nve + data_len);

        oem = ofpbuf_put_uninit(buf, sizeof *oem);
        oem->type = htons(NXET_VENDOR);
        oem->code = htons(NXVC_VENDOR_ERROR);

        nve = ofpbuf_put_uninit(buf, sizeof *nve);
        nve->vendor = htonl(triplet->vendor);
        nve->type = htons(triplet->type);
        nve->code = htons(triplet->code);
    } else {
        ovs_be32 vendor = htonl(triplet->vendor);

        buf = ofpraw_alloc_xid(OFPRAW_OFPT_ERROR, domain->version, xid,
                               sizeof *oem + sizeof(uint32_t) + data_len);

        oem = ofpbuf_put_uninit(buf, sizeof *oem);
        oem->type = htons(OFPET12_EXPERIMENTER);
        oem->code = htons(triplet->type);
        ofpbuf_put(buf, &vendor, sizeof vendor);
    }

    ofpbuf_put(buf, data, MIN(data_len, UINT16_MAX - buf->size));
    ofpmsg_update_length(buf);

    return buf;
}
Exemplo n.º 6
0
/* Returns a buffer owned by the caller that encodes 'features' in the format
 * required by 'protocol' with the given 'xid'.  The caller should append port
 * information to the buffer with subsequent calls to
 * ofputil_put_switch_features_port(). */
struct ofpbuf *
ofputil_encode_switch_features(const struct ofputil_switch_features *features,
                               enum ofputil_protocol protocol, ovs_be32 xid)
{
    struct ofp_switch_features *osf;
    struct ofpbuf *b;
    enum ofp_version version;
    enum ofpraw raw;

    version = ofputil_protocol_to_ofp_version(protocol);
    switch (version) {
    case OFP10_VERSION:
        raw = OFPRAW_OFPT10_FEATURES_REPLY;
        break;
    case OFP11_VERSION:
    case OFP12_VERSION:
        raw = OFPRAW_OFPT11_FEATURES_REPLY;
        break;
    case OFP13_VERSION:
    case OFP14_VERSION:
    case OFP15_VERSION:
    case OFP16_VERSION:
        raw = OFPRAW_OFPT13_FEATURES_REPLY;
        break;
    default:
        OVS_NOT_REACHED();
    }
    b = ofpraw_alloc_xid(raw, version, xid, 0);
    osf = ofpbuf_put_zeros(b, sizeof *osf);
    osf->datapath_id = htonll(features->datapath_id);
    osf->n_buffers = htonl(features->n_buffers);
    osf->n_tables = features->n_tables;

    osf->capabilities = htonl(features->capabilities &
                              ofputil_capabilities_mask(version));
    switch (version) {
    case OFP10_VERSION:
        if (features->capabilities & OFPUTIL_C_STP) {
            osf->capabilities |= htonl(OFPC10_STP);
        }
        osf->actions = ofpact_bitmap_to_openflow(features->ofpacts,
                                                 OFP10_VERSION);
        break;
    case OFP13_VERSION:
    case OFP14_VERSION:
    case OFP15_VERSION:
    case OFP16_VERSION:
        osf->auxiliary_id = features->auxiliary_id;
        /* fall through */
    case OFP11_VERSION:
    case OFP12_VERSION:
        if (features->capabilities & OFPUTIL_C_GROUP_STATS) {
            osf->capabilities |= htonl(OFPC11_GROUP_STATS);
        }
        break;
    default:
        OVS_NOT_REACHED();
    }

    return b;
}