diff --git a/tools/python/tests/benchmark.py b/tools/python/tests/benchmark.py
index d0e4890ff7dc201b9b345f70d1010a613c7ba03e..401b2cd077d9d42b8dba23521f58faeef7989bd3 100644
--- a/tools/python/tests/benchmark.py
+++ b/tools/python/tests/benchmark.py
@@ -2,7 +2,7 @@
 # Copyright (C) 2015 Savoir-Faire Linux Inc.
 # Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
 
-import sys, subprocess, argparse, time, random, string, math, ipaddress, threading, queue
+import sys, subprocess, argparse, time, random, string, threading, signal
 from pyroute2.netns.process.proxy import NSPopen
 import numpy as np
 import matplotlib.pyplot as plt
@@ -17,9 +17,11 @@ def random_hash():
 parser = argparse.ArgumentParser(description='Create a dummy network interface for testing')
 parser.add_argument('-i', '--ifname', help='interface name', default='ethdht')
 parser.add_argument('-n', '--node-num', help='number of dht nodes to run', type=int, default=32)
-parser.add_argument('-v', '--virtual-locs', help='number of virtual locations', type=int, default=8)
+parser.add_argument('-v', '--virtual-locs', help='number of virtual locations (node clusters)', type=int, default=8)
 parser.add_argument('-l', '--loss', help='simulated cluster packet loss (percent)', type=int, default=0)
 parser.add_argument('-d', '--delay', help='simulated cluster latency (ms)', type=int, default=0)
+parser.add_argument('-no4', '--disable-ipv4', help='Enable IPv4', action="store_true")
+parser.add_argument('-no6', '--disable-ipv6', help='Enable IPv6', action="store_true")
 
 args = parser.parse_args()
 
@@ -29,7 +31,13 @@ node_per_loc = int(args.node_num / clusters)
 print("Launching", args.node_num, "nodes (", clusters, "clusters of", node_per_loc, "nodes)")
 
 if args.virtual_locs > 1:
-    p = subprocess.Popen(["/usr/bin/sudo", "python3", "dummy_if.py", "-i", args.ifname, "-n", str(clusters), '-l', str(args.loss), '-d', str(args.delay)], stdout=subprocess.PIPE)
+    cmd = ["/usr/bin/sudo", "python3", "dummy_if.py", "-i", args.ifname, "-n", str(clusters), '-l', str(args.loss), '-d', str(args.delay)]
+    if not args.disable_ipv4:
+        cmd.append('-4')
+    if not args.disable_ipv6:
+        cmd.append('-6')
+    print(cmd)
+    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     output, err = p.communicate()
     print(output.decode())
 
@@ -38,10 +46,35 @@ bootstrap.resize(1)
 
 procs = [None for _ in range(clusters)]
 
+def start_cluster(i):
+    global procs
+    cmd = ["python3", "dhtnetwork.py", "-n", str(node_per_loc), '-I', args.ifname+str(i)+'.1']
+    if not args.disable_ipv4 and bootstrap.ip4:
+        cmd.extend(['-b', bootstrap.ip4])
+    if not args.disable_ipv6 and bootstrap.ip6:
+        cmd.extend(['-b6', bootstrap.ip6])
+    procs[i] = NSPopen('node'+str(i), cmd)
+    plt.pause(2)
+
+def stop_cluster(i):
+    global procs
+    if procs[i]:
+        try:
+            procs[i].send_signal(signal.SIGINT);
+            procs[i].wait()
+            procs[i].release()
+        except Exception as e:
+            print(e)
+        procs[i] = None
+
+def replace_cluster():
+    n = random.randrange(0, clusters)
+    stop_cluster(n)
+    start_cluster(n)
+
 try:
     for i in range(clusters):
-        procs[i] = NSPopen('node'+str(i), ["python3", "dhtnetwork.py", "-n", str(node_per_loc), "-b", bootstrap.ip4, "-b6", bootstrap.ip6, '-I', args.ifname+str(i)+'.1'])
-        plt.pause(2)
+        start_cluster(i)
 
     plt.ion()
 
@@ -80,17 +113,6 @@ try:
         lines = plt.plot(times, color='blue')
         plt.draw()
 
-    def replace_cluster():
-        n = random.randrange(0, clusters)
-        if procs[n]:
-            print("Terminating process...")
-            try:
-                procs[n].terminate()
-                procs[n].release()
-            except:
-                pass
-        procs[n] = NSPopen('node'+str(n), ["python3", "dhtnetwork.py", "-n", str(node_per_loc), "-b", bootstrap.ip4, "-b6", bootstrap.ip6, '-I', args.ifname+str(n)+'.1'])
-
     plt.pause(5)
 
     plt.show()
@@ -98,15 +120,10 @@ try:
 
     times = []
     for n in range(10):
-        #nnodes = (n+1)*args.node_num
-        #net.resize(nnodes)
-        #time.sleep(2.5)
-        replace_cluster()
-        print("Getting 10 random hashes succesively.")
+        #replace_cluster()
+        plt.pause(2)
+        print("Getting 50 random hashes succesively.")
         for i in range(50):
-            #net.replace_node()
-            #if not (i % 10):
-            #    net.replace_node()
             with lock:
                 done += 1
                 start = time.time()
@@ -121,12 +138,15 @@ try:
 except Exception as e:
     print(e)
 finally:
-    for p in procs:
-        if p:
-            print("Terminating process...")
-            try:
-                p.terminate()
-                p.release()
-            except:
-                pass
+    for i in range(clusters):
+        if procs[i]:
+            procs[i].send_signal(signal.SIGINT);
+    bootstrap.resize(0)
     subprocess.call(["/usr/bin/sudo", "python3", "dummy_if.py", "-i", args.ifname, "-n", str(clusters), "-r"])
