ofp-util: New function for parsing key-value pairs.
[openvswitch] / lib / classifier.c
index e89a6c8fb4659fa8d71f409506da662503fa580b..430c5994095d5c56d5378878b469ef7b7982810f 100644 (file)
@@ -390,10 +390,10 @@ cls_rule_set_ipv6_dst_masked(struct cls_rule *rule, const struct in6_addr *dst,
 }
 
 void
-cls_rule_set_nd_target(struct cls_rule *rule, const struct in6_addr target)
+cls_rule_set_nd_target(struct cls_rule *rule, const struct in6_addr *target)
 {
     rule->wc.wildcards &= ~FWW_ND_TARGET;
-    rule->flow.nd_target = target;
+    rule->flow.nd_target = *target;
 }
 
 /* Returns true if 'a' and 'b' have the same priority, wildcard the same
@@ -406,20 +406,23 @@ cls_rule_equal(const struct cls_rule *a, const struct cls_rule *b)
             && flow_equal(&a->flow, &b->flow));
 }
 
+/* Returns a hash value for the flow, wildcards, and priority in 'rule',
+ * starting from 'basis'. */
+uint32_t
+cls_rule_hash(const struct cls_rule *rule, uint32_t basis)
+{
+    uint32_t h0 = flow_hash(&rule->flow, basis);
+    uint32_t h1 = flow_wildcards_hash(&rule->wc, h0);
+    return hash_int(rule->priority, h1);
+}
+
 static void
 format_ip_netmask(struct ds *s, const char *name, ovs_be32 ip,
                   ovs_be32 netmask)
 {
     if (netmask) {
-        ds_put_format(s, "%s="IP_FMT, name, IP_ARGS(&ip));
-        if (netmask != htonl(UINT32_MAX)) {
-            if (ip_is_cidr(netmask)) {
-                int wcbits = ofputil_netmask_to_wcbits(netmask);
-                ds_put_format(s, "/%d", 32 - wcbits);
-            } else {
-                ds_put_format(s, "/"IP_FMT, IP_ARGS(&netmask));
-            }
-        }
+        ds_put_format(s, "%s=", name);
+        ip_format_masked(ip, netmask, s);
         ds_put_char(s, ',');
     }
 }
@@ -431,16 +434,7 @@ format_ipv6_netmask(struct ds *s, const char *name,
 {
     if (!ipv6_mask_is_any(netmask)) {
         ds_put_format(s, "%s=", name);
-        print_ipv6_addr(s, addr);
-        if (!ipv6_mask_is_exact(netmask)) {
-            if (ipv6_is_cidr(netmask)) {
-                int cidr_bits = ipv6_count_cidr_bits(netmask);
-                ds_put_format(s, "/%d", cidr_bits);
-            } else {
-                ds_put_char(s, '/');
-                print_ipv6_addr(s, netmask);
-            }
-        }
+        print_ipv6_masked(s, addr, netmask);
         ds_put_char(s, ',');
     }
 }
@@ -457,6 +451,8 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
 
     int i;
 
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1);
+
     if (rule->priority != OFP_DEFAULT_PRIORITY) {
         ds_put_format(s, "priority=%d,", rule->priority);
     }
@@ -582,7 +578,7 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
     }
     if (!skip_proto && !(w & FWW_NW_PROTO)) {
         if (f->dl_type == htons(ETH_TYPE_ARP)) {
-            ds_put_format(s, "opcode=%"PRIu8",", f->nw_proto);
+            ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto);
         } else {
             ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
         }
@@ -620,11 +616,11 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
             ds_put_char(s, ',');
         }
         if (!(w & FWW_ARP_SHA)) {
-            ds_put_format(s, "nd_sll="ETH_ADDR_FMT",", 
+            ds_put_format(s, "nd_sll="ETH_ADDR_FMT",",
                     ETH_ADDR_ARGS(f->arp_sha));
         }
         if (!(w & FWW_ARP_THA)) {
-            ds_put_format(s, "nd_tll="ETH_ADDR_FMT",", 
+            ds_put_format(s, "nd_tll="ETH_ADDR_FMT",",
                     ETH_ADDR_ARGS(f->arp_tha));
         }
    } else {
@@ -969,7 +965,7 @@ find_table(const struct classifier *cls, const struct flow_wildcards *wc)
 {
     struct cls_table *table;
 
-    HMAP_FOR_EACH_IN_BUCKET (table, hmap_node, flow_wildcards_hash(wc),
+    HMAP_FOR_EACH_IN_BUCKET (table, hmap_node, flow_wildcards_hash(wc, 0),
                              &cls->tables) {
         if (flow_wildcards_equal(wc, &table->wc)) {
             return table;
@@ -986,7 +982,7 @@ insert_table(struct classifier *cls, const struct flow_wildcards *wc)
     table = xzalloc(sizeof *table);
     hmap_init(&table->rules);
     table->wc = *wc;
-    hmap_insert(&cls->tables, &table->hmap_node, flow_wildcards_hash(wc));
+    hmap_insert(&cls->tables, &table->hmap_node, flow_wildcards_hash(wc, 0));
 
     return table;
 }
@@ -1128,7 +1124,7 @@ flow_equal_except(const struct flow *a, const struct flow *b,
     const flow_wildcards_t wc = wildcards->wildcards;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 100 + FLOW_N_REGS * 4);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1);
 
     for (i = 0; i < FLOW_N_REGS; i++) {
         if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
@@ -1162,7 +1158,7 @@ flow_equal_except(const struct flow *a, const struct flow *b,
                     &wildcards->ipv6_src_mask)
             && ipv6_equal_except(&a->ipv6_dst, &b->ipv6_dst,
                     &wildcards->ipv6_dst_mask)
-            && (wc & FWW_ND_TARGET 
+            && (wc & FWW_ND_TARGET
                 || ipv6_addr_equals(&a->nd_target, &b->nd_target)));
 }
 
@@ -1172,7 +1168,7 @@ zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
     const flow_wildcards_t wc = wildcards->wildcards;
     int i;
 
-    BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 100 + 4 * FLOW_N_REGS);
+    BUILD_ASSERT_DECL(FLOW_WC_SEQ == 1);
 
     for (i = 0; i < FLOW_N_REGS; i++) {
         flow->regs[i] &= wildcards->reg_masks[i];