#include "openflow/openflow-common.h"
-/* Nothing here yet. */
+/* OpenFlow 1.1 uses 32-bit port numbers. Open vSwitch, for now, uses OpenFlow
+ * 1.0 port numbers internally. We map them to OpenFlow 1.0 as follows:
+ *
+ * OF1.1 <=> OF1.0
+ * ----------------------- ---------------
+ * 0x00000000...0x0000feff <=> 0x0000...0xfeff "physical" ports
+ * 0x0000ff00...0xfffffeff <=> not supported
+ * 0xffffff00...0xffffffff <=> 0xff00...0xffff "reserved" OFPP_* ports
+ *
+ * OFPP11_OFFSET is the value that must be added or subtracted to convert
+ * an OpenFlow 1.0 reserved port number to or from, respectively, the
+ * corresponding OpenFlow 1.1 reserved port number.
+ */
+#define OFPP11_MAX 0xffffff00
+#define OFPP11_OFFSET (OFPP11_MAX - OFPP_MAX)
#endif /* openflow/openflow-1.1.h */
return true;
}
+/* Converts the OpenFlow 1.1+ port number 'ofp11_port' into an OpenFlow 1.0
+ * port number and stores the latter in '*ofp10_port', for the purpose of
+ * decoding OpenFlow 1.1+ protocol messages. Returns 0 if successful,
+ * otherwise an OFPERR_* number.
+ *
+ * See the definition of OFP11_MAX for an explanation of the mapping. */
+enum ofperr
+ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_port)
+{
+ uint32_t ofp11_port_h = ntohl(ofp11_port);
+
+ if (ofp11_port_h < OFPP_MAX) {
+ *ofp10_port = ofp11_port_h;
+ return 0;
+ } else if (ofp11_port_h >= OFPP11_MAX) {
+ *ofp10_port = ofp11_port_h - OFPP11_OFFSET;
+ return 0;
+ } else {
+ VLOG_WARN_RL(&bad_ofmsg_rl, "port %"PRIu32" is outside the supported "
+ "range 0 through %d or 0x%"PRIx32" through 0x%"PRIx32,
+ ofp11_port_h, OFPP_MAX - 1,
+ (uint32_t) OFPP11_MAX, UINT32_MAX);
+ return OFPERR_OFPBAC_BAD_OUT_PORT;
+ }
+}
+
+/* Returns the OpenFlow 1.1+ port number equivalent to the OpenFlow 1.0 port
+ * number 'ofp10_port', for encoding OpenFlow 1.1+ protocol messages.
+ *
+ * See the definition of OFP11_MAX for an explanation of the mapping. */
+ovs_be32
+ofputil_port_to_ofp11(uint16_t ofp10_port)
+{
+ return htonl(ofp10_port < OFPP_MAX
+ ? ofp10_port
+ : ofp10_port + OFPP11_OFFSET);
+}
+
/* Checks that 'port' is a valid output port for the OFPAT_OUTPUT action, given
* that the switch will never have more than 'max_ports' ports. Returns 0 if
* 'port' is valid, otherwise an OpenFlow return code. */
const char *ofputil_msg_type_name(const struct ofputil_msg_type *);
/* Port numbers. */
+enum ofperr ofputil_port_from_ofp11(ovs_be32 ofp11_port, uint16_t *ofp10_port);
+ovs_be32 ofputil_port_to_ofp11(uint16_t ofp10_port);
+
enum ofperr ofputil_check_output_port(uint16_t ofp_port, int max_ports);
bool ofputil_port_from_string(const char *, uint16_t *port);
void ofputil_format_port(uint16_t port, struct ds *);