+    for i in range(clusters):
+        if procs[i]:
+            try:
+                procs[i].wait()
+                procs[i].release()
+            except Exception as e:
+                print(e)
diff --git a/tools/python/tests/dhtnetwork.py b/tools/python/tests/dhtnetwork.py
index 42bea60e641d0e5b0cd311b44624cb620655758b..3105c62407271fdd310117c75b20256255f04699 100644
--- a/tools/python/tests/dhtnetwork.py
+++ b/tools/python/tests/dhtnetwork.py
@@ -2,7 +2,7 @@
 # Copyright (C) 2015 Savoir-Faire Linux Inc.
 # Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
 
-import signal, os, sys, ipaddress
+import signal, os, sys, ipaddress, random
 from pyroute2 import IPDB
 
 sys.path.append('..')
@@ -68,11 +68,11 @@ class DhtNetwork(object):
     def end_node(self):
         if not self.nodes:
             return
-        random.shuffle(self.nodes)
         n = self.nodes.pop()
         n[1].join()
 
     def replace_node(self):
+        random.shuffle(self.nodes)
         self.end_node()
         self.launch_node()
 
@@ -82,11 +82,12 @@ class DhtNetwork(object):
         if n == l:
             return
         if n > l:
-            print("Launching", n-l, "nodes to reach", n)
+            print("Launching", n-l, "nodes")
             for i in range(l, n):
                 self.launch_node()
         else:
-            print("Ending", l-n, "nodes to reach", n)
+            print("Ending", l-n, "nodes")
+            random.shuffle(self.nodes)
             for i in range(n, l):
                 self.end_node()
 
@@ -107,6 +108,7 @@ if __name__ == '__main__':
     signal.signal(signal.SIGINT, handler)
     signal.signal(signal.SIGTERM, handler)
 
+    net = None
     try:
         parser = argparse.ArgumentParser(description='Create a dht network of -n nodes')
         parser.add_argument('-n', '--node-num', help='number of dht nodes to run', type=int, default=32)
@@ -130,3 +132,6 @@ if __name__ == '__main__':
                 lock.wait()
     except Exception as e:
         pass
+    finally:
+        if net:
+            net.resize(0)
diff --git a/tools/python/tests/dummy_if.py b/tools/python/tests/dummy_if.py
index 993122403b544830e7d9db624bc51b0c4245e2ff..9c1ab110306cfa0e346fdd839ddc33a469a0fa96 100755
--- a/tools/python/tests/dummy_if.py
+++ b/tools/python/tests/dummy_if.py
@@ -13,6 +13,9 @@ parser.add_argument('-n', '--ifnum', type=int, help='interface number', default=
 parser.add_argument('-r', '--remove', help='remove instead of adding the interface', action="store_true")
 parser.add_argument('-l', '--loss', help='simulated packet loss (percent)', type=int, default=0)
 parser.add_argument('-d', '--delay', help='simulated latency (ms)', type=int, default=0)
+parser.add_argument('-4', '--ipv4', help='Enable IPv4', action="store_true")
+parser.add_argument('-6', '--ipv6', help='Enable IPv6', action="store_true")
+
 args = parser.parse_args()
 
 local_addr4 = '10.0.42.'
@@ -28,8 +31,6 @@ try:
             if iface in ip.interfaces:
                 with ip.interfaces[iface] as i:
                     i.remove()
-                #with ip.interfaces[iface+'.1'] as i:
-                #    i.remove()
         if 'tap'+args.ifname in ip.interfaces:
             with ip.interfaces['tap'+args.ifname] as i:
                 i.remove()
@@ -53,8 +54,10 @@ try:
                 iface = args.ifname+str(ifn)
                 i.add_port(ip.interfaces[iface])
             i.add_port(ip.interfaces['tap'+args.ifname])
-            i.add_ip(local_addr4+'1/24')  # the same as i.add_ip('10.0.0.1', 24)
-            i.add_ip(local_addr6+'1/24')
+            if args.ipv4:
+                i.add_ip(local_addr4+'1/24')
+            if args.ipv6:
+                i.add_ip(local_addr6+'1/24')
             i.up()
 
         with ip.interfaces['tap'+args.ifname] as tap:
@@ -76,8 +79,10 @@ try:
                 with ip_ns.interfaces.lo as lo:
                     lo.up()
                 with ip_ns.interfaces[iface1] as i:
-                    i.add_ip(local_addr4+str(ifn+8)+'/24')
-                    i.add_ip(local_addr6+str(ifn+8)+'/64')
+                    if args.ipv4:
+                        i.add_ip(local_addr4+str(ifn+8)+'/24')
+                    if args.ipv6:
+                        i.add_ip(local_addr6+str(ifn+8)+'/64')
                     i.up()
             finally:
                 ip_ns.release()
@@ -88,8 +93,10 @@ try:
             nsp.wait()
             nsp.release()
 
-        subprocess.call(["sysctl", "-w", "net.ipv4.conf."+brige_name+".forwarding=1"])
-        subprocess.call(["sysctl", "-w", "net.ipv6.conf."+brige_name+".forwarding=1"])
+        if args.ipv4:
+            subprocess.call(["sysctl", "-w", "net.ipv4.conf."+brige_name+".forwarding=1"])
+        if args.ipv6:
+            subprocess.call(["sysctl", "-w", "net.ipv6.conf."+brige_name+".forwarding=1"])
 
 except Exception as e:
       print('Error',e)