Merge branch 'mainstream'
[sliver-openvswitch.git] / lib / ofp-util.h
index 57d35c4..7e50db2 100644 (file)
@@ -81,6 +81,15 @@ enum ofputil_protocol {
 #define OFPUTIL_P_OF10_STD_ANY (OFPUTIL_P_OF10_STD | OFPUTIL_P_OF10_STD_TID)
 #define OFPUTIL_P_OF10_NXM_ANY (OFPUTIL_P_OF10_NXM | OFPUTIL_P_OF10_NXM_TID)
 
+    /* OpenFlow 1.1 protocol.
+     *
+     * We only support the standard OpenFlow 1.1 flow format.
+     *
+     * OpenFlow 1.1 always operates with an equivalent of the
+     * nx_flow_mod_table_id Nicira extension enabled, so there is no "TID"
+     * variant. */
+    OFPUTIL_P_OF11_STD     = 1 << 4,
+
     /* OpenFlow 1.2+ protocols (only one variant each).
      *
      * These use the standard OpenFlow Extensible Match (OXM) flow format.
@@ -88,16 +97,28 @@ enum ofputil_protocol {
      * OpenFlow 1.2+ always operates with an equivalent of the
      * nx_flow_mod_table_id Nicira extension enabled, so there is no "TID"
      * variant. */
-    OFPUTIL_P_OF12_OXM      = 1 << 4,
-    OFPUTIL_P_OF13_OXM      = 1 << 5,
+    OFPUTIL_P_OF12_OXM      = 1 << 5,
+    OFPUTIL_P_OF13_OXM      = 1 << 6,
 #define OFPUTIL_P_ANY_OXM (OFPUTIL_P_OF12_OXM | OFPUTIL_P_OF13_OXM)
 
+#define OFPUTIL_P_NXM_OF11_UP (OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_OF11_STD | \
+                               OFPUTIL_P_ANY_OXM)
+
+#define OFPUTIL_P_NXM_OXM_ANY (OFPUTIL_P_OF10_NXM_ANY | OFPUTIL_P_ANY_OXM)
+
+#define OFPUTIL_P_OF11_UP (OFPUTIL_P_OF11_STD | OFPUTIL_P_ANY_OXM)
+
+#define OFPUTIL_P_OF12_UP (OFPUTIL_P_ANY_OXM)
+
+#define OFPUTIL_P_OF13_UP (OFPUTIL_P_OF13_OXM)
+
     /* All protocols. */
-#define OFPUTIL_P_ANY ((1 << 6) - 1)
+#define OFPUTIL_P_ANY ((1 << 7) - 1)
 
     /* Protocols in which a specific table may be specified in flow_mods. */
 #define OFPUTIL_P_TID (OFPUTIL_P_OF10_STD_TID | \
                        OFPUTIL_P_OF10_NXM_TID | \
+                       OFPUTIL_P_OF11_STD |     \
                        OFPUTIL_P_ANY_OXM)
 };
 
