ofp-util: Add OFPUTIL_P_OF12 and NXFF_OPENFLOW12
[openvswitch] / lib / ofp-util.h
index 3f9e440b380eb50e8662134c8a2eb1ce8f952c29..36ae5815242f0c51b68248f6315dd594c97de99f 100644 (file)
@@ -22,6 +22,7 @@
 #include <stddef.h>
 #include <stdint.h>
 #include "classifier.h"
+#include "compiler.h"
 #include "flow.h"
 #include "netdev.h"
 #include "openflow/nicira-ext.h"
@@ -85,14 +86,19 @@ enum ofputil_msg_code {
     OFPUTIL_NXT_FLOW_AGE,
     OFPUTIL_NXT_SET_ASYNC_CONFIG,
     OFPUTIL_NXT_SET_CONTROLLER_ID,
+    OFPUTIL_NXT_FLOW_MONITOR_CANCEL,
+    OFPUTIL_NXT_FLOW_MONITOR_PAUSED,
+    OFPUTIL_NXT_FLOW_MONITOR_RESUMED,
 
     /* NXST_* stat requests. */
     OFPUTIL_NXST_FLOW_REQUEST,
     OFPUTIL_NXST_AGGREGATE_REQUEST,
+    OFPUTIL_NXST_FLOW_MONITOR_REQUEST,
 
     /* NXST_* stat replies. */
     OFPUTIL_NXST_FLOW_REPLY,
-    OFPUTIL_NXST_AGGREGATE_REPLY
+    OFPUTIL_NXST_AGGREGATE_REPLY,
+    OFPUTIL_NXST_FLOW_MONITOR_REPLY,
 };
 
 struct ofputil_msg_type;
@@ -141,6 +147,9 @@ enum ofputil_protocol {
     OFPUTIL_P_NXM_TID  = 1 << 3, /* NXM + flow_mod_table_id extension. */
 #define OFPUTIL_P_NXM_ANY (OFPUTIL_P_NXM | OFPUTIL_P_NXM_TID)
 
+    /* OpenFlow 1.2 */
+    OFPUTIL_P_OF12      = 1 << 4, /* OpenFlow 1.2 flow format. */
+
     /* All protocols. */
 #define OFPUTIL_P_ANY (OFPUTIL_P_OF10_ANY | OFPUTIL_P_NXM_ANY)
 
@@ -236,13 +245,14 @@ struct ofputil_flow_mod {
     uint32_t buffer_id;
     uint16_t out_port;
     uint16_t flags;
-    union ofp_action *actions;
-    size_t n_actions;
+    struct ofpact *ofpacts;     /* Series of "struct ofpact"s. */
+    size_t ofpacts_len;         /* Length of ofpacts, in bytes. */
 };
 
 enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *,
                                     const struct ofp_header *,
-                                    enum ofputil_protocol);
+                                    enum ofputil_protocol,
+                                    struct ofpbuf *ofpacts);
 struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *,
                                        enum ofputil_protocol);
 
@@ -279,13 +289,14 @@ struct ofputil_flow_stats {
     int hard_age;               /* Seconds since last change, -1 if unknown. */
     uint64_t packet_count;      /* Packet count, UINT64_MAX if unknown. */
     uint64_t byte_count;        /* Byte count, UINT64_MAX if unknown. */
-    union ofp_action *actions;
-    size_t n_actions;
+    struct ofpact *ofpacts;
+    size_t ofpacts_len;
 };
 
 int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *,
                                     struct ofpbuf *msg,
-                                    bool flow_age_extension);
+                                    bool flow_age_extension,
+                                    struct ofpbuf *ofpacts);
 void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *,
                                      struct list *replies);
 
