Пример #1
0
/* Returns an OpenFlow message that, sent on an OpenFlow connection whose
 * protocol is 'current', at least partly transitions the protocol to 'want'.
 * Stores in '*next' the protocol that will be in effect on the OpenFlow
 * connection if the switch processes the returned message correctly.  (If
 * '*next != want' then the caller will have to iterate.)
 *
 * If 'current == want', or if it is not possible to transition from 'current'
 * to 'want' (because, for example, 'current' and 'want' use different OpenFlow
 * protocol versions), returns NULL and stores 'current' in '*next'. */
struct ofpbuf *
ofputil_encode_set_protocol(enum ofputil_protocol current,
                            enum ofputil_protocol want,
                            enum ofputil_protocol *next)
{
    enum ofp_version cur_version, want_version;
    enum ofputil_protocol cur_base, want_base;
    bool cur_tid, want_tid;

    cur_version = ofputil_protocol_to_ofp_version(current);
    want_version = ofputil_protocol_to_ofp_version(want);
    if (cur_version != want_version) {
        *next = current;
        return NULL;
    }

    cur_base = ofputil_protocol_to_base(current);
    want_base = ofputil_protocol_to_base(want);
    if (cur_base != want_base) {
        *next = ofputil_protocol_set_base(current, want_base);
        switch (want_base) {
        case OFPUTIL_P_OF10_NXM:
        case OFPUTIL_P_OF10_STD:
            return ofputil_encode_nx_set_flow_format(want_base);

        case OFPUTIL_P_OF11_STD:
        case OFPUTIL_P_OF12_OXM:
        case OFPUTIL_P_OF13_OXM:
        case OFPUTIL_P_OF14_OXM:
        case OFPUTIL_P_OF15_OXM:
        case OFPUTIL_P_OF16_OXM:
            /* There is only one variant of each OpenFlow 1.1+ protocol, and we
             * verified above that we're not trying to change versions. */
            OVS_NOT_REACHED();

        case OFPUTIL_P_OF10_STD_TID:
        case OFPUTIL_P_OF10_NXM_TID:
            OVS_NOT_REACHED();
        }
    }

    cur_tid = (current & OFPUTIL_P_TID) != 0;
    want_tid = (want & OFPUTIL_P_TID) != 0;
    if (cur_tid != want_tid) {
        *next = ofputil_protocol_set_tid(current, want_tid);
        return ofputil_encode_nx_flow_mod_table_id(want_tid);
    }

    ovs_assert(current == want);

    *next = current;
    return NULL;
}
Пример #2
0
struct ofpbuf *
port_stats_request(enum ofputil_protocol proto)
{
    uint32_t port_no = 0xffffffff;
    return ofputil_encode_dump_ports_request(
        ofputil_protocol_to_ofp_version(proto), port_no);
}
Пример #3
0
struct ofpbuf *
meter_mod(enum ofputil_protocol proto)
{
    const int N_BANDS = 2;
    struct ofputil_meter_mod mm;
    struct ofputil_meter_band bands[N_BANDS];

    memset(bands, 0, sizeof(*bands)*2);
    bands[0].type = 1;         // OFPMBT_DROP
    bands[0].rate = 1000;
    bands[0].burst_size = 10;
    bands[1].type = 2;         // OFPMBT_DSCP_REMARK
    bands[1].prec_level = 1;
    bands[1].rate = 1000;
    bands[1].burst_size = 10;

    memset(&mm, 0, sizeof(mm));
    mm.command = 0;              // OFPMC_ADD
    mm.meter.meter_id = 100;
    mm.meter.flags = 14;         // OFPMF_PKTPS, OFPMF_BURST, OFPMF_STATS
    mm.meter.n_bands = N_BANDS;
    mm.meter.bands = bands;

    return ofputil_encode_meter_mod(
        ofputil_protocol_to_ofp_version(proto), &mm);
}
Пример #4
0
struct ofpbuf *
group_mod(enum ofputil_protocol proto)
{
    struct ofputil_group_mod gm;
    struct ofpbuf acts;
    struct ofpact_ipv4 *a_set_field;
    struct ofpact_goto_table *a_goto;
    struct ofputil_bucket bckt;

    memset(&gm, 0, sizeof(gm));
    gm.command = OFPGC15_INSERT_BUCKET;
    gm.type = OFPGT11_SELECT;
    gm.group_id = 0xaaaaaaaa;
    gm.command_bucket_id = 0xbbbbbbbb;

    ofpbuf_init(&acts, 0x18);
    ofpact_put_STRIP_VLAN(&acts);
    a_set_field = ofpact_put_SET_IPV4_DST(&acts);
    a_set_field->ipv4 = inet_addr("192.168.2.9");

    bckt.weight = 0xcccc;
    bckt.watch_port = 0xdddd;
    bckt.watch_group = 0xeeeeeeee;
    bckt.bucket_id = 0x12345678;
    bckt.ofpacts = acts.data;
    bckt.ofpacts_len = acts.size;

    list_init(&(gm.buckets));
    list_push_back(&(gm.buckets), &(bckt.list_node));

    return ofputil_encode_group_mod(
        ofputil_protocol_to_ofp_version(proto), &gm);
}
Пример #5
0
struct ofpbuf *
group_stats_request(enum ofputil_protocol proto)
{
    uint32_t group_id = 0xfffffffc;
    return ofputil_encode_group_stats_request(
        ofputil_protocol_to_ofp_version(proto), group_id);
}
Пример #6
0
void
ofputil_encode_bundle_msgs(const struct ofputil_bundle_msg *bms,
                           size_t n_bms, struct ovs_list *requests,
                           enum ofputil_protocol protocol)
{
    enum ofp_version version = ofputil_protocol_to_ofp_version(protocol);

