/* The most significant bit being set in the version field indicates an
* experimental OpenFlow version.
*/
-#define OFP_VERSION 0x88
+#define OFP_VERSION 0x89
#define OFP_MAX_TABLE_NAME_LEN 32
#define OFP_MAX_PORT_NAME_LEN 16
OFPC_SEND_FLOW_EXP = 1 << 0,
/* Handling of IP fragments. */
- OFPC_FRAG_NORMAL = 0 << 1, /* No special handling for fragments. */
- OFPC_FRAG_DROP = 1 << 1, /* Drop fragments. */
- OFPC_FRAG_REASM = 2 << 1, /* Reassemble (only if OFPC_IP_REASM set). */
- OFPC_FRAG_MASK = 3 << 1
+ OFPC_FRAG_NORMAL = 0 << 1, /* No special handling for fragments. */
+ OFPC_FRAG_DROP = 1 << 1, /* Drop fragments. */
+ OFPC_FRAG_REASM = 2 << 1, /* Reassemble (only if OFPC_IP_REASM set). */
+ OFPC_FRAG_MASK = 3 << 1
};
/* Switch configuration. */
/* Flags to indicate behavior of the physical port */
enum ofp_port_flags {
- OFPPFL_NO_FLOOD = 1 << 0, /* Do not include this port when flooding */
+ OFPPFL_NO_FLOOD = 1 << 0, /* Do not include this port when flooding. */
+ OFPPFL_PORT_DOWN = 1 << 1, /* Port is configured down. */
+ OFPPFL_LINK_DOWN = 1 << 2, /* No physical link on interface.
+ NOTE: Non-settable field */
};
/* Features of physical ports available in a datapath. */
uint8_t pad[4]; /* Align to 64-bits. */
/* Port info.*/
- struct ofp_phy_port ports[0]; /* Port definitions. The number of ports
+ struct ofp_phy_port ports[0]; /* Port definitions. The number of ports
is inferred from the length field in
the header. */
};
/* Modify behavior of the physical port */
struct ofp_port_mod {
struct ofp_header header;
+ uint32_t mask; /* Bitmap of "ofp_port_flags" that should be
+ changed. */
struct ofp_phy_port desc;
};
-OFP_ASSERT(sizeof(struct ofp_port_mod) == 44);
+OFP_ASSERT(sizeof(struct ofp_port_mod) == 48);
/* Why is this packet being sent to the controller? */
enum ofp_packet_in_reason {
OFPFW_DL_SRC = 1 << 2, /* Ethernet source address. */
OFPFW_DL_DST = 1 << 3, /* Ethernet destination address. */
OFPFW_DL_TYPE = 1 << 4, /* Ethernet frame type. */
- OFPFW_NW_SRC = 1 << 5, /* IP source address. */
- OFPFW_NW_DST = 1 << 6, /* IP destination address. */
- OFPFW_NW_PROTO = 1 << 7, /* IP protocol. */
- OFPFW_TP_SRC = 1 << 8, /* TCP/UDP source port. */
- OFPFW_TP_DST = 1 << 9, /* TCP/UDP destination port. */
- OFPFW_ALL = (1 << 10) - 1
+ OFPFW_NW_PROTO = 1 << 5, /* IP protocol. */
+ OFPFW_TP_SRC = 1 << 6, /* TCP/UDP source port. */
+ OFPFW_TP_DST = 1 << 7, /* TCP/UDP destination port. */
+
+ /* IP source address wildcard bit count. 0 is exact match, 1 ignores the
+ * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
+ * the entire field. This is the *opposite* of the usual convention where
+ * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded. */
+ OFPFW_NW_SRC_SHIFT = 8,
+ OFPFW_NW_SRC_BITS = 6,
+ OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT,
+ OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT,
+
+ /* IP destination address wildcard bit count. Same format as source. */
+ OFPFW_NW_DST_SHIFT = 14,
+ OFPFW_NW_DST_BITS = 6,
+ OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT,
+ OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT,
+
+ /* Wildcard all fields. */
+ OFPFW_ALL = ((1 << 20) - 1)
};
/* Values below this cutoff are 802.3 packets and the two bytes
/* Fields to match against flows */
struct ofp_match {
- uint16_t wildcards; /* Wildcard fields. */
+ uint32_t wildcards; /* Wildcard fields. */
uint16_t in_port; /* Input switch port. */
uint8_t dl_src[OFP_ETH_ALEN]; /* Ethernet source address. */
uint8_t dl_dst[OFP_ETH_ALEN]; /* Ethernet destination address. */
uint16_t dl_vlan; /* Input VLAN. */
uint16_t dl_type; /* Ethernet frame type. */
+ uint8_t nw_proto; /* IP protocol. */
+ uint8_t pad; /* Align to 32-bits. */
uint32_t nw_src; /* IP source address. */
uint32_t nw_dst; /* IP destination address. */
- uint8_t nw_proto; /* IP protocol. */
- uint8_t pad[3]; /* Align to 32-bits. */
uint16_t tp_src; /* TCP/UDP source port. */
uint16_t tp_dst; /* TCP/UDP destination port. */
};
enum ofp_stats_types {
/* Description of this OpenFlow switch.
* The request body is empty.
- * The reply body is struct ofp_version_stats. */
- OFPST_VERSION,
+ * The reply body is struct ofp_desc_stats. */
+ OFPST_DESC,
/* Individual flow statistics.
* The request body is struct ofp_flow_stats_request.
/* Physical port statistics.
* The request body is empty.
* The reply body is an array of struct ofp_port_stats. */
- OFPST_PORT
+ OFPST_PORT,
+
+ /* Switch status.
+ * The request body is an ASCII string that specifies a prefix of the key
+ * names to include in the output; if it is the null string, then all
+ * key-value pairs are included.
+ * The reply body is an ASCII string of key-value pairs in the form
+ * "key=value\n". */
+ OFPST_SWITCH
};
struct ofp_stats_request {
};
OFP_ASSERT(sizeof(struct ofp_stats_reply) == 12);
-#define VERSION_STR_LEN 256
-/* Body of reply to OFPST_VERSION request. Each entry is a NULL-terminated
+#define DESC_STR_LEN 256
+#define SERIAL_NUM_LEN 32
+/* Body of reply to OFPST_DESC request. Each entry is a NULL-terminated
* ASCII string. */
-struct ofp_version_stats {
- char mfr_desc[VERSION_STR_LEN]; /* Manufacturer description. */
- char hw_desc[VERSION_STR_LEN]; /* Hardware description. */
- char sw_desc[VERSION_STR_LEN]; /* Software description. */
+struct ofp_desc_stats {
+ char mfr_desc[DESC_STR_LEN]; /* Manufacturer description. */
+ char hw_desc[DESC_STR_LEN]; /* Hardware description. */
+ char sw_desc[DESC_STR_LEN]; /* Software description. */
+ char serial_num[SERIAL_NUM_LEN]; /* Serial number. */
};
-OFP_ASSERT(sizeof(struct ofp_version_stats) == 768);
+OFP_ASSERT(sizeof(struct ofp_desc_stats) == 800);
/* Body for ofp_stats_request of type OFPST_FLOW. */
struct ofp_flow_stats_request {