X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fmeta-flow.c;h=f85f7a468c12c1afef6d719a6c8b2bf854fd275e;hb=e2a3d183f60b93265c095ede1379194916444822;hp=e7b860b23bc2bd4876bce9025b2fff8b9606f010;hpb=b5e5143b6a808d3463b205c36d49cdd9a9a9e4c3;p=openvswitch diff --git a/lib/meta-flow.c b/lib/meta-flow.c index e7b860b2..f85f7a46 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -55,6 +55,15 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { true, NXM_NX_TUN_ID, "NXM_NX_TUN_ID", NXM_NX_TUN_ID, "NXM_NX_TUN_ID", + }, { + MFF_METADATA, "metadata", NULL, + MF_FIELD_SIZES(be64), + MFM_FULLY, 0, + MFS_HEXADECIMAL, + MFP_NONE, + true, + OXM_OF_METADATA, "OXM_OF_METADATA", + OXM_OF_METADATA, "OXM_OF_METADATA", }, { MFF_IN_PORT, "in_port", NULL, MF_FIELD_SIZES(be16), @@ -563,34 +572,10 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) case MFF_TUN_ID: return !wc->tun_id_mask; + case MFF_METADATA: + return !wc->metadata_mask; -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif + CASE_MFF_REGS: return !wc->reg_masks[mf->id - MFF_REG0]; case MFF_ETH_SRC: @@ -673,34 +658,11 @@ mf_get_mask(const struct mf_field *mf, const struct flow_wildcards *wc, case MFF_TUN_ID: mask->be64 = wc->tun_id_mask; break; + case MFF_METADATA: + mask->be64 = wc->metadata_mask; + break; -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif + CASE_MFF_REGS: mask->be32 = htonl(wc->reg_masks[mf->id - MFF_REG0]); break; @@ -872,34 +834,9 @@ mf_is_value_valid(const struct mf_field *mf, const union mf_value *value) { switch (mf->id) { case MFF_TUN_ID: + case MFF_METADATA: case MFF_IN_PORT: -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif + CASE_MFF_REGS: case MFF_ETH_SRC: case MFF_ETH_DST: case MFF_ETH_TYPE: @@ -962,38 +899,15 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow, case MFF_TUN_ID: value->be64 = flow->tun_id; break; + case MFF_METADATA: + value->be64 = flow->metadata; + break; case MFF_IN_PORT: value->be16 = htons(flow->in_port); break; -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif + CASE_MFF_REGS: value->be32 = htonl(flow->regs[mf->id - MFF_REG0]); break; @@ -1084,17 +998,11 @@ mf_get_value(const struct mf_field *mf, const struct flow *flow, break; case MFF_TCP_SRC: - value->be16 = flow->tp_src; - break; - - case MFF_TCP_DST: - value->be16 = flow->tp_dst; - break; - case MFF_UDP_SRC: value->be16 = flow->tp_src; break; + case MFF_TCP_DST: case MFF_UDP_DST: value->be16 = flow->tp_dst; break; @@ -1130,42 +1038,17 @@ mf_set_value(const struct mf_field *mf, case MFF_TUN_ID: cls_rule_set_tun_id(rule, value->be64); break; + case MFF_METADATA: + cls_rule_set_metadata(rule, value->be64); + break; case MFF_IN_PORT: cls_rule_set_in_port(rule, ntohs(value->be16)); break; -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif -#if FLOW_N_REGS > 0 + CASE_MFF_REGS: cls_rule_set_reg(rule, mf->id - MFF_REG0, ntohl(value->be32)); break; -#endif case MFF_ETH_SRC: cls_rule_set_dl_src(rule, value->mac); @@ -1254,17 +1137,11 @@ mf_set_value(const struct mf_field *mf, break; case MFF_TCP_SRC: - cls_rule_set_tp_src(rule, value->be16); - break; - - case MFF_TCP_DST: - cls_rule_set_tp_dst(rule, value->be16); - break; - case MFF_UDP_SRC: cls_rule_set_tp_src(rule, value->be16); break; + case MFF_TCP_DST: case MFF_UDP_DST: cls_rule_set_tp_dst(rule, value->be16); break; @@ -1300,42 +1177,17 @@ mf_set_flow_value(const struct mf_field *mf, case MFF_TUN_ID: flow->tun_id = value->be64; break; + case MFF_METADATA: + flow->metadata = value->be64; + break; case MFF_IN_PORT: flow->in_port = ntohs(value->be16); break; -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif -#if FLOW_N_REGS > 0 + CASE_MFF_REGS: flow->regs[mf->id - MFF_REG0] = ntohl(value->be32); break; -#endif case MFF_ETH_SRC: memcpy(flow->dl_src, value->mac, ETH_ADDR_LEN); @@ -1479,55 +1331,17 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) case MFF_TUN_ID: cls_rule_set_tun_id_masked(rule, htonll(0), htonll(0)); break; + case MFF_METADATA: + cls_rule_set_metadata_masked(rule, htonll(0), htonll(0)); case MFF_IN_PORT: rule->wc.wildcards |= FWW_IN_PORT; rule->flow.in_port = 0; break; -#if FLOW_N_REGS > 0 - case MFF_REG0: - cls_rule_set_reg_masked(rule, 0, 0, 0); - break; -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: - cls_rule_set_reg_masked(rule, 1, 0, 0); - break; -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: - cls_rule_set_reg_masked(rule, 2, 0, 0); - break; -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: - cls_rule_set_reg_masked(rule, 3, 0, 0); - break; -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: - cls_rule_set_reg_masked(rule, 4, 0, 0); - break; -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: - cls_rule_set_reg_masked(rule, 5, 0, 0); - break; -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: - cls_rule_set_reg_masked(rule, 6, 0, 0); - break; -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: - cls_rule_set_reg_masked(rule, 7, 0, 0); + CASE_MFF_REGS: + cls_rule_set_reg_masked(rule, mf->id - MFF_REG0, 0, 0); break; -#endif -#if FLOW_N_REGS > 8 -#error -#endif case MFF_ETH_SRC: memset(rule->flow.dl_src, 0, ETH_ADDR_LEN); @@ -1698,34 +1512,11 @@ mf_set(const struct mf_field *mf, case MFF_TUN_ID: cls_rule_set_tun_id_masked(rule, value->be64, mask->be64); break; + case MFF_METADATA: + cls_rule_set_metadata_masked(rule, value->be64, mask->be64); + break; -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif + CASE_MFF_REGS: cls_rule_set_reg_masked(rule, mf->id - MFF_REG0, ntohl(value->be32), ntohl(mask->be32)); break; @@ -1857,34 +1648,9 @@ mf_random_value(const struct mf_field *mf, union mf_value *value) switch (mf->id) { case MFF_TUN_ID: + case MFF_METADATA: case MFF_IN_PORT: -#if FLOW_N_REGS > 0 - case MFF_REG0: -#endif -#if FLOW_N_REGS > 1 - case MFF_REG1: -#endif -#if FLOW_N_REGS > 2 - case MFF_REG2: -#endif -#if FLOW_N_REGS > 3 - case MFF_REG3: -#endif -#if FLOW_N_REGS > 4 - case MFF_REG4: -#endif -#if FLOW_N_REGS > 5 - case MFF_REG5: -#endif -#if FLOW_N_REGS > 6 - case MFF_REG6: -#endif -#if FLOW_N_REGS > 7 - case MFF_REG7: -#endif -#if FLOW_N_REGS > 8 -#error -#endif + CASE_MFF_REGS: case MFF_ETH_SRC: case MFF_ETH_DST: case MFF_ETH_TYPE: @@ -2297,13 +2063,7 @@ mf_format(const struct mf_field *mf, /* Makes subfield 'sf' within 'rule' exactly match the 'sf->n_bits' * least-significant bits in 'x'. - * - * See mf_set_subfield() for an example. - * - * The difference between this function and mf_set_subfield() is that the - * latter function can only handle subfields up to 64 bits wide, whereas this - * one handles the general case. On the other hand, mf_set_subfield() is - * arguably easier to use. */ + */ void mf_write_subfield(const struct mf_subfield *sf, const union mf_subvalue *x, struct cls_rule *rule) @@ -2317,80 +2077,6 @@ mf_write_subfield(const struct mf_subfield *sf, const union mf_subvalue *x, mf_set(field, &value, &mask, rule); } -/* Makes subfield 'sf' within 'rule' exactly match the 'sf->n_bits' - * least-significant bits of 'x'. - * - * Example: suppose that 'sf->field' is originally the following 2-byte field - * in 'rule': - * - * value == 0xe00a == 2#1110000000001010 - * mask == 0xfc3f == 2#1111110000111111 - * - * The call mf_set_subfield(sf, 0x55, 8, 7, rule), where sf->ofs == 8 and - * sf->n_bits == 7 would have the following effect (note that 0x55 is - * 2#1010101): - * - * value == 0xd50a == 2#1101010100001010 - * mask == 0xff3f == 2#1111111100111111 - * ^^^^^^^ affected bits - * - * The caller is responsible for ensuring that the result will be a valid - * wildcard pattern for 'sf->field'. The caller is responsible for ensuring - * that 'rule' meets 'sf->field''s prerequisites. */ -void -mf_set_subfield(const struct mf_subfield *sf, uint64_t x, - struct cls_rule *rule) -{ - const struct mf_field *field = sf->field; - unsigned int n_bits = sf->n_bits; - unsigned int ofs = sf->ofs; - - if (ofs == 0 && field->n_bytes * 8 == n_bits) { - union mf_value value; - int i; - - for (i = field->n_bytes - 1; i >= 0; i--) { - ((uint8_t *) &value)[i] = x; - x >>= 8; - } - mf_set_value(field, &value, rule); - } else { - union mf_value value, mask; - uint8_t *vp = (uint8_t *) &value; - uint8_t *mp = (uint8_t *) &mask; - - mf_get(field, rule, &value, &mask); - bitwise_put(x, vp, field->n_bytes, ofs, n_bits); - bitwise_put(UINT64_MAX, mp, field->n_bytes, ofs, n_bits); - mf_set(field, &value, &mask, rule); - } -} - -/* Similar to mf_set_subfield() but modifies only a flow, not a cls_rule. */ -void -mf_set_subfield_value(const struct mf_subfield *sf, uint64_t x, - struct flow *flow) -{ - const struct mf_field *field = sf->field; - unsigned int n_bits = sf->n_bits; - unsigned int ofs = sf->ofs; - union mf_value value; - - if (ofs == 0 && field->n_bytes * 8 == n_bits) { - int i; - - for (i = field->n_bytes - 1; i >= 0; i--) { - ((uint8_t *) &value)[i] = x; - x >>= 8; - } - mf_set_flow_value(field, &value, flow); - } else { - mf_get_value(field, flow, &value); - bitwise_put(x, &value, field->n_bytes, ofs, n_bits); - mf_set_flow_value(field, &value, flow); - } -} - /* Initializes 'x' to the value of 'sf' within 'flow'. 'sf' must be valid for * reading 'flow', e.g. as checked by mf_check_src(). */ void