Previously we handled the error that we faced in the Mininet constructor. Following are the 2 information that is needed by Mininet software in order to establish a connection to multiple controllers:
You mention about the remote controller using --controller=remote,<ip_addr_of_controller>. We thought of extending the same method for specifying multiple IP addresses. Hence, the format we have specified is:
--controller=remote,<ipaddr1>,<ipaddr2>,<ipaddr3>" and so on.
Now, since there is a variation in the input style, we also have to manage the underlying code.
After the command-line parsing in parseArgs() method, the string passed in the RHS of = in the command-line is made available via self.options.controller. We modified the controller creation code with the following:
So,
controller = customConstructor( CONTROLLERS, self.options.controller )
was transformed to:
addresses = self.options.controller.split(',')[1:]
and then append each address into customConstructor in the loop using
controller.append(customConstructor( CONTROLLERS, 'remote,%s' % addresses[i] ) )
Well, this way it's easy to test too. If the user passed a single address, then controller is just an instance of type customConstructor. If he passed multiple addresses, then controller is a list.
For this association, we added multictrl as a command-line input. So a typical multictrl command would appear as:
--multictrl=s1:c0@c1,s2:c2 and so on.
Rules:
self.multiCtrl = switchControlPair( multiCtrl ) if multiCtrl else False
and defined switchControlPair in util.py, where all utility methods are written. The switchControlPair will convert the string s1:c0@c1,s2:c1 into a dictionary as {'s1':['c0', 'c1'], 's2':['c1']} and return this dictionary. This returned dictionary is of not much use to us, we have to create an association between the switch and the controller object, not string. So we will setup another associative array where we will have the controller associated to switch name. So, in the addController method of the same class Mininet, we added the following lines:
In buildFromTopo() method where addController is called, there is a comparison that was already present in the source to check if the controllers taken from user is a list or not, if not then make it to a list. So since we passed the controller as a list in case of multiple remote controllers, we don't have to bother much.
We know that the changes made is consuming more memory, as in, we are associating a copy of the controller object into switchToCtrl. Also we know that we are doing double work of first creating an associative array of strings to strings and using the same for strings to controller objects. Better memory usage and implementation will be managed in further iterations when we confirm that our logic is meeting the results.
The next post will address the execution of the changes made in the code and their results.
- Controllers to which Mininet should connect
- Which switches are connected to which controllers
1. Specifying multiple remote controllers for Mininet
You mention about the remote controller using --controller=remote,<ip_addr_of_controller>. We thought of extending the same method for specifying multiple IP addresses. Hence, the format we have specified is:
--controller=remote,<ipaddr1>,<ipaddr2>,<ipaddr3>" and so on.
Now, since there is a variation in the input style, we also have to manage the underlying code.
After the command-line parsing in parseArgs() method, the string passed in the RHS of = in the command-line is made available via self.options.controller. We modified the controller creation code with the following:
So,
controller = customConstructor( CONTROLLERS, self.options.controller )
was transformed to:
[...] if self.options.controller.split(',')[0] == 'remote': controller = list() length = len(self.options.controller.split(',')) - 1 addresses = self.options.controller.split(',')[1:] for i in range (0, length): controller.append(customConstructor( CONTROLLERS, 'remote,%s' % addresses[i] ) ) else: controller = customConstructor( CONTROLLERS, self.options.controller ) [...]With no intention to disturb the underlying method of customConstructor, we decided to create the controllers one at a time in a loop. Therefore, we first split the left most argument to check if it is remote. If it isn't, it would go back as how normally the controllers are created using customConstructor. If it was remote controller, we further segragate the remaining ip addresses passed by
addresses = self.options.controller.split(',')[1:]
and then append each address into customConstructor in the loop using
controller.append(customConstructor( CONTROLLERS, 'remote,%s' % addresses[i] ) )
Well, this way it's easy to test too. If the user passed a single address, then controller is just an instance of type customConstructor. If he passed multiple addresses, then controller is a list.
2. Switch to Controller association
For this association, we added multictrl as a command-line input. So a typical multictrl command would appear as:
--multictrl=s1:c0@c1,s2:c2 and so on.
Rules:
- Use a switch name first followed by a colon, :, and then the controller name.
- To mention 2 or more controllers then use '@' in between, like, s1:c1@c2@c3
- c0, c1 are actually controllers in which the remote controllers are written.
For eg: --controller=remote,192.168.1.2,192.168.1.3, c0 will take the value as 192.168.1.2 and c1 will take the value as 192.168.1.3
self.multiCtrl = switchControlPair( multiCtrl ) if multiCtrl else False
and defined switchControlPair in util.py, where all utility methods are written. The switchControlPair will convert the string s1:c0@c1,s2:c1 into a dictionary as {'s1':['c0', 'c1'], 's2':['c1']} and return this dictionary. This returned dictionary is of not much use to us, we have to create an association between the switch and the controller object, not string. So we will setup another associative array where we will have the controller associated to switch name. So, in the addController method of the same class Mininet, we added the following lines:
[...] if self.multiCtrl is not False: for switchName, controlList in self.multiCtrl.items(): switchKeys = self.switchToCtrl.keys() if name in controlList: if switchName not in switchKeys: self.switchToCtrl[ switchName ] = list() self.switchToCtrl[switchName].append(controller_new) [...]In the above lines, we collect switchName will be the key and controlList will be the list of controller names. We have another empty associative array called self.switchToCtrl defined in the __init__. We then check the existence of the controller object's "name" created in this method with those in that controlList. If they exist then we check if switchName exists in the keys of switchToCtrl dictionary, switchKeys. If they don't, we create a list() against the switch name, and start appending.
In buildFromTopo() method where addController is called, there is a comparison that was already present in the source to check if the controllers taken from user is a list or not, if not then make it to a list. So since we passed the controller as a list in case of multiple remote controllers, we don't have to bother much.
[...] #the snippet converting the controller variable to a list classes = self.controller if type( classes ) is not list: classes = [ classes ] for i, cls in enumerate( classes ): self.addController( 'c%d' % i, cls ) [...]The for loop then iterates to add those many controllers in the list.
We know that the changes made is consuming more memory, as in, we are associating a copy of the controller object into switchToCtrl. Also we know that we are doing double work of first creating an associative array of strings to strings and using the same for strings to controller objects. Better memory usage and implementation will be managed in further iterations when we confirm that our logic is meeting the results.
The next post will address the execution of the changes made in the code and their results.
No comments:
Post a Comment