Catalli's threaded switch
[sliver-openvswitch.git] / lib / dpif.c
index 097b38d..28b936b 100644 (file)
 #include "svec.h"
 #include "util.h"
 #include "valgrind.h"
-
+#include "fatal-signal.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,
 };
 
@@ -52,6 +55,7 @@ struct registered_dpif_class {
 };
 static struct shash dpif_classes = SHASH_INITIALIZER(&dpif_classes);
 
+
 /* Rate limit for individual messages going to or from the datapath, output at
  * DBG level.  This is very high because, if these are enabled, it is because
  * we really need to see them. */
@@ -76,14 +80,30 @@ dp_initialize(void)
 
     if (status < 0) {
         int i;
+#ifdef THREADED
+        struct shash_node *node;
+#endif
 
         status = 0;
         for (i = 0; i < ARRAY_SIZE(base_dpif_classes); i++) {
             dp_register_provider(base_dpif_classes[i]);
         }
+        
+#ifdef THREADED
+        /* register an exit handler for the registered classes */
+        SHASH_FOR_EACH(node, &dpif_classes) {
+            const struct registered_dpif_class *registered_class = node->data;
+            if (registered_class->dpif_class.exit_hook) {
+                fatal_signal_add_hook(registered_class->dpif_class.exit_hook,
+                        NULL, NULL, true);
+            }
+        }
+#endif
     }
 }
 
+
+
 /* Performs periodic work needed by all the various kinds of dpifs.
  *
  * If your program opens any dpifs, it must call both this function and
@@ -116,13 +136,34 @@ dp_wait(void)
     }
 }
 
+#ifdef THREADED
+/* Start the datapath management.
+ * 
+ * This function has been thought for a scenario in which the management of the
+ * datapath module and the ofproto module are performed in separate
+ * threads/processes module. */
+void
+dp_start(void)
+{
+    struct shash_node *node;
+
+    SHASH_FOR_EACH(node, &dpif_classes) {
+        const struct registered_dpif_class *registered_class = node->data;
+        if (registered_class->dpif_class.start) {
+            registered_class->dpif_class.start();
+        }
+    }
+}
+#endif
+
+
 /* Registers a new datapath provider.  After successful registration, new
  * datapaths of that type can be opened using dpif_open(). */
 int
 dp_register_provider(const struct dpif_class *new_class)
 {
     struct registered_dpif_class *registered_class;
-
+       
     if (shash_find(&dpif_classes, new_class->type)) {
         VLOG_WARN("attempted to register duplicate datapath provider: %s",
                   new_class->type);
@@ -319,7 +360,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);
@@ -1094,6 +1135,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,