    for (size_t i = 0; i < n_bms; i++) {
        struct ofpbuf *request = NULL;

        switch ((int)bms[i].type) {
        case OFPTYPE_FLOW_MOD:
            request = ofputil_encode_flow_mod(&bms[i].fm, protocol);
            break;
        case OFPTYPE_GROUP_MOD:
            request = ofputil_encode_group_mod(version, &bms[i].gm, NULL, -1);
            break;
        case OFPTYPE_PACKET_OUT:
            request = ofputil_encode_packet_out(&bms[i].po, protocol);
            break;
        default:
            break;
        }
        if (request) {
            ovs_list_push_back(requests, &request->list_node);
        }
    }
}
Пример #7
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:
        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:
        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;
}
Пример #8
0
struct ofpbuf *
port_desc_request(enum ofputil_protocol proto)
{
    uint32_t port_no = 0xbcda;

    return ofputil_encode_port_desc_stats_request(
        ofputil_protocol_to_ofp_version(proto), port_no);
}
Пример #9
0
struct ofpbuf *
meter_stats_request(enum ofputil_protocol proto)
{
    uint32_t meter_id = 0xffffffff;
    return ofputil_encode_meter_request(
        ofputil_protocol_to_ofp_version(proto),
        OFPUTIL_METER_STATS, meter_id);
}
Пример #10
0
struct ofpbuf *
queue_stats_request(enum ofputil_protocol proto)
{
    struct ofputil_queue_stats_request oqsr;
    memset(&oqsr, 0, sizeof(oqsr));
    oqsr.port_no = 0xabcd;
    oqsr.queue_id = 0xffffffff;
    return ofputil_encode_queue_stats_request(
        ofputil_protocol_to_ofp_version(proto), &oqsr);
}
Пример #11
0
/* Returns a bitmap of OpenFlow versions that are supported by at
 * least one of the 'protocols'. */
