From fbbc602d9efd9f88ce35b09c02f1226881c32bfb Mon Sep 17 00:00:00 2001
From: Marco Capitani <m.capitani@nextworks.it>
Date: Fri, 14 Apr 2017 11:57:47 +0200
Subject: Bugfixing for IRATI prototype and QEMU testbed

---
 rumba/prototypes/enroll.py          | 117 ++++++++++++++
 rumba/prototypes/irati.py           |   3 +-
 rumba/prototypes/irati_rsa          |  27 ++++
 rumba/prototypes/irati_templates.py | 313 +++++++++++++++++++-----------------
 rumba/testbeds/qemu.py              |  27 ++--
 tools/dc-vpns.conf                  | 114 +++++++++++++
 tools/democonf2rumba.py             |   3 +-
 tools/geant2-renumber.conf          |  86 ++++++++++
 tools/insane-stacking.conf          |  29 ++++
 tools/isp-sec.conf                  | 189 ++++++++++++++++++++++
 tools/resilient-square.conf         |  16 ++
 tools/secure-two-layers.conf        |  25 +++
 tools/seven.conf                    |  34 ++++
 tools/star.conf                     |   7 +
 tools/triangle.conf                 |   9 ++
 tools/tutorial1.conf                |   4 +
 tools/tutorial2.conf                |   6 +
 tools/two-layers.conf               |  17 ++
 18 files changed, 863 insertions(+), 163 deletions(-)
 create mode 100755 rumba/prototypes/enroll.py
 create mode 100644 rumba/prototypes/irati_rsa
 create mode 100644 tools/dc-vpns.conf
 create mode 100644 tools/geant2-renumber.conf
 create mode 100644 tools/insane-stacking.conf
 create mode 100644 tools/isp-sec.conf
 create mode 100644 tools/resilient-square.conf
 create mode 100644 tools/secure-two-layers.conf
 create mode 100644 tools/seven.conf
 create mode 100644 tools/star.conf
 create mode 100644 tools/triangle.conf
 create mode 100644 tools/tutorial1.conf
 create mode 100644 tools/tutorial2.conf
 create mode 100644 tools/two-layers.conf

