+ uint16_t hard_timeout;
+ uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
+ uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
+};
+
+enum ofperr ofputil_decode_flow_removed(struct ofputil_flow_removed *,
+ const struct ofp_header *);
+struct ofpbuf *ofputil_encode_flow_removed(const struct ofputil_flow_removed *,
+ enum ofputil_protocol);
+
+/* Abstract packet-in message. */
+struct ofputil_packet_in {
+ /* Packet data and metadata.
+ *
+ * To save bandwidth, in some cases a switch may send only the first
+ * several bytes of a packet, indicated by 'packet_len < total_len'. When
+ * the full packet is included, 'packet_len == total_len'. */
+ const void *packet;
+ size_t packet_len; /* Number of bytes in 'packet'. */
+ size_t total_len; /* Size of packet, pre-truncation. */
+ struct flow_metadata fmd;
+
+ /* Identifies a buffer in the switch that contains the full packet, to
+ * allow the controller to reference it later without having to send the
+ * entire packet back to the switch.
+ *
+ * UINT32_MAX indicates that the packet is not buffered in the switch. A
+ * switch should only use UINT32_MAX when it sends the entire packet. */
+ uint32_t buffer_id;
+
+ /* Reason that the packet-in is being sent. */
+ enum ofp_packet_in_reason reason; /* One of OFPR_*. */
+
+ /* Information about the OpenFlow flow that triggered the packet-in.
+ *
+ * A packet-in triggered by a flow table miss has no associated flow. In
+ * that case, 'cookie' is UINT64_MAX. */
+ uint8_t table_id; /* OpenFlow table ID. */
+ ovs_be64 cookie; /* Flow's cookie. */
+};
+
+enum ofperr ofputil_decode_packet_in(struct ofputil_packet_in *,
+ const struct ofp_header *);
+struct ofpbuf *ofputil_encode_packet_in(const struct ofputil_packet_in *,
+ enum ofputil_protocol protocol,
+ enum nx_packet_in_format);
+
+enum { OFPUTIL_PACKET_IN_REASON_BUFSIZE = INT_STRLEN(int) + 1 };
+const char *ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason,
+ char *reasonbuf,
+ size_t bufsize);
+bool ofputil_packet_in_reason_from_string(const char *,
+ enum ofp_packet_in_reason *);
+
+/* Abstract packet-out message.
+ *
+ * ofputil_decode_packet_out() will ensure that 'in_port' is a physical port
+ * (OFPP_MAX or less) or one of OFPP_LOCAL, OFPP_NONE, or OFPP_CONTROLLER. */
+struct ofputil_packet_out {
+ const void *packet; /* Packet data, if buffer_id == UINT32_MAX. */
+ size_t packet_len; /* Length of packet data in bytes. */
+ uint32_t buffer_id; /* Buffer id or UINT32_MAX if no buffer. */
+ ofp_port_t in_port; /* Packet's input port. */
+ struct ofpact *ofpacts; /* Actions. */
+ size_t ofpacts_len; /* Size of ofpacts in bytes. */
+};
+
+enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
+ const struct ofp_header *,
+ struct ofpbuf *ofpacts);
+struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *,
+ enum ofputil_protocol protocol);
+
+enum ofputil_port_config {
+ /* OpenFlow 1.0 and 1.1 share these values for these port config bits. */
+ OFPUTIL_PC_PORT_DOWN = 1 << 0, /* Port is administratively down. */
+ OFPUTIL_PC_NO_RECV = 1 << 2, /* Drop all packets received by port. */
+ OFPUTIL_PC_NO_FWD = 1 << 5, /* Drop packets forwarded to port. */
+ OFPUTIL_PC_NO_PACKET_IN = 1 << 6, /* No send packet-in msgs for port. */
+ /* OpenFlow 1.0 only. */
+ OFPUTIL_PC_NO_STP = 1 << 1, /* No 802.1D spanning tree for port. */
+ OFPUTIL_PC_NO_RECV_STP = 1 << 3, /* Drop received 802.1D STP packets. */
+ OFPUTIL_PC_NO_FLOOD = 1 << 4, /* Do not include port when flooding. */
+ /* There are no OpenFlow 1.1-only bits. */
+};
+
+enum ofputil_port_state {
+ /* OpenFlow 1.0 and 1.1 share this values for these port state bits. */
+ OFPUTIL_PS_LINK_DOWN = 1 << 0, /* No physical link present. */
+ /* OpenFlow 1.1 only. */
+ OFPUTIL_PS_BLOCKED = 1 << 1, /* Port is blocked */
+ OFPUTIL_PS_LIVE = 1 << 2, /* Live for Fast Failover Group. */
+ /* OpenFlow 1.0 only. */
+ OFPUTIL_PS_STP_LISTEN = 0 << 8, /* Not learning or relaying frames. */
+ OFPUTIL_PS_STP_LEARN = 1 << 8, /* Learning but not relaying frames. */
+ OFPUTIL_PS_STP_FORWARD = 2 << 8, /* Learning and relaying frames. */
+ OFPUTIL_PS_STP_BLOCK = 3 << 8, /* Not part of spanning tree. */
+ OFPUTIL_PS_STP_MASK = 3 << 8 /* Bit mask for OFPPS10_STP_* values. */
+};
+
+/* Abstract ofp10_phy_port or ofp11_port. */
+struct ofputil_phy_port {
+ ofp_port_t port_no;
+ uint8_t hw_addr[OFP_ETH_ALEN];
+ char name[OFP_MAX_PORT_NAME_LEN];
+ enum ofputil_port_config config;
+ enum ofputil_port_state state;
+
+ /* NETDEV_F_* feature bitmasks. */
+ enum netdev_features curr; /* Current features. */
+ enum netdev_features advertised; /* Features advertised by the port. */
+ enum netdev_features supported; /* Features supported by the port. */
+ enum netdev_features peer; /* Features advertised by peer. */
+
+ /* Speed. */
+ uint32_t curr_speed; /* Current speed, in kbps. */
+ uint32_t max_speed; /* Maximum supported speed, in kbps. */
+};
+
+enum ofputil_capabilities {
+ /* OpenFlow 1.0, 1.1, 1.2, and 1.3 share these capability values. */
+ OFPUTIL_C_FLOW_STATS = 1 << 0, /* Flow statistics. */
+ OFPUTIL_C_TABLE_STATS = 1 << 1, /* Table statistics. */
+ OFPUTIL_C_PORT_STATS = 1 << 2, /* Port statistics. */
+ OFPUTIL_C_IP_REASM = 1 << 5, /* Can reassemble IP fragments. */
+ OFPUTIL_C_QUEUE_STATS = 1 << 6, /* Queue statistics. */
+
+ /* OpenFlow 1.0 and 1.1 share this capability. */
+ OFPUTIL_C_ARP_MATCH_IP = 1 << 7, /* Match IP addresses in ARP pkts. */
+
+ /* OpenFlow 1.0 only. */
+ OFPUTIL_C_STP = 1 << 3, /* 802.1d spanning tree. */
+
+ /* OpenFlow 1.1, 1.2, and 1.3 share this capability. */
+ OFPUTIL_C_GROUP_STATS = 1 << 4, /* Group statistics. */
+
+ /* OpenFlow 1.2 and 1.3 share this capability */
+ OFPUTIL_C_PORT_BLOCKED = 1 << 8, /* Switch will block looping ports */
+};
+
+enum ofputil_action_bitmap {
+ OFPUTIL_A_OUTPUT = 1 << 0,
+ OFPUTIL_A_SET_VLAN_VID = 1 << 1,
+ OFPUTIL_A_SET_VLAN_PCP = 1 << 2,
+ OFPUTIL_A_STRIP_VLAN = 1 << 3,
+ OFPUTIL_A_SET_DL_SRC = 1 << 4,
+ OFPUTIL_A_SET_DL_DST = 1 << 5,
+ OFPUTIL_A_SET_NW_SRC = 1 << 6,
+ OFPUTIL_A_SET_NW_DST = 1 << 7,
+ OFPUTIL_A_SET_NW_ECN = 1 << 8,
+ OFPUTIL_A_SET_NW_TOS = 1 << 9,
+ OFPUTIL_A_SET_TP_SRC = 1 << 10,
+ OFPUTIL_A_SET_TP_DST = 1 << 11,
+ OFPUTIL_A_ENQUEUE = 1 << 12,
+ OFPUTIL_A_COPY_TTL_OUT = 1 << 13,
+ OFPUTIL_A_COPY_TTL_IN = 1 << 14,
+ OFPUTIL_A_SET_MPLS_LABEL = 1 << 15,
+ OFPUTIL_A_SET_MPLS_TC = 1 << 16,
+ OFPUTIL_A_SET_MPLS_TTL = 1 << 17,
+ OFPUTIL_A_DEC_MPLS_TTL = 1 << 18,
+ OFPUTIL_A_PUSH_VLAN = 1 << 19,
+ OFPUTIL_A_POP_VLAN = 1 << 20,
+ OFPUTIL_A_PUSH_MPLS = 1 << 21,
+ OFPUTIL_A_POP_MPLS = 1 << 22,
+ OFPUTIL_A_SET_QUEUE = 1 << 23,
+ OFPUTIL_A_GROUP = 1 << 24,
+ OFPUTIL_A_SET_NW_TTL = 1 << 25,
+ OFPUTIL_A_DEC_NW_TTL = 1 << 26,
+ OFPUTIL_A_SET_FIELD = 1 << 27,
+};
+
+/* Abstract ofp_switch_features. */
+struct ofputil_switch_features {
+ uint64_t datapath_id; /* Datapath unique ID. */
+ uint32_t n_buffers; /* Max packets buffered at once. */
+ uint8_t n_tables; /* Number of tables supported by datapath. */
+ uint8_t auxiliary_id; /* Identify auxiliary connections */
+ enum ofputil_capabilities capabilities;
+ enum ofputil_action_bitmap actions;
+};
+
+enum ofperr ofputil_decode_switch_features(const struct ofp_header *,
+ struct ofputil_switch_features *,
+ struct ofpbuf *);
+
+struct ofpbuf *ofputil_encode_switch_features(
+ const struct ofputil_switch_features *, enum ofputil_protocol,
+ ovs_be32 xid);
+void ofputil_put_switch_features_port(const struct ofputil_phy_port *,
+ struct ofpbuf *);
+bool ofputil_switch_features_ports_trunc(struct ofpbuf *b);
+
+/* phy_port helper functions. */
+int ofputil_pull_phy_port(enum ofp_version ofp_version, struct ofpbuf *,
+ struct ofputil_phy_port *);
+size_t ofputil_count_phy_ports(uint8_t ofp_version, struct ofpbuf *);
+
+/* Abstract ofp_port_status. */
+struct ofputil_port_status {
+ enum ofp_port_reason reason;
+ struct ofputil_phy_port desc;
+};
+
+enum ofperr ofputil_decode_port_status(const struct ofp_header *,
+ struct ofputil_port_status *);
+struct ofpbuf *ofputil_encode_port_status(const struct ofputil_port_status *,
+ enum ofputil_protocol);
+
+/* Abstract ofp_port_mod. */
+struct ofputil_port_mod {
+ ofp_port_t port_no;
+ uint8_t hw_addr[OFP_ETH_ALEN];
+ enum ofputil_port_config config;
+ enum ofputil_port_config mask;
+ enum netdev_features advertise;
+};
+
+enum ofperr ofputil_decode_port_mod(const struct ofp_header *,
+ struct ofputil_port_mod *);
+struct ofpbuf *ofputil_encode_port_mod(const struct ofputil_port_mod *,
+ enum ofputil_protocol);
+
+/* Abstract ofp_table_mod. */
+struct ofputil_table_mod {
+ uint8_t table_id; /* ID of the table, 0xff indicates all tables. */
+ enum ofp_table_config config;
+};
+
+enum ofperr ofputil_decode_table_mod(const struct ofp_header *,
+ struct ofputil_table_mod *);
+struct ofpbuf *ofputil_encode_table_mod(const struct ofputil_table_mod *,
+ enum ofputil_protocol);
+
+/* Abstract ofp_table_features. */
+struct ofputil_table_features {
+ uint8_t table_id; /* Identifier of table. Lower numbered tables
+ are consulted first. */
+ char name[OFP_MAX_TABLE_NAME_LEN];
+ ovs_be64 metadata_match; /* Bits of metadata table can match. */
+ ovs_be64 metadata_write; /* Bits of metadata table can write. */
+ uint32_t config; /* Bitmap of OFPTC_* values */
+ uint32_t max_entries; /* Max number of entries supported. */
+
+ /* Table features related to instructions. There are two instances:
+ *
+ * - 'miss' reports features available in the table miss flow.
+ *
+ * - 'nonmiss' reports features available in other flows. */
+ struct ofputil_table_instruction_features {
+ /* Tables that "goto-table" may jump to. */
+ unsigned long int next[BITMAP_N_LONGS(255)];
+
+ /* Bitmap of OVSINST_* for supported instructions. */
+ uint32_t instructions;
+
+ /* Table features related to actions. There are two instances:
+ *
+ * - 'write' reports features available in a "write_actions"
+ * instruction.
+ *
+ * - 'apply' reports features available in an "apply_actions"
+ * instruction. */
+ struct ofputil_table_action_features {
+ uint32_t actions; /* Bitmap of supported OFPAT*. */
+ uint64_t set_fields; /* Bitmap of MFF_* "set-field" supports. */
+ } write, apply;
+ } nonmiss, miss;
+
+ /* MFF_* bitmaps.
+ *
+ * For any given field the following combinations are valid:
+ *
+ * - match=0, wildcard=0, mask=0: Flows in this table cannot match on
+ * this field.
+ *
+ * - match=1, wildcard=0, mask=0: Flows in this table must match on all
+ * the bits in this field.
+ *
+ * - match=1, wildcard=1, mask=0: Flows in this table must either match
+ * on all the bits in the field or wildcard the field entirely.
+ *
+ * - match=1, wildcard=1, mask=1: Flows in this table may arbitrarily
+ * mask this field (as special cases, they may match on all the bits
+ * or wildcard it entirely).
+ *
+ * Other combinations do not make sense.
+ */
+ uint64_t match; /* Fields that may be matched. */
+ uint64_t mask; /* Subset of 'match' that may have masks. */
+ uint64_t wildcard; /* Subset of 'match' that may be wildcarded. */
+};
+
+int ofputil_decode_table_features(struct ofpbuf *,
+ struct ofputil_table_features *, bool loose);
+struct ofpbuf *ofputil_encode_table_features_request(
+ enum ofp_version ofp_version);
+void ofputil_append_table_features_reply(
+ const struct ofputil_table_features *tf,
+ struct list *replies);
+
+uint16_t table_feature_prop_get_size(enum ofp13_table_feature_prop_type type);
+char *table_feature_prop_get_name(enum ofp13_table_feature_prop_type type);
+
+/* Meter band configuration for all supported band types. */
+struct ofputil_meter_band {
+ uint16_t type;
+ uint8_t prec_level; /* Non-zero if type == OFPMBT_DSCP_REMARK. */
+ uint32_t rate;
+ uint32_t burst_size;
+};
+
+struct ofputil_meter_band_stats {