flow: Better abstract flow_wildcards and use it more widely.
authorBen Pfaff <blp@nicira.com>
Mon, 8 Nov 2010 18:37:35 +0000 (10:37 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 8 Nov 2010 18:43:32 +0000 (10:43 -0800)
lib/classifier.c
lib/classifier.h
lib/flow.c
lib/flow.h
ofproto/ofproto.c
tests/test-classifier.c

index e98e7fb8e4b3a91b512e73b4c63aaee0aea08446..85c3c45afb0957a8a1a4857858b781a01cf75fc5 100644 (file)
@@ -99,22 +99,27 @@ cls_table_next_rule(const struct cls_table *table, const struct cls_rule *rule)
                                                 &next->hmap_node)));
 }
 
-static void
-cls_rule_init__(struct cls_rule *rule,
-                const struct flow *flow, uint32_t wildcards)
+/* Converts the flow in 'flow' into a cls_rule in 'rule', with the given
+ * 'wildcards' and 'priority'. */
+void
+cls_rule_init(const struct flow *flow, const struct flow_wildcards *wildcards,
+              unsigned int priority, struct cls_rule *rule)
 {
     rule->flow = *flow;
-    flow_wildcards_init(&rule->wc, wildcards);
+    rule->wc = *wildcards;
+    rule->priority = priority;
     cls_rule_zero_wildcarded_fields(rule);
 }
 
-/* Converts the flow in 'flow' into a cls_rule in 'rule', with the given
- * 'wildcards' and 'priority'.*/
+/* Converts the flow in 'flow' into an exact-match cls_rule in 'rule', with the
+ * given 'priority'.  (For OpenFlow 1.0, exact-match rule are always highest
+ * priority, so 'priority' should be at least 65535.) */
 void
-cls_rule_from_flow(const struct flow *flow, uint32_t wildcards,
-                   unsigned int priority, struct cls_rule *rule)
+cls_rule_init_exact(const struct flow *flow,
+                    unsigned int priority, struct cls_rule *rule)
 {
-    cls_rule_init__(rule, flow, wildcards);
+    rule->flow = *flow;
+    flow_wildcards_init_exact(&rule->wc);
     rule->priority = priority;
 }
 
