summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/learning-switch.c23
-rw-r--r--lib/learning-switch.h11
-rw-r--r--lib/ofp-util.c2
-rw-r--r--lib/ofp-util.h1
-rw-r--r--utilities/ovs-controller.8.in13
-rw-r--r--utilities/ovs-controller.c13
6 files changed, 42 insertions, 21 deletions
diff --git a/lib/learning-switch.c b/lib/learning-switch.c
index 6bd228623..fc45b0434 100644
--- a/lib/learning-switch.c
+++ b/lib/learning-switch.c
@@ -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;
diff --git a/lib/learning-switch.h b/lib/learning-switch.h
index e5036906f..c6f347e19 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 df2f21dfc..e21831fdd 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 152f4dd80..bba366300 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 18d77de20..016c7e393 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 f97797472..022b1a4db 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 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"