rule->flow.regs[reg_idx] = value & mask;
}
+void
+cls_rule_set_metadata(struct cls_rule *rule, ovs_be64 metadata)
+{
+ cls_rule_set_metadata_masked(rule, metadata, htonll(UINT64_MAX));
+}
+
+void
+cls_rule_set_metadata_masked(struct cls_rule *rule, ovs_be64 metadata,
+ ovs_be64 mask)
+{
+ rule->wc.metadata_mask = mask;
+ rule->flow.metadata = metadata & mask;
+}
+
void
cls_rule_set_tun_id(struct cls_rule *rule, ovs_be64 tun_id)
{
cls_rule_set_dl_vlan(struct cls_rule *rule, ovs_be16 dl_vlan)
{
flow_set_vlan_vid(&rule->flow, dl_vlan);
- if (dl_vlan == htons(OFP_VLAN_NONE)) {
+ if (dl_vlan == htons(OFP10_VLAN_NONE)) {
rule->wc.vlan_tci_mask = htons(UINT16_MAX);
} else {
rule->wc.vlan_tci_mask |= htons(VLAN_VID_MASK | VLAN_CFI);
int i;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 12);
if (rule->priority != OFP_DEFAULT_PRIORITY) {
ds_put_format(s, "priority=%d,", rule->priority);
ntohll(f->tun_id), ntohll(wc->tun_id_mask));
break;
}
+ switch (wc->metadata_mask) {
+ case 0:
+ break;
+ case CONSTANT_HTONLL(UINT64_MAX):
+ ds_put_format(s, "metadata=%#"PRIx64",", ntohll(f->metadata));
+ break;
+ default:
+ ds_put_format(s, "metadata=%#"PRIx64"/%#"PRIx64",",
+ ntohll(f->metadata), ntohll(wc->metadata_mask));
+ break;
+ }
if (!(w & FWW_IN_PORT)) {
ds_put_format(s, "in_port=%"PRIu16",", f->in_port);
}
return false;
}
+
+/* Returns true if 'rule' exactly matches 'criteria' or if 'rule' is more
+ * specific than 'criteria'. That is, 'rule' matches 'criteria' and this
+ * function returns true if, for every field:
+ *
+ * - 'criteria' and 'rule' specify the same (non-wildcarded) value for the
+ * field, or
+ *
+ * - 'criteria' wildcards the field,
+ *
+ * Conversely, 'rule' does not match 'criteria' and this function returns false
+ * if, for at least one field:
+ *
+ * - 'criteria' and 'rule' specify different values for the field, or
+ *
+ * - 'criteria' specifies a value for the field but 'rule' wildcards it.
+ *
+ * Equivalently, the truth table for whether a field matches is:
+ *
+ * rule
+ *
+ * c wildcard exact
+ * r +---------+---------+
+ * i wild | yes | yes |
+ * t card | | |
+ * e +---------+---------+
+ * r exact | no |if values|
+ * i | |are equal|
+ * a +---------+---------+
+ *
+ * This is the matching rule used by OpenFlow 1.0 non-strict OFPT_FLOW_MOD
+ * commands and by OpenFlow 1.0 aggregate and flow stats.
+ *
+ * Ignores rule->priority and criteria->priority. */
+bool
+cls_rule_is_loose_match(const struct cls_rule *rule,
+ const struct cls_rule *criteria)
+{
+ return (!flow_wildcards_has_extra(&rule->wc, &criteria->wc)
+ && flow_equal_except(&rule->flow, &criteria->flow, &criteria->wc));
+}
\f
/* Iteration. */
return NULL;
}
-/* Initializes 'cursor' for iterating through 'cls' rules that exactly match
- * 'target' or are more specific than 'target'. That is, a given 'rule'
- * matches 'target' if, for every field:
- *
- * - 'target' and 'rule' specify the same (non-wildcarded) value for the
- * field, or
+/* Initializes 'cursor' for iterating through rules in 'cls':
*
- * - 'target' wildcards the field,
- *
- * but not if:
- *
- * - 'target' and 'rule' specify different values for the field, or
- *
- * - 'target' specifies a value for the field but 'rule' wildcards it.
- *
- * Equivalently, the truth table for whether a field matches is:
- *
- * rule
- *
- * wildcard exact
- * +---------+---------+
- * t wild | yes | yes |
- * a card | | |
- * r +---------+---------+
- * g exact | no |if values|
- * e | |are equal|
- * t +---------+---------+
- *
- * This is the matching rule used by OpenFlow 1.0 non-strict OFPT_FLOW_MOD
- * commands and by OpenFlow 1.0 aggregate and flow stats.
+ * - If 'target' is null, the cursor will visit every rule in 'cls'.
*
- * Ignores target->priority.
+ * - If 'target' is nonnull, the cursor will visit each 'rule' in 'cls'
+ * such that cls_rule_is_loose_match(rule, target) returns true.
*
- * 'target' may be NULL to iterate over every rule in 'cls'. */
+ * Ignores target->priority. */
void
cls_cursor_init(struct cls_cursor *cursor, const struct classifier *cls,
const struct cls_rule *target)
const flow_wildcards_t wc = wildcards->wildcards;
int i;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 11);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 12);
for (i = 0; i < FLOW_N_REGS; i++) {
if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
}
return (!((a->tun_id ^ b->tun_id) & wildcards->tun_id_mask)
+ && !((a->metadata ^ b->metadata) & wildcards->metadata_mask)
&& !((a->nw_src ^ b->nw_src) & wildcards->nw_src_mask)
&& !((a->nw_dst ^ b->nw_dst) & wildcards->nw_dst_mask)
&& (wc & FWW_IN_PORT || a->in_port == b->in_port)
&& (wc & FWW_DL_TYPE || a->dl_type == b->dl_type)
&& !((a->tp_src ^ b->tp_src) & wildcards->tp_src_mask)
&& !((a->tp_dst ^ b->tp_dst) & wildcards->tp_dst_mask)
- && !eth_addr_equal_except(a->dl_src, b->dl_src,
- wildcards->dl_src_mask)
- && !eth_addr_equal_except(a->dl_dst, b->dl_dst,
- wildcards->dl_dst_mask)
+ && eth_addr_equal_except(a->dl_src, b->dl_src,
+ wildcards->dl_src_mask)
+ && eth_addr_equal_except(a->dl_dst, b->dl_dst,
+ wildcards->dl_dst_mask)
&& (wc & FWW_NW_PROTO || a->nw_proto == b->nw_proto)
&& (wc & FWW_NW_TTL || a->nw_ttl == b->nw_ttl)
&& (wc & FWW_NW_DSCP || !((a->nw_tos ^ b->nw_tos) & IP_DSCP_MASK))