@@ -126,12 +131,9 @@ cls_rule_from_match(const struct ofp_match *match, unsigned int priority,
                     int flow_format, uint64_t cookie,
                     struct cls_rule *rule)
 {
-    uint32_t wildcards;
-    struct flow flow;
-
-    flow_from_match(match, flow_format, cookie, &flow, &wildcards);
-    cls_rule_init__(rule, &flow, wildcards);
-    rule->priority = rule->wc.wildcards ? priority : UINT16_MAX;
+    flow_from_match(match, flow_format, cookie, &rule->flow, &rule->wc);
+    rule->priority = !rule->wc.wildcards ? UINT16_MAX : priority;
+    cls_rule_zero_wildcarded_fields(rule);
 }
 
 /* Initializes 'rule' as a "catch-all" rule that matches every packet, with
index 5de2b32d2932f8f0445150b46bcce41cb1556b35..0d95a2ea411b862bfcb4b9520156bc39ecd38bb6 100644 (file)
@@ -73,8 +73,10 @@ enum {
     CLS_INC_ALL = CLS_INC_EXACT | CLS_INC_WILD
 };
 
-void cls_rule_from_flow(const struct flow *, uint32_t wildcards,
-                        unsigned int priority, struct cls_rule *);
+void cls_rule_init(const struct flow *, const struct flow_wildcards *,
+                   unsigned int priority, struct cls_rule *);
+void cls_rule_init_exact(const struct flow *, unsigned int priority,
+                         struct cls_rule *);
 void cls_rule_from_match(const struct ofp_match *, unsigned int priority,
                          int flow_format, uint64_t cookie, struct cls_rule *);
 void cls_rule_init_catchall(struct cls_rule *, unsigned int priority);
index 678ae43090875c70ab4b27b77533ac155a13f9ba..c85219e59394dcb9bc652aaac74a8fefa72e0740 100644 (file)
@@ -279,18 +279,20 @@ flow_to_match(const struct flow *flow, uint32_t wildcards,
 
 void
 flow_from_match(const struct ofp_match *match, int flow_format,
-                ovs_be64 cookie, struct flow *flow, uint32_t *flow_wildcards)
+                ovs_be64 cookie, struct flow *flow,
+                struct flow_wildcards *wc)
 {
-       uint32_t wildcards = ntohl(match->wildcards);
-
-    flow->nw_src = match->nw_src;
-    flow->nw_dst = match->nw_dst;
-    if (flow_format == NXFF_TUN_ID_FROM_COOKIE && !(wildcards & NXFW_TUN_ID)) {
+    flow_wildcards_init(wc, ntohl(match->wildcards));
+    if (flow_format == NXFF_TUN_ID_FROM_COOKIE
+        && !(wc->wildcards & NXFW_TUN_ID)) {
         flow->tun_id = htonl(ntohll(cookie) >> 32);
     } else {
-        wildcards |= NXFW_TUN_ID;
+        wc->wildcards |= NXFW_TUN_ID;
         flow->tun_id = 0;
     }
+
+    flow->nw_src = match->nw_src;
+    flow->nw_dst = match->nw_dst;
     flow->in_port = (match->in_port == htons(OFPP_LOCAL) ? ODPP_LOCAL
                      : ntohs(match->in_port));
     flow->dl_vlan = match->dl_vlan;
@@ -302,9 +304,6 @@ flow_from_match(const struct ofp_match *match, int flow_format,
     memcpy(flow->dl_dst, match->dl_dst, ETH_ADDR_LEN);
     flow->nw_tos = match->nw_tos;
     flow->nw_proto = match->nw_proto;
-    if (flow_wildcards) {
-        *flow_wildcards = wildcards;
-    }
 }
 
 char *
index a154df2b92235d3d55bcb3d0b154d54c5e15cd7b..7a1084af1b46b6a1688cd19af38e60f23181ae7c 100644 (file)
@@ -28,6 +28,7 @@
 #include "util.h"
 
 struct ds;
+struct flow_wildcards;
 struct ofp_match;
 struct ofpbuf;
 
@@ -62,7 +63,7 @@ void flow_extract_stats(const struct flow *flow, struct ofpbuf *packet,
 void flow_to_match(const struct flow *, uint32_t wildcards, int flow_format,
                    struct ofp_match *);
 void flow_from_match(const struct ofp_match *, int flow_format,
-                     ovs_be64 cookie, struct flow *, uint32_t *wildcards);
+                     ovs_be64 cookie, struct flow *, struct flow_wildcards *);
 char *flow_to_string(const struct flow *);
 void flow_format(struct ds *, const struct flow *);
 void flow_print(FILE *, const struct flow *);
index 9b63d022397768f7d3fe0b07719b969f1d5c77b8..e53835e1ae62587aa843e8c06b3c2d8b78d6934f 100644 (file)
@@ -2053,8 +2053,9 @@ rule_create_subrule(struct ofproto *ofproto, struct rule *rule,
                                        rule->idle_timeout, rule->hard_timeout,
                                        0, false);
     COVERAGE_INC(ofproto_subrule_create);
-    cls_rule_from_flow(flow, 0, (rule->cr.priority <= UINT16_MAX ? UINT16_MAX
-                        : rule->cr.priority), &subrule->cr);
+    cls_rule_init_exact(flow, (rule->cr.priority <= UINT16_MAX ? UINT16_MAX
+                               : rule->cr.priority),
+                        &subrule->cr);
 
     if (classifier_insert(&ofproto->cls, &subrule->cr)) {
         /* Can't happen,  */
@@ -4270,7 +4271,7 @@ ofproto_update_used(struct ofproto *p)
         struct flow flow;
 
         odp_flow_key_to_flow(&f->key, &flow);
-        cls_rule_from_flow(&flow, 0, UINT16_MAX, &target);
+        cls_rule_init_exact(&flow, UINT16_MAX, &target);
 
         rule = rule_from_cls_rule(classifier_find_rule_exactly(&p->cls,
                                                                &target));
index 70af7ed05475d11164bc08909a26b2ba566781c7..6c296ecce641a78538495077c544742f91b515fa 100644 (file)
@@ -477,6 +477,7 @@ static struct test_rule *
 make_rule(int wc_fields, unsigned int priority, int value_pat)
 {
     const struct cls_field *f;
+    struct flow_wildcards wc;
     struct test_rule *rule;
     uint32_t wildcards;
     struct flow flow;
@@ -494,8 +495,9 @@ make_rule(int wc_fields, unsigned int priority, int value_pat)
     }
 
     rule = xzalloc(sizeof *rule);
-    cls_rule_from_flow(&flow, wildcards, !wildcards ? UINT_MAX : priority,
-                       &rule->cls_rule);
+    flow_wildcards_init(&wc, wildcards);
+    cls_rule_init(&flow, &wc, !wildcards ? UINT_MAX : priority,
+                  &rule->cls_rule);
     return rule;
 }