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;
/*
- * 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.
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.
/* 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. */
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);
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).
.
/* -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;
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;
{"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'},
break;
case 'w':
- exact_flows = false;
+ wildcards = optarg ? strtol(optarg, NULL, 16) : UINT32_MAX;
break;
case OPT_MAX_IDLE:
" -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"