/*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* experimental OpenFlow version.
*/
#define OFP_VERSION 0x01
+#define OFP10_VERSION 0x01
#define OFP_MAX_TABLE_NAME_LEN 32
#define OFP_MAX_PORT_NAME_LEN 16
OFPC_FRAG_NORMAL = 0, /* No special handling for fragments. */
OFPC_FRAG_DROP = 1, /* Drop fragments. */
OFPC_FRAG_REASM = 2, /* Reassemble (only if OFPC_IP_REASM set). */
- OFPC_FRAG_MASK = 3
+ OFPC_FRAG_NX_MATCH = 3, /* Make first fragments available for matching. */
+ OFPC_FRAG_MASK = 3,
+
+ /* TTL processing - applicable for IP and MPLS packets. */
+ OFPC_INVALID_TTL_TO_CONTROLLER = 1 << 2, /* Send packets with invalid TTL
+ to the controller. */
};
/* Switch configuration. */
/* Why is this packet being sent to the controller? */
enum ofp_packet_in_reason {
OFPR_NO_MATCH, /* No matching flow. */
- OFPR_ACTION /* Action explicitly output to controller. */
+ OFPR_ACTION, /* Action explicitly output to controller. */
+ OFPR_INVALID_TTL /* Packet has invalid TTL. */
};
/* Packet received on port (datapath -> controller). */
/* Send packet (controller -> datapath). */
struct ofp_packet_out {
struct ofp_header header;
- ovs_be32 buffer_id; /* ID assigned by datapath (-1 if none). */
+ ovs_be32 buffer_id; /* ID assigned by datapath or UINT32_MAX. */
ovs_be16 in_port; /* Packet's input port (OFPP_NONE if none). */
ovs_be16 actions_len; /* Size of action array in bytes. */
- struct ofp_action_header actions[0]; /* Actions. */
- /* uint8_t data[0]; */ /* Packet data. The length is inferred
- from the length field in the header.
- (Only meaningful if buffer_id == -1.) */
+ /* Followed by:
+ * - Exactly 'actions_len' bytes (possibly 0 bytes, and always a multiple
+ * of 8) containing actions.
+ * - If 'buffer_id' == UINT32_MAX, packet data to fill out the remainder
+ * of the message length.
+ */
};
OFP_ASSERT(sizeof(struct ofp_packet_out) == 16);
};
OFP_ASSERT(sizeof(struct ofp_match) == 40);
-/* The match fields for ICMP type and code use the transport source and
- * destination port fields, respectively. */
-#define icmp_type tp_src
-#define icmp_code tp_dst
-
/* Value used in "idle_timeout" and "hard_timeout" to indicate that the entry
* is permanent. */
#define OFP_FLOW_PERMANENT 0
};
OFP_ASSERT(sizeof(struct ofp_flow_removed) == 88);
-/* Values for 'type' in ofp_error_message. These values are immutable: they
- * will not change in future versions of the protocol (although new values may
- * be added). */
-enum ofp_error_type {
- OFPET_HELLO_FAILED, /* Hello protocol failed. */
- OFPET_BAD_REQUEST, /* Request was not understood. */
- OFPET_BAD_ACTION, /* Error in action description. */
- OFPET_FLOW_MOD_FAILED, /* Problem modifying flow entry. */
- OFPET_PORT_MOD_FAILED, /* OFPT_PORT_MOD failed. */
- OFPET_QUEUE_OP_FAILED /* Queue operation failed. */
-};
-
-/* ofp_error_msg 'code' values for OFPET_HELLO_FAILED. 'data' contains an
- * ASCII text string that may give failure details. */
-enum ofp_hello_failed_code {
- OFPHFC_INCOMPATIBLE, /* No compatible version. */
- OFPHFC_EPERM /* Permissions error. */
-};
-
-/* ofp_error_msg 'code' values for OFPET_BAD_REQUEST. 'data' contains at least
- * the first 64 bytes of the failed request. */
-enum ofp_bad_request_code {
- OFPBRC_BAD_VERSION, /* ofp_header.version not supported. */
- OFPBRC_BAD_TYPE, /* ofp_header.type not supported. */
- OFPBRC_BAD_STAT, /* ofp_stats_request.type not supported. */
- OFPBRC_BAD_VENDOR, /* Vendor not supported (in ofp_vendor_header
- * or ofp_stats_request or ofp_stats_reply). */
- OFPBRC_BAD_SUBTYPE, /* Vendor subtype not supported. */
- OFPBRC_EPERM, /* Permissions error. */
- OFPBRC_BAD_LEN, /* Wrong request length for type. */
- OFPBRC_BUFFER_EMPTY, /* Specified buffer has already been used. */
- OFPBRC_BUFFER_UNKNOWN /* Specified buffer does not exist. */
-};
-
-/* ofp_error_msg 'code' values for OFPET_BAD_ACTION. 'data' contains at least
- * the first 64 bytes of the failed request. */
-enum ofp_bad_action_code {
- OFPBAC_BAD_TYPE, /* Unknown action type. */
- OFPBAC_BAD_LEN, /* Length problem in actions. */
- OFPBAC_BAD_VENDOR, /* Unknown vendor id specified. */
- OFPBAC_BAD_VENDOR_TYPE, /* Unknown action type for vendor id. */
- OFPBAC_BAD_OUT_PORT, /* Problem validating output action. */
- OFPBAC_BAD_ARGUMENT, /* Bad action argument. */
- OFPBAC_EPERM, /* Permissions error. */
- OFPBAC_TOO_MANY, /* Can't handle this many actions. */
- OFPBAC_BAD_QUEUE /* Problem validating output queue. */
-};
-
-/* ofp_error_msg 'code' values for OFPET_FLOW_MOD_FAILED. 'data' contains
- * at least the first 64 bytes of the failed request. */
-enum ofp_flow_mod_failed_code {
- OFPFMFC_ALL_TABLES_FULL, /* Flow not added because of full tables. */
- OFPFMFC_OVERLAP, /* Attempted to add overlapping flow with
- * CHECK_OVERLAP flag set. */
- OFPFMFC_EPERM, /* Permissions error. */
- OFPFMFC_BAD_EMERG_TIMEOUT, /* Flow not added because of non-zero idle/hard
- * timeout. */
- OFPFMFC_BAD_COMMAND, /* Unknown command. */
- OFPFMFC_UNSUPPORTED /* Unsupported action list - cannot process in
- the order specified. */
-};
-
-/* ofp_error_msg 'code' values for OFPET_PORT_MOD_FAILED. 'data' contains
- * at least the first 64 bytes of the failed request. */
-enum ofp_port_mod_failed_code {
- OFPPMFC_BAD_PORT, /* Specified port does not exist. */
- OFPPMFC_BAD_HW_ADDR, /* Specified hardware address is wrong. */
-};
-
-/* ofp_error msg 'code' values for OFPET_QUEUE_OP_FAILED. 'data' contains
- * at least the first 64 bytes of the failed request */
-enum ofp_queue_op_failed_code {
- OFPQOFC_BAD_PORT, /* Invalid port (or port does not exist). */
- OFPQOFC_BAD_QUEUE, /* Queue does not exist. */
- OFPQOFC_EPERM /* Permissions error. */
-};
-
/* OFPT_ERROR: Error message (datapath -> controller). */
struct ofp_error_msg {
struct ofp_header header;
enum ofp_stats_types {
/* Description of this OpenFlow switch.
- * The request body is empty.
- * The reply body is struct ofp_desc_stats. */
+ * The request is struct ofp_stats_msg.
+ * The reply is struct ofp_desc_stats. */
OFPST_DESC,
/* Individual flow statistics.
- * The request body is struct ofp_flow_stats_request.
+ * The request is struct ofp_flow_stats_request.
* The reply body is an array of struct ofp_flow_stats. */
OFPST_FLOW,
/* Aggregate flow statistics.
- * The request body is struct ofp_aggregate_stats_request.
- * The reply body is struct ofp_aggregate_stats_reply. */
+ * The request is struct ofp_flow_stats_request.
+ * The reply is struct ofp_aggregate_stats_reply. */
OFPST_AGGREGATE,
/* Flow table statistics.
- * The request body is empty.
+ * The request is struct ofp_stats_msg.
* The reply body is an array of struct ofp_table_stats. */
OFPST_TABLE,
/* Physical port statistics.
- * The request body is struct ofp_port_stats_request.
+ * The request is struct ofp_port_stats_request.
* The reply body is an array of struct ofp_port_stats. */
OFPST_PORT,
- /* Queue statistics for a port
+ /* Queue statistics for a port.
* The request body is struct ofp_queue_stats_request.
* The reply body is an array of struct ofp_queue_stats. */
OFPST_QUEUE,
/* Vendor extension.
- * The request and reply bodies begin with a 32-bit vendor ID, which takes
- * the same form as in "struct ofp_vendor_header". The request and reply
- * bodies are otherwise vendor-defined. */
+ * The request and reply begin with "struct ofp_vendor_stats". */
OFPST_VENDOR = 0xffff
};
-struct ofp_stats_request {
+/* Statistics request or reply message. */
+struct ofp_stats_msg {
struct ofp_header header;
ovs_be16 type; /* One of the OFPST_* constants. */
- ovs_be16 flags; /* OFPSF_REQ_* flags (none yet defined). */
- uint8_t body[0]; /* Body of the request. */
+ ovs_be16 flags; /* Requests: always 0.
+ * Replies: 0 or OFPSF_REPLY_MORE. */
};
-OFP_ASSERT(sizeof(struct ofp_stats_request) == 12);
+OFP_ASSERT(sizeof(struct ofp_stats_msg) == 12);
enum ofp_stats_reply_flags {
OFPSF_REPLY_MORE = 1 << 0 /* More replies to follow. */
};
-struct ofp_stats_reply {
- struct ofp_header header;
- ovs_be16 type; /* One of the OFPST_* constants. */
- ovs_be16 flags; /* OFPSF_REPLY_* flags. */
- uint8_t body[0]; /* Body of the reply. */
-};
-OFP_ASSERT(sizeof(struct ofp_stats_reply) == 12);
-
#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. */
+/* Reply to OFPST_DESC request. Each entry is a NULL-terminated ASCII
+ * string. */
struct ofp_desc_stats {
+ struct ofp_stats_msg osm;
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 dp_desc[DESC_STR_LEN]; /* Human readable description of
the datapath. */
};
-OFP_ASSERT(sizeof(struct ofp_desc_stats) == 1056);
+OFP_ASSERT(sizeof(struct ofp_desc_stats) == 1068);
-/* Body for ofp_stats_request of type OFPST_FLOW. */
+/* Stats request of type OFPST_AGGREGATE or OFPST_FLOW. */
struct ofp_flow_stats_request {
+ struct ofp_stats_msg osm;
struct ofp_match match; /* Fields to match. */
uint8_t table_id; /* ID of table to read (from ofp_table_stats)
or 0xff for all tables. */
as an output port. A value of OFPP_NONE
indicates no restriction. */
};
-OFP_ASSERT(sizeof(struct ofp_flow_stats_request) == 44);
+OFP_ASSERT(sizeof(struct ofp_flow_stats_request) == 56);
/* Body of reply to OFPST_FLOW request. */
struct ofp_flow_stats {
};
OFP_ASSERT(sizeof(struct ofp_flow_stats) == 88);
-/* Body for ofp_stats_request of type OFPST_AGGREGATE. */
-struct ofp_aggregate_stats_request {
- struct ofp_match match; /* Fields to match. */
- uint8_t table_id; /* ID of table to read (from ofp_table_stats)
- or 0xff for all tables. */
- uint8_t pad; /* Align to 32 bits. */
- ovs_be16 out_port; /* Require matching entries to include this
- as an output port. A value of OFPP_NONE
- indicates no restriction. */
-};
-OFP_ASSERT(sizeof(struct ofp_aggregate_stats_request) == 44);
-
-/* Body of reply to OFPST_AGGREGATE request. */
+/* Reply to OFPST_AGGREGATE request. */
struct ofp_aggregate_stats_reply {
+ struct ofp_stats_msg osm;
ovs_32aligned_be64 packet_count; /* Number of packets in flows. */
ovs_32aligned_be64 byte_count; /* Number of bytes in flows. */
ovs_be32 flow_count; /* Number of flows. */
uint8_t pad[4]; /* Align to 64 bits. */
};
-OFP_ASSERT(sizeof(struct ofp_aggregate_stats_reply) == 24);
+OFP_ASSERT(sizeof(struct ofp_aggregate_stats_reply) == 36);
/* Body of reply to OFPST_TABLE request. */
struct ofp_table_stats {
};
OFP_ASSERT(sizeof(struct ofp_table_stats) == 64);
-/* Body for ofp_stats_request of type OFPST_PORT. */
+/* Stats request of type OFPST_PORT. */
struct ofp_port_stats_request {
+ struct ofp_stats_msg osm;
ovs_be16 port_no; /* OFPST_PORT message may request statistics
for a single port (specified with port_no)
or for all ports (port_no == OFPP_NONE). */
uint8_t pad[6];
};
-OFP_ASSERT(sizeof(struct ofp_port_stats_request) == 8);
+OFP_ASSERT(sizeof(struct ofp_port_stats_request) == 20);
/* Body of reply to OFPST_PORT request. If a counter is unsupported, set
* the field to all ones. */
/* All ones is used to indicate all queues in a port (for stats retrieval). */
#define OFPQ_ALL 0xffffffff
-/* Body for ofp_stats_request of type OFPST_QUEUE. */
+/* Body for stats request of type OFPST_QUEUE. */
struct ofp_queue_stats_request {
+ struct ofp_stats_msg osm;
ovs_be16 port_no; /* All ports if OFPP_ALL. */
uint8_t pad[2]; /* Align to 32-bits. */
ovs_be32 queue_id; /* All queues if OFPQ_ALL. */
};
-OFP_ASSERT(sizeof(struct ofp_queue_stats_request) == 8);
+OFP_ASSERT(sizeof(struct ofp_queue_stats_request) == 20);
-/* Body for ofp_stats_reply of type OFPST_QUEUE consists of an array of this
+/* Body for stats reply of type OFPST_QUEUE consists of an array of this
* structure type. */
struct ofp_queue_stats {
ovs_be16 port_no;
};
OFP_ASSERT(sizeof(struct ofp_queue_stats) == 32);
+/* Vendor extension stats message. */
+struct ofp_vendor_stats_msg {
+ struct ofp_stats_msg osm; /* Type OFPST_VENDOR. */
+ ovs_be32 vendor; /* Vendor ID:
+ * - MSB 0: low-order bytes are IEEE OUI.
+ * - MSB != 0: defined by OpenFlow
+ * consortium. */
+ /* Followed by vendor-defined arbitrary additional data. */
+};
+OFP_ASSERT(sizeof(struct ofp_vendor_stats_msg) == 16);
+
/* Vendor extension. */
struct ofp_vendor_header {
struct ofp_header header; /* Type OFPT_VENDOR. */