void
ofputil_wildcard_from_ofpfw10(uint32_t ofpfw, struct flow_wildcards *wc)
{
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 18);
/* Initialize most of wc. */
flow_wildcards_init_catchall(wc);
#define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
enum ofputil_protocol ofputil_flow_dump_protocols[] = {
+ OFPUTIL_P_OF12_OXM,
OFPUTIL_P_OF10_NXM,
OFPUTIL_P_OF10_STD,
};
return protocols;
}
-static enum ofp_version
+static int
ofputil_version_from_string(const char *s)
{
if (!strcasecmp(s, "OpenFlow10")) {
if (!strcasecmp(s, "OpenFlow12")) {
return OFP12_VERSION;
}
- VLOG_FATAL("Unknown OpenFlow version: \"%s\"", s);
+ return 0;
}
static bool
while (s[i]) {
size_t j;
- enum ofp_version version;
+ int version;
char *key;
if (is_delimiter(s[i])) {
}
key = xmemdup0(s + i, j);
version = ofputil_version_from_string(key);
+ if (!version) {
+ VLOG_FATAL("Unknown OpenFlow version: \"%s\"", key);
+ }
free(key);
bitmap |= 1u << version;
i += j;
return bitmap;
}
+uint32_t
+ofputil_versions_from_strings(char ** const s, size_t count)
+{
+ uint32_t bitmap = 0;
+
+ while (count--) {
+ int version = ofputil_version_from_string(s[count]);
+ if (!version) {
+ VLOG_WARN("Unknown OpenFlow version: \"%s\"", s[count]);
+ } else {
+ bitmap |= 1u << version;
+ }
+ }
+
+ return bitmap;
+}
+
const char *
ofputil_version_to_string(enum ofp_version ofp_version)
{
return true;
}
+static bool
+tun_parms_fully_wildcarded(const struct flow_wildcards *wc)
+{
+ return (!wc->masks.tunnel.ip_src &&
+ !wc->masks.tunnel.ip_dst &&
+ !wc->masks.tunnel.ip_ttl &&
+ !wc->masks.tunnel.ip_tos &&
+ !wc->masks.tunnel.flags);
+}
+
/* Returns a bit-mask of ofputil_protocols that can be used for sending 'match'
* to a switch (e.g. to add or remove a flow). Only NXM can handle tunnel IDs,
* registers, or fixing the Ethernet multicast bit. Otherwise, it's better to
{
const struct flow_wildcards *wc = &match->wc;
- BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
+ BUILD_ASSERT_DECL(FLOW_WC_SEQ == 18);
+
+ /* tunnel params other than tun_id can't be sent in a flow_mod */
+ if (!tun_parms_fully_wildcarded(wc)) {
+ return OFPUTIL_P_NONE;
+ }
/* NXM, OXM, and OF1.1 support bitwise matching on ethernet addresses. */
if (!eth_mask_is_exact(wc->masks.dl_src)
return ofputil_encode_nx_set_flow_format(NXFF_OPENFLOW10);
case OFPUTIL_P_OF12_OXM:
- return ofputil_encode_nx_set_flow_format(NXFF_OPENFLOW12);
+ /* There's only one OpenFlow 1.2 protocol and we already verified
+ * above that we're not trying to change versions. */
+ NOT_REACHED();
case OFPUTIL_P_OF10_STD_TID:
case OFPUTIL_P_OF10_NXM_TID:
case NXFF_NXM:
return OFPUTIL_P_OF10_NXM;
- case NXFF_OPENFLOW12:
- return OFPUTIL_P_OF12_OXM;
-
default:
return 0;
}
return "openflow10";
case NXFF_NXM:
return "nxm";
- case NXFF_OPENFLOW12:
- return "openflow12";
default:
NOT_REACHED();
}
usable_protocols &= OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF12_OXM;
}
}
- assert(usable_protocols);
return usable_protocols;
}