Prepare Open vSwitch 1.1.2 release.
[sliver-openvswitch.git] / lib / dpif.c
index c225e2b..81e180f 100644 (file)
@@ -36,7 +36,7 @@
 #include "packets.h"
 #include "poll-loop.h"
 #include "shash.h"
-#include "svec.h"
+#include "sset.h"
 #include "timeval.h"
 #include "util.h"
 #include "valgrind.h"
@@ -184,36 +184,36 @@ dp_unregister_provider(const char *type)
 }
 
 /* Clears 'types' and enumerates the types of all currently registered datapath
- * providers into it.  The caller must first initialize the svec. */
+ * providers into it.  The caller must first initialize the sset. */
 void
-dp_enumerate_types(struct svec *types)
+dp_enumerate_types(struct sset *types)
 {
     struct shash_node *node;
 
     dp_initialize();
-    svec_clear(types);
+    sset_clear(types);
 
     SHASH_FOR_EACH(node, &dpif_classes) {
         const struct registered_dpif_class *registered_class = node->data;
-        svec_add(types, registered_class->dpif_class->type);
+        sset_add(types, registered_class->dpif_class->type);
     }
 }
 
 /* Clears 'names' and enumerates the names of all known created datapaths with
- * the given 'type'.  The caller must first initialize the svec. Returns 0 if
+ * the given 'type'.  The caller must first initialize the sset.  Returns 0 if
  * successful, otherwise a positive errno value.
  *
  * Some kinds of datapaths might not be practically enumerable.  This is not
  * considered an error. */
 int
