ofp-util: Make make_flow_mod() take cls_rule instead of struct flow.
authorBen Pfaff <blp@nicira.com>
Wed, 10 Nov 2010 22:51:49 +0000 (14:51 -0800)
committerBen Pfaff <blp@nicira.com>
Mon, 22 Nov 2010 18:11:41 +0000 (10:11 -0800)
This reduces code duplication, by eliminating a function that translates
from "struct flow" to "struct ofp_match" in favor of the existing function
ofputil_cls_rule_to_match().  It also allows the caller to specify the
desired priority (as part of the cls_rule).

lib/learning-switch.c
lib/ofp-util.c
lib/ofp-util.h

index 63edc0fb8c1bacefe859253d4d399cef0b1d3377..ef715dbabc1052e8fa2a7caf6d08a50d36e65ee3 100644 (file)
@@ -24,6 +24,7 @@
 #include <time.h>
 
 #include "byte-order.h"
+#include "classifier.h"
 #include "flow.h"
 #include "hmap.h"
 #include "mac-learning.h"
@@ -57,7 +58,7 @@ struct lswitch {
     unsigned long long int datapath_id;
     time_t last_features_request;
     struct mac_learning *ml;    /* NULL to act as hub instead of switch. */
-    uint32_t wildcards;         /* Wildcards to apply to flows. */
+    struct flow_wildcards wc;   /* Wildcards to apply to flows. */
     bool action_normal;         /* Use OFPP_NORMAL? */
 
     /* Queue distribution. */
@@ -97,15 +98,16 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
     sw->last_features_request = time_now() - 1;
     sw->ml = cfg->mode == LSW_LEARN ? mac_learning_create() : NULL;
     sw->action_normal = cfg->mode == LSW_NORMAL;
-    if (cfg->exact_flows) {
-        /* Exact match. */
-        sw->wildcards = 0;
-    } else {
+
+    flow_wildcards_init_exact(&sw->wc);
+    if (!cfg->exact_flows) {
         /* We cannot wildcard all fields.
          * We need in_port to detect moves.
          * We need both SA and DA to do learning. */
-        sw->wildcards = (OFPFW_DL_TYPE | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK
-                         | OFPFW_NW_PROTO | OFPFW_TP_SRC | OFPFW_TP_DST);
+        sw->wc.wildcards = (FWW_DL_TYPE | FWW_NW_PROTO
+                            | FWW_TP_SRC | FWW_TP_DST);
+        sw->wc.nw_src_mask = htonl(0);
+        sw->wc.nw_dst_mask = htonl(0);
     }
 
     sw->default_queue = cfg->default_queue;
@@ -423,14 +425,15 @@ process_packet_in(struct lswitch *sw, struct rconn *rconn, void *opi_)
     if (sw->max_idle >= 0 && (!sw->ml || out_port != OFPP_FLOOD)) {
         struct ofpbuf *buffer;
         struct ofp_flow_mod *ofm;
+        struct cls_rule rule;
 
         /* The output port is known, or we always flood everything, so add a
          * new flow. */
-        buffer = make_add_flow(&flow, ntohl(opi->buffer_id),
+        cls_rule_init(&flow, &sw->wc, 0, &rule);
+        buffer = make_add_flow(&rule, ntohl(opi->buffer_id),
                                sw->max_idle, actions_len);
         ofpbuf_put(buffer, actions, actions_len);
         ofm = buffer->data;
-        ofm->match.wildcards = htonl(sw->wildcards);
         queue_tx(sw, rconn, buffer);
 
         /* If the switch didn't buffer the packet, we need to send a copy. */
index 82797d4d5f1cbf806fa32814e4f11725b1260064..208eabb5c56844efbaf9921f2ae1301806a74ac9 100644 (file)
@@ -328,7 +328,8 @@ update_openflow_length(struct ofpbuf *buffer)
 }
 
 struct ofpbuf *
-make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len)
+make_flow_mod(uint16_t command, const struct cls_rule *rule,
+              size_t actions_len)
 {
     struct ofp_flow_mod *ofm;
     size_t size = sizeof *ofm + actions_len;
@@ -338,29 +339,17 @@ make_flow_mod(uint16_t command, const struct flow *flow, size_t actions_len)
     ofm->header.type = OFPT_FLOW_MOD;
     ofm->header.length = htons(size);
     ofm->cookie = 0;
-    ofm->match.wildcards = htonl(0);
-    ofm->match.in_port = htons(flow->in_port == ODPP_LOCAL ? OFPP_LOCAL
-                               : flow->in_port);
-    memcpy(ofm->match.dl_src, flow->dl_src, sizeof ofm->match.dl_src);
-    memcpy(ofm->match.dl_dst, flow->dl_dst, sizeof ofm->match.dl_dst);
-    ofm->match.dl_vlan = flow->dl_vlan;
-    ofm->match.dl_vlan_pcp = flow->dl_vlan_pcp;
-    ofm->match.dl_type = flow->dl_type;
-    ofm->match.nw_src = flow->nw_src;
-    ofm->match.nw_dst = flow->nw_dst;
-    ofm->match.nw_proto = flow->nw_proto;
-    ofm->match.nw_tos = flow->nw_tos;
-    ofm->match.tp_src = flow->tp_src;
-    ofm->match.tp_dst = flow->tp_dst;
+    ofm->priority = htons(MIN(rule->priority, UINT16_MAX));
+    ofputil_cls_rule_to_match(rule, NXFF_OPENFLOW10, &ofm->match);
     ofm->command = htons(command);
     return out;
 }
 
 struct ofpbuf *
-make_add_flow(const struct flow *flow, uint32_t buffer_id,
+make_add_flow(const struct cls_rule *rule, uint32_t buffer_id,
               uint16_t idle_timeout, size_t actions_len)
 {
-    struct ofpbuf *out = make_flow_mod(OFPFC_ADD, flow, actions_len);
+    struct ofpbuf *out = make_flow_mod(OFPFC_ADD, rule, actions_len);
     struct ofp_flow_mod *ofm = out->data;
     ofm->idle_timeout = htons(idle_timeout);
     ofm->hard_timeout = htons(OFP_FLOW_PERMANENT);
@@ -369,16 +358,16 @@ make_add_flow(const struct flow *flow, uint32_t buffer_id,
 }
 
 struct ofpbuf *
-make_del_flow(const struct flow *flow)
+make_del_flow(const struct cls_rule *rule)
 {
-    struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, flow, 0);
+    struct ofpbuf *out = make_flow_mod(OFPFC_DELETE_STRICT, rule, 0);
     struct ofp_flow_mod *ofm = out->data;
     ofm->out_port = htons(OFPP_NONE);
     return out;
 }
 
 struct ofpbuf *
-make_add_simple_flow(const struct flow *flow,
+make_add_simple_flow(const struct cls_rule *rule,
                      uint32_t buffer_id, uint16_t out_port,
                      uint16_t idle_timeout)
 {
@@ -386,14 +375,14 @@ make_add_simple_flow(const struct flow *flow,
         struct ofp_action_output *oao;
         struct ofpbuf *buffer;
 
-        buffer = make_add_flow(flow, buffer_id, idle_timeout, sizeof *oao);
+        buffer = make_add_flow(rule, buffer_id, idle_timeout, sizeof *oao);
         oao = ofpbuf_put_zeros(buffer, sizeof *oao);
         oao->type = htons(OFPAT_OUTPUT);
         oao->len = htons(sizeof *oao);
         oao->port = htons(out_port);
         return buffer;
     } else {
-        return make_add_flow(flow, buffer_id, idle_timeout, 0);
+        return make_add_flow(rule, buffer_id, idle_timeout, 0);
     }
 }
 
index 02a84decb6f3e77aa8dd437fb6a482471ab29848..fdca005fb217a155445e9fefc4798300e070d89d 100644 (file)
@@ -56,12 +56,12 @@ void *put_openflow(size_t openflow_len, uint8_t type, struct ofpbuf *);
 void *put_openflow_xid(size_t openflow_len, uint8_t type, ovs_be32 xid,
                        struct ofpbuf *);
 void update_openflow_length(struct ofpbuf *);
-struct ofpbuf *make_flow_mod(uint16_t command, const struct flow *,
+struct ofpbuf *make_flow_mod(uint16_t command, const struct cls_rule *,
                              size_t actions_len);
-struct ofpbuf *make_add_flow(const struct flow *, uint32_t buffer_id,
+struct ofpbuf *make_add_flow(const struct cls_rule *, uint32_t buffer_id,
                              uint16_t max_idle, size_t actions_len);
-struct ofpbuf *make_del_flow(const struct flow *);
-struct ofpbuf *make_add_simple_flow(const struct flow *,
+struct ofpbuf *make_del_flow(const struct cls_rule *);
+struct ofpbuf *make_add_simple_flow(const struct cls_rule *,
                                     uint32_t buffer_id, uint16_t out_port,
                                     uint16_t max_idle);
 struct ofpbuf *make_packet_in(uint32_t buffer_id, uint16_t in_port,