@@ -352,12 +363,13 @@ struct ofputil_packet_out {
     size_t packet_len;          /* Length of packet data in bytes. */
     uint32_t buffer_id;         /* Buffer id or UINT32_MAX if no buffer. */
     uint16_t in_port;           /* Packet's input port. */
-    union ofp_action *actions;  /* Actions. */
-    size_t n_actions;           /* Number of elements in 'actions' array. */
+    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_packet_out *);
+                                      const struct ofp_packet_out *,
+                                      struct ofpbuf *ofpacts);
 struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *);
 
 enum ofputil_port_config {
@@ -502,6 +514,48 @@ enum ofperr ofputil_decode_port_mod(const struct ofp_header *,
 struct ofpbuf *ofputil_encode_port_mod(const struct ofputil_port_mod *,
                                        enum ofputil_protocol);
 
+/* Abstract nx_flow_monitor_request. */
+struct ofputil_flow_monitor_request {
+    uint32_t id;
+    enum nx_flow_monitor_flags flags;
+    uint16_t out_port;
+    uint8_t table_id;
+    struct cls_rule match;
+};
+
+int ofputil_decode_flow_monitor_request(struct ofputil_flow_monitor_request *,
+                                        struct ofpbuf *msg);
+void ofputil_append_flow_monitor_request(
+    const struct ofputil_flow_monitor_request *, struct ofpbuf *msg);
+
+/* Abstract nx_flow_update. */
+struct ofputil_flow_update {
+    enum nx_flow_update_event event;
+
+    /* Used only for NXFME_ADDED, NXFME_DELETED, NXFME_MODIFIED. */
+    enum ofp_flow_removed_reason reason;
+    uint16_t idle_timeout;
+    uint16_t hard_timeout;
+    uint8_t table_id;
+    ovs_be64 cookie;
+    struct cls_rule *match;
+    struct ofpact *ofpacts;
+    size_t ofpacts_len;
+
+    /* Used only for NXFME_ABBREV. */
+    ovs_be32 xid;
+};
+
+int ofputil_decode_flow_update(struct ofputil_flow_update *,
+                               struct ofpbuf *msg, struct ofpbuf *ofpacts);
+void ofputil_start_flow_update(struct list *replies);
+void ofputil_append_flow_update(const struct ofputil_flow_update *,
+                                struct list *replies);
+
+/* Abstract nx_flow_monitor_cancel. */
+uint32_t ofputil_decode_flow_monitor_cancel(const struct ofp_header *);
+struct ofpbuf *ofputil_encode_flow_monitor_cancel(uint32_t id);
+
 /* OpenFlow protocol utility functions. */
 void *make_openflow(size_t openflow_len, uint8_t type, struct ofpbuf **);
 void *make_nxmsg(size_t openflow_len, uint32_t subtype, struct ofpbuf **);
@@ -527,10 +581,15 @@ void *ofputil_make_stats_reply(size_t openflow_len,
                                const struct ofp_stats_msg *request,
                                struct ofpbuf **);
 
+void ofputil_put_stats_header(ovs_be32 xid, uint8_t ofp_type,
+                              ovs_be16 ofpst_type, ovs_be32 nxst_subtype,
+                              struct ofpbuf *);
+
 void ofputil_start_stats_reply(const struct ofp_stats_msg *request,
                                struct list *);
 struct ofpbuf *ofputil_reserve_stats_reply(size_t len, struct list *);
 void *ofputil_append_stats_reply(size_t len, struct list *);
+void ofputil_postappend_stats_reply(size_t start_ofs, struct list *);
 
 void ofputil_append_port_desc_stats_reply(uint8_t ofp_version,
                                           const struct ofputil_phy_port *pp,
@@ -542,13 +601,7 @@ size_t ofputil_stats_body_len(const struct ofp_header *);
 const void *ofputil_nxstats_body(const struct ofp_header *);
 size_t ofputil_nxstats_body_len(const struct ofp_header *);
 
-struct ofpbuf *make_flow_mod(uint16_t command, const struct cls_rule *,
-                             size_t actions_len);
-struct ofpbuf *make_add_flow(const struct cls_rule *, uint32_t buffer_id,
-                             uint16_t max_idle, size_t actions_len);
-struct ofpbuf *make_packet_in(uint32_t buffer_id, uint16_t in_port,
-                              uint8_t reason,
-                              const struct ofpbuf *payload, int max_send_len);
+/*  */
 struct ofpbuf *make_echo_request(void);
 struct ofpbuf *make_echo_reply(const struct ofp_header *rq);
 
@@ -597,25 +650,23 @@ bool ofputil_frag_handling_from_string(const char *, enum ofp_config_flags *);
  *
  * (The above list helps developers who want to "grep" for these definitions.)
  */
-enum ofputil_action_code {
+enum OVS_PACKED_ENUM ofputil_action_code {
     OFPUTIL_ACTION_INVALID,
-#define OFPAT10_ACTION(ENUM, STRUCT, NAME)             OFPUTIL_##ENUM,
+#define OFPAT10_ACTION(ENUM, STRUCT, NAME)           OFPUTIL_##ENUM,
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME)           OFPUTIL_##ENUM,
 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) OFPUTIL_##ENUM,
 #include "ofp-util.def"
 };
 
 /* The number of values of "enum ofputil_action_code". */
 enum {
-#define OFPAT10_ACTION(ENUM, STRUCT, NAME)             + 1
+#define OFPAT10_ACTION(ENUM, STRUCT, NAME)           + 1
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME)           + 1
 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
     OFPUTIL_N_ACTIONS = 1
 #include "ofp-util.def"
 };
 
-int ofputil_decode_action(const union ofp_action *);
-enum ofputil_action_code ofputil_decode_action_unsafe(
-    const union ofp_action *);
-
 int ofputil_action_code_from_name(const char *);
 
 void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf);
