Exemplo n.º 1
0
/* Appends a description of 'mp' to 's', in the format that ovs-ofctl(8)
 * describes. */
void
multipath_format(const struct ofpact_multipath *mp, struct ds *s)
{
    const char *fields, *algorithm;

    fields = flow_hash_fields_to_str(mp->fields);

    switch (mp->algorithm) {
    case NX_MP_ALG_MODULO_N:
        algorithm = "modulo_n";
        break;
    case NX_MP_ALG_HASH_THRESHOLD:
        algorithm = "hash_threshold";
        break;
    case NX_MP_ALG_HRW:
        algorithm = "hrw";
        break;
    case NX_MP_ALG_ITER_HASH:
        algorithm = "iter_hash";
        break;
    default:
        algorithm = "<unknown>";
    }

    ds_put_format(s, "%smultipath(%s%s,%"PRIu16",%s,%d,%"PRIu32",",
                  colors.paren, colors.end, fields, mp->basis, algorithm,
                  mp->max_link + 1, mp->arg);
    mf_format_subfield(&mp->dst, s);
    ds_put_format(s, "%s)%s", colors.paren, colors.end);
}
Exemplo n.º 2
0
/* Appends a human-readable representation of 'nab' to 's'. */
void
bundle_format(const struct ofpact_bundle *bundle, struct ds *s)
{
    const char *action, *fields, *algorithm;
    size_t i;

    fields = flow_hash_fields_to_str(bundle->fields);

    switch (bundle->algorithm) {
    case NX_BD_ALG_HRW:
        algorithm = "hrw";
        break;
    case NX_BD_ALG_ACTIVE_BACKUP:
        algorithm = "active_backup";
        break;
    default:
        algorithm = "<unknown>";
    }

    action = bundle->dst.field ? "bundle_load" : "bundle";

    ds_put_format(s, "%s(%s,%"PRIu16",%s,%s,", action, fields,
                  bundle->basis, algorithm, "ofport");

    if (bundle->dst.field) {
        mf_format_subfield(&bundle->dst, s);
        ds_put_cstr(s, ",");
    }

    ds_put_cstr(s, "slaves:");
    for (i = 0; i < bundle->n_slaves; i++) {
        if (i) {
            ds_put_cstr(s, ",");
        }

        ofputil_format_port(bundle->slaves[i], s);
    }

    ds_put_cstr(s, ")");
}
Exemplo n.º 3
0
void
multipath_format(const struct nx_action_multipath *mp, struct ds *s)
{
    const char *fields, *algorithm;

    uint16_t mp_fields    = ntohs(mp->fields);
    uint16_t mp_algorithm = ntohs(mp->algorithm);

    struct mf_subfield dst;

    fields = flow_hash_fields_to_str(mp_fields);

    switch ((enum nx_mp_algorithm) mp_algorithm) {
    case NX_MP_ALG_MODULO_N:
        algorithm = "modulo_n";
        break;
    case NX_MP_ALG_HASH_THRESHOLD:
        algorithm = "hash_threshold";
        break;
    case NX_MP_ALG_HRW:
        algorithm = "hrw";
        break;
    case NX_MP_ALG_ITER_HASH:
        algorithm = "iter_hash";
        break;
    default:
        algorithm = "<unknown>";
    }

    ds_put_format(s, "multipath(%s,%"PRIu16",%s,%d,%"PRIu16",",
                  fields, ntohs(mp->basis), algorithm, ntohs(mp->max_link) + 1,
                  ntohl(mp->arg));
    nxm_decode(&dst, mp->dst, mp->ofs_nbits);
    mf_format_subfield(&dst, s);
    ds_put_char(s, ')');
}
Exemplo n.º 4
0
/* Appends a description of 'learn' to 's', in the format that ovs-ofctl(8)
 * describes. */
