Implement OFPT_TABLE_STATUS Message.
[cascardo/ovs.git] / lib / ofp-util.h
index 21c97af..31cbe2d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include "openflow/nicira-ext.h"
 #include "openvswitch/types.h"
 #include "type-props.h"
+#include "uuid.h"
 
 struct ofpbuf;
 union ofp_action;
 struct ofpact_set_field;
+struct pktbuf;
 
 /* Port numbers. */
 enum ofperr ofputil_port_from_ofp11(ovs_be32 ofp11_port,
@@ -140,22 +142,6 @@ enum ofputil_protocol {
                        OFPUTIL_P_ANY_OXM)
 };
 
-    /* Valid value of mask for asynchronous messages. */
-#define MAXIMUM_MASK_PACKET_IN ((1 << OFPR_N_REASONS) - 1)
-
-#define MAXIMUM_MASK_FLOW_REMOVED ((1 << OVS_OFPRR_NONE) - 1)
-
-#define MAXIMUM_MASK_PORT_STATUS ((1 << OFPPR_N_REASONS) - 1)
-
-#define MAXIMUM_MASK_ROLE_STATUS ((1 << OFPCRR_N_REASONS) - 1)
-
-#define MINIMUM_MASK_TABLE_STATUS (1 << OFPTR_VACANCY_DOWN)
-
-#define MAXIMUM_MASK_TABLE_STATUS ((1 << OFPTR_N_REASONS) - \
-                                   MINIMUM_MASK_TABLE_STATUS)
-
-#define MAXIMUM_MASK_REQUESTFORWARD ((1 << OFPRFR_N_REASONS) - 1)
-
 /* Protocols to use for flow dumps, from most to least preferred. */
 extern enum ofputil_protocol ofputil_flow_dump_protocols[];
 extern size_t ofputil_n_flow_dump_protocols;
@@ -427,25 +413,25 @@ enum ofperr ofputil_decode_flow_removed(struct ofputil_flow_removed *,
 struct ofpbuf *ofputil_encode_flow_removed(const struct ofputil_flow_removed *,
                                            enum ofputil_protocol);
 
-/* Abstract packet-in message. */
+/* Abstract packet-in message.
+ *
+ * This omits the 'total_len' and 'buffer_id' fields, which we handle
+ * differently for encoding and decoding.*/
 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 match flow_metadata;
-
-    /* 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.
+     * On encoding, the full packet should be supplied, but depending on its
+     * other parameters ofputil_encode_packet_in() might send only the first
+     * part of the packet.
      *
-     * 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;
+     * On decoding, the 'len' bytes in 'packet' might only be the first part of
+     * the original packet.  ofputil_decode_packet_in() reports the full
+     * original length of the packet using its 'total_len' output parameter. */
+    void *packet;               /* The packet. */
+    size_t packet_len;          /* Length of 'packet' in bytes. */
+
+    /* Input port and other metadata for packet. */
+    struct match flow_metadata;
 
     /* Reason that the packet-in is being sent. */
     enum ofp_packet_in_reason reason;    /* One of OFPR_*. */
@@ -456,13 +442,22 @@ struct ofputil_packet_in {
      * that case, 'cookie' is UINT64_MAX. */
     uint8_t table_id;                    /* OpenFlow table ID. */
     ovs_be64 cookie;                     /* Flow's cookie. */
+
+    /* Arbitrary user-provided data. */
+    uint8_t *userdata;
+    size_t userdata_len;
 };
 
-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);
+void ofputil_packet_in_destroy(struct ofputil_packet_in *);
+
+enum ofperr ofputil_decode_packet_in(const struct ofp_header *, bool loose,
+                                     struct ofputil_packet_in *,
+                                     size_t *total_len, uint32_t *buffer_id,
+                                     struct ofpbuf *continuation);
+
+struct ofpbuf *ofputil_encode_resume(const struct ofputil_packet_in *pin,
+                                     const struct ofpbuf *continuation,
+                                     enum ofputil_protocol);
 
 enum { OFPUTIL_PACKET_IN_REASON_BUFSIZE = INT_STRLEN(int) + 1 };
 const char *ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason,
@@ -471,6 +466,48 @@ const char *ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason,
 bool ofputil_packet_in_reason_from_string(const char *,
                                           enum ofp_packet_in_reason *);
 
