Exemple #1
0
void
dump_message(const char *name, struct ofpbuf *buf)
{

    ofpmsg_update_length(buf);
    dump_ofpbuf(name, buf);
}
Exemple #2
0
/* In OpenFlow 1.0, 1.1, and 1.2, an OFPT_FEATURES_REPLY message lists all the
 * switch's ports, unless there are too many to fit.  In OpenFlow 1.3 and
 * later, an OFPT_FEATURES_REPLY does not list ports at all.
 *
 * Given a buffer 'b' that contains a Features Reply message, this message
 * checks if it contains a complete list of the switch's ports.  Returns true,
 * if so.  Returns false if the list is missing (OF1.3+) or incomplete
 * (OF1.0/1.1/1.2), and in the latter case removes all of the ports from the
 * message.
 *
 * When this function returns false, the caller should send an OFPST_PORT_DESC
 * stats request to get the ports. */
bool
ofputil_switch_features_has_ports(struct ofpbuf *b)
{
    struct ofp_header *oh = b->data;
    size_t phy_port_size;

    if (oh->version >= OFP13_VERSION) {
        /* OpenFlow 1.3+ never has ports in the feature reply. */
        return false;
    }

    phy_port_size = (oh->version == OFP10_VERSION
                     ? sizeof(struct ofp10_phy_port)
                     : sizeof(struct ofp11_port));
    if (ntohs(oh->length) + phy_port_size <= UINT16_MAX) {
        /* There's room for additional ports in the feature reply.
         * Assume that the list is complete. */
        return true;
    }

    /* The feature reply has no room for more ports.  Probably the list is
     * truncated.  Drop the ports and tell the caller to retrieve them with
     * OFPST_PORT_DESC. */
    b->size = sizeof *oh + sizeof(struct ofp_switch_features);
    ofpmsg_update_length(b);
    return false;
}
Exemple #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(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);
}
Exemple #4
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);
}
Exemple #5
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;
}
Exemple #6
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;
}