-dp_enumerate_names(const char *type, struct svec *names)
+dp_enumerate_names(const char *type, struct sset *names)
 {
     const struct registered_dpif_class *registered_class;
     const struct dpif_class *dpif_class;
     int error;
 
     dp_initialize();
-    svec_clear(names);
+    sset_clear(names);
 
     registered_class = shash_find_data(&dpif_classes, type);
     if (!registered_class) {
@@ -363,33 +363,6 @@ dpif_base_name(const struct dpif *dpif)
     return dpif->base_name;
 }
 
-/* Enumerates all names that may be used to open 'dpif' into 'all_names'.  The
- * Linux datapath, for example, supports opening a datapath both by number,
- * e.g. "dp0", and by the name of the datapath's local port.  For some
- * datapaths, this might be an infinite set (e.g. in a file name, slashes may
- * be duplicated any number of times), in which case only the names most likely
- * to be used will be enumerated.
- *
- * The caller must already have initialized 'all_names'.  Any existing names in
- * 'all_names' will not be disturbed. */
-int
-dpif_get_all_names(const struct dpif *dpif, struct svec *all_names)
-{
-    if (dpif->dpif_class->get_all_names) {
-        int error = dpif->dpif_class->get_all_names(dpif, all_names);
-        if (error) {
-            VLOG_WARN_RL(&error_rl,
-                         "failed to retrieve names for datpath %s: %s",
-                         dpif_name(dpif), strerror(error));
-        }
-        return error;
-    } else {
-        svec_add(all_names, dpif_base_name(dpif));
-        return 0;
-    }
-}
-
-
 /* Destroys the datapath that 'dpif' is connected to, first removing all of its
  * ports.  After calling this function, it does not make sense to pass 'dpif'
  * to any functions other than dpif_name() or dpif_close(). */
@@ -731,7 +704,7 @@ dpif_flow_flush(struct dpif *dpif)
  * If 'stats' is nonnull, then on success it will be updated with the flow's
  * statistics. */
 int
-dpif_flow_get(const struct dpif *dpif, int flags,
+dpif_flow_get(const struct dpif *dpif,
               const struct nlattr *key, size_t key_len,
               struct ofpbuf **actionsp, struct dpif_flow_stats *stats)
 {
@@ -739,8 +712,7 @@ dpif_flow_get(const struct dpif *dpif, int flags,
 
     COVERAGE_INC(dpif_flow_get);
 
-    error = dpif->dpif_class->flow_get(dpif, flags, key, key_len, actionsp,
-                                       stats);
+    error = dpif->dpif_class->flow_get(dpif, key, key_len, actionsp, stats);
     if (error) {
         if (actionsp) {
             *actionsp = NULL;
@@ -769,25 +741,25 @@ dpif_flow_get(const struct dpif *dpif, int flags,
 /* Adds or modifies a flow in 'dpif'.  The flow is specified by the Netlink
  * attributes with types ODP_KEY_ATTR_* in the 'key_len' bytes starting at
  * 'key'.  The associated actions are specified by the Netlink attributes with
- * types ODPAT_* in the 'actions_len' bytes starting at 'actions'.
+ * types ODP_ACTION_ATTR_* in the 'actions_len' bytes starting at 'actions'.
  *
  * - If the flow's key does not exist in 'dpif', then the flow will be added if
- *   'flags' includes ODPPF_CREATE.  Otherwise the operation will fail with
+ *   'flags' includes DPIF_FP_CREATE.  Otherwise the operation will fail with
  *   ENOENT.
  *
  *   If the operation succeeds, then 'stats', if nonnull, will be zeroed.
  *
  * - If the flow's key does exist in 'dpif', then the flow's actions will be
- *   updated if 'flags' includes ODPPF_MODIFY.  Otherwise the operation will
+ *   updated if 'flags' includes DPIF_FP_MODIFY.  Otherwise the operation will
  *   fail with EEXIST.  If the flow's actions are updated, then its statistics
- *   will be zeroed if 'flags' includes ODPPF_ZERO_STATS, and left as-is
+ *   will be zeroed if 'flags' includes DPIF_FP_ZERO_STATS, and left as-is
  *   otherwise.
  *
  *   If the operation succeeds, then 'stats', if nonnull, will be set to the
  *   flow's statistics before the update.
  */
 int
-dpif_flow_put(struct dpif *dpif, int flags,
+dpif_flow_put(struct dpif *dpif, enum dpif_flow_put_flags flags,
               const struct nlattr *key, size_t key_len,
               const struct nlattr *actions, size_t actions_len,
               struct dpif_flow_stats *stats)
@@ -795,6 +767,7 @@ dpif_flow_put(struct dpif *dpif, int flags,
     int error;
 
     COVERAGE_INC(dpif_flow_put);
+    assert(!(flags & ~(DPIF_FP_CREATE | DPIF_FP_MODIFY | DPIF_FP_ZERO_STATS)));
 
     error = dpif->dpif_class->flow_put(dpif, flags, key, key_len,
                                        actions, actions_len, stats);
@@ -802,23 +775,19 @@ dpif_flow_put(struct dpif *dpif, int flags,
         memset(stats, 0, sizeof *stats);
     }
     if (should_log_flow_message(error)) {
-        enum { ODPPF_ALL = ODPPF_CREATE | ODPPF_MODIFY | ODPPF_ZERO_STATS };
         struct ds s;
 
         ds_init(&s);
         ds_put_cstr(&s, "put");
-        if (flags & ODPPF_CREATE) {
+        if (flags & DPIF_FP_CREATE) {
             ds_put_cstr(&s, "[create]");
         }
-        if (flags & ODPPF_MODIFY) {
+        if (flags & DPIF_FP_MODIFY) {
             ds_put_cstr(&s, "[modify]");
         }
-        if (flags & ODPPF_ZERO_STATS) {
+        if (flags & DPIF_FP_ZERO_STATS) {
             ds_put_cstr(&s, "[zero]");
         }
-        if (flags & ~ODPPF_ALL) {
-            ds_put_format(&s, "[%x]", flags & ~ODPPF_ALL);
-        }
         log_flow_message(dpif, error, ds_cstr(&s), key, key_len, stats,
                          actions, actions_len);
         ds_destroy(&s);
@@ -876,9 +845,9 @@ dpif_flow_dump_start(struct dpif_flow_dump *dump, const struct dpif *dpif)
  * On success, if 'key' and 'key_len' are nonnull then '*key' and '*key_len'
  * will be set to Netlink attributes with types ODP_KEY_ATTR_* representing the
  * dumped flow's key.  If 'actions' and 'actions_len' are nonnull then they are
- * set to Netlink attributes with types ODPAT_* representing the dumped flow's
- * actions.  If 'stats' is nonnull then it will be set to the dumped flow's
- * statistics.
+ * set to Netlink attributes with types ODP_ACTION_ATTR_* representing the
+ * dumped flow's actions.  If 'stats' is nonnull then it will be set to the
+ * dumped flow's statistics.
  *
  * All of the returned data is owned by 'dpif', not by the caller, and the
  * caller must not modify or free it.  'dpif' guarantees that it remains
@@ -977,9 +946,18 @@ dpif_execute(struct dpif *dpif,
     return error;
 }
 
-/* Retrieves 'dpif''s "listen mask" into '*listen_mask'.  Each ODPL_* bit set
- * in '*listen_mask' indicates that dpif_recv() will receive messages of that
- * type.  Returns 0 if successful, otherwise a positive errno value. */
+static bool OVS_UNUSED
+is_valid_listen_mask(int listen_mask)
+{
+    return !(listen_mask & ~((1u << DPIF_UC_MISS) |
+                             (1u << DPIF_UC_ACTION) |
+                             (1u << DPIF_UC_SAMPLE)));
+}
+
+/* Retrieves 'dpif''s "listen mask" into '*listen_mask'.  A 1-bit of value 2**X
+ * set in '*listen_mask' indicates that dpif_recv() will receive messages of
+ * the type (from "enum dpif_upcall_type") with value X.  Returns 0 if
+ * successful, otherwise a positive errno value. */
 int
 dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask)
 {
@@ -987,17 +965,23 @@ dpif_recv_get_mask(const struct dpif *dpif, int *listen_mask)
     if (error) {
         *listen_mask = 0;
     }
+    assert(is_valid_listen_mask(*listen_mask));
     log_operation(dpif, "recv_get_mask", error);
     return error;
 }
 
-/* Sets 'dpif''s "listen mask" to 'listen_mask'.  Each ODPL_* bit set in
- * '*listen_mask' requests that dpif_recv() receive messages of that type.
- * Returns 0 if successful, otherwise a positive errno value. */
+/* Sets 'dpif''s "listen mask" to 'listen_mask'.  A 1-bit of value 2**X set in
+ * '*listen_mask' requests that dpif_recv() will receive messages of the type
+ * (from "enum dpif_upcall_type") with value X.  Returns 0 if successful,
+ * otherwise a positive errno value. */
 int
 dpif_recv_set_mask(struct dpif *dpif, int listen_mask)
 {
-    int error = dpif->dpif_class->recv_set_mask(dpif, listen_mask);
+    int error;
+
+    assert(is_valid_listen_mask(listen_mask));
+
+    error = dpif->dpif_class->recv_set_mask(dpif, listen_mask);
     log_operation(dpif, "recv_set_mask", error);
     return error;
 }
@@ -1038,7 +1022,7 @@ dpif_set_sflow_probability(struct dpif *dpif, uint32_t probability)
 }
 
 /* Polls for an upcall from 'dpif'.  If successful, stores the upcall into
- * '*upcall'.  Only upcalls of the types selected with the set_listen_mask
+ * '*upcall'.  Only upcalls of the types selected with dpif_recv_set_mask()
  * member function will ordinarily be received (but if a message type is
  * enabled and then later disabled, some stragglers might pop up).
  *
@@ -1063,9 +1047,9 @@ dpif_recv(struct dpif *dpif, struct dpif_upcall *upcall)
         odp_flow_key_to_flow(upcall->key, upcall->key_len, &flow);
 
         VLOG_DBG("%s: %s upcall on port %"PRIu16": %s", dpif_name(dpif),
-                 (upcall->type == _ODPL_MISS_NR ? "miss"
-                  : upcall->type == _ODPL_ACTION_NR ? "action"
-                  : upcall->type == _ODPL_SFLOW_NR ? "sFlow"
+                 (upcall->type == DPIF_UC_MISS ? "miss"
+                  : upcall->type == DPIF_UC_ACTION ? "action"
+                  : upcall->type == DPIF_UC_SAMPLE ? "sample"
                   : "<unknown>"),
                  flow.in_port, s);
         free(s);
@@ -1103,9 +1087,9 @@ dpif_get_netflow_ids(const struct dpif *dpif,
 }
 
 /* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a priority
- * value for use in the ODPAT_SET_PRIORITY action.  On success, returns 0 and
- * stores the priority into '*priority'.  On failure, returns a positive errno
- * value and stores 0 into '*priority'. */
+ * value for use in the ODP_ACTION_ATTR_SET_PRIORITY action.  On success,
+ * returns 0 and stores the priority into '*priority'.  On failure, returns a
+ * positive errno value and stores 0 into '*priority'. */
 int
 dpif_queue_to_priority(const struct dpif *dpif, uint32_t queue_id,
                        uint32_t *priority)