ovs-controller: Allow --wildcards to specify a wildcard set.
authorBen Pfaff <blp@nicira.com>
Wed, 1 Jun 2011 16:09:20 +0000 (09:09 -0700)
committerBen Pfaff <blp@nicira.com>
Wed, 1 Jun 2011 16:09:20 +0000 (09:09 -0700)
Based on a patch by Jean Tourrilhes <jt@hpl.hp.com>.  According to Jean,
besides increasing flexibility, this reduces  normalization warnings.

Tested-by: Jean Tourrilhes <jt@hpl.hp.com>
lib/learning-switch.c
lib/learning-switch.h
lib/ofp-util.c
lib/ofp-util.h
utilities/ovs-controller.8.in
utilities/ovs-controller.c

index 6bd2286234ca031d83d5f1fe6682e5963d830e11..fc45b04349f035cd436e820d930efffeddb9bacc 100644 (file)
@@ -100,14 +100,21 @@ 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) {
+            /* Try to wildcard as many fields as possible, but we cannot
+             * wildcard all fields.  We need in_port to detect moves.  We need
+             * Ethernet source and dest and VLAN 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;
index e5036906fdb32c7d83aeef36bf4a7606af7392da..c6f347e197dd247501e2ef44594bab6d14f157aa 100644 (file)
@@ -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.
index df2f21dfcca77faef3e10bb357c92787d2a4ee0d..e21831fdd8e47315b273986cd3b49da84fbfcbea 100644 (file)
@@ -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. */
index 152f4dd805e299d39217f98a39a403afa3e66f40..bba366300eb1ef9f94e0152d355f3d279f8273df 100644 (file)
@@ -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);
index 18d77de200ea442acc48e8f2aa5a1fafab8f4180..016c7e3934d7bf7dbef1e0949204e787cafffb71 100644 (file)
@@ -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).
 .
index f97797472447539348946347178870cff49bdae8..022b1a4db98df0895ca7bcfce4b53e5f60402c13 100644 (file)
@@ -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 specific 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"