route-table: Remove Unregister.
[cascardo/ovs.git] / lib / dpif.c
index 64e6a0e..49432f2 100644 (file)
 #include "packet-dpif.h"
 #include "packets.h"
 #include "poll-loop.h"
+#include "route-table.h"
+#include "seq.h"
 #include "shash.h"
 #include "sset.h"
 #include "timeval.h"
+#include "tnl-arp-cache.h"
+#include "tnl-ports.h"
 #include "util.h"
 #include "valgrind.h"
 #include "vlog.h"
@@ -101,6 +105,9 @@ static void log_execute_message(struct dpif *, const struct dpif_execute *,
 static void log_flow_get_message(const struct dpif *,
                                  const struct dpif_flow_get *, int error);
 
+/* Incremented whenever tnl route, arp, etc changes. */
+struct seq *tnl_conf_seq;
+
 static void
 dp_initialize(void)
 {
@@ -109,10 +116,16 @@ dp_initialize(void)
     if (ovsthread_once_start(&once)) {
         int i;
 
+        tnl_conf_seq = seq_create();
+        dpctl_unixctl_register();
+        tnl_port_map_init();
+        tnl_arp_cache_init();
+        route_table_init();
+
         for (i = 0; i < ARRAY_SIZE(base_dpif_classes); i++) {
             dp_register_provider(base_dpif_classes[i]);
         }
-        dpctl_unixctl_register();
+
         ovsthread_once_done(&once);
     }
 }
@@ -402,12 +415,13 @@ dpif_close(struct dpif *dpif)
 }
 
 /* Performs periodic work needed by 'dpif'. */
-void
+bool
 dpif_run(struct dpif *dpif)
 {
     if (dpif->dpif_class->run) {
-        dpif->dpif_class->run(dpif);
+        return dpif->dpif_class->run(dpif);
     }
+    return false;
 }
 
 /* Arranges for poll_block() to wake up when dp_run() needs to be called for
@@ -817,6 +831,21 @@ dpif_flow_stats_format(const struct dpif_flow_stats *stats, struct ds *s)
     }
 }
 
+/* Places the hash of the 'key_len' bytes starting at 'key' into '*hash'. */
+void
+dpif_flow_hash(const struct dpif *dpif OVS_UNUSED,
+               const void *key, size_t key_len, ovs_u128 *hash)
+{
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+    static uint32_t secret;
+
+    if (ovsthread_once_start(&once)) {
+        secret = random_uint32();
+        ovsthread_once_done(&once);
+    }
+    hash_bytes128(key, key_len, secret, hash);
+}
+
 /* Deletes all flows from 'dpif'.  Returns 0 if successful, otherwise a
  * positive errno value.  */
 int
@@ -1002,6 +1031,8 @@ dpif_execute_helper_cb(void *aux_, struct dpif_packet **packets, int cnt,
 
     switch ((enum ovs_action_attr)type) {
     case OVS_ACTION_ATTR_OUTPUT:
+    case OVS_ACTION_ATTR_TUNNEL_PUSH:
+    case OVS_ACTION_ATTR_TUNNEL_POP:
     case OVS_ACTION_ATTR_USERSPACE:
     case OVS_ACTION_ATTR_RECIRC: {
         struct dpif_execute execute;
@@ -1379,6 +1410,22 @@ dpif_recv_wait(struct dpif *dpif, uint32_t handler_id)
     }
 }
 
+/*
+ * Return the datapath version. Caller is responsible for freeing
+ * the string.
+ */
+char *
+dpif_get_dp_version(const struct dpif *dpif)
+{
+    char *version = NULL;
+
+    if (dpif->dpif_class->get_datapath_version) {
+        version = dpif->dpif_class->get_datapath_version();
+    }
+
+    return version;
+}
+
 /* Obtains the NetFlow engine type and engine ID for 'dpif' into '*engine_type'
  * and '*engine_id', respectively. */
 void
@@ -1592,3 +1639,10 @@ log_flow_get_message(const struct dpif *dpif, const struct dpif_flow_get *get,
                          get->flow->actions, get->flow->actions_len);
     }
 }
+
+bool
+dpif_supports_tnl_push_pop(const struct dpif *dpif)
+{
+   return !strcmp(dpif->dpif_class->type, "netdev") ||
+          !strcmp(dpif->dpif_class->type, "dummy");
+}