HIGUCHI Yuta
Committed by Yuta HIGUCHI

ONOS-3422 inter-domain cross connect

- Add network configuration about cross connect port for CO-ONOS
- revised metro.py requires ecord.co app after
  (Change-Id: I3892e780bc6550f8a8d8be622b9fee5322c1dab5)
  to be loaded.
- stop using onos-topo-cfg to send netcfg

Change-Id: Ie90e69c4134d1f71893bf43ee6c290bdbd273aeb
......@@ -83,6 +83,7 @@ public class BasicNetworkConfigs {
return new BasicLinkConfig();
}
},
// TODO move this optical specific configuration out to optical app
new ConfigFactory<ConnectPoint, OpticalPortConfig>(CONNECT_POINT_SUBJECT_FACTORY,
OpticalPortConfig.class,
"optical") {
......
#!/usr/bin/env python
import json
from mininet.net import Mininet
from mininet.node import UserSwitch, DefaultController, RemoteController, Host
from mininet.topo import Topo
from mininet.log import setLogLevel, info
from mininet.log import setLogLevel, info, error, warn
from mininet.cli import CLI
from mininet.link import OVSIntf
from mininet.util import quietRun
from opticalUtils import LINCSwitch, LINCLink
......@@ -33,6 +36,7 @@ class Domain(object):
self.__ctrls[name] = args if args else {}
return name
# Note: This method will return the name of the swich, not the switch object
def addSwitch(self, name, **args):
self.__switches[name] = args if args else {}
return name
......@@ -90,10 +94,12 @@ class OpticalDomain(Domain):
oean = { "optical.regens": 0 }
self.addSwitch('OE%s' % i, dpid='0000ffffffffff0%s' % i, annotations=oean, cls=LINCSwitch)
# ROADM port number OE"1" -> OE'2' = "1"'2'00
# leaving port number up to 100 open for use by Och port
an = { "durable": "true" }
self.addLink('OE1', 'OE2', port1=50, port2=30, annotations=an, cls=LINCLink)
self.addLink('OE2', 'OE3', port1=50, port2=30, annotations=an, cls=LINCLink)
self.addLink('OE3', 'OE1', port1=50, port2=30, annotations=an, cls=LINCLink)
self.addLink('OE1', 'OE2', port1=1200, port2=2100, annotations=an, cls=LINCLink)
self.addLink('OE2', 'OE3', port1=2300, port2=3200, annotations=an, cls=LINCLink)
self.addLink('OE3', 'OE1', port1=3100, port2=1300, annotations=an, cls=LINCLink)
class FabricDomain(Domain):
"""
......@@ -139,10 +145,11 @@ class FabricDomain(Domain):
domains to the core. name: the UserSwitch to connect the OVS to.
"""
self.__tether = self.addSwitch(tname, dpid=tdpid)
# Note: OVS port number '1' reserved for port facing the fabric
self.addLink(tname, name, port1=1)
def getTether(self):
""" get connection point of this fabric to the core """
""" get the switch name of this fabric facing the core """
return self.__tether
......@@ -157,10 +164,6 @@ class IpHost(Host):
self.cmd(mtu)
self.cmd('ip route add default via %s' % self.gateway)
# fixed port numbers for attachment points (APs) between CORD and metro domains
OVS_AP=2
OE_AP=10
def setup(argv):
domains = []
ctlsets = sys.argv[1:]
......@@ -180,6 +183,16 @@ def setup(argv):
for j in range (len(ctls)):
f.addController('c%s%s' % (i,j), controller=RemoteController, ip=ctls[j])
# netcfg for each domains
# Note: Separate netcfg for domain0 is created in opticalUtils
domainCfgs = []
for i in range (0,len(ctlsets)):
cfg = {}
cfg['devices'] = {}
cfg['ports'] = {}
cfg['links'] = {}
domainCfgs.append(cfg)
# make/setup Mininet object
net = Mininet()
for d in domains:
......@@ -187,10 +200,19 @@ def setup(argv):
d.injectInto(net)
# connect COs to core - sort of hard-wired at this moment
# adding cross-connect links
for i in range(1,len(domains)):
an = { "bandwidth": 100000, "durable": "true" }
# add 10 cross-connect links between domains
xcPortNo=2
ochPortNo=10
for j in range(0, 10):
an = { "bandwidth": 10, "durable": "true" }
net.addLink(domains[i].getTether(), d0.getSwitches('OE%s' % i),
port1=OVS_AP, port2=OE_AP, speed=10000, annotations=an, cls=LINCLink)
port1=xcPortNo+j, port2=ochPortNo+j, speed=10000, annotations=an, cls=LINCLink)
xcId = 'of:' + domains[i].getSwitches(name=domains[i].getTether()).dpid + '/' + str(xcPortNo+j)
ochId = 'of:' + d0.getSwitches('OE%s' % i).dpid + '/' + str(ochPortNo+j)
domainCfgs[i]['ports'][xcId] = {'cross-connect': {'remote': ochId}}
# fire everything up
net.build()
......@@ -203,6 +225,22 @@ def setup(argv):
cfgnet.controllers = d0.getControllers()
LINCSwitch.bootOE(cfgnet, d0.getSwitches())
# send netcfg json to each CO-ONOS
for i in range(1,len(domains)):
info('*** Pushing Topology.json to CO-ONOS %d\n' % i)
filename = 'Topology%d.json' % i
with open(filename, 'w') as outfile:
json.dump(domainCfgs[i], outfile, indent=4, separators=(',', ': '))
output = quietRun('%s/tools/test/bin/onos-netcfg %s %s &'\
% (LINCSwitch.onosDir,
domains[i].getControllers()[0].ip,
filename), shell=True)
# successful output contains the two characters '{}'
# if there is more output than this, there is an issue
if output.strip('{}'):
warn('***WARNING: Could not push topology file to ONOS: %s\n' % output)
CLI(net)
net.stop()
LINCSwitch.shutdownOE()
......
......@@ -287,8 +287,8 @@ class LINCSwitch(OpticalSwitch):
with open("crossConnect.json", 'w') as fd:
json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': '))
info('*** Pushing crossConnect.json to ONOS\n')
output = quietRun('%s/tools/test/bin/onos-topo-cfg %s\
Topology.json network/configuration/' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)
output = quietRun('%s/tools/test/bin/onos-netcfg %s\
Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)
def stop_oe(self):
'''
......@@ -455,21 +455,20 @@ class LINCSwitch(OpticalSwitch):
opener.open(url)
urllib2.install_opener(opener)
# focus on just checking the state of devices we're interested in
devlist = map( lambda x: x['uri'], devices )
# expected devices availability map
devMap = dict.fromkeys(map( lambda x: x['uri'], devices ), False)
while True:
response = json.load(urllib2.urlopen(url))
devs = response.get('devices')
# Wait for all devices to be registered. There is a chance that this is only a subgraph.
if (len(devices) == len(devs)):
# Wait for all devices to available
available = True
# update availability map
for d in devs:
if d['id'] in devlist:
available &= d['available']
if available:
break
if devMap.has_key(d['id']):
devMap[d['id']] = d['available']
# Check if all devices we're interested became available
if all(devMap.viewvalues()):
break;
if (time >= TIMEOUT):
error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT)
......@@ -480,7 +479,7 @@ class LINCSwitch(OpticalSwitch):
info('*** Pushing Topology.json to ONOS\n')
for index in range(len(LINCSwitch.controllers)):
output = quietRun('%s/tools/test/bin/onos-topo-cfg %s Topology.json network/configuration/ &'\
output = quietRun('%s/tools/test/bin/onos-netcfg %s Topology.json &'\
% (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].ip), shell=True)
# successful output contains the two characters '{}'
# if there is more output than this, there is an issue
......