+/* A packet-in message, including continuation data.  The format of
+ * continuation data is subject to change and thus it is supposed to be opaque
+ * to any process other than ovs-vswitchd.  Therefore, only ovs-vswitchd should
+ * use ofputil_packet_in_private and the functions that operate on it. */
+struct ofputil_packet_in_private {
+    struct ofputil_packet_in public;
+
+    /* NXCPT_BRIDGE. */
+    struct uuid bridge;
+
+    /* NXCPT_STACK. */
+    union mf_subvalue *stack;
+    size_t n_stack;
+
+    /* NXCPT_MIRRORS. */
+    uint32_t mirrors;
+
+    /* NXCPT_CONNTRACKED. */
+    bool conntracked;
+
+    /* NXCPT_ACTIONS. */
+    struct ofpact *actions;
+    size_t actions_len;
+
+    /* NXCPT_ACTION_SET. */
+    struct ofpact *action_set;
+    size_t action_set_len;
+};
+
+struct ofpbuf *ofputil_encode_packet_in_private(
+    const struct ofputil_packet_in_private *,
+    enum ofputil_protocol protocol,
+    enum nx_packet_in_format,
+    uint16_t max_len, struct pktbuf *);
+
+enum ofperr ofputil_decode_packet_in_private(
+    const struct ofp_header *, bool loose,
+    struct ofputil_packet_in_private *,
+    size_t *total_len, uint32_t *buffer_id);
+
+void ofputil_packet_in_private_destroy(struct ofputil_packet_in_private *);
+
 /* Abstract packet-out message.
  *
  * ofputil_decode_packet_out() will ensure that 'in_port' is a physical port
@@ -490,6 +527,41 @@ enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
 struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *,
                                          enum ofputil_protocol protocol);
 
+enum ofputil_frag_handling {
+    OFPUTIL_FRAG_NORMAL = OFPC_FRAG_NORMAL,    /* No special handling. */
+    OFPUTIL_FRAG_DROP = OFPC_FRAG_DROP,        /* Drop fragments. */
+    OFPUTIL_FRAG_REASM = OFPC_FRAG_REASM,      /* Reassemble (if supported). */
+    OFPUTIL_FRAG_NX_MATCH = OFPC_FRAG_NX_MATCH /* Match on frag bits. */
+};
+
+const char *ofputil_frag_handling_to_string(enum ofputil_frag_handling);
+bool ofputil_frag_handling_from_string(const char *,
+                                       enum ofputil_frag_handling *);
+
+/* Abstract struct ofp_switch_config. */
+struct ofputil_switch_config {
+    /* Fragment handling. */
+    enum ofputil_frag_handling frag;
+
+    /* 0: Do not send packet to controller when decrementing invalid IP TTL.
+     * 1: Do send packet to controller when decrementing invalid IP TTL.
+     * -1: Unspecified (only OpenFlow 1.1 and 1.2 support this setting. */
+    int invalid_ttl_to_controller;
+
+    /* Maximum bytes of packet to send to controller on miss. */
+    uint16_t miss_send_len;
+};
+
+void ofputil_decode_get_config_reply(const struct ofp_header *,
+                                     struct ofputil_switch_config *);
+struct ofpbuf *ofputil_encode_get_config_reply(
+    const struct ofp_header *request, const struct ofputil_switch_config *);
+
+enum ofperr ofputil_decode_set_config(const struct ofp_header *,
+                                      struct ofputil_switch_config *);
+struct ofpbuf *ofputil_encode_set_config(
+    const struct ofputil_switch_config *, enum ofp_version);
+
 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. */
@@ -567,9 +639,8 @@ struct ofputil_switch_features {
     uint64_t ofpacts;           /* Bitmap of OFPACT_* bits. */
 };
 
