treewide: Remove trailing whitespace
[sliver-openvswitch.git] / lib / dpif.c
index 315f11f..01e905d 100644 (file)
 #include "svec.h"
 #include "util.h"
 #include "valgrind.h"
-
 #include "vlog.h"
-#define THIS_MODULE VLM_dpif
+
+VLOG_DEFINE_THIS_MODULE(dpif)
 
 static const struct dpif_class *base_dpif_classes[] = {
+#ifdef HAVE_NETLINK
     &dpif_linux_class,
+#endif
     &dpif_netdev_class,
 };
 
@@ -58,7 +60,7 @@ static struct shash dpif_classes = SHASH_INITIALIZER(&dpif_classes);
 static struct vlog_rate_limit dpmsg_rl = VLOG_RATE_LIMIT_INIT(600, 600);
 
 /* Not really much point in logging many dpif errors. */
-static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5);
+static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(60, 5);
 
 static void log_operation(const struct dpif *, const char *operation,
                           int error);
@@ -319,7 +321,7 @@ dpif_close(struct dpif *dpif)
     if (dpif) {
         struct registered_dpif_class *registered_class;
 
-        registered_class = shash_find_data(&dpif_classes, 
+        registered_class = shash_find_data(&dpif_classes,
                 dpif->dpif_class->type);
         assert(registered_class);
         assert(registered_class->refcount);
@@ -724,6 +726,11 @@ dpif_flow_get(const struct dpif *dpif, struct odp_flow *flow)
     if (!error) {
         error = flow->stats.error;
     }
+    if (error) {
+        /* Make the results predictable on error. */
+        memset(&flow->stats, 0, sizeof flow->stats);
+        flow->n_actions = 0;
+    }
     if (should_log_flow_message(error)) {
         log_flow_operation(dpif, "flow_get", error, flow);
     }
@@ -1010,7 +1017,8 @@ dpif_set_sflow_probability(struct dpif *dpif, uint32_t probability)
 
 /* Attempts to receive a message from 'dpif'.  If successful, stores the
  * message into '*packetp'.  The message, if one is received, will begin with
- * 'struct odp_msg' as a header.  Only messages of the types selected with
+ * 'struct odp_msg' as a header, and will have at least DPIF_RECV_MSG_PADDING
+ * bytes of headroom.  Only messages of the types selected with
  * dpif_set_listen_mask() will ordinarily be received (but if a message type is
  * enabled and then later disabled, some stragglers might pop up).
  *
@@ -1021,8 +1029,10 @@ dpif_recv(struct dpif *dpif, struct ofpbuf **packetp)
 {
     int error = dpif->dpif_class->recv(dpif, packetp);
     if (!error) {
+        struct ofpbuf *buf = *packetp;
+
+        assert(ofpbuf_headroom(buf) >= DPIF_RECV_MSG_PADDING);
         if (VLOG_IS_DBG_ENABLED()) {
-            struct ofpbuf *buf = *packetp;
             struct odp_msg *msg = buf->data;
             void *payload = msg + 1;
             size_t payload_len = buf->size - sizeof *msg;
@@ -1086,6 +1096,25 @@ dpif_get_netflow_ids(const struct dpif *dpif,
     *engine_type = dpif->netflow_engine_type;
     *engine_id = dpif->netflow_engine_id;
 }
+
+/* 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'. */
+int
+dpif_queue_to_priority(const struct dpif *dpif, uint32_t queue_id,
+                       uint32_t *priority)
+{
+    int error = (dpif->dpif_class->queue_to_priority
+                 ? dpif->dpif_class->queue_to_priority(dpif, queue_id,
+                                                       priority)
+                 : EOPNOTSUPP);
+    if (error) {
+        *priority = 0;
+    }
+    log_operation(dpif, "queue_to_priority", error);
+    return error;
+}
 \f
 void
 dpif_init(struct dpif *dpif, const struct dpif_class *dpif_class,