use a single dataplane instance for all tests

Creating and destroying dataplane instances was taking about 1/3 of the total
runtime.
diff --git a/oft b/oft
index 6d1dfa9..885b5b2 100755
--- a/oft
+++ b/oft
@@ -566,6 +566,11 @@
 signal.signal(signal.SIGINT, signal.SIG_DFL)
 
 if __name__ == "__main__":
+    # Set up the dataplane
+    oftest.dataplane_instance = oftest.dataplane.DataPlane(config)
+    for of_port, ifname in config["port_map"].items():
+        oftest.dataplane_instance.port_add(ifname, of_port)
+
     logging.info("*** TEST RUN START: " + time.asctime())
     result = unittest.TextTestRunner(verbosity=_verb).run(suite)
     if oftest.testutils.skipped_test_count > 0:
@@ -574,6 +579,11 @@
         logging.info("Skipped " + str(oftest.testutils.skipped_test_count) + ts)
         print("Skipped " + str(oftest.testutils.skipped_test_count) + ts)
     logging.info("*** TEST RUN END  : " + time.asctime())
+
+    # Shutdown the dataplane
+    oftest.dataplane_instance.kill()
+    oftest.dataplane_instance = None
+
     if result.failures or result.errors:
         # exit(1) hangs sometimes
         os._exit(1)
diff --git a/src/python/oftest/__init__.py b/src/python/oftest/__init__.py
index c1cbb78..3974e08 100644
--- a/src/python/oftest/__init__.py
+++ b/src/python/oftest/__init__.py
@@ -3,3 +3,7 @@
 # Global config dictionary
 # Populated by oft.
 config = {}
+
+# Global DataPlane instance used by all tests.
+# Populated by oft.
+dataplane_instance = None
diff --git a/src/python/oftest/base_tests.py b/src/python/oftest/base_tests.py
index db9e4a9..38621af 100644
--- a/src/python/oftest/base_tests.py
+++ b/src/python/oftest/base_tests.py
@@ -8,6 +8,7 @@
 import logging
 import unittest
 
+import oftest
 from oftest import config
 import oftest.controller as controller
 import oftest.cstruct as ofp
@@ -95,9 +96,8 @@
     """
     def setUp(self):
         SimpleProtocol.setUp(self)
-        self.dataplane = dataplane.DataPlane(config)
-        for of_port, ifname in config["port_map"].items():
-            self.dataplane.port_add(ifname, of_port)
+        self.dataplane = oftest.dataplane_instance
+        self.dataplane.flush()
 
     def inheritSetup(self, parent):
         """
@@ -111,9 +111,6 @@
     def tearDown(self):
         logging.info("Teardown for simple dataplane test")
         SimpleProtocol.tearDown(self)
-        if hasattr(self, 'dataplane'):
-            self.dataplane.kill()
-            del self.dataplane
         logging.info("Teardown done")
 
     def runTest(self):
@@ -130,14 +127,11 @@
     def setUp(self):
         self.clean_shutdown = True
         logging.info("** START DataPlaneOnly CASE " + str(self))
-        self.dataplane = dataplane.DataPlane(config)
-        for of_port, ifname in config["port_map"].items():
-            self.dataplane.port_add(ifname, of_port)
+        self.dataplane = oftest.dataplane_instance
+        self.dataplane.flush()
 
     def tearDown(self):
         logging.info("Teardown for simple dataplane test")
-        self.dataplane.kill()
-        del self.dataplane
         logging.info("Teardown done")
 
     def runTest(self):
diff --git a/src/python/oftest/dataplane.py b/src/python/oftest/dataplane.py
index d53e223..a5b4e26 100644
--- a/src/python/oftest/dataplane.py
+++ b/src/python/oftest/dataplane.py
@@ -347,3 +347,10 @@
     def port_up(self, port_number):
         """Brings the specified port up"""
         self.ports[port_number].up()
+
+    def flush(self):
+        """
+        Drop any queued packets.
+        """
+        for port_number in self.packet_queues.keys():
+            self.packet_queues[port_number] = []