Merge "Dumping Flows on each test now"
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 1b7c8fd..08f242d 100644
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -431,7 +431,7 @@
main.exit()
def addHostIntent( self, hostIdOne, hostIdTwo, appId='org.onosproject.cli',
- ip="DEFAULT", port="DEFAULT" ):
+ ip="DEFAULT", port="DEFAULT", vlanId="" ):
"""
Description:
Adds a host-to-host intent ( bidirectional ) by
@@ -454,6 +454,9 @@
"constraints": [{"type": "LinkTypeConstraint",
"types": ["OPTICAL"],
"inclusive": 'false' }]}
+ if vlanId:
+ intentJson[ 'selector' ][ 'criteria' ].append( { "type":"VLAN_VID",
+ "vlanId":vlanId } )
output = None
if ip == "DEFAULT":
main.log.warn( "No ip given, reverting to ip from topo file" )
@@ -501,7 +504,8 @@
tcpSrc="",
tcpDst="",
ip="DEFAULT",
- port="DEFAULT" ):
+ port="DEFAULT",
+ vlanId="" ):
"""
Description:
Adds a point-to-point intent ( uni-directional ) by
@@ -599,6 +603,10 @@
intentJson[ 'selector' ][ 'criteria' ].append(
{ "type":"IP_PROTO",
"protocol": ipProto } )
+ if vlanId:
+ intentJson[ 'selector' ][ 'criteria' ].append(
+ { "type":"VLAN_VID",
+ "vlanId": vlanId } )
# TODO: Bandwidth and Lambda will be implemented if needed
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 6443467..61c38b7 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -2207,7 +2207,7 @@
return returnValue
except ( TypeError, ValueError ):
main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
- return None
+ return main.ERROR
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
@@ -2797,7 +2797,7 @@
"""
try:
topology = self.getTopology( topologyResult )
- if topology == {}:
+ if topology == {} or topology == None:
return main.ERROR
output = ""
# Is the number of switches is what we expected
diff --git a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
index f48ae3b..60fc47f 100644
--- a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
+++ b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
@@ -941,8 +941,8 @@
main.step( "VLAN1: Add vlan host intents between h4 and h12" )
main.assertReturnString = "Assertion Result vlan IPV4\n"
- host1 = { "name":"h4","id":"00:00:00:00:00:04/100" }
- host2 = { "name":"h12","id":"00:00:00:00:00:0C/100" }
+ host1 = { "name":"h4","id":"00:00:00:00:00:04/100", "vlanId":"100" }
+ host2 = { "name":"h12","id":"00:00:00:00:00:0C/100", "vlanId":"100" }
testResult = main.FALSE
installResult = main.intentFunction.installHostIntent( main,
name='VLAN1',
@@ -966,32 +966,33 @@
onpass=main.assertReturnString,
onfail=main.assertReturnString )
- main.step( "VLAN2: Add inter vlan host intents between h13 and h20" )
- main.assertReturnString = "Assertion Result different VLAN negative test\n"
- host1 = { "name":"h13" }
- host2 = { "name":"h20" }
- testResult = main.FALSE
- installResult = main.intentFunction.installHostIntent( main,
- name='VLAN2',
- onosNode='0',
- host1=host1,
- host2=host2 )
+ # This step isn't currently possible to perform in the REST API
+ # main.step( "VLAN2: Add inter vlan host intents between h13 and h20" )
+ # main.assertReturnString = "Assertion Result different VLAN negative test\n"
+ # host1 = { "name":"h13" }
+ # host2 = { "name":"h20" }
+ # testResult = main.FALSE
+ # installResult = main.intentFunction.installHostIntent( main,
+ # name='VLAN2',
+ # onosNode='0',
+ # host1=host1,
+ # host2=host2 )
- if installResult:
- testResult = main.intentFunction.testHostIntent( main,
- name='VLAN2',
- intentId = installResult,
- onosNode='0',
- host1=host1,
- host2=host2,
- sw1='s5',
- sw2='s2',
- expectedLink = 18 )
+ # if installResult:
+ # testResult = main.intentFunction.testHostIntent( main,
+ # name='VLAN2',
+ # intentId = installResult,
+ # onosNode='0',
+ # host1=host1,
+ # host2=host2,
+ # sw1='s5',
+ # sw2='s2',
+ # expectedLink = 18 )
- utilities.assert_equals( expect=main.TRUE,
- actual=testResult,
- onpass=main.assertReturnString,
- onfail=main.assertReturnString )
+ # utilities.assert_equals( expect=main.TRUE,
+ # actual=testResult,
+ # onpass=main.assertReturnString,
+ # onfail=main.assertReturnString )
# Change the following to use the REST API when leader checking is
# supported by it
@@ -1194,7 +1195,8 @@
recipients=recipients,
sw1="s5",
sw2="s2",
- expectedLink=18)
+ expectedLink=18,
+ useTCP=True )
utilities.assert_equals( expect=main.TRUE,
actual=testResult,
@@ -1266,23 +1268,22 @@
main.step( "VLAN: Add point intents between h5 and h21" )
main.assertReturnString = "Assertion Result for VLAN IPV4 with mac address point intents\n"
senders = [
- { "name":"h5","device":"of:0000000000000005/5","mac":"00:00:00:00:00:05" }
+ { "name":"h5","device":"of:0000000000000005/5","mac":"00:00:00:00:00:05", "vlanId":"200" }
]
recipients = [
- { "name":"h21","device":"of:0000000000000007/5","mac":"00:00:00:00:00:15" }
+ { "name":"h21","device":"of:0000000000000007/5","mac":"00:00:00:00:00:15", "vlanId":"200" }
]
installResult = main.intentFunction.installPointIntent(
main,
- name="DUALSTACK1",
+ name="VLAN",
senders=senders,
- recipients=recipients,
- ethType="IPV4" )
+ recipients=recipients )
if installResult:
testResult = main.intentFunction.testPointIntent(
main,
intentId=installResult,
- name="DUALSTACK1",
+ name="VLAN",
senders=senders,
recipients=recipients,
sw1="s5",
@@ -1294,6 +1295,8 @@
onpass=main.assertReturnString,
onfail=main.assertReturnString )
+ # TODO: implement VLAN selector REST API intent test once supported
+
main.step( "1HOP: Add point intents between h1 and h3" )
main.assertReturnString = "Assertion Result for 1HOP IPV4 with no mac address point intents\n"
senders = [
diff --git a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
index 4ad42b2..cefb077 100644
--- a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
+++ b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
@@ -75,12 +75,14 @@
if not host2.get( "id" ):
main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )
+ vlanId = host1.get( "vlanId" )
# Adding host intents
main.log.info( itemName + ": Adding host intents" )
intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
- hostIdTwo=host2.get( "id" ) )
+ hostIdTwo=host2.get( "id" ),
+ vlanId=vlanId )
# Get all intents ID in the system, time delay right after intents are added
time.sleep( main.addIntentSleep )
@@ -175,6 +177,7 @@
senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
+ vlanId = host1.get( "vlanId" )
except ( KeyError, TypeError ):
main.log.error( "There was a problem loading the hosts data." )
return main.FALSE
@@ -197,7 +200,7 @@
testResult = main.FALSE
# Check Connectivity
- if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
+ if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
main.assertReturnString += 'Initial Ping Passed\n'
else:
main.assertReturnString += 'Initial Ping Failed\n'
@@ -234,7 +237,7 @@
testResult = main.FALSE
# Check Connection
- if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
+ if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
main.assertReturnString += 'Link Down Pingall Passed\n'
else:
main.assertReturnString += 'Link Down Pingall Failed\n'
@@ -272,7 +275,7 @@
testResult = main.FALSE
# Check Connection
- if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
+ if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
main.assertReturnString += 'Link Up Pingall Passed\n'
else:
main.assertReturnString += 'Link Up Pingall Failed\n'
@@ -357,6 +360,7 @@
if not recipient.get( "device" ):
main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
+ vlanId = senders[ 0 ].get( "vlanId" )
ingressDevice = senders[ 0 ].get( "device" )
@@ -387,7 +391,8 @@
ipSrc=ipSrc,
ipDst=ipDst,
tcpSrc=tcpSrc,
- tcpDst=tcpDst )
+ tcpDst=tcpDst,
+ vlanId=vlanId )
time.sleep( main.addIntentSleep )
intentsId = main.CLIs[ 0 ].getIntentsId()
@@ -422,7 +427,8 @@
tcp="",
sw1="s5",
sw2="s2",
- expectedLink=0):
+ expectedLink=0,
+ useTCP=False ):
"""
Test a Point Intent
@@ -500,6 +506,7 @@
if not recipient.get( "device" ):
main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
+ vlanId=senders[ 0 ].get( "vlanId" )
except (KeyError, TypeError):
main.log.error( "There was a problem loading the hosts data." )
return main.FALSE
@@ -522,7 +529,7 @@
testResult = main.FALSE
# Check Connectivity
- if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
+ if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
main.assertReturnString += 'Initial Ping Passed\n'
else:
main.assertReturnString += 'Initial Ping Failed\n'
@@ -576,7 +583,7 @@
testResult = main.FALSE
# Check Connection
- if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
+ if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
main.assertReturnString += 'Link Down Pingall Passed\n'
else:
main.assertReturnString += 'Link Down Pingall Failed\n'
@@ -614,7 +621,7 @@
testResult = main.FALSE
# Check Connection
- if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
+ if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
else:
main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
@@ -1616,7 +1623,7 @@
main.log.error( "TypeError while populating hostsData" )
return main.FALSE
-def scapyCheckConnection( main, senders, recipients, packet=None, packetFilter=None, expectFailure=False ):
+def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
"""
Checks the connectivity between all given sender hosts and all given recipient hosts
Packet may be specified. Defaults to Ether/IP packet
@@ -1630,7 +1637,8 @@
if not packetFilter:
packetFilter = 'ether host {}'
-
+ if useTCP:
+ packetFilter += ' ip proto \\tcp tcp port {}'.format(main.params[ 'SDNIP' ][ 'dstPort' ])
if expectFailure:
timeout = 1
else:
@@ -1655,17 +1663,31 @@
connectionsFunctional = main.FALSE
continue
- recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
+ if vlanId:
+ recipientComp.startFilter( pktFilter = ( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
+ else:
+ recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
if not packet:
- pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
- senderComp.hostMac,
- senderComp.hostIp,
- recipientComp.hostMac,
- recipientComp.hostIp )
+ if vlanId:
+ pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
+ senderComp.hostMac,
+ senderComp.hostIp,
+ recipientComp.hostMac,
+ recipientComp.hostIp,
+ vlanId )
+ else:
+ pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
+ senderComp.hostMac,
+ senderComp.hostIp,
+ recipientComp.hostMac,
+ recipientComp.hostIp )
else:
pkt = packet
- senderComp.sendPacket( packet = pkt )
+ if vlanId:
+ senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
+ else:
+ senderComp.sendPacket( packet = pkt )
if recipientComp.checkFilter( timeout ):
if expectFailure:
diff --git a/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py b/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py
index ca5e240..b767835 100755
--- a/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py
+++ b/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py
@@ -184,8 +184,8 @@
cliResult = main.TRUE
for i in range( i, main.numCtrls ):
cliResult = cliResult and \
- main.CLIs[ i ].startOnosCli( ONOSIp=main.ONOSip[ i ] )
- main.log.info("ONOSip is: " + main.ONOSip[i])
+ main.ONOScli1.startCellCli( )
+ main.log.info("ONOSip is: " + main.ONOScli1.ip_address)
stepResult = cliResult
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
@@ -204,8 +204,7 @@
main.step("Activate openflow-base App")
app = main.params['CASE10']['app']
- stepResult = main.ONOSbench.onosCli( ONOSIp = main.ONOSip[0],
- cmdstr = "app activate " + app )
+ stepResult = main.ONOScli1.activateApp( app )
time.sleep(main.cfgSleep)
main.log.info(stepResult)
utilities.assert_equals( expect=main.TRUE,
@@ -216,9 +215,9 @@
time.sleep(main.cfgSleep)
- main.step( "Disable AdaptiveFlowSampling ")
- stepResult = main.ONOSbench.onosCfgSet( main.ONOSip[0], "org.onosproject.provider.of.flow.impl.OpenFlowRuleProvider",
- "adaptiveFlowSampling " + main.params['CASE10']['adaptiveFlowenabled'])
+ main.step( "Configure AdaptiveFlowSampling ")
+ stepResult = main.ONOScli1.setCfg( component = "org.onosproject.provider.of.flow.impl.OpenFlowRuleProvider",
+ propName = "adaptiveFlowSampling ", value = main.params['CASE10']['adaptiveFlowenabled'])
utilities.assert_equals( expect=main.TRUE,
actual=stepResult,
onpass="App Configuration Succeeded! ",
diff --git a/TestON/tests/MISC/__init__.py b/TestON/tests/MISC/__init__.py
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/MISC/__init__.py
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/README b/TestON/tests/USECASE/USECASE_ReactiveRouting/README
new file mode 100644
index 0000000..de225b9
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/README
@@ -0,0 +1,6 @@
+Please ask Pingping(pingping@onlab.us) for topology figure.
+
+The default route 0.0.0.0 will have a flow entry look like blow inside the internal switch, which connects host inside SDN network.
+ cookie=0x17000048f91093, duration=3134.048s, table=0, n_packets=1978, n_bytes=193613, idle_age=0, priority=100,ip,in_port=3 actions=mod_dl_dst:00:00:00:00:00:04,output:1
+
+00:00:00:00:00:04 is the next hop peer MAC address.
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/USECASE_ReactiveRoutingI2MN.py b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/USECASE_ReactiveRoutingI2MN.py
new file mode 100755
index 0000000..5fca446
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/USECASE_ReactiveRoutingI2MN.py
@@ -0,0 +1,366 @@
+#!/usr/bin/python
+
+"""
+Set up the SDN-IP topology as same as it on Internet2
+"""
+
+"""
+AS 64513, (SDN AS)
+AS 64514, reachable by 10.0.4.1
+AS 64515, reachable by 10.0.5.1
+AS 64516, reachable by 10.0.6.1
+"""
+
+from mininet.net import Mininet
+from mininet.node import Controller, RemoteController
+from mininet.log import setLogLevel, info
+from mininet.cli import CLI
+from mininet.topo import Topo
+from mininet.util import quietRun
+from mininet.moduledeps import pathCheck
+
+import os.path
+import time
+from subprocess import Popen, STDOUT, PIPE
+
+QUAGGA_DIR = '/usr/lib/quagga'
+QUAGGA_RUN_DIR = '/usr/local/var/run/quagga'
+QUAGGA_CONFIG_DIR = '~/OnosSystemTest/TestON/tests/ReactiveRouting/Dependency/'
+onos1IP = '10.128.4.52'
+numSw = 39
+
+
+class SDNTopo( Topo ):
+ "SDN Topology"
+
+ def __init__( self, *args, **kwargs ):
+
+ Topo.__init__( self, *args, **kwargs )
+
+ # BGP peer hosts
+ peer64514 = self.addHost( 'peer64514' )
+ peer64515 = self.addHost( 'peer64515' )
+ peer64516 = self.addHost( 'peer64516' )
+
+ sw1 = self.addSwitch( 'sw1', dpid = '00000000000000a1' )
+ sw2 = self.addSwitch( 'sw2', dpid = '00000000000000a2' )
+ sw3 = self.addSwitch( 'sw3', dpid = '00000000000000a3' )
+ sw4 = self.addSwitch( 'sw4', dpid = '00000000000000a4' )
+ sw5 = self.addSwitch( 'sw5', dpid = '00000000000000a5' )
+ sw6 = self.addSwitch( 'sw6', dpid = '00000000000000a6' )
+ sw7 = self.addSwitch( 'sw7', dpid = '00000000000000a7' )
+ sw8 = self.addSwitch( 'sw8', dpid = '00000000000000a8' )
+ sw9 = self.addSwitch( 'sw9', dpid = '00000000000000a9' )
+ sw10 = self.addSwitch( 'sw10', dpid = '0000000000000a10' )
+ sw11 = self.addSwitch( 'sw11', dpid = '0000000000000a11' )
+ sw12 = self.addSwitch( 'sw12', dpid = '0000000000000a12' )
+ sw13 = self.addSwitch( 'sw13', dpid = '0000000000000a13' )
+ sw14 = self.addSwitch( 'sw14', dpid = '0000000000000a14' )
+ sw15 = self.addSwitch( 'sw15', dpid = '0000000000000a15' )
+ sw16 = self.addSwitch( 'sw16', dpid = '0000000000000a16' )
+ sw17 = self.addSwitch( 'sw17', dpid = '0000000000000a17' )
+ sw18 = self.addSwitch( 'sw18', dpid = '0000000000000a18' )
+ sw19 = self.addSwitch( 'sw19', dpid = '0000000000000a19' )
+ sw20 = self.addSwitch( 'sw20', dpid = '0000000000000a20' )
+ sw21 = self.addSwitch( 'sw21', dpid = '0000000000000a21' )
+ sw22 = self.addSwitch( 'sw22', dpid = '0000000000000a22' )
+ sw23 = self.addSwitch( 'sw23', dpid = '0000000000000a23' )
+ sw24 = self.addSwitch( 'sw24', dpid = '0000000000000a24' )
+ sw25 = self.addSwitch( 'sw25', dpid = '0000000000000a25' )
+ sw26 = self.addSwitch( 'sw26', dpid = '0000000000000a26' )
+ sw27 = self.addSwitch( 'sw27', dpid = '0000000000000a27' )
+ sw28 = self.addSwitch( 'sw28', dpid = '0000000000000a28' )
+ sw29 = self.addSwitch( 'sw29', dpid = '0000000000000a29' )
+ sw30 = self.addSwitch( 'sw30', dpid = '0000000000000a30' )
+ sw31 = self.addSwitch( 'sw31', dpid = '0000000000000a31' )
+ sw32 = self.addSwitch( 'sw32', dpid = '0000000000000a32' )
+ sw33 = self.addSwitch( 'sw33', dpid = '0000000000000a33' )
+ sw34 = self.addSwitch( 'sw34', dpid = '0000000000000a34' )
+ sw35 = self.addSwitch( 'sw35', dpid = '0000000000000a35' )
+ sw36 = self.addSwitch( 'sw36', dpid = '0000000000000a36' )
+ sw37 = self.addSwitch( 'sw37', dpid = '0000000000000a37' )
+ sw38 = self.addSwitch( 'sw38', dpid = '0000000000000a38' )
+ sw39 = self.addSwitch( 'sw39', dpid = '0000000000000a39' )
+
+
+ # Add a layer2 switch for control plane connectivity
+ # This switch isn't part of the SDN topology
+ # We'll use the ovs-controller to turn this into a learning switch
+ swCtl100 = self.addSwitch( 'swCtl100', dpid = '0000000000000100' )
+
+
+ # BGP speaker hosts
+ speaker1 = self.addHost( 'speaker1' )
+ speaker2 = self.addHost( 'speaker2' )
+
+ root = self.addHost( 'root', inNamespace = False , ip = '0' )
+
+ # hosts behind each AS
+ host64514 = self.addHost( 'host64514' )
+ host64515 = self.addHost( 'host64515' )
+ host64516 = self.addHost( 'host64516' )
+
+ host1 = self.addHost( 'host1' )
+ host2 = self.addHost( 'host2' )
+ host6 = self.addHost( 'host6' )
+ host13 = self.addHost( 'host13' )
+
+ self.addLink( 'speaker1', sw24 )
+ self.addLink( 'speaker2', sw24 )
+
+ # connect all switches
+ self.addLink( sw1, sw2 )
+ self.addLink( sw1, sw6 )
+ self.addLink( sw1, sw8 )
+ self.addLink( sw2, sw3 )
+ self.addLink( sw3, sw4 )
+ self.addLink( sw3, sw5 )
+ self.addLink( sw4, sw8 )
+ self.addLink( sw5, sw7 )
+ self.addLink( sw5, sw9 )
+ self.addLink( sw6, sw13 )
+ self.addLink( sw7, sw8 )
+ self.addLink( sw8, sw11 )
+ self.addLink( sw9, sw10 )
+ self.addLink( sw10, sw12 )
+ self.addLink( sw11, sw12 )
+ self.addLink( sw11, sw14 )
+ self.addLink( sw12, sw17 )
+ self.addLink( sw13, sw14 )
+ self.addLink( sw13, sw21 )
+ self.addLink( sw14, sw15 )
+ self.addLink( sw14, sw18 )
+ self.addLink( sw14, sw23 )
+ self.addLink( sw15, sw16 )
+ self.addLink( sw16, sw17 )
+ self.addLink( sw17, sw19 )
+ self.addLink( sw17, sw20 )
+ self.addLink( sw18, sw23 )
+ self.addLink( sw19, sw27 )
+ self.addLink( sw20, sw28 )
+ self.addLink( sw21, sw22 )
+ self.addLink( sw21, sw29 )
+ self.addLink( sw22, sw23 )
+ self.addLink( sw23, sw24 )
+ self.addLink( sw23, sw31 )
+ self.addLink( sw24, sw25 )
+ self.addLink( sw25, sw26 )
+ self.addLink( sw26, sw27 )
+ self.addLink( sw27, sw28 )
+ self.addLink( sw27, sw34 )
+ self.addLink( sw29, sw30 )
+ self.addLink( sw29, sw35 )
+ self.addLink( sw30, sw31 )
+ self.addLink( sw31, sw32 )
+ self.addLink( sw32, sw33 )
+ self.addLink( sw32, sw39 )
+ self.addLink( sw33, sw34 )
+ self.addLink( sw35, sw36 )
+ self.addLink( sw36, sw37 )
+ self.addLink( sw37, sw38 )
+ self.addLink( sw38, sw39 )
+
+ # connection between switches and peers
+ self.addLink( peer64514, sw32 )
+ self.addLink( peer64515, sw8 )
+ self.addLink( peer64516, sw28 )
+
+ # connection between BGP peer and hosts behind the BGP peer
+ self.addLink( peer64514, host64514 )
+ self.addLink( peer64515, host64515 )
+ self.addLink( peer64516, host64516 )
+
+ self.addLink( sw1, host1 )
+ self.addLink( sw2, host2 )
+ self.addLink( sw6, host6 )
+ self.addLink( sw13, host13 )
+
+ # Internal Connection To Hosts
+ self.addLink( swCtl100, peer64514 )
+ self.addLink( swCtl100, peer64515 )
+ self.addLink( swCtl100, peer64516 )
+ self.addLink( swCtl100, speaker1 )
+ self.addLink( swCtl100, speaker2 )
+
+
+
+ # add host64514 to control plane for ping test
+ self.addLink( swCtl100, host64514 )
+ self.addLink( swCtl100, root )
+
+
+def startsshd( host ):
+ "Start sshd on host"
+ info( '*** Starting sshd\n' )
+ name, intf, ip = host.name, host.defaultIntf(), host.IP()
+ banner = '/tmp/%s.banner' % name
+ host.cmd( 'echo "Welcome to %s at %s" > %s' % ( name, ip, banner ) )
+ host.cmd( '/usr/sbin/sshd -o "Banner %s"' % banner, '-o "UseDNS no"' )
+ info( '***', host.name, 'is running sshd on', intf, 'at', ip, '\n' )
+
+def startsshds ( hosts ):
+ for h in hosts:
+ startsshd( h )
+
+def stopsshd():
+ "Stop *all* sshd processes with a custom banner"
+ info( '*** Shutting down stale sshd/Banner processes ',
+ quietRun( "pkill -9 -f Banner" ), '\n' )
+
+def startquagga( host, num, config_file ):
+ info( '*** Starting Quagga on %s\n' % host )
+ host.cmd( "cd %s" % QUAGGA_CONFIG_DIR )
+ zebra_cmd = \
+ '%s/zebra -d -f ./zebra.conf -z %s/zserv%s.api -i %s/zebra%s.pid'\
+ % ( QUAGGA_DIR, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+ quagga_cmd = '%s/bgpd -d -f %s -z %s/zserv%s.api -i %s/bgpd%s.pid' \
+ % ( QUAGGA_DIR, config_file, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+
+ print zebra_cmd
+ print quagga_cmd
+
+ host.cmd( zebra_cmd )
+ host.cmd( quagga_cmd )
+
+def startquaggahost5( host, num ):
+ info( '*** Starting Quagga on %s\n' % host )
+ zebra_cmd = \
+ '%s/zebra -d -f ./zebra.conf -z %s/zserv%s.api -i %s/zebra%s.pid' \
+ % ( QUAGGA_DIR, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+ quagga_cmd = \
+ '%s/bgpd -d -f ./as4quaggas/quagga%s.conf -z %s/zserv%s.api -i %s/bgpd%s.pid'\
+ % ( QUAGGA_DIR, num, QUAGGA_RUN_DIR, num, QUAGGA_RUN_DIR, num )
+
+ host.cmd( zebra_cmd )
+ host.cmd( quagga_cmd )
+
+
+def stopquagga():
+ quietRun( 'sudo pkill -9 -f bgpd' )
+ quietRun( 'sudo pkill -9 -f zebra' )
+
+def sdn1net():
+ topo = SDNTopo()
+ info( '*** Creating network\n' )
+ # time.sleep( 30 )
+ net = Mininet( topo = topo, controller = RemoteController )
+
+
+ speaker1, speaker2, peer64514, peer64515, peer64516 = \
+ net.get( 'speaker1', 'speaker2' ,
+ 'peer64514', 'peer64515', 'peer64516' )
+
+ # Adding addresses to host64513_1 interface connected to sw24
+ # for BGP peering
+ speaker1.setMAC( '00:00:00:00:00:01', 'speaker1-eth0' )
+ speaker1.cmd( 'ip addr add 10.0.4.101/24 dev speaker1-eth0' )
+ speaker1.cmd( 'ip addr add 10.0.5.101/24 dev speaker1-eth0' )
+ speaker1.cmd( 'ip addr add 10.0.6.101/24 dev speaker1-eth0' )
+
+ speaker1.defaultIntf().setIP( '10.1.4.101/24' )
+ speaker1.defaultIntf().setMAC( '00:00:00:00:00:01' )
+
+ # Net has to be start after adding the above link
+ net.start()
+
+ # setup configuration on the interface connected to switch
+ peer64514.cmd( "ifconfig peer64514-eth0 10.0.4.1 up" )
+ peer64514.setMAC( '00:00:00:00:00:04', 'peer64514-eth0' )
+ peer64515.cmd( "ifconfig peer64515-eth0 10.0.5.1 up" )
+ peer64515.setMAC( '00:00:00:00:00:05', 'peer64515-eth0' )
+ peer64516.cmd( "ifconfig peer64516-eth0 10.0.6.1 up" )
+ peer64516.setMAC( '00:00:00:00:00:06', 'peer64516-eth0' )
+
+ # setup configuration on the interface connected to hosts
+ peer64514.setIP( "4.0.0.254", 8, "peer64514-eth1" )
+ peer64514.setMAC( '00:00:00:00:00:44', 'peer64514-eth1' )
+ peer64515.setIP( "5.0.0.254", 8, "peer64515-eth1" )
+ peer64515.setMAC( '00:00:00:00:00:55', 'peer64515-eth1' )
+ peer64516.setIP( "6.0.0.254", 8, "peer64516-eth1" )
+ peer64516.setMAC( '00:00:00:00:00:66', 'peer64516-eth1' )
+
+ # enable forwarding on BGP peer hosts
+ peer64514.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+ peer64515.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+ peer64516.cmd( 'sysctl net.ipv4.conf.all.forwarding=1' )
+
+ # config interface for control plane connectivity
+ peer64514.setIP( "192.168.0.4", 24, "peer64514-eth2" )
+ peer64515.setIP( "192.168.0.5", 24, "peer64515-eth2" )
+ peer64516.setIP( "192.168.0.6", 24, "peer64516-eth2" )
+
+ # Setup hosts in each non-SDN AS
+ host64514, host64515, host64516 = \
+ net.get( 'host64514', 'host64515', 'host64516' )
+ host64514.cmd( 'ifconfig host64514-eth0 4.0.0.1 up' )
+ host64514.cmd( 'ip route add default via 4.0.0.254' )
+ host64514.setIP( '192.168.0.44', 24, 'host64514-eth1' ) # for control plane
+ host64515.cmd( 'ifconfig host64515-eth0 5.0.0.1 up' )
+ host64515.cmd( 'ip route add default via 5.0.0.254' )
+ host64516.cmd( 'ifconfig host64516-eth0 6.0.0.1 up' )
+ host64516.cmd( 'ip route add default via 6.0.0.254' )
+
+ host1, host2, host6, host13 = \
+ net.get( 'host1', 'host2', 'host6', 'host13' )
+ host1.cmd( 'ifconfig host1-eth0 201.0.0.1 up' )
+ host1.cmd( 'route add default gw 201.0.0.254' )
+ host2.cmd( 'ifconfig host2-eth0 202.0.0.1 up' )
+ host2.cmd( 'route add default gw 202.0.0.254' )
+ host6.cmd( 'ifconfig host6-eth0 206.0.0.1 up' )
+ host6.cmd( 'route add default gw 206.0.0.254' )
+ host13.cmd( 'ifconfig host13-eth0 213.0.0.13 up' )
+ host13.cmd( 'route add default gw 213.0.0.254' )
+
+
+ # set up swCtl100 as a learning
+ swCtl100 = net.get( 'swCtl100' )
+ swCtl100.cmd( 'ovs-vsctl set-controller swCtl100 none' )
+ swCtl100.cmd( 'ovs-vsctl set-fail-mode swCtl100 standalone' )
+
+ # connect all switches to controller
+
+ for i in range ( 1, numSw + 1 ):
+ swX = net.get( 'sw%s' % ( i ) )
+ swX.cmd( 'ovs-vsctl set-controller sw%s tcp:%s:6653' % ( i, onos1IP ) )
+
+ # Start Quagga on border routers
+ '''
+ for i in range ( 64514, 64516 + 1 ):
+ startquagga( 'peer%s' % ( i ), i, 'quagga%s.conf' % ( i ) )
+ '''
+ startquagga( peer64514, 64514, 'quagga64514.conf' )
+ startquagga( peer64515, 64515, 'quagga64515.conf' )
+ startquagga( peer64516, 64516, 'quagga64516.conf' )
+
+ # start Quagga in SDN network
+ startquagga( speaker1, 64513, 'quagga-sdn.conf' )
+
+
+ root = net.get( 'root' )
+ root.intf( 'root-eth0' ).setIP( '1.1.1.2/24' )
+ root.cmd( 'ip addr add 192.168.0.100/24 dev root-eth0' )
+
+ speaker1.intf( 'speaker1-eth1' ).setIP( '1.1.1.1/24' )
+
+
+ stopsshd()
+
+ hosts = [ peer64514, peer64515, peer64516, host64514];
+ startsshds( hosts )
+ #
+
+ forwarding1 = '%s:2000:%s:2000' % ( '1.1.1.2', onos1IP )
+ root.cmd( 'ssh -nNT -o "PasswordAuthentication no" \
+ -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding1, onos1IP ) )
+
+ # time.sleep( 3000000000 )
+ CLI( net )
+
+
+ stopsshd()
+ stopquagga()
+ net.stop()
+
+if __name__ == '__main__':
+ setLogLevel( 'debug' )
+ sdn1net()
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga-sdn.conf b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga-sdn.conf
new file mode 100644
index 0000000..98f2fa2
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga-sdn.conf
@@ -0,0 +1,44 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+!
+router bgp 64513
+ bgp router-id 10.0.4.101
+ timers bgp 1 3
+ !timers bgp 3 9
+ neighbor 10.0.4.1 remote-as 64514
+ neighbor 10.0.4.1 ebgp-multihop
+ neighbor 10.0.4.1 timers connect 5
+ neighbor 10.0.5.1 remote-as 64515
+ neighbor 10.0.5.1 ebgp-multihop
+ neighbor 10.0.5.1 timers connect 5
+ neighbor 10.0.6.1 remote-as 64516
+ neighbor 10.0.6.1 ebgp-multihop
+ neighbor 10.0.6.1 timers connect 5
+
+ neighbor 1.1.1.2 remote-as 64513
+ neighbor 1.1.1.2 port 2000
+ neighbor 1.1.1.2 timers connect 5
+
+ network 201.0.0.0/24
+ network 202.0.0.0/24
+ !network 206.0.0.0/24
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64514.conf b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64514.conf
new file mode 100644
index 0000000..09440af
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64514.conf
@@ -0,0 +1,28 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64514
+ bgp router-id 10.0.4.1
+! timers bgp 1 3
+ neighbor 10.0.4.101 remote-as 64513
+ network 4.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
\ No newline at end of file
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64515.conf b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64515.conf
new file mode 100644
index 0000000..6d0b701
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64515.conf
@@ -0,0 +1,28 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64515
+ bgp router-id 10.0.5.1
+! timers bgp 1 3
+ neighbor 10.0.5.101 remote-as 64513
+ network 5.0.0.0/24
+
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64516.conf b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64516.conf
new file mode 100644
index 0000000..5401c05
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/quagga64516.conf
@@ -0,0 +1,31 @@
+! -*- bgp -*-
+!
+! BGPd sample configuratin file
+!
+! $Id: bgpd.conf.sample,v 1.1 2002/12/13 20:15:29 paul Exp $
+!
+hostname bgpd
+password hello
+!enable password please-set-at-here
+!
+!bgp mulitple-instance
+!
+router bgp 64516
+ bgp router-id 10.0.6.1
+! timers bgp 1 3
+ neighbor 10.0.6.101 remote-as 64513
+ network 6.0.0.0/24
+
+! neighbor 10.0.0.2 route-map set-nexthop out
+! neighbor 10.0.0.2 ebgp-multihop
+! neighbor 10.0.0.2 next-hop-self
+!
+! access-list all permit any
+!
+!route-map set-nexthop permit 10
+! match ip address all
+! set ip next-hop 10.0.0.1
+!
+!log file /usr/local/var/log/quagga/bgpd.log
+!
+log stdout
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/zebra.conf b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/zebra.conf
new file mode 100644
index 0000000..517db94
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/dependencies/zebra.conf
@@ -0,0 +1,26 @@
+! -*- zebra -*-
+!
+! zebra sample configuration file
+!
+! $Id: zebra.conf.sample,v 1.1 2002/12/13 20:15:30 paul Exp $
+!
+hostname zebra
+password hello
+enable password 0fw0rk
+log stdout
+!
+! Interfaces description.
+!
+!interface lo
+! description test of desc.
+!
+!interface sit0
+! multicast
+
+!
+! Static default route sample.
+!
+!ip route 0.0.0.0/0 203.181.89.241
+!
+
+!log file /usr/local/var/log/quagga/zebra.log
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json b/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json
new file mode 100644
index 0000000..cd1065f
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json
@@ -0,0 +1,76 @@
+{
+ "ports" : {
+ "of:00000000000000a8/5" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.5.101/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a32/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.4.101/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a28/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.6.101/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a1/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "201.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a2/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "202.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a6/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "206.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a13/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "213.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ }
+ },
+ "apps" : {
+ "org.onosproject.router" : {
+ "bgp" : {
+ "bgpSpeakers" : [
+ {
+ "connectPoint" : "of:0000000000000a24/1",
+ "peers" : [
+ "10.0.4.1",
+ "10.0.5.1",
+ "10.0.6.1"
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json.withBGP b/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json.withBGP
new file mode 100644
index 0000000..cd1065f
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json.withBGP
@@ -0,0 +1,76 @@
+{
+ "ports" : {
+ "of:00000000000000a8/5" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.5.101/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a32/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.4.101/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a28/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "10.0.6.101/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a1/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "201.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a2/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "202.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a6/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "206.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a13/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "213.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ }
+ },
+ "apps" : {
+ "org.onosproject.router" : {
+ "bgp" : {
+ "bgpSpeakers" : [
+ {
+ "connectPoint" : "of:0000000000000a24/1",
+ "peers" : [
+ "10.0.4.1",
+ "10.0.5.1",
+ "10.0.6.1"
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json.withoutBGP b/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json.withoutBGP
new file mode 100644
index 0000000..8d21d37
--- /dev/null
+++ b/TestON/tests/USECASE/USECASE_ReactiveRouting/network-cfg.json.withoutBGP
@@ -0,0 +1,36 @@
+{
+ "ports" : {
+ "of:00000000000000a1/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "201.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a2/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "202.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:00000000000000a6/3" : {
+ "interfaces" : [
+ {
+ "ips" : [ "206.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ },
+ "of:0000000000000a13/4" : {
+ "interfaces" : [
+ {
+ "ips" : [ "213.0.0.200/24" ],
+ "mac" : "00:00:00:00:00:01"
+ }
+ ]
+ }
+ }
+}