void
learn_format(const struct ofpact_learn *learn, struct ds *s)
{
    const struct ofpact_learn_spec *spec;
    struct match match;

    match_init_catchall(&match);

    ds_put_format(s, "learn(table=%"PRIu8, learn->table_id);
    if (learn->idle_timeout != OFP_FLOW_PERMANENT) {
        ds_put_format(s, ",idle_timeout=%"PRIu16, learn->idle_timeout);
    }
    if (learn->hard_timeout != OFP_FLOW_PERMANENT) {
        ds_put_format(s, ",hard_timeout=%"PRIu16, learn->hard_timeout);
    }
    if (learn->fin_idle_timeout) {
        ds_put_format(s, ",fin_idle_timeout=%"PRIu16, learn->fin_idle_timeout);
    }
    if (learn->fin_hard_timeout) {
        ds_put_format(s, ",fin_hard_timeout=%"PRIu16, learn->fin_hard_timeout);
    }
    if (learn->priority != OFP_DEFAULT_PRIORITY) {
        ds_put_format(s, ",priority=%"PRIu16, learn->priority);
    }
    if (learn->flags & NX_LEARN_F_SEND_FLOW_REM) {
        ds_put_cstr(s, ",send_flow_rem");
    }
    if (learn->flags & NX_LEARN_F_DELETE_LEARNED) {
        ds_put_cstr(s, ",delete_learned");
    }
    if (learn->cookie != 0) {
        ds_put_format(s, ",cookie=%#"PRIx64, ntohll(learn->cookie));
    }

    for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; spec++) {
        ds_put_char(s, ',');

        switch (spec->src_type | spec->dst_type) {
        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_MATCH:
            if (spec->dst.ofs == 0
                && spec->dst.n_bits == spec->dst.field->n_bits) {
                union mf_value value;

                memset(&value, 0, sizeof value);
                bitwise_copy(&spec->src_imm, sizeof spec->src_imm, 0,
                             &value, spec->dst.field->n_bytes, 0,
                             spec->dst.field->n_bits);
                ds_put_format(s, "%s=", spec->dst.field->name);
                mf_format(spec->dst.field, &value, NULL, s);
            } else {
                mf_format_subfield(&spec->dst, s);
                ds_put_char(s, '=');
                mf_format_subvalue(&spec->src_imm, s);
            }
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_MATCH:
            mf_format_subfield(&spec->dst, s);
            if (spec->src.field != spec->dst.field ||
                spec->src.ofs != spec->dst.ofs) {
                ds_put_char(s, '=');
                mf_format_subfield(&spec->src, s);
            }
            break;

        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_LOAD:
            ds_put_format(s, "load:");
            mf_format_subvalue(&spec->src_imm, s);
            ds_put_cstr(s, "->");
            mf_format_subfield(&spec->dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_LOAD:
            ds_put_cstr(s, "load:");
            mf_format_subfield(&spec->src, s);
            ds_put_cstr(s, "->");
            mf_format_subfield(&spec->dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_OUTPUT:
            ds_put_cstr(s, "output:");
            mf_format_subfield(&spec->src, s);
            break;
        }
    }
    ds_put_char(s, ')');
}
Exemplo n.º 5
0
void
learn_format(const struct nx_action_learn *learn, struct ds *s)
{
    struct cls_rule rule;
    const void *p, *end;

    cls_rule_init_catchall(&rule, 0);

    ds_put_format(s, "learn(table=%"PRIu8, learn->table_id);
    if (learn->idle_timeout != htons(OFP_FLOW_PERMANENT)) {
        ds_put_format(s, ",idle_timeout=%"PRIu16, ntohs(learn->idle_timeout));
    }
    if (learn->hard_timeout != htons(OFP_FLOW_PERMANENT)) {
        ds_put_format(s, ",hard_timeout=%"PRIu16, ntohs(learn->hard_timeout));
    }
    if (learn->fin_idle_timeout) {
        ds_put_format(s, ",fin_idle_timeout=%"PRIu16,
                      ntohs(learn->fin_idle_timeout));
    }
    if (learn->fin_hard_timeout) {
        ds_put_format(s, ",fin_hard_timeout=%"PRIu16,
                      ntohs(learn->fin_hard_timeout));
    }
    if (learn->priority != htons(OFP_DEFAULT_PRIORITY)) {
        ds_put_format(s, ",priority=%"PRIu16, ntohs(learn->priority));
    }
    if (learn->flags & htons(OFPFF_SEND_FLOW_REM)) {
        ds_put_cstr(s, ",OFPFF_SEND_FLOW_REM");
    }
    if (learn->flags & htons(~OFPFF_SEND_FLOW_REM)) {
        ds_put_format(s, ",***flags=%"PRIu16"***",
                      ntohs(learn->flags) & ~OFPFF_SEND_FLOW_REM);
    }
    if (learn->cookie != htonll(0)) {
        ds_put_format(s, ",cookie=0x%"PRIx64, ntohll(learn->cookie));
    }
    if (learn->pad != 0) {
        ds_put_cstr(s, ",***nonzero pad***");
    }

    end = (char *) learn + ntohs(learn->len);
    for (p = learn + 1; p != end; ) {
        uint16_t header = ntohs(get_be16(&p));
        int n_bits = header & NX_LEARN_N_BITS_MASK;

        int src_type = header & NX_LEARN_SRC_MASK;
        struct mf_subfield src;
        const uint8_t *src_value;
        int src_value_bytes;

        int dst_type = header & NX_LEARN_DST_MASK;
        struct mf_subfield dst;

        enum ofperr error;
        int i;

        if (!header) {
            break;
        }

        error = learn_check_header(header, (char *) end - (char *) p);
        if (error == OFPERR_OFPBAC_BAD_ARGUMENT) {
            ds_put_format(s, ",***bad flow_mod_spec header %"PRIx16"***)",
                          header);
            return;
        } else if (error == OFPERR_OFPBAC_BAD_LEN) {
            ds_put_format(s, ",***flow_mod_spec at offset %td is %u bytes "
                          "long but only %td bytes are left***)",
                          (char *) p - (char *) (learn + 1) - 2,
                          learn_min_len(header) + 2,
                          (char *) end - (char *) p + 2);
            return;
        }
        assert(!error);

        /* Get the source. */
        if (src_type == NX_LEARN_SRC_FIELD) {
            get_subfield(n_bits, &p, &src);
            src_value_bytes = 0;
            src_value = NULL;
        } else {
            src.field = NULL;
            src.ofs = 0;
            src.n_bits = 0;
            src_value_bytes = 2 * DIV_ROUND_UP(n_bits, 16);
            src_value = p;
            p = (const void *) ((const uint8_t *) p + src_value_bytes);
        }

        /* Get the destination. */
        if (dst_type == NX_LEARN_DST_MATCH || dst_type == NX_LEARN_DST_LOAD) {
            get_subfield(n_bits, &p, &dst);
        } else {
            dst.field = NULL;
            dst.ofs = 0;
            dst.n_bits = 0;
        }

        ds_put_char(s, ',');

        switch (src_type | dst_type) {
        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_MATCH:
            if (dst.field && dst.ofs == 0 && n_bits == dst.field->n_bits) {
                union mf_value value;
                uint8_t *bytes = (uint8_t *) &value;

                if (src_value_bytes > dst.field->n_bytes) {
                    /* The destination field is an odd number of bytes, which
                     * got rounded up to a multiple of 2 to be put into the
                     * learning action.  Skip over the leading byte, which
                     * should be zero anyway.  Otherwise the memcpy() below
                     * will overrun the start of 'value'. */
                    int diff = src_value_bytes - dst.field->n_bytes;
                    src_value += diff;
                    src_value_bytes -= diff;
                }

                memset(&value, 0, sizeof value);
                memcpy(&bytes[dst.field->n_bytes - src_value_bytes],
                       src_value, src_value_bytes);
                ds_put_format(s, "%s=", dst.field->name);
                mf_format(dst.field, &value, NULL, s);
            } else {
                mf_format_subfield(&dst, s);
                ds_put_cstr(s, "=0x");
                for (i = 0; i < src_value_bytes; i++) {
                    ds_put_format(s, "%02"PRIx8, src_value[i]);
                }
            }
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_MATCH:
            mf_format_subfield(&dst, s);
            if (src.field != dst.field || src.ofs != dst.ofs) {
                ds_put_char(s, '=');
                mf_format_subfield(&src, s);
            }
            break;

        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_LOAD:
            ds_put_cstr(s, "load:0x");
            for (i = 0; i < src_value_bytes; i++) {
                ds_put_format(s, "%02"PRIx8, src_value[i]);
            }
            ds_put_cstr(s, "->");
            mf_format_subfield(&dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_LOAD:
            ds_put_cstr(s, "load:");
            mf_format_subfield(&src, s);
            ds_put_cstr(s, "->");
            mf_format_subfield(&dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_OUTPUT:
            ds_put_cstr(s, "output:");
            mf_format_subfield(&src, s);
            break;
        }
    }
    if (!is_all_zeros(p, (char *) end - (char *) p)) {
        ds_put_cstr(s, ",***nonzero trailer***");
    }
    ds_put_char(s, ')');
}
Exemplo n.º 6
0
/* Appends a description of 'learn' to 's', in the format that ovs-ofctl(8)
 * describes. */
void
learn_format(const struct ofpact_learn *learn,
             const struct ofputil_port_map *port_map, struct ds *s)
{
    const struct ofpact_learn_spec *spec;
    struct match match;

    match_init_catchall(&match);

    ds_put_format(s, "%slearn(%s%stable=%s%"PRIu8,
                  colors.learn, colors.end, colors.special, colors.end,
                  learn->table_id);
    if (learn->idle_timeout != OFP_FLOW_PERMANENT) {
        ds_put_format(s, ",%sidle_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->idle_timeout);
    }
    if (learn->hard_timeout != OFP_FLOW_PERMANENT) {
        ds_put_format(s, ",%shard_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->hard_timeout);
    }
    if (learn->fin_idle_timeout) {
        ds_put_format(s, ",%sfin_idle_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->fin_idle_timeout);
    }
    if (learn->fin_hard_timeout) {
        ds_put_format(s, "%s,fin_hard_timeout=%s%"PRIu16,
                      colors.param, colors.end, learn->fin_hard_timeout);
    }
    if (learn->priority != OFP_DEFAULT_PRIORITY) {
        ds_put_format(s, "%s,priority=%s%"PRIu16,
                      colors.special, colors.end, learn->priority);
    }
    if (learn->flags & NX_LEARN_F_SEND_FLOW_REM) {
        ds_put_format(s, ",%ssend_flow_rem%s", colors.value, colors.end);
    }
    if (learn->flags & NX_LEARN_F_DELETE_LEARNED) {
        ds_put_format(s, ",%sdelete_learned%s", colors.value, colors.end);
    }
    if (learn->cookie != 0) {
        ds_put_format(s, ",%scookie=%s%#"PRIx64,
                      colors.param, colors.end, ntohll(learn->cookie));
    }
    if (learn->limit != 0) {
        ds_put_format(s, ",%slimit=%s%"PRIu32,
                      colors.param, colors.end, learn->limit);
    }
    if (learn->flags & NX_LEARN_F_WRITE_RESULT) {
        ds_put_format(s, ",%sresult_dst=%s", colors.param, colors.end);
        mf_format_subfield(&learn->result_dst, s);
    }

    OFPACT_LEARN_SPEC_FOR_EACH (spec, learn) {
        unsigned int n_bytes = DIV_ROUND_UP(spec->n_bits, 8);
        ds_put_char(s, ',');

        switch (spec->src_type | spec->dst_type) {
        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_MATCH: {
            if (spec->dst.ofs == 0
                && spec->dst.n_bits == spec->dst.field->n_bits) {
                union mf_value value;

                memset(&value, 0, sizeof value);
                memcpy(&value.b[spec->dst.field->n_bytes - n_bytes],
                       ofpact_learn_spec_imm(spec), n_bytes);
                ds_put_format(s, "%s%s=%s", colors.param,
                              spec->dst.field->name, colors.end);
                mf_format(spec->dst.field, &value, NULL, port_map, s);
            } else {
                ds_put_format(s, "%s", colors.param);
                mf_format_subfield(&spec->dst, s);
                ds_put_format(s, "=%s", colors.end);
                ds_put_hex(s, ofpact_learn_spec_imm(spec), n_bytes);
            }
            break;
        }
        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_MATCH:
            ds_put_format(s, "%s", colors.param);
            mf_format_subfield(&spec->dst, s);
            ds_put_format(s, "%s", colors.end);
            if (spec->src.field != spec->dst.field ||
                spec->src.ofs != spec->dst.ofs) {
                ds_put_format(s, "%s=%s", colors.param, colors.end);
                mf_format_subfield(&spec->src, s);
            }
            break;

        case NX_LEARN_SRC_IMMEDIATE | NX_LEARN_DST_LOAD:
            ds_put_format(s, "%sload:%s", colors.special, colors.end);
            ds_put_hex(s, ofpact_learn_spec_imm(spec), n_bytes);
            ds_put_format(s, "%s->%s", colors.special, colors.end);
            mf_format_subfield(&spec->dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_LOAD:
            ds_put_format(s, "%sload:%s", colors.special, colors.end);
            mf_format_subfield(&spec->src, s);
            ds_put_format(s, "%s->%s", colors.special, colors.end);
            mf_format_subfield(&spec->dst, s);
            break;

        case NX_LEARN_SRC_FIELD | NX_LEARN_DST_OUTPUT:
            ds_put_format(s, "%soutput:%s", colors.special, colors.end);
            mf_format_subfield(&spec->src, s);
            break;
        }
    }