lswitch_create(struct rconn *rconn, const struct lswitch_config *cfg)
{
struct lswitch *sw;
+ uint32_t ofpfw;
sw = xzalloc(sizeof *sw);
sw->rconn = rconn;
: NULL);
sw->action_normal = cfg->mode == LSW_NORMAL;
- flow_wildcards_init_exact(&sw->wc);
- 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 VID to do L2 learning. */
- ofpfw = (OFPFW10_DL_TYPE | OFPFW10_DL_VLAN_PCP
- | OFPFW10_NW_SRC_ALL | OFPFW10_NW_DST_ALL
- | OFPFW10_NW_TOS | OFPFW10_NW_PROTO
- | OFPFW10_TP_SRC | OFPFW10_TP_DST);
- } else {
- ofpfw = cfg->wildcards;
- }
+ switch (cfg->wildcards) {
+ case 0:
+ ofpfw = 0;
+ break;
- ofputil_wildcard_from_ofpfw10(ofpfw, &sw->wc);
+ case 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 VID to do L2 learning. */
+ ofpfw = (OFPFW10_DL_TYPE | OFPFW10_DL_VLAN_PCP
+ | OFPFW10_NW_SRC_ALL | OFPFW10_NW_DST_ALL
+ | OFPFW10_NW_TOS | OFPFW10_NW_PROTO
+ | OFPFW10_TP_SRC | OFPFW10_TP_DST);
+ break;
+
+ default:
+ ofpfw = cfg->wildcards;
+ break;
}
+ ofputil_wildcard_from_ofpfw10(ofpfw, &sw->wc);
sw->default_queue = cfg->default_queue;
hmap_init(&sw->queue_numbers);
}
#include "ofp-util.def"
-/* "Normalizes" the wildcards in 'rule'. That means:
- *
- * 1. If the type of level N is known, then only the valid fields for that
- * level may be specified. For example, ARP does not have a TOS field,
- * so nw_tos must be wildcarded if 'rule' specifies an ARP flow.
- * Similarly, IPv4 does not have any IPv6 addresses, so ipv6_src and
- * ipv6_dst (and other fields) must be wildcarded if 'rule' specifies an
- * IPv4 flow.
- *
- * 2. If the type of level N is not known (or not understood by Open
- * vSwitch), then no fields at all for that level may be specified. For
- * example, Open vSwitch does not understand SCTP, an L4 protocol, so the
- * L4 fields tp_src and tp_dst must be wildcarded if 'rule' specifies an
- * SCTP flow.
- */
-void
-ofputil_normalize_rule(struct cls_rule *rule)
+static void
+ofputil_normalize_rule__(struct cls_rule *rule, bool may_log)
{
enum {
MAY_NW_ADDR = 1 << 0, /* nw_src, nw_dst */
/* Log any changes. */
if (!flow_wildcards_equal(&wc, &rule->wc)) {
- bool log = !VLOG_DROP_INFO(&bad_ofmsg_rl);
+ bool log = may_log && !VLOG_DROP_INFO(&bad_ofmsg_rl);
char *pre = log ? cls_rule_to_string(rule) : NULL;
rule->wc = wc;
}
}
+/* "Normalizes" the wildcards in 'rule'. That means:
+ *
+ * 1. If the type of level N is known, then only the valid fields for that
+ * level may be specified. For example, ARP does not have a TOS field,
+ * so nw_tos must be wildcarded if 'rule' specifies an ARP flow.
+ * Similarly, IPv4 does not have any IPv6 addresses, so ipv6_src and
+ * ipv6_dst (and other fields) must be wildcarded if 'rule' specifies an
+ * IPv4 flow.
+ *
+ * 2. If the type of level N is not known (or not understood by Open
+ * vSwitch), then no fields at all for that level may be specified. For
+ * example, Open vSwitch does not understand SCTP, an L4 protocol, so the
+ * L4 fields tp_src and tp_dst must be wildcarded if 'rule' specifies an
+ * SCTP flow.
+ *
+ * If this function changes 'rule', it logs a rate-limited informational
+ * message. */
+void
+ofputil_normalize_rule(struct cls_rule *rule)
+{
+ ofputil_normalize_rule__(rule, true);
+}
+
+/* Same as ofputil_normalize_rule() without the logging. Thus, this function
+ * is suitable for a program's internal use, whereas ofputil_normalize_rule()
+ * sense for use on flows received from elsewhere (so that a bug in the program
+ * that sent them can be reported and corrected). */
+void
+ofputil_normalize_rule_quiet(struct cls_rule *rule)
+{
+ ofputil_normalize_rule__(rule, false);
+}
+
/* Parses a key or a key-value pair from '*stringp'.
*
* On success: Stores the key into '*keyp'. Stores the value, if present, into