[ovs-dev] [ovs-controller 3/3] ovs-controller: Allow --wildcards to specify a wildcard set.

Ben Pfaff blp at nicira.com
Tue May 31 23:15:46 UTC 2011


Based on a patch by Jean Tourrilhes <jt at hpl.hp.com>.  According to Jean,
besides increasing flexibility, this reduces  normalization warnings.
---
 lib/learning-switch.c         |   24 ++++++++++++++++--------
 lib/learning-switch.h         |   11 ++++++++---
 lib/ofp-util.c                |    2 +-
 lib/ofp-util.h                |    1 +
 utilities/ovs-controller.8.in |   13 ++++++++++---
 utilities/ovs-controller.c    |   13 +++++++------
 6 files changed, 43 insertions(+), 21 deletions(-)

diff --git a/lib/learning-switch.c b/lib/learning-switch.c
index 6bd2286..e9ae93f 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -100,14 +100,22 @@ lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
     sw->action_normal = cfg->mode == LSW_NORMAL;
 
     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->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);
+    if (cfg->wildcards) {
+        uint32_t ofpfw;
+
+        if (cfg->wildcards == UINT32_MAX) {
+            /* No wildcard defined, try to wildcard as many fields
+             * as possible, however we cannot wildcard all fields.
+             * We need in_port to detect moves.
+             * We need both MAC SA and DA to do L2 learning. */
+            ofpfw = (OFPFW_DL_TYPE | OFPFW_NW_SRC_ALL | OFPFW_NW_DST_ALL
+                     | OFPFW_NW_TOS | OFPFW_NW_PROTO
+                     | OFPFW_TP_SRC | OFPFW_TP_DST);
+        } else {
+            ofpfw = cfg->wildcards;
+        }
+
+        ofputil_wildcard_from_openflow(ofpfw, &sw->wc);
     }
 
     sw->default_queue = cfg->default_queue;