@@ -119,7 +140,6 @@ enum ofputil_protocol ofputil_protocol_set_base(
 const char *ofputil_protocol_to_string(enum ofputil_protocol);
 char *ofputil_protocols_to_string(enum ofputil_protocol);
 enum ofputil_protocol ofputil_protocols_from_string(const char *);
-enum ofputil_protocol ofputil_usable_protocols(const struct match *);
 
 void ofputil_format_version(struct ds *, enum ofp_version);
 void ofputil_format_version_name(struct ds *, enum ofp_version);
@@ -178,7 +198,10 @@ enum ofperr ofputil_pull_ofp11_match(struct ofpbuf *, struct match *,
                                      uint16_t *padded_match_len);
 enum ofperr ofputil_match_from_ofp11_match(const struct ofp11_match *,
                                            struct match *);
+int ofputil_put_ofp11_match(struct ofpbuf *, const struct match *,
+                            enum ofputil_protocol);
 void ofputil_match_to_ofp11_match(const struct match *, struct ofp11_match *);
+int ofputil_match_typical_len(enum ofputil_protocol);
 
 /* dl_type translation between OpenFlow and 'struct flow' format. */
 ovs_be16 ofputil_dl_type_to_openflow(ovs_be16 flow_dl_type);
@@ -194,37 +217,58 @@ struct ofpbuf *ofputil_make_set_packet_in_format(enum ofp_version,
 /* NXT_FLOW_MOD_TABLE_ID extension. */
 struct ofpbuf *ofputil_make_flow_mod_table_id(bool flow_mod_table_id);
 
+/* Protocol-independent flow_mod flags. */
+enum ofputil_flow_mod_flags {
+    OFPUTIL_FF_SEND_FLOW_REM = 1 << 0, /* All versions. */
+    OFPUTIL_FF_CHECK_OVERLAP = 1 << 1, /* All versions. */
+    OFPUTIL_FF_EMERG         = 1 << 2, /* OpenFlow 1.0 only. */
+    OFPUTIL_FF_RESET_COUNTS  = 1 << 3, /* OpenFlow 1.2+. */
+    OFPUTIL_FF_NO_PKT_COUNTS = 1 << 4, /* OpenFlow 1.3+. */
+    OFPUTIL_FF_NO_BYT_COUNTS = 1 << 5  /* OpenFlow 1.3+. */
+};
+
 /* Protocol-independent flow_mod.
  *
  * The handling of cookies across multiple versions of OpenFlow is a bit
- * confusing.  A full description of Open vSwitch's cookie handling is
- * in the DESIGN file.  The following table shows the expected values of
- * the cookie-related fields for the different flow_mod commands in
- * OpenFlow 1.0 ("OF10") and NXM.  "<used>" and "-" indicate a value
- * that may be populated and an ignored field, respectively.
- *
- *               cookie  cookie_mask  new_cookie
- *               ======  ===========  ==========
- * OF10 Add        -          0         <used>
- * OF10 Modify     -          0         <used>
- * OF10 Delete     -          0           -
- * NXM Add         -          0         <used>
- * NXM Modify    <used>     <used>      <used>
- * NXM Delete    <used>     <used>        -
- */
+ * confusing.  See DESIGN for the details. */
 struct ofputil_flow_mod {
+    struct list list_node;    /* For queuing flow_mods. */
+
     struct match match;
     unsigned int priority;
+
+    /* Cookie matching.  The flow_mod affects only flows that have cookies that
+     * bitwise match 'cookie' bits in positions where 'cookie_mask has 1-bits.
+     *
+     * 'cookie_mask' should be zero for OFPFC_ADD flow_mods. */
     ovs_be64 cookie;         /* Cookie bits to match. */
     ovs_be64 cookie_mask;    /* 1-bit in each 'cookie' bit to match. */
-    ovs_be64 new_cookie;     /* New cookie to install or -1. */
+
+    /* Cookie changes.
+     *
+     * OFPFC_ADD uses 'new_cookie' as the new flow's cookie.  'new_cookie'
+     * should not be UINT64_MAX.
+     *
+     * OFPFC_MODIFY and OFPFC_MODIFY_STRICT have two cases:
+     *
+     *   - If one or more matching flows exist and 'modify_cookie' is true,
+     *     then the flow_mod changes the existing flows' cookies to
+     *     'new_cookie'.  'new_cookie' should not be UINT64_MAX.
+     *
+     *   - If no matching flow exists, 'new_cookie' is not UINT64_MAX, and
+     *     'cookie_mask' is 0, then the flow_mod adds a new flow with
+     *     'new_cookie' as its cookie.
+     */
+    ovs_be64 new_cookie;     /* New cookie to install or UINT64_MAX. */
+    bool modify_cookie;      /* Set cookie of existing flow to 'new_cookie'? */
+
     uint8_t table_id;
     uint16_t command;
     uint16_t idle_timeout;
     uint16_t hard_timeout;
     uint32_t buffer_id;
     ofp_port_t out_port;
-    uint16_t flags;
+    enum ofputil_flow_mod_flags flags;
     struct ofpact *ofpacts;     /* Series of "struct ofpact"s. */
     size_t ofpacts_len;         /* Length of ofpacts, in bytes. */
 };
@@ -236,9 +280,6 @@ enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *,
 struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *,
                                        enum ofputil_protocol);
 
-enum ofputil_protocol ofputil_flow_mod_usable_protocols(
-    const struct ofputil_flow_mod *fms, size_t n_fms);
-
 /* Flow stats or aggregate stats request, independent of protocol. */
 struct ofputil_flow_stats_request {
     bool aggregate;             /* Aggregate results? */
@@ -253,8 +294,6 @@ enum ofperr ofputil_decode_flow_stats_request(
     struct ofputil_flow_stats_request *, const struct ofp_header *);
 struct ofpbuf *ofputil_encode_flow_stats_request(
     const struct ofputil_flow_stats_request *, enum ofputil_protocol);
-enum ofputil_protocol ofputil_flow_stats_request_usable_protocols(
-    const struct ofputil_flow_stats_request *);
 
 /* Flow stats reply, independent of protocol. */
 struct ofputil_flow_stats {
@@ -272,7 +311,7 @@ struct ofputil_flow_stats {
     uint64_t byte_count;        /* Byte count, UINT64_MAX if unknown. */
     struct ofpact *ofpacts;
     size_t ofpacts_len;
-    uint16_t flags;             /* Added for OF 1.3 */
+    enum ofputil_flow_mod_flags flags;
 };
 
 int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *,
@@ -318,6 +357,8 @@ struct ofpbuf *ofputil_encode_flow_removed(const struct ofputil_flow_removed *,
 
 /* Abstract packet-in message. */
 struct ofputil_packet_in {
+    struct list list_node; /* For queueing packet_ins. */
+
     const void *packet;
     size_t packet_len;
 
@@ -514,10 +555,10 @@ enum ofperr ofputil_decode_port_mod(const struct ofp_header *,
 struct ofpbuf *ofputil_encode_port_mod(const struct ofputil_port_mod *,
                                        enum ofputil_protocol);
 
+/* Meter band configuration for all supported band types. */
 struct ofputil_meter_band {
     uint16_t type;
-    uint8_t pad;
-    uint8_t prec_level;   /* Non-zero if type == OFPMBT_DSCP_REMARK */
+    uint8_t prec_level;         /* Non-zero if type == OFPMBT_DSCP_REMARK. */
     uint32_t rate;
     uint32_t burst_size;
 };
@@ -548,21 +589,21 @@ struct ofputil_meter_stats {
     uint32_t duration_sec;
     uint32_t duration_nsec;
     uint16_t n_bands;
-    struct ofputil_meter_band_stats *bands; /* band stats */
+    struct ofputil_meter_band_stats *bands;
 };
 
 struct ofputil_meter_features {
-    uint32_t max_meters; /* Maximum number of meters */
-    uint32_t band_types; /* Can support max 32 band types */
-    uint32_t capabilities; /* Supported flags */
+    uint32_t max_meters;        /* Maximum number of meters. */
+    uint32_t band_types;        /* Can support max 32 band types. */
+    uint32_t capabilities;      /* Supported flags. */
     uint8_t  max_bands;
     uint8_t  max_color;
 };
 
 enum ofperr ofputil_decode_meter_mod(const struct ofp_header *,
                                      struct ofputil_meter_mod *,
-                                    struct ofpbuf *bands);
-struct ofpbuf *ofputil_encode_meter_mod(enum ofp_version ofp_version,
+                                     struct ofpbuf *bands);
+struct ofpbuf *ofputil_encode_meter_mod(enum ofp_version,
                                         const struct ofputil_meter_mod *);
 
 void ofputil_decode_meter_features(const struct ofp_header *,
@@ -575,10 +616,10 @@ void ofputil_decode_meter_request(const struct ofp_header *,
                                   uint32_t *meter_id);
 
 void ofputil_append_meter_config(struct list *replies,
-                                 const struct ofputil_meter_config *omc);
+                                 const struct ofputil_meter_config *);
 
 void ofputil_append_meter_stats(struct list *replies,
-                                const struct ofputil_meter_stats *oms);
+                                const struct ofputil_meter_stats *);
 
 enum ofputil_meter_request_type {
     OFPUTIL_METER_FEATURES,
@@ -590,15 +631,15 @@ struct ofpbuf *ofputil_encode_meter_request(enum ofp_version,
                                             enum ofputil_meter_request_type,
                                             uint32_t meter_id);
 
-int ofputil_decode_meter_stats(struct ofpbuf *msg,
-                               struct ofputil_meter_stats *ms,
+int ofputil_decode_meter_stats(struct ofpbuf *,
+                               struct ofputil_meter_stats *,
                                struct ofpbuf *bands);
 
-int ofputil_decode_meter_config(struct ofpbuf *msg,
-                                struct ofputil_meter_config *mc,
+int ofputil_decode_meter_config(struct ofpbuf *,
+                                struct ofputil_meter_config *,
                                 struct ofpbuf *bands);
 
-/* Type for meter_id in ofproto provider interface, UINT32_MAX if none */
+/* Type for meter_id in ofproto provider interface, UINT32_MAX if invalid. */
 typedef struct { uint32_t uint32; } ofproto_meter_id;
 
 /* Abstract ofp_role_request and reply. */
@@ -810,7 +851,15 @@ ofputil_encode_queue_stats_request(enum ofp_version ofp_version,
 struct ofputil_queue_stats {
     ofp_port_t port_no;
     uint32_t queue_id;
-    struct netdev_queue_stats stats;
+
+    /* Values of unsupported statistics are set to all-1-bits (UINT64_MAX). */
+    uint64_t tx_bytes;
+    uint64_t tx_packets;
+    uint64_t tx_errors;
+
+    /* UINT32_MAX if unknown. */
+    uint32_t duration_sec;
+    uint32_t duration_nsec;
 };
 
 size_t ofputil_count_queue_stats(const struct ofp_header *);