Example #1
0
    def __init__(self, fileName = None, network={'ip':'192.168.1.','netmask':'/24'}, controller = None):
        """
        Create a testbed topology
        :param fileName: filename for configuration (None for hard-coded default)
        :param network: Hash of ip, netmask for host IPv4 address assignment
        :param controller: Controller object (or subclass thereof)
        :return:
        """
        self.hostID = 1
        self.switchID = 1
        self.dpidIndex = 1
        self.nodes = {}
        self.hosts = []
        self.hostIndex = {} # [hostname] = Host
        self.switches = []
        self.switchIndex = {} # [switchname] = Switch
        self.links = [] # all links including those in sites, pops, vpns, and wan
        self.linkIndex = {} # [linkname] = Link
        self.ports = [] # all ports
        self.portIndex = {} # [portname] = Port
        self.sites = []
        self.siteIndex = {} # [sitename] = Site
        self.sitesConfig = []
        self.pops = []
        self.popIndex = {} # [popname] = SDNPop
        self.wan = Wan(name='esnet')
        self.network = network
        if self.network['ip'][-1] == '.':
            self.network['ip'] = self.network['ip'][:-1]
        self.dpidToName = {}
        self.mininetToRealNames = {}
        self.controller = controller

        if fileName != None:
            self.loadConfiguration(fileName)
        else:
            self.locations = locations
            self.sitesConfig = sites
        self.loadDefault()