uint32_t
ofputil_protocols_to_version_bitmap(enum ofputil_protocol protocols)
{
    uint32_t bitmap = 0;

    for (; protocols; protocols = zero_rightmost_1bit(protocols)) {
        enum ofputil_protocol protocol = rightmost_1bit(protocols);

        bitmap |= 1u << ofputil_protocol_to_ofp_version(protocol);
    }

    return bitmap;
}
Пример #12
0
struct ofpbuf *
set_config(enum ofputil_protocol proto)
{
    struct ofputil_switch_config sc;

    memset(&sc, 0, sizeof(sc));
    sc.frag = OFPUTIL_FRAG_NORMAL;
    // sc.invalid_ttl_to_controller is for only OFP11 and OFP12
    sc.miss_send_len = 128;  // The default of OpenFlow Spec

    return ofputil_encode_set_config(
        &sc, ofputil_protocol_to_ofp_version(proto));
}
Пример #13
0
struct ofpbuf *
echo_reply(enum ofputil_protocol proto)
{
    struct ofp_header oh;

    memset(&oh, 0, sizeof(oh));
    oh.version = ofputil_protocol_to_ofp_version(proto);
    oh.type = 3;           // OFPT_ECHO_REPLY
    oh.length = htons(8);  // lenght of ofp_header
    oh.xid = 0;

    return make_echo_reply(&oh);
}
Пример #14
0
struct ofpbuf *
bundle_ctrl(enum ofputil_protocol proto)
{
    struct ofputil_bundle_ctrl_msg msg;
    struct ofp_header oh;

    memset(&oh, 0, sizeof(oh));
    oh.xid = 0;
    oh.version = ofputil_protocol_to_ofp_version(proto);
    memset(&msg, 0, sizeof(msg));
    msg.bundle_id = 99999999;
    msg.type = OFPBCT_OPEN_REPLY;
    msg.flags = OFPBF_ATOMIC;
    return ofputil_encode_bundle_ctrl_reply(&oh, &msg);
}
Пример #15
0
struct ofpbuf *
get_config_reply(enum ofputil_protocol proto)
{
    struct ofputil_switch_config sc;
    struct ofp_header oh;

    memset(&oh, 0, sizeof(oh));
    oh.xid = 0;
    oh.version = ofputil_protocol_to_ofp_version(proto);
    memset(&sc, 0, sizeof(sc));
    sc.frag = OFPUTIL_FRAG_NORMAL;
    // sc.invalid_ttl_to_controller is for only OFP11 and OFP12
    sc.miss_send_len = 128;  // The default of OpenFlow Spec

    return ofputil_encode_get_config_reply(&oh, &sc);
}
Пример #16
0
struct ofpbuf *
error_msg(enum ofputil_protocol proto)
{
    struct ofp_header oh;

    memset(&oh, 0, sizeof(oh));
    oh.version = ofputil_protocol_to_ofp_version(proto);
    oh.type = 14;          // OFPT_FLOW_MOD
    oh.length = htons(8);  // lenght of ofp_header
    oh.xid = 0;

    // OFPERR_OFPBMC_BAD_FIELD means
    // "Unsupported field in the match."
    //  - type: OFPET_BAD_MATCH = 4
    //  - code: OFPBMC_BAD_FIELD = 6
    return ofperr_encode_reply(OFPERR_OFPBMC_BAD_FIELD, &oh);
}
Пример #17
0
struct ofpbuf *
bundle_add(enum ofputil_protocol proto)
{
    struct ofputil_bundle_add_msg msg;
    struct ofpbuf *fm;
    struct ofpbuf *add;

    memset(&msg, 0, sizeof(msg));
    msg.bundle_id = 99999999;
    msg.flags = OFPBF_ATOMIC;
    fm = flow_mod(proto);
    clear_xid(fm);
    msg.msg = fm->data;
    add = ofputil_encode_bundle_add(
        ofputil_protocol_to_ofp_version(proto), &msg);
    ofpbuf_delete(fm);
    return add;
}
Пример #18
0
struct ofpbuf *
echo_request(enum ofputil_protocol proto)
{
    return make_echo_request(ofputil_protocol_to_ofp_version(proto));
}
Пример #19
0
struct ofpbuf *
barrier_request(enum ofputil_protocol proto)
{
    return ofputil_encode_barrier_request(
        ofputil_protocol_to_ofp_version(proto));
}
Пример #20
0
struct ofpbuf *
table_desc_request(enum ofputil_protocol proto)
{
    return ofputil_encode_table_desc_request(
        ofputil_protocol_to_ofp_version(proto));
}
Пример #21
0
struct ofpbuf *
group_features_request(enum ofputil_protocol proto)
{
    return ofputil_encode_group_features_request(
        ofputil_protocol_to_ofp_version(proto));
}