-enum ofperr ofputil_decode_switch_features(const struct ofp_header *,
-                                           struct ofputil_switch_features *,
-                                           struct ofpbuf *);
+enum ofperr ofputil_pull_switch_features(struct ofpbuf *,
+                                         struct ofputil_switch_features *);
 
 struct ofpbuf *ofputil_encode_switch_features(
     const struct ofputil_switch_features *, enum ofputil_protocol,
@@ -951,14 +1022,16 @@ int ofputil_decode_table_stats_reply(struct ofpbuf *reply,
 
 /* Queue configuration request. */
 struct ofpbuf *ofputil_encode_queue_get_config_request(enum ofp_version,
-                                                       ofp_port_t port);
+                                                       ofp_port_t port,
+                                                       uint32_t queue);
 enum ofperr ofputil_decode_queue_get_config_request(const struct ofp_header *,
-                                                    ofp_port_t *port);
+                                                    ofp_port_t *port,
+                                                    uint32_t *queue);
 
 /* Queue configuration reply. */
 struct ofputil_queue_config {
     ofp_port_t port;
-    uint32_t queue_id;
+    uint32_t queue;
 
     /* Each of these optional values is expressed in tenths of a percent.
      * Values greater than 1000 indicate that the feature is disabled.
@@ -967,13 +1040,11 @@ struct ofputil_queue_config {
     uint16_t max_rate;
 };
 
-struct ofpbuf *ofputil_encode_queue_get_config_reply(
-    const struct ofp_header *request);
+void ofputil_start_queue_get_config_reply(const struct ofp_header *request,
+                                          struct ovs_list *replies);
 void ofputil_append_queue_get_config_reply(
-    struct ofpbuf *reply, const struct ofputil_queue_config *);
+    const struct ofputil_queue_config *, struct ovs_list *replies);
 
-enum ofperr ofputil_decode_queue_get_config_reply(struct ofpbuf *reply,
-                                                  ofp_port_t *);
 int ofputil_pull_queue_get_config_reply(struct ofpbuf *reply,
                                         struct ofputil_queue_config *);
 
@@ -1035,10 +1106,6 @@ struct ofpbuf *make_echo_request(enum ofp_version);
 struct ofpbuf *make_echo_reply(const struct ofp_header *rq);
 
 struct ofpbuf *ofputil_encode_barrier_request(enum ofp_version);
-
-const char *ofputil_frag_handling_to_string(enum ofp_config_flags);
-bool ofputil_frag_handling_from_string(const char *, enum ofp_config_flags *);
-
 \f
 /* Actions. */
 
@@ -1284,24 +1351,38 @@ enum ofperr ofputil_decode_tlv_table_reply(const struct ofp_header *,
 void ofputil_uninit_tlv_table(struct ovs_list *mappings);
 
 enum ofputil_async_msg_type {
+    /* Standard asynchronous messages. */
     OAM_PACKET_IN,              /* OFPT_PACKET_IN or NXT_PACKET_IN. */
     OAM_PORT_STATUS,            /* OFPT_PORT_STATUS. */
-    OAM_FLOW_REMOVED,           /* OFPT_FLOW_REMOVED or
-                                 * NXT_FLOW_REMOVED. */
+    OAM_FLOW_REMOVED,           /* OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED. */
     OAM_ROLE_STATUS,            /* OFPT_ROLE_STATUS. */
     OAM_TABLE_STATUS,           /* OFPT_TABLE_STATUS. */
     OAM_REQUESTFORWARD,         /* OFPT_REQUESTFORWARD. */
+
+    /* Extension asynchronous messages (none yet--coming soon!). */
+#define OAM_EXTENSIONS 0        /* Bitmap of all extensions. */
+
     OAM_N_TYPES
 };
+const char *ofputil_async_msg_type_to_string(enum ofputil_async_msg_type);
+
+struct ofputil_async_cfg {
+    uint32_t master[OAM_N_TYPES];
+    uint32_t slave[OAM_N_TYPES];
+};
+#define OFPUTIL_ASYNC_CFG_INIT (struct ofputil_async_cfg) { .master[0] = 0 }
 
 enum ofperr ofputil_decode_set_async_config(const struct ofp_header *,
-                                            uint32_t master[OAM_N_TYPES],
-                                            uint32_t slave[OAM_N_TYPES],
-                                            bool loose);
+                                            bool loose,
+                                            const struct ofputil_async_cfg *,
+                                            struct ofputil_async_cfg *);
+
+struct ofpbuf *ofputil_encode_get_async_reply(
+    const struct ofp_header *, const struct ofputil_async_cfg *);
+struct ofpbuf *ofputil_encode_set_async_config(
+    const struct ofputil_async_cfg *, uint32_t oams, enum ofp_version);
 
-struct ofpbuf *ofputil_encode_get_async_config(const struct ofp_header *,
-                                               uint32_t master[OAM_N_TYPES],
-                                               uint32_t slave[OAM_N_TYPES]);
+struct ofputil_async_cfg ofputil_async_cfg_default(enum ofp_version);
 
 struct ofputil_requestforward {
     ovs_be32 xid;
@@ -1324,4 +1405,16 @@ enum ofperr ofputil_decode_requestforward(const struct ofp_header *,
                                           struct ofputil_requestforward *);
 void ofputil_destroy_requestforward(struct ofputil_requestforward *);
 
+/* Abstract ofp14_table_status. */
+struct ofputil_table_status {
+    enum ofp14_table_reason reason;     /* One of OFPTR_*. */
+    struct ofputil_table_desc desc;   /* New table config. */
+};
+
+enum ofperr ofputil_decode_table_status(const struct ofp_header *oh,
+                                        struct ofputil_table_status *ts);
+
+struct ofpbuf *
+ofputil_encode_table_status(const struct ofputil_table_status *ts,
+                            enum ofputil_protocol protocol);
 #endif /* ofp-util.h */