diff --git a/rumba/prototypes/enroll.py b/rumba/prototypes/enroll.py
new file mode 100755
index 0000000..458736a
--- /dev/null
+++ b/rumba/prototypes/enroll.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+#
+# Author: Vincenzo Maffione <v.maffione@nextworks.it>
+#
+
+import argparse
+import socket
+import time
+import re
+
+def printalo(byt):
+    print(repr(byt).replace('\\n', '\n'))
+
+
+def get_response(s):
+    data = bytes()
+    while 1:
+        data += s.recv(1024)
+        lines = str(data).replace('\\n', '\n').split('\n')
+        #print(lines)
+        if lines[-1].find("IPCM") != -1:
+            return lines[:len(lines)-1]
+
+
+description = "Python script to enroll IPCPs"
+epilog = "2016 Vincenzo Maffione <v.maffione@nextworks.it>"
+
+argparser = argparse.ArgumentParser(description = description,
+                                    epilog = epilog)
+argparser.add_argument('--ipcm-conf', help = "Path to the IPCM configuration file",
+                       type = str, required = True)
+argparser.add_argument('--enrollee-name', help = "Name of the enrolling IPCP",
+                       type = str, required = True)
+argparser.add_argument('--dif', help = "Name of DIF to enroll to",
+                       type = str, required = True)
+argparser.add_argument('--lower-dif', help = "Name of the lower level DIF",
+                       type = str, required = True)
+argparser.add_argument('--enroller-name', help = "Name of the remote neighbor IPCP to enroll to",
+                       type = str, required = True)
+args = argparser.parse_args()
+
+socket_name = None
+
+fin = open(args.ipcm_conf, 'r')
+while 1:
+    line = fin.readline()
+    if line == '':
+        break
+
+    m = re.search(r'"(\S+ipcm-console.sock)', line)
+    if m != None:
+        socket_name = m.group(1)
+        break
+fin.close()
+
+if socket_name == None:
+    print('Cannot find %s' % (socket_name))
+    quit(1)
+
+s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+
+connected = False
+trials = 0
+while trials < 4:
+    try:
+        s.connect(socket_name)
+        connected = True
+        break
+    except:
+        pass
+    trials += 1
+    time.sleep(1)
+
+if connected:
+    try:
+        # Receive the banner
+        get_response(s)
+
+        # Send the IPCP list command
+        cmd = 'list-ipcps\n'
+        s.sendall(bytes(cmd, 'ascii'))
+
+        # Get the list of IPCPs and parse it to look for the enroller ID
+        print('Looking up identifier for IPCP %s' % args.enrollee_name)
+        lines = get_response(s)
+        print(lines)
+        enrollee_id = None
+        for line in lines:
+            rs = r'^\s*(\d+)\s*\|\s*' + args.enrollee_name.replace('.', '\\.')
+            m = re.match(rs, line)
+            if m != None:
+                enrollee_id = m.group(1)
+
+        if enrollee_id == None:
+            print('Could not find the ID of enrollee IPCP %s' \
+                    % args.enrollee_name)
+            raise Exception()
+
+        # Send the enroll command
+        cmd = 'enroll-to-dif %s %s %s %s 1\n' \
+                % (enrollee_id, args.dif, args.lower_dif, args.enroller_name)
+        print(cmd)
+
+        s.sendall(bytes(cmd, 'ascii'))
+
+        # Get the enroll command answer
+        lines = get_response(s)
+        print(lines)
+    except:
+        s.close()
+        raise
+
+else:
+    print('Failed to connect to "%s"' % socket_name)
+
+s.close()
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index 44eadb0..dd7086e 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -114,7 +114,8 @@ class Experiment(mod.Experiment):
         gen_files = ' '.join([gen_files_conf, gen_files_bin_full])
 
         sshopts = ('-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'
-                   ' -o IdentityFile=buildroot/irati_rsa')
+                   ' -o IdentityFile=%s'
+                   % (os.path.join(dir_path, 'irati_rsa',)))
         format_args = {'name': name,
                        'ssh': node.ssh_config.port,
                        'username': self.testbed.username,
diff --git a/rumba/prototypes/irati_rsa b/rumba/prototypes/irati_rsa
new file mode 100644
index 0000000..8119a76
--- /dev/null
+++ b/rumba/prototypes/irati_rsa
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyfuwhIYMa2pCcbLYfeDblxaXNxLcJS8aJFjpwPVdXQoTwO79
+BmbZXFObrdxy3paaYyJBAIpOyAcn4B9oEcpHF7J6+IvDA6TpOf45tZzqVRdZxFd7
+ESPlleCpRxTWTmIFiR8j734v8sj0CXYjiegjhS9izhPobjz3ZaTDO4xfQbQs37JF
+7Xdcbjph/8ExqYyvz9yxU5rbCr3u7AurBRM/o5kfV5Ps+52WXNJT2RTjgQjmL1PQ
+0/K8DATPKW9ns1d90Zguf0cE2oZiUn85ukuvVAAOsvO0GOpncFhEUrTLCw/DMayP
+Wk1mjL1jJDeYbqf1cnOG+Wzt5glueKzSGhh6ewIDAQABAoIBAGN62QeMVhWZcjw5
+j7L/ymdxsuxnF5IgzslUGVz1/BPU4MHHc0tx4GA+tZA94T2MA2IL/uPbOs396D/U
+eBc6/yTGvRYpD9V9pXjwo0+1hxx9sbKoO27HtU3KJtVhh+N3F67fbX2JMuhq3PbD
+/uDvOn9gRVOmLnYNBPRE3/s2ObxLtkbT4QIuSF/XItxECBOwWNyTYdOmqhoz6XzA
+OPN9mGsKPMevWoKTfLffuMncIEyEEtV2Jnck/cHPha2GGuzty+faOGSF7GwHOpfu
+DQTK30lUFRmlHnId5UIRG0J+MfSJhk/VillJwvUFmCYgH5Ur7htDTER7JIeU8ym6
+YxY3HDECgYEA+fnqiqmst9LNXnjGnIAtnIi11DsmwDQaxW+kNvXvJsEWWboUbcPs
+q/Fzm0ACMLHARje4wynzIrBY5Iw8qzTswzPFo9CO4MNw/hvMO1iB0Dvo8rWqMJv4
+b2qsuo9r4QkVt53K6WVG/h9Ua/mqr2AQOaATj1ScGKpx0g10GjVqDGcCgYEAztm1
+NKxwqw/j1Pn5AnRRIMkDgO2O6fXKZEgoBdXDWrlHn4vr8fspNE+DMuonQS8GY7Xd
+a+APpPqNk32WKDCfeuKNZX7gXCnV39GOhNrhpfT14/dea1YEQ03vcxVD1aqkw2jl
+Y+qOG2kDBpYkPPEf5od6cfFvUet15d8NBwJXlM0CgYBypkcGNe/7l3mNvMMLAFbr
+FmCe6EpLmRo2N5APjRiUo7aGjKvV9ChWbDVjnSXkA4J2MhRRnqne3RbIK/GfbHSy
+ysn46iy9taXbRhCTn3JaeT/MIbne9YoqP7jdD+6glbQaNQrdpQ+8ec4Uf7vjF6IZ
+a+vMrzewsGvntTfs1VbAPQKBgQCl+8LRkrISQnzzEOfFFWtoYIUENxxgFxCiadhb
+3k2Vhmm32EKr+Xv18vv3pjd7se1xo6UbBD/phfiHatZMR8Ahjpwh3q7Qpe1uXaz8
+ZNt/HVMW7BADF5HyJB7J/T1ivjzaZVj1VWlVC24XIfHQSTjs9rfFqRRH6ya/H75H
+apS23QKBgCj4TWnRtMsEaZZIamgzxMw1eUdYH27ZeaG0Do+hZ1XGixq4CWxCqxVg
+nwbXRkRYwqI+2zzsaeNji4OX6wJdO7lZntuk4v6O0WeY9aJxGaLkYaRk5eF2TLyW
+IVQbpcC/q1fnCo3HjWxR3w8QYmsQi97AC7xUMsjqwntIGV1QrR7s
+-----END RSA PRIVATE KEY-----
diff --git a/rumba/prototypes/irati_templates.py b/rumba/prototypes/irati_templates.py
index 0f3ef05..b8d9788 100644
--- a/rumba/prototypes/irati_templates.py
+++ b/rumba/prototypes/irati_templates.py
@@ -35,189 +35,197 @@ da_map_base = {
 
 
 # Template for a normal DIF configuration file
-normal_dif_base =  {
-    "difType" : "normal-ipc",
-    "dataTransferConstants" : {
-        "addressLength" : 2,
-        "cepIdLength" : 2,
-        "lengthLength" : 2,
-        "portIdLength" : 2,
-        "qosIdLength" : 2,
-        "rateLength" : 4,
-        "frameLength" : 4,
-        "sequenceNumberLength" : 4,
-        "ctrlSequenceNumberLength" : 4,
-        "maxPduSize" : 10000,
-        "maxPduLifetime" : 60000
+normal_dif_base = {
+    "difType": "normal-ipc",
+    "dataTransferConstants": {
+        "addressLength": 2,
+        "cepIdLength": 2,
+        "lengthLength": 2,
+        "portIdLength": 2,
+        "qosIdLength": 2,
+        "rateLength": 4,
+        "frameLength": 4,
+        "sequenceNumberLength": 4,
+        "ctrlSequenceNumberLength": 4,
+        "maxPduSize": 10000,
+        "maxPduLifetime": 60000
     },
 
-    "qosCubes" : [ {
-            "name" : "unreliablewithflowcontrol",
-            "id" : 1,
-            "partialDelivery" : False,
-            "orderedDelivery" : True,
-            "efcpPolicies" : {
-                "dtpPolicySet" : {
-                    "name" : "default",
-                    "version" : "0"
+    "qosCubes": [
+        {
+            "name": "unreliablewithflowcontrol",
+            "id": 1,
+            "partialDelivery": False,
+            "orderedDelivery": True,
+            "efcpPolicies": {
+                "dtpPolicySet": {
+                    "name": "default",
+                    "version": "0"
                 },
-                "initialATimer" : 0,
-                "dtcpPresent" : True,
-                "dtcpConfiguration" : {
-                    "dtcpPolicySet" : {
-                        "name" : "default",
-                        "version" : "0"
+                "initialATimer": 0,
+                "dtcpPresent": True,
+                "dtcpConfiguration": {
+                    "dtcpPolicySet": {
+                        "name": "default",
+                        "version": "0"
                     },
-                    "rtxControl" : False,
-                    "flowControl" : True,
-                    "flowControlConfig" : {
-                        "rateBased" : False,
-                        "windowBased" : True,
-                        "windowBasedConfig" : {
-                            "maxClosedWindowQueueLength" : 10,
-                            "initialCredit" : 200
+                    "rtxControl": False,
+                    "flowControl": True,
+                    "flowControlConfig": {
+                        "rateBased": False,
+                        "windowBased": True,
+                        "windowBasedConfig": {
+                            "maxClosedWindowQueueLength": 10,
+                            "initialCredit": 200
                         }
                     }
                 }
             }
         }, {
-            "name" : "reliablewithflowcontrol",
-            "id" : 2,
-            "partialDelivery" : False,
-            "orderedDelivery" : True,
+            "name": "reliablewithflowcontrol",
+            "id": 2,
+            "partialDelivery": False,
+            "orderedDelivery": True,
             "maxAllowableGap": 0,
-            "efcpPolicies" : {
-                "dtpPolicySet" : {
-                    "name" : "default",
-                    "version" : "0"
+            "efcpPolicies": {
+                "dtpPolicySet": {
+                    "name": "default",
+                    "version": "0"
                 },
-                "initialATimer" : 0,
-                "dtcpPresent" : True,
-                "dtcpConfiguration" : {
-                    "dtcpPolicySet" : {
-                        "name" : "default",
-                        "version" : "0"
+                "initialATimer": 0,
+                "dtcpPresent": True,
+                "dtcpConfiguration": {
+                    "dtcpPolicySet": {
+                        "name": "default",
+                        "version": "0"
                     },
-                    "rtxControl" : True,
-                    "rtxControlConfig" : {
-                        "dataRxmsNmax" : 5,
-                        "initialRtxTime" : 1000
+                    "rtxControl": True,
+                    "rtxControlConfig": {
+                        "dataRxmsNmax": 5,
+                        "initialRtxTime": 1000
                     },
-                    "flowControl" : True,
-                    "flowControlConfig" : {
-                        "rateBased" : False,
-                        "windowBased" : True,
-                        "windowBasedConfig" : {
-                            "maxClosedWindowQueueLength" : 10,
-                            "initialCredit" : 200
+                    "flowControl": True,
+                    "flowControlConfig": {
+                        "rateBased": False,
+                        "windowBased": True,
+                        "windowBasedConfig": {
+                            "maxClosedWindowQueueLength": 10,
+                            "initialCredit": 200
                         }
                     }
                 }
             }
-        } ],
+        }
+    ],
 
     "knownIPCProcessAddresses": [],
 
-    "addressPrefixes" : [ {
-            "addressPrefix" : 0,
-            "organization" : "N.Bourbaki"
+    "addressPrefixes": [
+        {
+            "addressPrefix": 0,
+            "organization": "N.Bourbaki"
         }, {
-            "addressPrefix" : 16,
-            "organization" : "IRATI"
-        } ],
-
-    "rmtConfiguration" : {
-        "pffConfiguration" : {
-            "policySet" : {
-                "name" : "default",
-                "version" : "0"
+            "addressPrefix": 16,
+            "organization": "IRATI"
+        }
+    ],
+
+    "rmtConfiguration": {
+        "pffConfiguration": {
+            "policySet": {
+                "name": "default",
+                "version": "0"
             }
         },
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "enrollmentTaskConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1",
-            "parameters" : [ {
-                "name"  : "enrollTimeoutInMs",
-                "value" : "10000"
-            }, {
-                "name"  : "watchdogPeriodInMs",
-                "value" : "30000"
-            }, {
-                "name"  : "declaredDeadIntervalInMs",
-                "value" : "120000"
-            }, {
-                "name"  : "neighborsEnrollerPeriodInMs",
-                "value" : "0"
-            }, {
-                "name"  : "maxEnrollmentRetries",
-                "value" : "0"
-            } ]
+    "enrollmentTaskConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1",
+            "parameters": [
+                {
+                    "name": "enrollTimeoutInMs",
+                    "value": "10000"
+                }, {
+                    "name": "watchdogPeriodInMs",
+                    "value": "30000"
+                }, {
+                    "name": "declaredDeadIntervalInMs",
+                    "value": "120000"
+                }, {
+                    "name": "neighborsEnrollerPeriodInMs",
+                    "value": "0"
+                }, {
+                    "name": "maxEnrollmentRetries",
+                    "value": "0"
+                }
+            ]
         }
-     },
+    },
 
-    "flowAllocatorConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+    "flowAllocatorConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "namespaceManagerConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+    "namespaceManagerConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "securityManagerConfiguration" : {
-        "policySet" : {
-            "name" : "default",
-            "version" : "1"
+    "securityManagerConfiguration": {
+        "policySet": {
+            "name": "default",
+            "version": "1"
         }
     },
 
-    "resourceAllocatorConfiguration" : {
-        "pduftgConfiguration" : {
-            "policySet" : {
-                "name" : "default",
-                "version" : "0"
+    "resourceAllocatorConfiguration": {
+        "pduftgConfiguration": {
+            "policySet": {
+                "name": "default",
+                "version": "0"
             }
         }
     },
 
-    "routingConfiguration" : {
-        "policySet" : {
-            "name" : "link-state",
-            "version" : "1",
-            "parameters" : [ {
-                    "name"  : "objectMaximumAge",
-                    "value" : "10000"
-                },{
-                    "name"  : "waitUntilReadCDAP",
-                    "value" : "5001"
-                },{
-                    "name"  : "waitUntilError",
-                    "value" : "5001"
-                },{
-                    "name"  : "waitUntilPDUFTComputation",
-                    "value" : "103"
-                },{
-                    "name"  : "waitUntilFSODBPropagation",
-                    "value" : "101"
-                },{
-                    "name"  : "waitUntilAgeIncrement",
-                    "value" : "997"
-                },{
-                    "name"  : "routingAlgorithm",
-                    "value" : "Dijkstra"
-                }]
+    "routingConfiguration": {
+        "policySet": {
+            "name": "link-state",
+            "version": "1",
+            "parameters": [
+                {
+                    "name": "objectMaximumAge",
+                    "value": "10000"
+                }, {
+                    "name": "waitUntilReadCDAP",
+                    "value": "5001"
+                }, {
+                    "name": "waitUntilError",
+                    "value": "5001"
+                }, {
+                    "name": "waitUntilPDUFTComputation",
+                    "value": "103"
+                }, {
+                    "name": "waitUntilFSODBPropagation",
+                    "value": "101"
+                }, {
+                    "name": "waitUntilAgeIncrement",
+                    "value": "997"
+                }, {
+                    "name": "routingAlgorithm",
+                    "value": "Dijkstra"
+                }
+            ]
         }
     }
 }
@@ -237,10 +245,12 @@ def ps_set(d, k, v, parms):
                         d[k]["parameters"][i]["value"] = value
                         break
             else:
-                d[k]["parameters"].append({ 'name': name, 'value': value })
+                d[k]["parameters"].append({'name': name, 'value': value})
 
     elif len(parms) > 0:
-        d[k]["parameters"] = [ { 'name': p.split('=')[0], 'value': p.split('=')[1]} for p in parms ]
+        d[k]["parameters"] = [
+            {'name': p.split('=')[0], 'value': p.split('=')[1]}
+            for p in parms]
 
     d[k]["name"] = v
 
@@ -252,7 +262,8 @@ def dtp_ps_set(d, v, parms):
 
 def dtcp_ps_set(d, v, parms):
     for i in range(len(d["qosCubes"])):
-        ps_set(d["qosCubes"][i]["efcpPolicies"]["dtcpConfiguration"], "dtcpPolicySet", v, parms)
+        ps_set(d["qosCubes"][i]["efcpPolicies"]["dtcpConfiguration"],
+               "dtcpPolicySet", v, parms)
 
 
 policy_translator = {
@@ -267,7 +278,8 @@ policy_translator = {
         d["namespaceManagerConfiguration"], "policySet", v, p),
     'security-manager': lambda d, v, p: ps_set(
         d["securityManagerConfiguration"], "policySet", v, p),
-    'routing': lambda d, v, p: ps_set(d["routingConfiguration"], "policySet", v, p),
+    'routing': lambda d, v, p: ps_set(
+        d["routingConfiguration"], "policySet", v, p),
     'resource-allocator.pduftg': lambda d, v, p: ps_set(
         d["resourceAllocatorConfiguration"], "policySet", v, p),
     'efcp.*.dtcp': None,
@@ -308,7 +320,7 @@ def translate_security_path(d, path, ps, parms):
 
         ps_set(d["default"], tr[component], ps, parms)
 
-    else: # profile is the name of a DIF
+    else:  # profile is the name of a DIF
         if "specific" not in d:
             d["specific"] = []
         j = -1
@@ -317,14 +329,14 @@ def translate_security_path(d, path, ps, parms):
                 j = i
                 break
 
-        if j == -1: # We need to create an entry for the new DIF
-            d["specific"].append({"underlyingDIF" : profile + ".DIF"})
+        if j == -1:  # We need to create an entry for the new DIF
+            d["specific"].append({"underlyingDIF": profile + ".DIF"})
 
         ps_set(d["specific"][j], tr[component], ps, parms)
 
 
 def translate_policy(difconf, path, ps, parms):
-    if path =='efcp.*.dtcp':
+    if path == 'efcp.*.dtcp':
         dtcp_ps_set(difconf, ps, parms)
 
     elif path == 'efcp.*.dtp':
@@ -335,4 +347,3 @@ def translate_policy(difconf, path, ps, parms):
 
     else:
         policy_translator[path](difconf, ps, parms)
-
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index d3e1698..8ccc704 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -76,6 +76,8 @@ class Testbed(mod.Testbed):
             results_queue.put("Command chain ran with %d errors" % errors)
 
     def recover_if_names(self, experiment):
+        next_vlan = 10
+        assigned_vlan = {}
         for node in experiment.nodes:
             for ipcp in node.ipcps:
                 if isinstance(ipcp, mod.ShimEthIPCP):
@@ -88,16 +90,20 @@ class Testbed(mod.Testbed):
                     mac = '00:0a:0a:0a:%02x:%02x' % (vm_id, port_id)
                     print('DEBUG: recovering ifname for port: '
                           + port['tap_id'] + '.')
-                    output = ssh_support.return_commands(
+                    output = ssh_support.execute_command(
                         self,
                         node.ssh_config,
-                        ['mac2ifname ' + mac])
-                    print('DEBUG: output is %s' % output)
-                    if not hasattr(output, '__len__') or len(output) != 1:
-                        raise Exception("Could not retrieve ifname for ipcp %s."
-                                        % ipcp.name)
-                    ipcp.ifname = output[0]
-                    args = {'vlan': int(port['shim'].name), 'port': ipcp.ifname}
+                        'mac2ifname ' + mac)
+                    ipcp.ifname = output
+                    try:
+                        vlan = int(port['shim'].name)
+                    except ValueError:
+                        vlan = assigned_vlan.get(port['shim'].name, None)
+                        if vlan is None:
+                            vlan = next_vlan
+                            next_vlan += 10
+                            assigned_vlan[port['shim'].name] = vlan
+                    args = {'vlan': vlan, 'port': ipcp.ifname}
                     cmds = ['ip link set %(port)s up'
                             % args,
                             'ip link add link %(port)s name %(port)s.%(vlan)s '
@@ -109,7 +115,6 @@ class Testbed(mod.Testbed):
                                                  node.ssh_config,
                                                  cmds)
 
-
     def swap_in(self, experiment):
         """
         :type experiment mod.Experiment
@@ -303,6 +308,10 @@ class Testbed(mod.Testbed):
             print('Sleeping %s secs waiting for the last VMs to boot' % tsleep)
             time.sleep(tsleep)
 
+        # TODO: to be removed, we should loop in the ssh part
+        print('Sleeping 5 seconds, just to be on the safe side')
+        time.sleep(5)
+
         self.recover_if_names(experiment)
 
     def swap_out(self, experiment):
diff --git a/tools/dc-vpns.conf b/tools/dc-vpns.conf
new file mode 100644
index 0000000..8bfde51
--- /dev/null
+++ b/tools/dc-vpns.conf
@@ -0,0 +1,114 @@
+eth 110 100Mbps tor1 spine1
+eth 120 100Mbps tor1 spine2
+eth 11 25Mbps s11 tor1
+eth 12 25Mbps s12 tor1
+eth 13 25Mbps s13 tor1
+eth 14 25Mbps s14 tor1
+eth 15 25Mbps s15 tor1
+eth 16 25Mbps s16 tor1
+eth 17 25Mbps s17 tor1
+eth 18 25Mbps s18 tor1
+eth 210 100Mbps tor2 spine1
+eth 220 100Mbps tor2 spine2
+eth 21 25Mbps s21 tor2
+eth 22 25Mbps s22 tor2
+eth 23 25Mbps s23 tor2
+eth 24 25Mbps s24 tor2
+eth 25 25Mbps s25 tor2
+eth 26 25Mbps s26 tor2
+eth 27 25Mbps s27 tor2
+eth 28 25Mbps s28 tor2
+eth 310 100Mbps tor3 spine1
+eth 320 100Mbps tor3 spine2
+eth 31 25Mbps s31 tor3
+eth 32 25Mbps s32 tor3
+eth 33 25Mbps s33 tor3
+eth 34 25Mbps s34 tor3
+eth 35 25Mbps s35 tor3
+eth 36 25Mbps s36 tor3
+eth 37 25Mbps s37 tor3
+eth 38 25Mbps s38 tor3
+eth 410 100Mbps tor4 spine1
+eth 420 100Mbps tor4 spine2
+eth 41 25Mbps s41 tor4
+eth 42 25Mbps s42 tor4
+eth 43 25Mbps s43 tor4
+eth 44 25Mbps s44 tor4
+eth 45 25Mbps s45 tor4
+eth 46 25Mbps s46 tor4
+eth 47 25Mbps s47 tor4
+eth 48 25Mbps s48 tor4
+
+# DIF dcfabric  
+dif dcfabric tor1 110 120
+dif dcfabric tor2 210 220
+dif dcfabric tor3 310 320
+dif dcfabric tor4 410 420
+dif dcfabric spine1 110 210 310 410
+dif dcfabric spine2 120 220 320 420
+
+# DIF VPN1
+dif vpn1 s11 11
+dif vpn1 s12 12
+dif vpn1 s13 13
+dif vpn1 s14 14
+dif vpn1 tor1 11 12 13 14 dcfabric
+dif vpn1 s21 21
+dif vpn1 s22 22
+dif vpn1 s23 23
+dif vpn1 s24 24
+dif vpn1 tor2 21 22 23 24 dcfabric
+
+# DIF VPN2
+dif vpn2 s31 31
+dif vpn2 s32 32
+dif vpn2 s33 33
+dif vpn2 s34 34
+dif vpn2 tor3 31 32 33 34 dcfabric
+dif vpn2 s41 41
+dif vpn2 s42 42
+dif vpn2 s43 43
+dif vpn2 s44 44
+dif vpn2 tor4 41 42 43 44 dcfabric
+
+# DIF VPN3
+dif vpn3 s15 15
+dif vpn3 s16 16
+dif vpn3 s17 17
+dif vpn3 s18 18
+dif vpn3 tor1 15 16 17 18 dcfabric
+dif vpn3 s25 25
+dif vpn3 s26 26
+dif vpn3 s27 27
+dif vpn3 s28 28
+dif vpn3 tor2 25 26 27 28  dcfabric
+
+# DIF VPN4
+dif vpn4 s35 35
+dif vpn4 s36 36
+dif vpn4 s37 37
+dif vpn4 s38 38
+dif vpn4 tor3 35 36 37 38 dcfabric
+dif vpn4 s45 45
+dif vpn4 s46 46
+dif vpn4 s47 47
+dif vpn4 s48 48
+dif vpn4 tor4 45 46 47 48 dcfabric
+
+#Policies
+
+#Multipath FABRIC
+#policy dcfabric spine1,spine2 rmt.pff multipath
+#policy dcfabric spine1,spine2 routing link-state routingAlgorithm=ECMPDijkstra
+#policy dcfabric * rmt cas-ps q_max=1000
+#policy dcfabric * efcp.*.dtcp cas-ps
+
+#Application to DIF mappings
+#appmap vpn1 traffic.generator.server 1
+#appmap vpn1 rina.apps.echotime.server 1
+#appmap vpn2 traffic.generator.server 1
+#appmap vpn2 rina.apps.echotime.server 1
+#appmap vpn3 traffic.generator.server 1
+#appmap vpn3 rina.apps.echotime.server 1
+#appmap vpn4 traffic.generator.server 1
+#appmap vpn4 rina.apps.echotime.server 1
diff --git a/tools/democonf2rumba.py b/tools/democonf2rumba.py
index d9ea8e7..c708e8e 100755
--- a/tools/democonf2rumba.py
+++ b/tools/democonf2rumba.py
@@ -90,8 +90,7 @@ def make_experiment(filename, experiment_class, experiment_kwargs,
                                       'dif_registrations': {},
                                       'registrations': {}})
                 nodes[vm]['difs'].append(dif)
-                nodes[vm]['dif_registrations'] \
-                         [dif] = dif_list
+                nodes[vm]['dif_registrations'][dif] = dif_list
                 # It is not defined yet, per check above.
 
                 continue
diff --git a/tools/geant2-renumber.conf b/tools/geant2-renumber.conf
new file mode 100644
index 0000000..07c014c
--- /dev/null
+++ b/tools/geant2-renumber.conf
@@ -0,0 +1,86 @@
+eth 2000 100Mbps lisbon madrid
+eth 2001 100Mbps lisbon london
+eth 2002 100Mbps london dublin
+eth 2003 100Mbps london paris
+eth 2004 100Mbps london brussels
+eth 2005 100Mbps paris madrid
+eth 2006 100Mbps paris luxemburg
+eth 2007 100Mbps paris bern
+eth 2008 100Mbps madrid bern
+eth 2009 100Mbps bern roma
+eth 2010 100Mbps roma madrid
+eth 2011 100Mbps brussels amsterdam
+eth 2012 100Mbps roma valleta
+eth 2013 100Mbps amsterdam valleta
+eth 2014 100Mbps bern berlin
+eth 2015 100Mbps luxemburg berlin
+eth 2016 100Mbps amsterdam berlin
+eth 2017 100Mbps amsterdam copenhagen
+eth 2018 100Mbps berlin copenhagen
+eth 2019 100Mbps copenhagen oslo
+eth 2020 100Mbps oslo stockholm
+eth 2021 100Mbps stockholm copenhagen
+eth 2023 100Mbps copenhagen tallin
+eth 2024 100Mbps tallin riga
+eth 2025 100Mbps riga vilnius
+eth 2026 100Mbps vilnius warsaw
+eth 2027 100Mbps warsaw berlin
+eth 2028 100Mbps warsaw praha
+eth 2029 100Mbps berlin praha
+eth 2030 100Mbps berlin viena
+eth 2031 100Mbps praha viena
+eth 2032 100Mbps viena budapest
+eth 2034 100Mbps viena ljubljana
+eth 2035 100Mbps ljubljana zagreb
+eth 2036 100Mbps zagreb budapest
+eth 2037 100Mbps budapest sofia
+eth 2038 100Mbps viena athens
+eth 2039 100Mbps sofia athens
+eth 2040 100Mbps athens roma
+eth 2041 100Mbps sofia bucharest
+eth 2042 100Mbps bucharest budapest
+eth 2043 100Mbps athens nicosia
+eth 2044 100Mbps roma nicosia
+eth 2045 100Mbps sofia ankara
+eth 2046 100Mbps bucharest ankara
+eth 2047 100Mbps berlin moscow
+eth 2048 100Mbps copenhagen moscow
+eth 2049 100Mbps roma viena
+
+# DIF renumber  
+dif renumber lisbon 2000 2001
+dif renumber madrid 2000 2005
+dif renumber london 2001 2002 2003 2004
+dif renumber dublin 2002
+dif renumber paris 2003 2005 2006 2007
+dif renumber brussels 2004 2011
+dif renumber luxemburg 2006 2015
+dif renumber bern 2007 2008 2009 2014
+dif renumber roma 2009 2010 2012 2040 2044 2049
+dif renumber amsterdam 2011 2013 2016 2017
+dif renumber valleta 2012 2013
+dif renumber berlin 2014 2015 2016 2018 2027 2029 2030 2047
+dif renumber copenhagen 2017 2018 2019 2021 2023 2048
+dif renumber oslo 2019 2020
+dif renumber stockholm 2020 2021
+dif renumber tallin 2023 2024
+dif renumber riga 2024 2025
+dif renumber vilnius 2025 2026
+dif renumber warsaw 2026 2027 2028
+dif renumber praha 2028 2029 2031
+dif renumber viena 2030 2031 2032 2034 2038
+dif renumber budapest 2032 2036 2037 2042
+dif renumber athens 2038 2039 2040 2043
+dif renumber ljubljana 2034 2035
+dif renumber zagreb 2035 2036
+dif renumber sofia 2037 2039 2041 2045
+dif renumber bucharest 2041 2042 2046
+dif renumber nicosia 2043 2044
+dif renumber ankara 2045 2046
+dif renumber moscow 2047 2048
+
+#Policies
+
+#address-change
+policy renumber * namespace-manager address-change useNewTimeout=20001 deprecateOldTimeout=80001 changePeriod=120001 addressRange=100
+policy renumber * routing link-state objectMaximumAge=10000 waitUntilReadCDAP=5001 waitUntilError=5001 waitUntilPDUFTComputation=103 waitUntilFSODBPropagation=101 waitUntilAgeIncrement=997 waitUntilDeprecateAddress=20001 routingAlgorithm=Dijkstra
diff --git a/tools/insane-stacking.conf b/tools/insane-stacking.conf
new file mode 100644
index 0000000..8032fea
--- /dev/null
+++ b/tools/insane-stacking.conf
@@ -0,0 +1,29 @@
+eth 300 0Mbps a b
+
+# DIF n1 lays over shim DIF 300
+dif n1 a 300
+dif n1 b 300
+
+# n2 lays over n1
+dif n2 a n1
+dif n2 b n1
+
+# n3 lays over n2
+dif n3 a n2
+dif n3 b n2
+
+# n4 lays over n3
+dif n4 a n3
+dif n4 b n3
+
+# n5 lays over n4
+dif n5 a n4
+dif n5 b n4
+
+# n6 lays over n5
+dif n6 a n5
+dif n6 b n5
+
+# n7 lays over n6
+dif n7 a n6
+dif n7 b n6
diff --git a/tools/isp-sec.conf b/tools/isp-sec.conf
new file mode 100644
index 0000000..33a35a6
--- /dev/null
+++ b/tools/isp-sec.conf
@@ -0,0 +1,189 @@
+eth 110 0Mbps cpe11 ar1
+eth 120 0Mbps cpe12 ar1
+eth 130 0Mbps cpe13 ar1
+eth 210 0Mbps cpe21 ar2
+eth 220 0Mbps cpe22 ar2
+eth 230 0Mbps cpe23 ar2
+eth 310 0Mbps cpe31 ar3
+eth 320 0Mbps cpe32 ar3
+eth 330 0Mbps cpe33 ar3
+eth 100 0Mbps ar1 manpe1
+eth 200 0Mbps ar2 manpe1
+eth 300 0Mbps ar3 manpe2
+eth 410 0Mbps manpe1 manpe2
+eth 411 0Mbps manpe1 manpe3
+eth 412 0Mbps manpe1 manpe4
+eth 420 0Mbps manpe2 manpe3
+eth 421 0Mbps manpe2 manpe4
+eth 430 0Mbps manpe3 manpe4
+eth 510 0Mbps manpe3 ser1
+eth 520 0Mbps manpe4 ser2
+eth 600 0Mbps ser1 core1
+eth 610 0Mbps ser1 core2
+eth 620 0Mbps ser2 core1
+eth 630 0Mbps ser2 core2
+eth 700 0Mbps core1 core2
+eth 710 0Mbps core1 core3
+eth 720 0Mbps core2 core4
+eth 730 0Mbps core3 core4
+eth 640 0Mbps core3 edge1
+eth 650 0Mbps core4 edge1
+eth 660 0Mbps core3 edge2
+eth 670 0Mbps core4 edge2
+eth 800 0Mbps edge1 isp2
+eth 810 0Mbps edge1 isp3
+eth 820 0Mbps edge2 isp4
+eth 830 0Mbps edge2 isp5
+
+# DIF core
+dif core ser1 600 610
+dif core ser2 620 630
+dif core core1 600 620 700 710
+dif core core2 610 630 700 720
+dif core core3 640 660 710 730 
+dif core core4 650 670 720 730
+dif core edge1 640 650
+dif core edge2 660 670
+
+# DIF access
+dif access ar1 100
+dif access ar2 200
+dif access ar3 300
+dif access manpe1 100 200 410 411 412
+dif access manpe2 300 410 420 421
+dif access manpe3 411 420 430 510
+dif access manpe4 412 421 430 520
+dif access ser1 510
+dif access ser2 520
+
+# DIF service
+dif service ar1 access
+dif service ar2 access
+dif service ar3 access
+dif service ser1 access core
+dif service ser2 access core
+dif service edge1 core
+dif service edge2 core
+
+# DIF emall1
+dif emall1 cpe11 110
+dif emall1 cpe12 120
+dif emall1 cpe21 210
+dif emall1 cpe22 220
+dif emall1 cpe31 310
+dif emall1 ar1 110 120 service
+dif emall1 ar2 210 220 service
+dif emall1 ar3 310 service
+dif emall1 edge1 service 800
+dif emall1 edge2 service 820
+dif emall1 isp2 800
+dif emall1 isp4 820
+
+# DIF emall2
+dif emall2 cpe13 130
+dif emall2 cpe23 230
+dif emall2 cpe32 320
+dif emall2 cpe33 330
+dif emall2 ar1 130 service
+dif emall2 ar2 230 service
+dif emall2 ar3 320 330 service
+dif emall2 edge1 service 810
+dif emall2 edge2 service 830
+dif emall2 isp3 810
+dif emall2 isp5 830
+
+#policies
+policy emall1 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
+policy emall1 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate 
+policy emall1 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
+policy emall2 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds/ssh2 keystorePass=test
+policy emall2 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
+policy emall2 ar1,ar2,ar3,edge1,edge2 security-manager.auth.service PSOC_authentication-none
+
+#Enrollments
+enroll access ar1 manpe1 100
+enroll access ar2 manpe1 200
+enroll access ar3 manpe2 300
+enroll access ser1 manpe3 510
+enroll access ser2 manpe4 520
+enroll access manpe1 manpe2 410
+enroll access manpe1 manpe3 411
+enroll access manpe1 manpe4 412
+enroll access manpe2 manpe3 420
+enroll access manpe2 manpe4 421
+enroll access manpe3 manpe4 430
+
+enroll core core1 core2 700
+enroll core core1 core3 710
+enroll core core2 core4 720
+enroll core core3 core4 730
+enroll core ser1 core1 600
+enroll core ser1 core2 610
+enroll core ser2 core1 620
+enroll core ser2 core2 630
+enroll core edge1 core3 640
+enroll core edge1 core4 650
+enroll core edge2 core3 660
+enroll core edge2 core4 670
+
+enroll service edge1 edge2 core
+enroll service edge1 ser1 core
+enroll service edge1 ser2 core
+enroll service edge2 ser1 core
+enroll service edge2 ser2 core
+enroll service ser1 ser2 core
+enroll service ar1 ser1 access
+enroll service ar1 ser2 access
+enroll service ar2 ser1 access
+enroll service ar2 ser2 access
+enroll service ar3 ser1 access
+enroll service ar3 ser2 access
+
+enroll emall1 cpe11 ar1 110
+enroll emall1 cpe12 ar1 120
+enroll emall1 cpe21 ar2 210
+enroll emall1 cpe22 ar2 220
+enroll emall1 cpe31 ar3 310
+enroll emall1 ar1 edge1 service
+enroll emall1 ar1 edge2 service
+enroll emall1 ar2 edge1 service
+enroll emall1 ar2 edge2 service
+enroll emall1 ar3 edge1 service
+enroll emall1 ar3 edge2 service
+enroll emall1 edge1 edge2 service
+enroll emall1 isp2 edge1 800
+enroll emall1 isp4 edge2 820
+
+enroll emall2 cpe13 ar1 130
+enroll emall2 cpe23 ar2 230
+enroll emall2 cpe32 ar3 320
+enroll emall2 cpe33 ar3 330
+enroll emall2 ar1 edge1 service
+enroll emall2 ar1 edge2 service
+enroll emall2 ar2 edge1 service
+enroll emall2 ar2 edge2 service
+enroll emall2 ar3 edge1 service
+enroll emall2 ar3 edge2 service
+enroll emall2 edge1 edge2 service
+enroll emall2 isp3 edge1 810
+enroll emall2 isp5 edge2 830
+
+#Overlays
+overlay ar1 overlays/ispsec/ar1
+overlay ar2 overlays/ispsec/ar2
+overlay ar3 overlays/ispsec/ar3
+overlay cpe11 overlays/ispsec/cpe11
+overlay cpe12 overlays/ispsec/cpe12
+overlay cpe13 overlays/ispsec/cpe13
+overlay cpe21 overlays/ispsec/cpe21
+overlay cpe22 overlays/ispsec/cpe22
+overlay cpe23 overlays/ispsec/cpe23
+overlay cpe31 overlays/ispsec/cpe31
+overlay cpe32 overlays/ispsec/cpe32
+overlay cpe33 overlays/ispsec/cpe33
+overlay edge1 overlays/ispsec/edge1
+overlay edge2 overlays/ispsec/edge2
+overlay isp2 overlays/ispsec/isp2
+overlay isp3 overlays/ispsec/isp3
+overlay isp4 overlays/ispsec/isp4
+overlay isp5 overlays/ispsec/isp5
diff --git a/tools/resilient-square.conf b/tools/resilient-square.conf
new file mode 100644
index 0000000..592b6a5
--- /dev/null
+++ b/tools/resilient-square.conf
@@ -0,0 +1,16 @@
+# a, b and c and d are connected through p2p shim DIFs, in circle.
+# Between a and c there is an additional diagonal link.
+eth 300 100Mbps a b
+eth 400 100Mbps b c
+eth 500 100Mbps c d
+eth 600 1Mbps   d a
+eth 700 100Mbps a c
+
+# DIF n1 spans over the p2p shim DIFs
+dif n1 a 300 600 700
+dif n1 b 300 400
+dif n1 c 400 500 700
+dif n1 d 500 600
+
+# Use LFA policy as PDU Forwarding Function
+policy n1 * rmt.pff lfa
diff --git a/tools/secure-two-layers.conf b/tools/secure-two-layers.conf
new file mode 100644
index 0000000..54c1da6
--- /dev/null
+++ b/tools/secure-two-layers.conf
@@ -0,0 +1,25 @@
+eth 300 0Mbps a b
+eth 400 0Mbps b c
+eth 500 0Mbps c d
+
+# DIF n1 spans a,b and c and runs over the shims
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400
+
+# DIF n2 spans c and d and runs over the shims
+dif n2 c 500
+dif n2 d 500
+
+# DIF n3 spans over n1 and n2
+dif n3 a n1
+dif n3 c n1 n2
+dif n3 d n2
+
+policy n3 * security-manager.auth.default PSOC_authentication-ssh2 keyExchangeAlg=EDH keystore=/creds keystorePass=test
+policy n3 * security-manager.encrypt.default default encryptAlg=AES128 macAlg=SHA256 compressAlg=deflate
+policy n3 * security-manager.ttl.default default initialValue=50
+policy n3 * security-manager.errorcheck.default CRC32
+policy n3 * security-manager.auth.n1 PSOC_authentication-password password=kf05j.a1234.af0k
+policy n3 * security-manager.ttl.n1 default initialValue=50
+policy n3 * security-manager.errorcheck.n1 CRC32
diff --git a/tools/seven.conf b/tools/seven.conf
new file mode 100644
index 0000000..b25f476
--- /dev/null
+++ b/tools/seven.conf
@@ -0,0 +1,34 @@
+# This configuration realizes the following seven-nodes topology
+#
+# MA ---- MB ---- MC --- MD --- ME
+#                 |             |
+#                 MF            MG
+#
+
+# 300 is a shim-eth-vlan DIF, with nodes a and b
+eth 300 0Mbps a b
+
+# 400 is a shim-eth-vlan DIF, with nodes b and c
+eth 400 0Mbps b c
+
+# 500 is a shim-eth-vlan DIF, with nodes c and f
+eth 500 0Mbps c f
+
+# 600 is a shim-eth-vlan DIF, with nodes c and d
+eth 600 0Mbps c d
+
+# 700 is a shim-eth-vlan DIF, with nodes d and e
+eth 700 0Mbps d e
+
+# 800 is a shim-eth-vlan DIF, with nodes e and g
+eth 800 0Mbps e g
+
+# DIF n1 spans over the two shim DIFs
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400 500 600
+dif n1 d 600 700
+dif n1 e 700 800
+dif n1 f 500
+dif n1 g 800
+
diff --git a/tools/star.conf b/tools/star.conf
new file mode 100644
index 0000000..8a4f6ab
--- /dev/null
+++ b/tools/star.conf
@@ -0,0 +1,7 @@
+# a,b and c are in the same L2 domain
+eth 300 0Mbps a b c
+
+# DIF n1 spans over the shim DIF
+dif n1 a 300
+dif n1 b 300
+dif n1 c 300
diff --git a/tools/triangle.conf b/tools/triangle.conf
new file mode 100644
index 0000000..f89811c
--- /dev/null
+++ b/tools/triangle.conf
@@ -0,0 +1,9 @@
+# a, b and c are connected through p2p shim DIFs
+eth 300 10Mbps a b
+eth 400 20Mbps b c
+eth 500 30Mbps a c
+
+# DIF n1 spans over the p2p shim DIFs
+dif n1 a 300 500
+dif n1 b 300 400
+dif n1 c 400 500
diff --git a/tools/tutorial1.conf b/tools/tutorial1.conf
new file mode 100644
index 0000000..8023687
--- /dev/null
+++ b/tools/tutorial1.conf
@@ -0,0 +1,4 @@
+eth 100 0Mbps system1 system2
+
+dif Normal system1 100
+dif Normal system2 100
diff --git a/tools/tutorial2.conf b/tools/tutorial2.conf
new file mode 100644
index 0000000..b43fc17
--- /dev/null
+++ b/tools/tutorial2.conf
@@ -0,0 +1,6 @@
+eth 100 0Mbps system1 system2
+eth 101 0Mbps system2 system3
+
+dif Normal system1 100
+dif Normal system2 100 101
+dif Normal system3 101
diff --git a/tools/two-layers.conf b/tools/two-layers.conf
new file mode 100644
index 0000000..dc1bab2
--- /dev/null
+++ b/tools/two-layers.conf
@@ -0,0 +1,17 @@
+eth 300 0Mbps a b
+eth 400 0Mbps b c
+eth 500 0Mbps c d
+
+# DIF n1 spans a,b and c and runs over the shims
+dif n1 a 300
+dif n1 b 300 400
+dif n1 c 400
+
+# DIF n2 spans c and d and runs over the shims
+dif n2 c 500
+dif n2 d 500
+
+# DIF n3 spans over n1 and n2
+dif n3 a n1
+dif n3 c n1 n2
+dif n3 d n2
-- 
cgit v1.2.3