Example #2
0
class TopoBuilder ():

    debug = False;

    def __init__(self, fileName = None, network={'ip':'192.168.1.','netmask':'/24'}, controller = None):
        """
        Create a testbed topology
        :param fileName: filename for configuration (None for hard-coded default)
        :param network: Hash of ip, netmask for host IPv4 address assignment
        :param controller: Controller object (or subclass thereof)
        :return:
        """
        self.hostID = 1
        self.switchID = 1
        self.dpidIndex = 1
        self.nodes = {}
        self.hosts = []
        self.hostIndex = {} # [hostname] = Host
        self.switches = []
        self.switchIndex = {} # [switchname] = Switch
        self.links = [] # all links including those in sites, pops, vpns, and wan
        self.linkIndex = {} # [linkname] = Link
        self.ports = [] # all ports
        self.portIndex = {} # [portname] = Port
        self.sites = []
        self.siteIndex = {} # [sitename] = Site
        self.sitesConfig = []
        self.pops = []
        self.popIndex = {} # [popname] = SDNPop
        self.wan = Wan(name='esnet')
        self.network = network
        if self.network['ip'][-1] == '.':
            self.network['ip'] = self.network['ip'][:-1]
        self.dpidToName = {}
        self.mininetToRealNames = {}
        self.controller = controller

        if fileName != None:
            self.loadConfiguration(fileName)
        else:
            self.locations = locations
            self.sitesConfig = sites
        self.loadDefault()

    def displaySwitches(self):
        print "\nName\t\t\tDPID\t\tODL Name\tMininet Name\n"
        for sw in self.switches:
            if 'dpid' in sw.props:
                print sw.name,"\t",binascii.hexlify(sw.props['dpid']),"\topenflow:" + str(sw.props['dpid'][7]),"\t",sw.props['mininetName']
        print "\n\n"

    def displayHosts(self,vpn):
        print "\nName\t\tIPv4 Address\tMininet Name\t"
        for host in self.hosts:
            print h.name,"\t",h.props['ip'],"\t",h.props['mininetName']
        print "\n\n"

    def addSwitch(self, switch):
        self.switches.append(switch)
        self.switchIndex[switch.name] = switch

    def addSDNPop(self, popname, hwswitchname, coreroutername, swswitchname, nbOfLinks):
        pop = SDNPop(popname, hwswitchname, coreroutername, swswitchname, nbOfLinks)
        self.addSwitch(pop.props['hwSwitch'])
        self.addSwitch(pop.props['coreRouter'])
        self.addSwitch(pop.props['swSwitch'])
        self.addHost(pop.props['serviceVm'])
        self.addLinks(pop.props['links'])
        self.popIndex[popname] = pop
        self.pops.append(pop)

    def updateHost(self, host):
        host.update(self.getHostParams(host.name))

    def updateSwitch(self, switch):
        switch.update(self.getSwitchParams(switch.name))
        role = switch.get('role')
        if role: # hwSwitch, coreRouter, swSwitch
            switch.update({'controller':self.controller})
    def loadDefault(self):
        """
            We make several simplifying assumptions here:
            1.  All POPs have roughly the same "shape", with a hardware switch, a software switch,
                and a core router.
            2.  The router is simulated by an OpenFlow switch.
            3.  All OpenFlow switches have the same controller object used to access them.
            4.  All OpenFlow switches can be represented by the same object class.
        """
        # init self.pops
        for location in self.locations:
            (popname, hwswitchname, coreroutername, swswitchname, nbOfLinks) = (location[0], location[1], location[2], location[0] + "-ovs", location[3])
            self.addSDNPop(popname, hwswitchname, coreroutername, swswitchname, nbOfLinks)

        # create mesh between core routers, attached to VLANs between the core routers and hardware switches
        self.wan.connectAll(self.pops, 1000)
        self.addLinks(self.wan.props['links'])

        for (sitename, hostnames, popname, portno) in self.sitesConfig:
            site = self.addSite(sitename, popname, portno)
            for name in hostnames:
                hostname = name + "@" + sitename
                host = Host(name=hostname)
                site.addHost(host)
                self.addHost(host)
            self.addLinks(site.props['links'])

        for host in self.hosts:
            self.updateHost(host)
        for switch in self.switches:
            self.updateSwitch(switch)
    def addSite(self, sitename, popname, portno = 0):
        # create the site
        site = Site(sitename)
        self.addSwitch(site.props['siteRouter'])

        # access the pop
        pop = self.popIndex[popname]

        # connect site and pop
        link = Link.create(site.props['siteRouter'], pop.props['coreRouter'])
        link.setPortType('SiteToCore', 'CoreToSite')
        site.setPop(pop, link)
        pop.addSite(site, link, portno)

        self.siteIndex[sitename] = site
        self.sites.append(site)
        return site
    def addHost(self, host):
        self.hosts.append(host)
        self.hostIndex[host.name] = host
    def addHosts(self, hosts):
        for host in hosts:
            self.addHost(host)
    def addLink(self, link):
        self.links.append(link)
        self.linkIndex[link.name] = link
        self.addPort(link.props['endpoints'][0])
        self.addPort(link.props['endpoints'][1])
    def addLinks(self, links):
        for link in links:
            self.addLink(link)
    def addPort(self, port):
        if not port.name in self.portIndex:
            self.ports.append(port)
            self.portIndex[port.name] = port
    def getHostParams(self,name):
        index = self.hostID
        self.hostID +=  1
        mininetName = "h" + str(index)
        self.mininetToRealNames[mininetName] = name
        ip = self.network['ip'] + "." + str(index) + self.network['netmask']
        return {'mininetName' : mininetName, 'ip' : ip, 'mac' : MACAddress(index)}

    def getSwitchParams(self,name):
        index = self.switchID
        self.switchID += 1
        # for mininet
        mininetName = "s" + str(index)
        self.mininetToRealNames[mininetName] = name
        # Create dpid
        index = self.dpidIndex
        self.dpidIndex += 1
        dpid = array('B',struct.unpack("8B", struct.pack("!Q", index)))
        self.dpidToName[binascii.hexlify(dpid)] = name
        return {"mininetName" : mininetName, "dpid" : dpid}


    def loadConfiguration(self,fileName):
        """
        loads the topology Mininet needs to create as described in a file. The format is a dictionary with
        the following structure:


        :param fileName:
        :return:
        """
        f = open(fileName,"r")
        self.config = eval (f.read())
        f.close()