Usually, a network emulated in Mininet assumes that all of the switches in a network are connected to the same controller(s)
. It is possible to point different switches in the same network to different controllers, as shown in some examples here and here, but I wanted make the procedure of creating such a network less manual, and handle a bit more like the existing Topo and Mininet classes.
What I ended up with was a Domain construct that does the work of pointing different switches in the same Mininet topology to different controllers in a way that fits better with the usual Mininet APIs. A Domain defines a group of switches in a network that are connected to the same (set of) controller(s). A Domain can be built up in a similar way as Topo objects and loaded into the emulated network, and requires no modifications to Mininet to be used.
(For those who come across this page and think this sounds useful, a link to the source is provided here.)
Example 1 – two-domain network.
To use this construct, multiple Domains are loaded into a single Mininet object and then interconnected, resulting in a single network where different parts are controlled by different controllers. For example, if the following topology is desired:
domain 1 : domain 2 : [c1] : [c2] / \ : / \ [sw11]--[sw12]---[sw21]--[sw22] :
The network can be seen as being built of two domains, each with two switches. Then, the following Domain defines a single one of those domains:
class TestDomain(Domain): """ A tiny domain of two nodes connected together """ def build(self): sw1 = 'sw%s1' % self.getId() sw2 = 'sw%s2' % self.getId() self.addSwitch(sw1) self.addSwitch(sw2) self.addLink(sw1, sw2)
And then, given that the TestDomain example is saved in a file called testdomain.py, the following script will construct the full network and start a CLI:
from domains import Domain from testdomain import TestDomain from mininet.net import Mininet from mininet.cli import CLI from mininet.log import setLogLevel, info if __name__ == '__main__': setLogLevel('info') #instantiate and build two TestDomains with Domain IDs '1' and '2' domain1 = TestDomain(1) domain2 = TestDomain(2) domain1.addController('c1') domain2.addController('c2') domain1.build() domain2.build() # add prepared domains to the network, and initialise net = Mininet() domain1.injectInto(net) domain2.injectInto(net) net.build() # connect the domains together Domain.interConnect(domain1.getSwitches('sw12'), domain2.getSwitches('sw21'), net) # start()ing the Domains associates the switches in the domains # with the controllers that had been added to them domain1.start() domain2.start() # start up a CLI, as usual. net.stop() will stop the domains it knows about. CLI(net) net.stop()
For such a small multi-domain network, it might seem overkill – but domains simplify the script given more complex or larger topologies.
At the end of the day, domains are still a hack, so things like connecting two domains is still pretty clunky-looking, even though it’s functional.
Example 2 – building Domains sans child class.
Just like a Topo or Mininet object, you don’t necessarily need a child class of a Domain to build one:
# default ID for a Domain is 0 domain = Domain() domain.addSwitch('sw1', cls=UserSwitch) domain.addSwitch('sw2', cls=UserSwitch) domain.addLink('sw1', 'sw2') # use as above, sans the call to build() domain.injectInto(net) ...
As shown above, normal Mininet API arguments can also be passed into a Domain’s methods. Some things differ slightly, like how the string names of nodes are passed to addLink(). Internally, all that these methods do is store the arguments until injectInto() is called, upon which they are passed to the Mininet object’s mid-level API and realized as Mininet network objects.