2 * Copyright (c) 2008-2017 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "openvswitch/ofp-protocol.h"
20 #include "openvswitch/dynamic-string.h"
21 #include "openvswitch/ofp-flow.h"
22 #include "openvswitch/vlog.h"
25 VLOG_DEFINE_THIS_MODULE(ofp_protocol
);
30 enum ofputil_protocol protocol
;
34 /* Most users really don't care about some of the differences between
35 * protocols. These abbreviations help with that. */
36 static const struct proto_abbrev proto_abbrevs
[] = {
37 { OFPUTIL_P_ANY
, "any" },
38 { OFPUTIL_P_OF10_STD_ANY
, "OpenFlow10" },
39 { OFPUTIL_P_OF10_NXM_ANY
, "NXM" },
40 { OFPUTIL_P_ANY_OXM
, "OXM" },
42 #define N_PROTO_ABBREVS ARRAY_SIZE(proto_abbrevs)
44 enum ofputil_protocol ofputil_flow_dump_protocols
[] = {
54 size_t ofputil_n_flow_dump_protocols
= ARRAY_SIZE(ofputil_flow_dump_protocols
);
56 /* Returns the set of ofputil_protocols that are supported with the given
57 * OpenFlow 'version'. 'version' should normally be an 8-bit OpenFlow version
58 * identifier (e.g. 0x01 for OpenFlow 1.0, 0x02 for OpenFlow 1.1). Returns 0
59 * if 'version' is not supported or outside the valid range. */
61 ofputil_protocols_from_ofp_version(enum ofp_version version
)
65 return OFPUTIL_P_OF10_STD_ANY
| OFPUTIL_P_OF10_NXM_ANY
;
67 return OFPUTIL_P_OF11_STD
;
69 return OFPUTIL_P_OF12_OXM
;
71 return OFPUTIL_P_OF13_OXM
;
73 return OFPUTIL_P_OF14_OXM
;
75 return OFPUTIL_P_OF15_OXM
;
77 return OFPUTIL_P_OF16_OXM
;
83 /* Returns the ofputil_protocol that is initially in effect on an OpenFlow
84 * connection that has negotiated the given 'version'. 'version' should
85 * normally be an 8-bit OpenFlow version identifier (e.g. 0x01 for OpenFlow
86 * 1.0, 0x02 for OpenFlow 1.1). Returns 0 if 'version' is not supported or
87 * outside the valid range. */
89 ofputil_protocol_from_ofp_version(enum ofp_version version
)
91 return rightmost_1bit(ofputil_protocols_from_ofp_version(version
));
94 /* Returns the OpenFlow protocol version number (e.g. OFP10_VERSION,
95 * etc.) that corresponds to 'protocol'. */
97 ofputil_protocol_to_ofp_version(enum ofputil_protocol protocol
)
100 case OFPUTIL_P_OF10_STD
:
101 case OFPUTIL_P_OF10_STD_TID
:
102 case OFPUTIL_P_OF10_NXM
:
103 case OFPUTIL_P_OF10_NXM_TID
:
104 return OFP10_VERSION
;
105 case OFPUTIL_P_OF11_STD
:
106 return OFP11_VERSION
;
107 case OFPUTIL_P_OF12_OXM
:
108 return OFP12_VERSION
;
109 case OFPUTIL_P_OF13_OXM
:
110 return OFP13_VERSION
;
111 case OFPUTIL_P_OF14_OXM
:
112 return OFP14_VERSION
;
113 case OFPUTIL_P_OF15_OXM
:
114 return OFP15_VERSION
;
115 case OFPUTIL_P_OF16_OXM
:
116 return OFP16_VERSION
;
122 /* Returns a bitmap of OpenFlow versions that are supported by at
123 * least one of the 'protocols'. */
125 ofputil_protocols_to_version_bitmap(enum ofputil_protocol protocols
)
129 for (; protocols
; protocols
= zero_rightmost_1bit(protocols
)) {
130 enum ofputil_protocol protocol
= rightmost_1bit(protocols
);
132 bitmap
|= 1u << ofputil_protocol_to_ofp_version(protocol
);
138 /* Returns the set of protocols that are supported on top of the
139 * OpenFlow versions included in 'bitmap'. */
140 enum ofputil_protocol
141 ofputil_protocols_from_version_bitmap(uint32_t bitmap
)
143 enum ofputil_protocol protocols
= 0;
145 for (; bitmap
; bitmap
= zero_rightmost_1bit(bitmap
)) {
146 enum ofp_version version
= rightmost_1bit_idx(bitmap
);
148 protocols
|= ofputil_protocols_from_ofp_version(version
);
154 /* Returns true if 'protocol' is a single OFPUTIL_P_* value, false
157 ofputil_protocol_is_valid(enum ofputil_protocol protocol
)
159 return protocol
& OFPUTIL_P_ANY
&& is_pow2(protocol
);
162 /* Returns the equivalent of 'protocol' with the Nicira flow_mod_table_id
163 * extension turned on or off if 'enable' is true or false, respectively.
165 * This extension is only useful for protocols whose "standard" version does
166 * not allow specific tables to be modified. In particular, this is true of
167 * OpenFlow 1.0. In later versions of OpenFlow, a flow_mod request always
168 * specifies a table ID and so there is no need for such an extension. When
169 * 'protocol' is such a protocol that doesn't need a flow_mod_table_id
170 * extension, this function just returns its 'protocol' argument unchanged
171 * regardless of the value of 'enable'. */
172 enum ofputil_protocol
173 ofputil_protocol_set_tid(enum ofputil_protocol protocol
, bool enable
)
176 case OFPUTIL_P_OF10_STD
:
177 case OFPUTIL_P_OF10_STD_TID
:
178 return enable
? OFPUTIL_P_OF10_STD_TID
: OFPUTIL_P_OF10_STD
;
180 case OFPUTIL_P_OF10_NXM
:
181 case OFPUTIL_P_OF10_NXM_TID
:
182 return enable
? OFPUTIL_P_OF10_NXM_TID
: OFPUTIL_P_OF10_NXM
;
184 case OFPUTIL_P_OF11_STD
:
185 return OFPUTIL_P_OF11_STD
;
187 case OFPUTIL_P_OF12_OXM
:
188 return OFPUTIL_P_OF12_OXM
;
190 case OFPUTIL_P_OF13_OXM
:
191 return OFPUTIL_P_OF13_OXM
;
193 case OFPUTIL_P_OF14_OXM
:
194 return OFPUTIL_P_OF14_OXM
;
196 case OFPUTIL_P_OF15_OXM
:
197 return OFPUTIL_P_OF15_OXM
;
199 case OFPUTIL_P_OF16_OXM
:
200 return OFPUTIL_P_OF16_OXM
;
207 /* Returns the "base" version of 'protocol'. That is, if 'protocol' includes
208 * some extension to a standard protocol version, the return value is the
209 * standard version of that protocol without any extension. If 'protocol' is a
210 * standard protocol version, returns 'protocol' unchanged. */
211 enum ofputil_protocol
212 ofputil_protocol_to_base(enum ofputil_protocol protocol
)
214 return ofputil_protocol_set_tid(protocol
, false);
217 /* Returns 'new_base' with any extensions taken from 'cur'. */
218 enum ofputil_protocol
219 ofputil_protocol_set_base(enum ofputil_protocol cur
,
220 enum ofputil_protocol new_base
)
222 bool tid
= (cur
& OFPUTIL_P_TID
) != 0;
225 case OFPUTIL_P_OF10_STD
:
226 case OFPUTIL_P_OF10_STD_TID
:
227 return ofputil_protocol_set_tid(OFPUTIL_P_OF10_STD
, tid
);
229 case OFPUTIL_P_OF10_NXM
:
230 case OFPUTIL_P_OF10_NXM_TID
:
231 return ofputil_protocol_set_tid(OFPUTIL_P_OF10_NXM
, tid
);
233 case OFPUTIL_P_OF11_STD
:
234 return ofputil_protocol_set_tid(OFPUTIL_P_OF11_STD
, tid
);
236 case OFPUTIL_P_OF12_OXM
:
237 return ofputil_protocol_set_tid(OFPUTIL_P_OF12_OXM
, tid
);
239 case OFPUTIL_P_OF13_OXM
:
240 return ofputil_protocol_set_tid(OFPUTIL_P_OF13_OXM
, tid
);
242 case OFPUTIL_P_OF14_OXM
:
243 return ofputil_protocol_set_tid(OFPUTIL_P_OF14_OXM
, tid
);
245 case OFPUTIL_P_OF15_OXM
:
246 return ofputil_protocol_set_tid(OFPUTIL_P_OF15_OXM
, tid
);
248 case OFPUTIL_P_OF16_OXM
:
249 return ofputil_protocol_set_tid(OFPUTIL_P_OF16_OXM
, tid
);
256 /* Returns a string form of 'protocol', if a simple form exists (that is, if
257 * 'protocol' is either a single protocol or it is a combination of protocols
258 * that have a single abbreviation). Otherwise, returns NULL. */
260 ofputil_protocol_to_string(enum ofputil_protocol protocol
)
262 const struct proto_abbrev
*p
;
264 /* Use a "switch" statement for single-bit names so that we get a compiler
265 * warning if we forget any. */
267 case OFPUTIL_P_OF10_NXM
:
268 return "NXM-table_id";
270 case OFPUTIL_P_OF10_NXM_TID
:
271 return "NXM+table_id";
273 case OFPUTIL_P_OF10_STD
:
274 return "OpenFlow10-table_id";
276 case OFPUTIL_P_OF10_STD_TID
:
277 return "OpenFlow10+table_id";
279 case OFPUTIL_P_OF11_STD
:
282 case OFPUTIL_P_OF12_OXM
:
283 return "OXM-OpenFlow12";
285 case OFPUTIL_P_OF13_OXM
:
286 return "OXM-OpenFlow13";
288 case OFPUTIL_P_OF14_OXM
:
289 return "OXM-OpenFlow14";
291 case OFPUTIL_P_OF15_OXM
:
292 return "OXM-OpenFlow15";
294 case OFPUTIL_P_OF16_OXM
:
295 return "OXM-OpenFlow16";
298 /* Check abbreviations. */
299 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
300 if (protocol
== p
->protocol
) {
308 /* Returns a string that represents 'protocols'. The return value might be a
309 * comma-separated list if 'protocols' doesn't have a simple name. The return
310 * value is "none" if 'protocols' is 0.
312 * The caller must free the returned string (with free()). */
314 ofputil_protocols_to_string(enum ofputil_protocol protocols
)
318 ovs_assert(!(protocols
& ~OFPUTIL_P_ANY
));
319 if (protocols
== 0) {
320 return xstrdup("none");
325 const struct proto_abbrev
*p
;
329 ds_put_char(&s
, ',');
332 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
333 if ((protocols
& p
->protocol
) == p
->protocol
) {
334 ds_put_cstr(&s
, p
->name
);
335 protocols
&= ~p
->protocol
;
340 for (i
= 0; i
< CHAR_BIT
* sizeof(enum ofputil_protocol
); i
++) {
341 enum ofputil_protocol bit
= 1u << i
;
343 if (protocols
& bit
) {
344 ds_put_cstr(&s
, ofputil_protocol_to_string(bit
));
353 return ds_steal_cstr(&s
);
356 static enum ofputil_protocol
357 ofputil_protocol_from_string__(const char *s
, size_t n
)
359 const struct proto_abbrev
*p
;
362 for (i
= 0; i
< CHAR_BIT
* sizeof(enum ofputil_protocol
); i
++) {
363 enum ofputil_protocol bit
= 1u << i
;
364 const char *name
= ofputil_protocol_to_string(bit
);
366 if (name
&& n
== strlen(name
) && !strncasecmp(s
, name
, n
)) {
371 for (p
= proto_abbrevs
; p
< &proto_abbrevs
[N_PROTO_ABBREVS
]; p
++) {
372 if (n
== strlen(p
->name
) && !strncasecmp(s
, p
->name
, n
)) {
380 /* Returns the nonempty set of protocols represented by 's', which can be a
381 * single protocol name or abbreviation or a comma-separated list of them.
383 * Aborts the program with an error message if 's' is invalid. */
384 enum ofputil_protocol
385 ofputil_protocols_from_string(const char *s
)
387 const char *orig_s
= s
;
388 enum ofputil_protocol protocols
;
392 enum ofputil_protocol p
;
401 p
= ofputil_protocol_from_string__(s
, n
);
403 ovs_fatal(0, "%.*s: unknown flow protocol", (int) n
, s
);
411 ovs_fatal(0, "%s: no flow protocol specified", orig_s
);
417 ofputil_version_from_string(const char *s
)
419 if (!strcasecmp(s
, "OpenFlow10")) {
420 return OFP10_VERSION
;
422 if (!strcasecmp(s
, "OpenFlow11")) {
423 return OFP11_VERSION
;
425 if (!strcasecmp(s
, "OpenFlow12")) {
426 return OFP12_VERSION
;
428 if (!strcasecmp(s
, "OpenFlow13")) {
429 return OFP13_VERSION
;
431 if (!strcasecmp(s
, "OpenFlow14")) {
432 return OFP14_VERSION
;
434 if (!strcasecmp(s
, "OpenFlow15")) {
435 return OFP15_VERSION
;
437 if (!strcasecmp(s
, "OpenFlow16")) {
438 return OFP16_VERSION
;
444 is_delimiter(unsigned char c
)
446 return isspace(c
) || c
== ',';
450 ofputil_versions_from_string(const char *s
)
460 if (is_delimiter(s
[i
])) {
465 while (s
[i
+ j
] && !is_delimiter(s
[i
+ j
])) {
468 key
= xmemdup0(s
+ i
, j
);
469 version
= ofputil_version_from_string(key
);
471 VLOG_FATAL("Unknown OpenFlow version: \"%s\"", key
);
474 bitmap
|= 1u << version
;
482 ofputil_versions_from_strings(char ** const s
, size_t count
)
487 int version
= ofputil_version_from_string(s
[count
]);
489 VLOG_WARN("Unknown OpenFlow version: \"%s\"", s
[count
]);
491 bitmap
|= 1u << version
;
499 ofputil_version_to_string(enum ofp_version ofp_version
)
501 switch (ofp_version
) {
522 ofputil_format_version(struct ds
*msg
, enum ofp_version version
)
524 ds_put_format(msg
, "0x%02x", version
);
528 ofputil_format_version_name(struct ds
*msg
, enum ofp_version version
)
530 ds_put_cstr(msg
, ofputil_version_to_string(version
));
534 ofputil_format_version_bitmap__(struct ds
*msg
, uint32_t bitmap
,
535 void (*format_version
)(struct ds
*msg
,
539 format_version(msg
, raw_ctz(bitmap
));
540 bitmap
= zero_rightmost_1bit(bitmap
);
542 ds_put_cstr(msg
, ", ");
548 ofputil_format_version_bitmap(struct ds
*msg
, uint32_t bitmap
)
550 ofputil_format_version_bitmap__(msg
, bitmap
, ofputil_format_version
);
554 ofputil_format_version_bitmap_names(struct ds
*msg
, uint32_t bitmap
)
556 ofputil_format_version_bitmap__(msg
, bitmap
, ofputil_format_version_name
);
559 /* Returns an OpenFlow message that, sent on an OpenFlow connection whose
560 * protocol is 'current', at least partly transitions the protocol to 'want'.
561 * Stores in '*next' the protocol that will be in effect on the OpenFlow
562 * connection if the switch processes the returned message correctly. (If
563 * '*next != want' then the caller will have to iterate.)
565 * If 'current == want', or if it is not possible to transition from 'current'
566 * to 'want' (because, for example, 'current' and 'want' use different OpenFlow
567 * protocol versions), returns NULL and stores 'current' in '*next'. */
569 ofputil_encode_set_protocol(enum ofputil_protocol current
,
570 enum ofputil_protocol want
,
571 enum ofputil_protocol
*next
)
573 enum ofp_version cur_version
, want_version
;
574 enum ofputil_protocol cur_base
, want_base
;
575 bool cur_tid
, want_tid
;
577 cur_version
= ofputil_protocol_to_ofp_version(current
);
578 want_version
= ofputil_protocol_to_ofp_version(want
);
579 if (cur_version
!= want_version
) {
584 cur_base
= ofputil_protocol_to_base(current
);
585 want_base
= ofputil_protocol_to_base(want
);
586 if (cur_base
!= want_base
) {
587 *next
= ofputil_protocol_set_base(current
, want_base
);
590 case OFPUTIL_P_OF10_NXM
:
591 return ofputil_encode_nx_set_flow_format(NXFF_NXM
);
593 case OFPUTIL_P_OF10_STD
:
594 return ofputil_encode_nx_set_flow_format(NXFF_OPENFLOW10
);
596 case OFPUTIL_P_OF11_STD
:
597 case OFPUTIL_P_OF12_OXM
:
598 case OFPUTIL_P_OF13_OXM
:
599 case OFPUTIL_P_OF14_OXM
:
600 case OFPUTIL_P_OF15_OXM
:
601 case OFPUTIL_P_OF16_OXM
:
602 /* There is only one variant of each OpenFlow 1.1+ protocol, and we
603 * verified above that we're not trying to change versions. */
606 case OFPUTIL_P_OF10_STD_TID
:
607 case OFPUTIL_P_OF10_NXM_TID
:
612 cur_tid
= (current
& OFPUTIL_P_TID
) != 0;
613 want_tid
= (want
& OFPUTIL_P_TID
) != 0;
614 if (cur_tid
!= want_tid
) {
615 *next
= ofputil_protocol_set_tid(current
, want_tid
);
616 return ofputil_make_flow_mod_table_id(want_tid
);
619 ovs_assert(current
== want
);