Esempio n. 1
0
/* Helper for bundle_parse and bundle_parse_load. */
static void
bundle_parse__(struct ofpbuf *b, const char *s, char **save_ptr,
               const char *fields, const char *basis, const char *algorithm,
               const char *slave_type, const char *dst,
               const char *slave_delim)
{
    enum ofputil_action_code code;
    struct nx_action_bundle *nab;
    uint16_t n_slaves;

    if (!slave_delim) {
        ovs_fatal(0, "%s: not enough arguments to bundle action", s);
    }

    if (strcasecmp(slave_delim, "slaves")) {
        ovs_fatal(0, "%s: missing slave delimiter, expected `slaves' got `%s'",
                   s, slave_delim);
    }

    code = dst ? OFPUTIL_NXAST_BUNDLE_LOAD : OFPUTIL_NXAST_BUNDLE;
    b->l2 = ofputil_put_action(code, b);

    n_slaves = 0;
    for (;;) {
        ovs_be16 slave_be;
        char *slave;

        slave = strtok_r(NULL, ", ", save_ptr);
        if (!slave || n_slaves >= BUNDLE_MAX_SLAVES) {
            break;
        }

        slave_be = htons(atoi(slave));
        ofpbuf_put(b, &slave_be, sizeof slave_be);

        n_slaves++;
    }

    /* Slaves array must be multiple of 8 bytes long. */
    if (b->size % 8) {
        ofpbuf_put_zeros(b, 8 - (b->size % 8));
    }

    nab = b->l2;
    nab->len = htons(b->size - ((char *) b->l2 - (char *) b->data));
    nab->n_slaves = htons(n_slaves);
    nab->basis = htons(atoi(basis));

    if (!strcasecmp(fields, "eth_src")) {
        nab->fields = htons(NX_HASH_FIELDS_ETH_SRC);
    } else if (!strcasecmp(fields, "symmetric_l4")) {
        nab->fields = htons(NX_HASH_FIELDS_SYMMETRIC_L4);
    } else {
        ovs_fatal(0, "%s: unknown fields `%s'", s, fields);
    }

    if (!strcasecmp(algorithm, "active_backup")) {
        nab->algorithm = htons(NX_BD_ALG_ACTIVE_BACKUP);
    } else if (!strcasecmp(algorithm, "hrw")) {
        nab->algorithm = htons(NX_BD_ALG_HRW);
    } else {
        ovs_fatal(0, "%s: unknown algorithm `%s'", s, algorithm);
    }

    if (!strcasecmp(slave_type, "ofport")) {
        nab->slave_type = htonl(NXM_OF_IN_PORT);
    } else {
        ovs_fatal(0, "%s: unknown slave_type `%s'", s, slave_type);
    }

    if (dst) {
        uint32_t reg;
        int ofs, n_bits;

        nxm_parse_field_bits(dst, &reg, &ofs, &n_bits);

        nab->dst = htonl(reg);
        nab->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits);
    }

    b->l2 = NULL;
}
Esempio n. 2
0
static void
parse_named_action(enum ofputil_action_code code, const struct flow *flow,
                   struct ofpbuf *b, char *arg)
{
    struct ofp_action_dl_addr *oada;
    struct ofp_action_vlan_pcp *oavp;
    struct ofp_action_vlan_vid *oavv;
    struct ofp_action_nw_addr *oana;
    struct ofp_action_tp_port *oata;

    switch (code) {
    case OFPUTIL_OFPAT_OUTPUT:
        parse_output(b, arg);
        break;

    case OFPUTIL_OFPAT_SET_VLAN_VID:
        oavv = ofputil_put_OFPAT_SET_VLAN_VID(b);
        oavv->vlan_vid = htons(str_to_u32(arg));
        break;

    case OFPUTIL_OFPAT_SET_VLAN_PCP:
        oavp = ofputil_put_OFPAT_SET_VLAN_PCP(b);
        oavp->vlan_pcp = str_to_u32(arg);
        break;

    case OFPUTIL_OFPAT_STRIP_VLAN:
        ofputil_put_OFPAT_STRIP_VLAN(b);
        break;

    case OFPUTIL_OFPAT_SET_DL_SRC:
    case OFPUTIL_OFPAT_SET_DL_DST:
        oada = ofputil_put_action(code, b);
        str_to_mac(arg, oada->dl_addr);
        break;

    case OFPUTIL_OFPAT_SET_NW_SRC:
    case OFPUTIL_OFPAT_SET_NW_DST:
        oana = ofputil_put_action(code, b);
        str_to_ip(arg, &oana->nw_addr);
        break;

    case OFPUTIL_OFPAT_SET_NW_TOS:
        ofputil_put_OFPAT_SET_NW_TOS(b)->nw_tos = str_to_u32(arg);
        break;

    case OFPUTIL_OFPAT_SET_TP_SRC:
    case OFPUTIL_OFPAT_SET_TP_DST:
        oata = ofputil_put_action(code, b);
        oata->tp_port = htons(str_to_u32(arg));
        break;

    case OFPUTIL_OFPAT_ENQUEUE:
        parse_enqueue(b, arg);
        break;

    case OFPUTIL_NXAST_RESUBMIT:
        parse_resubmit(b, arg);
        break;

    case OFPUTIL_NXAST_SET_TUNNEL:
        parse_set_tunnel(b, arg);
        break;

    case OFPUTIL_NXAST_SET_QUEUE:
        ofputil_put_NXAST_SET_QUEUE(b)->queue_id = htonl(str_to_u32(arg));
        break;

    case OFPUTIL_NXAST_POP_QUEUE:
        ofputil_put_NXAST_POP_QUEUE(b);
        break;

    case OFPUTIL_NXAST_REG_MOVE:
        nxm_parse_reg_move(ofputil_put_NXAST_REG_MOVE(b), arg);
        break;

    case OFPUTIL_NXAST_REG_LOAD:
        nxm_parse_reg_load(ofputil_put_NXAST_REG_LOAD(b), arg);
        break;

    case OFPUTIL_NXAST_NOTE:
        parse_note(b, arg);
        break;

    case OFPUTIL_NXAST_SET_TUNNEL64:
        ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(str_to_u64(arg));
        break;

    case OFPUTIL_NXAST_MULTIPATH:
        multipath_parse(ofputil_put_NXAST_MULTIPATH(b), arg);
        break;

    case OFPUTIL_NXAST_AUTOPATH:
        autopath_parse(ofputil_put_NXAST_AUTOPATH(b), arg);
        break;

    case OFPUTIL_NXAST_BUNDLE:
        bundle_parse(b, arg);
        break;

    case OFPUTIL_NXAST_BUNDLE_LOAD:
        bundle_parse_load(b, arg);
        break;

    case OFPUTIL_NXAST_RESUBMIT_TABLE:
    case OFPUTIL_NXAST_OUTPUT_REG:
        NOT_REACHED();

    case OFPUTIL_NXAST_LEARN:
        learn_parse(b, arg, flow);
        break;

    case OFPUTIL_NXAST_EXIT:
        ofputil_put_NXAST_EXIT(b);
        break;
    }
}