diff --git a/lib/learning-switch.h b/lib/learning-switch.h
index e503690..c6f347e 100644
--- a/lib/learning-switch.h
+++ b/lib/learning-switch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2010, 2011 Nicira Networks.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,8 +33,13 @@ enum lswitch_mode {
 struct lswitch_config {
     enum lswitch_mode mode;
 
-    /* Set up only exact-match flows? */
-    bool exact_flows;
+    /* 0 to use exact-match flow entries,
+     * a OFPFW_* bitmask to enable specific wildcards,
+     * or UINT32_MAX to use the default wildcards (wildcarding as many fields
+     * as possible.
+     *
+     * Ignored when max_idle < 0 (in which case no flows are set up). */
+    uint32_t wildcards;
 
     /* <0: Process every packet at the controller.
      * >=0: Expire flows after they are unused for 'max_idle' seconds.
diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index df2f21d..e21831f 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -104,7 +104,7 @@ static const flow_wildcards_t WC_INVARIANTS = 0
 /* Converts the wildcard in 'ofpfw' into a flow_wildcards in 'wc' for use in
  * struct cls_rule.  It is the caller's responsibility to handle the special
  * case where the flow match's dl_vlan is set to OFP_VLAN_NONE. */
-static void
+void
 ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *wc)
 {
     /* Initialize most of rule->wc. */
diff --git a/lib/ofp-util.h b/lib/ofp-util.h
index 152f4dd..bba3663 100644
--- a/lib/ofp-util.h
+++ b/lib/ofp-util.h
@@ -99,6 +99,7 @@ ovs_be32 ofputil_wcbits_to_netmask(int wcbits);
 int ofputil_netmask_to_wcbits(ovs_be32 netmask);
 
 /* Work with OpenFlow 1.0 ofp_match. */
+void ofputil_wildcard_from_openflow(uint32_t ofpfw, struct flow_wildcards *);
 void ofputil_cls_rule_from_match(const struct ofp_match *,
                                  unsigned int priority, struct cls_rule *);
 void ofputil_normalize_rule(struct cls_rule *, enum nx_flow_format);
diff --git a/utilities/ovs-controller.8.in b/utilities/ovs-controller.8.in
index 18d77de..016c7e3 100644
--- a/utilities/ovs-controller.8.in
+++ b/utilities/ovs-controller.8.in
@@ -65,13 +65,20 @@ through the controller and every packet is flooded.
 This option is most useful for debugging.  It reduces switching
 performance, so it should not be used in production.
 .
-.IP "\fB\-w\fR"
-.IQ "\fB\-\-wildcard\fR"
+.IP "\fB\-w\fR[\fIwildcard_mask\fR]"
+.IQ "\fB\-\-wildcards\fR[\fB=\fIwildcard_mask\fR]\fR"
 By default, \fBovs\-controller\fR sets up exact-match flows.  This
 option allows it to set up wildcarded flows, which may reduce
-flow-setup latency by causing less traffic to be sent up to the
+flow setup latency by causing less traffic to be sent up to the
 controller.
 .IP
+The optional \fIwildcard_mask\fR is an OpenFlow wildcard bitmask in
+hexadecimal that specifies the fields to wildcard.  If no
+\fIwildcard_mask\fR is specified, the default value 0x2820F0 is used
+which specifies L2-only switching and wildcards L3 and L4 fields.
+Another interesting value is 0x2000EC, which specifies L3-only
+switching and wildcards L2 and L4 fields.
+.IP
 This option has no effect when \fB\-n\fR (or \fB\-\-noflow\fR) is in use
 (because the controller does not set up flows in that case).
 .
diff --git a/utilities/ovs-controller.c b/utilities/ovs-controller.c
index f977974..86e0b34 100644
--- a/utilities/ovs-controller.c
+++ b/utilities/ovs-controller.c
@@ -61,8 +61,9 @@ static bool set_up_flows = true;
 /* -N, --normal: Use "NORMAL" action instead of explicit port? */
 static bool action_normal = false;
 
-/* -w, --wildcard: Set up exact match or wildcard flow entries? */
-static bool exact_flows = true;
+/* -w, --wildcard: 0 to disable wildcard flow entries, a OFPFW_* bitmask to
+ * enable wildcards, or UINT32_MAX to use the default wildcards. */
+static uint32_t wildcards = 0;
 
 /* --max-idle: Maximum idle time, in seconds, before flows expire. */
 static int max_idle = 60;
@@ -227,7 +228,7 @@ new_switch(struct switch_ *sw, struct vconn *vconn)
     cfg.mode = (action_normal ? LSW_NORMAL
                 : learn_macs ? LSW_LEARN
                 : LSW_FLOOD);
-    cfg.exact_flows = exact_flows;
+    cfg.wildcards = wildcards;
     cfg.max_idle = set_up_flows ? max_idle : -1;
     cfg.default_flows = &default_flows;
     cfg.default_queue = default_queue;
@@ -317,7 +318,7 @@ parse_options(int argc, char *argv[])
         {"hub",         no_argument, NULL, 'H'},
         {"noflow",      no_argument, NULL, 'n'},
         {"normal",      no_argument, NULL, 'N'},
-        {"wildcard",    no_argument, NULL, 'w'},
+        {"wildcards",   optional_argument, NULL, 'w'},
         {"max-idle",    required_argument, NULL, OPT_MAX_IDLE},
         {"mute",        no_argument, NULL, OPT_MUTE},
         {"queue",       required_argument, NULL, 'q'},
@@ -361,7 +362,7 @@ parse_options(int argc, char *argv[])
             break;
 
         case 'w':
-            exact_flows = false;
+            wildcards = optarg ? strtol(optarg, NULL, 16) : UINT32_MAX;
             break;
 
         case OPT_MAX_IDLE:
@@ -447,7 +448,7 @@ usage(void)
            "  -n, --noflow            pass traffic, but don't add flows\n"
            "  --max-idle=SECS         max idle time for new flows\n"
            "  -N, --normal            use OFPP_NORMAL action\n"
-           "  -w, --wildcard          use wildcards, not exact-match rules\n"
+           "  -w, --wildcards[=MASK]  wildcard (specified) bits in flows\n"
            "  -q, --queue=QUEUE-ID    OpenFlow queue ID to use for output\n"
            "  -Q PORT-NAME:QUEUE-ID   use QUEUE-ID for frames from PORT-NAME\n"
            "  --with-flows FILE       use the flows from FILE\n"
-- 
1.7.4.4




More information about the dev mailing list