@@ -637,6 +688,9 @@ void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf);
 #define OFPAT10_ACTION(ENUM, STRUCT, NAME)              \
     void ofputil_init_##ENUM(struct STRUCT *);          \
     struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME)              \
+    void ofputil_init_##ENUM(struct STRUCT *);          \
+    struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
 #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME)    \
     void ofputil_init_##ENUM(struct STRUCT *);          \
     struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
@@ -644,38 +698,6 @@ void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf);
 
 #define OFP_ACTION_ALIGN 8      /* Alignment of ofp_actions. */
 
-static inline union ofp_action *
-ofputil_action_next(const union ofp_action *a)
-{
-    return ((union ofp_action *) (void *)
-            ((uint8_t *) a + ntohs(a->header.len)));
-}
-
-static inline bool
-ofputil_action_is_valid(const union ofp_action *a, size_t n_actions)
-{
-    uint16_t len = ntohs(a->header.len);
-    return (!(len % OFP_ACTION_ALIGN)
-            && len >= sizeof *a
-            && len / sizeof *a <= n_actions);
-}
-
-/* This macro is careful to check for actions with bad lengths. */
-#define OFPUTIL_ACTION_FOR_EACH(ITER, LEFT, ACTIONS, N_ACTIONS)         \
-    for ((ITER) = (ACTIONS), (LEFT) = (N_ACTIONS);                      \
-         (LEFT) > 0 && ofputil_action_is_valid(ITER, LEFT);             \
-         ((LEFT) -= ntohs((ITER)->header.len) / sizeof(union ofp_action), \
-          (ITER) = ofputil_action_next(ITER)))
-
-/* This macro does not check for actions with bad lengths.  It should only be
- * used with actions from trusted sources or with actions that have already
- * been validated (e.g. with OFPUTIL_ACTION_FOR_EACH).  */
-#define OFPUTIL_ACTION_FOR_EACH_UNSAFE(ITER, LEFT, ACTIONS, N_ACTIONS)  \
-    for ((ITER) = (ACTIONS), (LEFT) = (N_ACTIONS);                      \
-         (LEFT) > 0;                                                    \
-         ((LEFT) -= ntohs((ITER)->header.len) / sizeof(union ofp_action), \
-          (ITER) = ofputil_action_next(ITER)))
-
 enum ofperr validate_actions(const union ofp_action *, size_t n_actions,
                              const struct flow *, int max_ports);
 bool action_outputs_to_port(const union ofp_action *, ovs_be16 port);