projects
/
openvswitch
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ofp-util: Make ofputil_encode_set_protocol() able to return failure.
[openvswitch]
/
lib
/
ofp-util.c
diff --git
a/lib/ofp-util.c
b/lib/ofp-util.c
index c2e97384639a14b9fd1e51a7a26b0a99ac201c55..ad3fb369219fe8f666219719be1ef1fa40f4d9a4 100644
(file)
--- a/
lib/ofp-util.c
+++ b/
lib/ofp-util.c
@@
-726,7
+726,7
@@
ofputil_protocol_to_string(enum ofputil_protocol protocol)
return "OpenFlow10+table_id";
case OFPUTIL_P_OF12_OXM:
return "OpenFlow10+table_id";
case OFPUTIL_P_OF12_OXM:
- return
NULL
;
+ return
"OXM"
;
}
/* Check abbreviations. */
}
/* Check abbreviations. */
@@
-969,71
+969,71
@@
ofputil_usable_protocols(const struct match *match)
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
BUILD_ASSERT_DECL(FLOW_WC_SEQ == 17);
- /* NXM
and OF1.1+ supports
bitwise matching on ethernet addresses. */
+ /* NXM
, OXM, and OF1.1 support
bitwise matching on ethernet addresses. */
if (!eth_mask_is_exact(wc->masks.dl_src)
&& !eth_addr_is_zero(wc->masks.dl_src)) {
if (!eth_mask_is_exact(wc->masks.dl_src)
&& !eth_addr_is_zero(wc->masks.dl_src)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
if (!eth_mask_is_exact(wc->masks.dl_dst)
&& !eth_addr_is_zero(wc->masks.dl_dst)) {
}
if (!eth_mask_is_exact(wc->masks.dl_dst)
&& !eth_addr_is_zero(wc->masks.dl_dst)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /* NXM and OF1.1+ support matching metadata. */
+ /* NXM
, OXM,
and OF1.1+ support matching metadata. */
if (wc->masks.metadata != htonll(0)) {
if (wc->masks.metadata != htonll(0)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching ARP hardware addresses. */
+ /*
NXM and OXM support
matching ARP hardware addresses. */
if (!eth_addr_is_zero(wc->masks.arp_sha) ||
!eth_addr_is_zero(wc->masks.arp_tha)) {
if (!eth_addr_is_zero(wc->masks.arp_sha) ||
!eth_addr_is_zero(wc->masks.arp_tha)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching IPv6 traffic. */
+ /*
NXM and OXM support
matching IPv6 traffic. */
if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) {
if (match->flow.dl_type == htons(ETH_TYPE_IPV6)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching registers. */
+ /*
NXM and OXM support
matching registers. */
if (!regs_fully_wildcarded(wc)) {
if (!regs_fully_wildcarded(wc)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching tun_id. */
+ /*
NXM and OXM support
matching tun_id. */
if (wc->masks.tunnel.tun_id != htonll(0)) {
if (wc->masks.tunnel.tun_id != htonll(0)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching fragments. */
+ /*
NXM and OXM support
matching fragments. */
if (wc->masks.nw_frag) {
if (wc->masks.nw_frag) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching IPv6 flow label. */
+ /*
NXM and OXM support
matching IPv6 flow label. */
if (wc->masks.ipv6_label) {
if (wc->masks.ipv6_label) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching IP ECN bits. */
+ /*
NXM and OXM support
matching IP ECN bits. */
if (wc->masks.nw_tos & IP_ECN_MASK) {
if (wc->masks.nw_tos & IP_ECN_MASK) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
matching IP TTL/hop limit. */
+ /*
NXM and OXM support
matching IP TTL/hop limit. */
if (wc->masks.nw_ttl) {
if (wc->masks.nw_ttl) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
non-CIDR IPv4 address masks. */
+ /*
NXM and OXM support
non-CIDR IPv4 address masks. */
if (!ip_is_cidr(wc->masks.nw_src) || !ip_is_cidr(wc->masks.nw_dst)) {
if (!ip_is_cidr(wc->masks.nw_src) || !ip_is_cidr(wc->masks.nw_dst)) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
- /*
Only NXM supports
bitwise matching on transport port. */
+ /*
NXM and OXM support
bitwise matching on transport port. */
if ((wc->masks.tp_src && wc->masks.tp_src != htons(UINT16_MAX)) ||
(wc->masks.tp_dst && wc->masks.tp_dst != htons(UINT16_MAX))) {
if ((wc->masks.tp_src && wc->masks.tp_src != htons(UINT16_MAX)) ||
(wc->masks.tp_dst && wc->masks.tp_dst != htons(UINT16_MAX))) {
- return OFPUTIL_P_OF10_NXM_ANY;
+ return OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
/* Other formats can express this rule. */
}
/* Other formats can express this rule. */
@@
-1201,15
+1201,25
@@
ofputil_encode_hello(uint32_t allowed_versions)
* connection if the switch processes the returned message correctly. (If
* '*next != want' then the caller will have to iterate.)
*
* connection if the switch processes the returned message correctly. (If
* '*next != want' then the caller will have to iterate.)
*
- * If 'current == want', returns NULL and stores 'current' in '*next'. */
+ * If 'current == want', or if it is not possible to transition from 'current'
+ * to 'want' (because, for example, 'current' and 'want' use different OpenFlow
+ * protocol versions), returns NULL and stores 'current' in '*next'. */
struct ofpbuf *
ofputil_encode_set_protocol(enum ofputil_protocol current,
enum ofputil_protocol want,
enum ofputil_protocol *next)
{
struct ofpbuf *
ofputil_encode_set_protocol(enum ofputil_protocol current,
enum ofputil_protocol want,
enum ofputil_protocol *next)
{
+ enum ofp_version cur_version, want_version;
enum ofputil_protocol cur_base, want_base;
bool cur_tid, want_tid;
enum ofputil_protocol cur_base, want_base;
bool cur_tid, want_tid;
+ cur_version = ofputil_protocol_to_ofp_version(current);
+ want_version = ofputil_protocol_to_ofp_version(want);
+ if (cur_version != want_version) {
+ *next = current;
+ return NULL;
+ }
+
cur_base = ofputil_protocol_to_base(current);
want_base = ofputil_protocol_to_base(want);
if (cur_base != want_base) {
cur_base = ofputil_protocol_to_base(current);
want_base = ofputil_protocol_to_base(want);
if (cur_base != want_base) {
@@
-1597,9
+1607,9
@@
ofputil_flow_mod_usable_protocols(const struct ofputil_flow_mod *fms,
usable_protocols &= OFPUTIL_P_TID;
}
usable_protocols &= OFPUTIL_P_TID;
}
- /* Matching of the cookie is only supported through NXM. */
+ /* Matching of the cookie is only supported through NXM
or OF1.1+
. */
if (fm->cookie_mask != htonll(0)) {
if (fm->cookie_mask != htonll(0)) {
- usable_protocols &= OFPUTIL_P_OF10_NXM_ANY;
+ usable_protocols &= OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
}
assert(usable_protocols);
}
}
assert(usable_protocols);
@@
-1791,7
+1801,7
@@
ofputil_flow_stats_request_usable_protocols(
usable_protocols = ofputil_usable_protocols(&fsr->match);
if (fsr->cookie_mask != htonll(0)) {
usable_protocols = ofputil_usable_protocols(&fsr->match);
if (fsr->cookie_mask != htonll(0)) {
- usable_protocols &= OFPUTIL_P_OF10_NXM_ANY;
+ usable_protocols &= OFPUTIL_P_OF10_NXM_ANY
| OFPUTIL_P_OF12_OXM
;
}
return usable_protocols;
}
}
return usable_protocols;
}