X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=lib%2Fmeta-flow.c;h=8bc3d1a59e89d6bc057ee5a74c99e5fa72b0a4cd;hb=32455024044444678a8d500d716dad7fb77e18d0;hp=8e7d4fc8ae50d698d5f28d07340296bacb120f1b;hpb=0d7e2fe4d5decafe1d52c4dbdb0d77d17ac53a80;p=openvswitch diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 8e7d4fc8..8bc3d1a5 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -222,7 +222,7 @@ static const struct mf_field mf_fields[MFF_N_IDS] = { { MFF_IPV6_LABEL, "ipv6_label", NULL, 4, 20, - MFM_NONE, FWW_IPV6_LABEL, + MFM_FULLY, 0, MFS_HEXADECIMAL, MFP_IPV6, false, @@ -561,7 +561,6 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) case MFF_IP_DSCP: case MFF_IP_ECN: case MFF_IP_TTL: - case MFF_IPV6_LABEL: case MFF_ARP_OP: case MFF_ARP_SHA: case MFF_ARP_THA: @@ -600,6 +599,9 @@ mf_is_all_wild(const struct mf_field *mf, const struct flow_wildcards *wc) case MFF_IPV6_DST: return ipv6_mask_is_any(&wc->ipv6_dst_mask); + case MFF_IPV6_LABEL: + return !wc->ipv6_label_mask; + case MFF_ND_TARGET: return ipv6_mask_is_any(&wc->nd_target_mask); @@ -998,17 +1000,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; @@ -1143,17 +1139,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; @@ -1403,7 +1393,7 @@ mf_set_wild(const struct mf_field *mf, struct cls_rule *rule) break; case MFF_IPV6_LABEL: - rule->wc.wildcards |= FWW_IPV6_LABEL; + rule->wc.ipv6_label_mask = 0; rule->flow.ipv6_label = 0; break; @@ -1505,7 +1495,6 @@ mf_set(const struct mf_field *mf, case MFF_ETH_TYPE: case MFF_VLAN_VID: case MFF_VLAN_PCP: - case MFF_IPV6_LABEL: case MFF_IP_PROTO: case MFF_IP_TTL: case MFF_IP_DSCP: @@ -1561,6 +1550,14 @@ mf_set(const struct mf_field *mf, cls_rule_set_ipv6_dst_masked(rule, &value->ipv6, &mask->ipv6); break; + case MFF_IPV6_LABEL: + if ((mask->be32 & htonl(IPV6_LABEL_MASK)) == htonl(IPV6_LABEL_MASK)) { + mf_set_value(mf, value, rule); + } else { + cls_rule_set_ipv6_label_masked(rule, value->be32, mask->be32); + } + break; + case MFF_ND_TARGET: cls_rule_set_nd_target_masked(rule, &value->ipv6, &mask->ipv6); break; @@ -2075,13 +2072,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) @@ -2095,80 +2086,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