diff options
author | Marcel Enguehard <mengueha+fdio@cisco.com> | 2017-07-19 11:26:26 +0200 |
---|---|---|
committer | Marcel Enguehard <mengueha+fdio@cisco.com> | 2017-07-19 11:51:26 +0000 |
commit | 3e6678f9c692553e8902da4d6fb1fe6c087db1f4 (patch) | |
tree | 580a46ca5de22a044319eabb295ad980d50589ec /vicn/resource/ns3/emulated_channel.py | |
parent | 08c4f765cf29dbd6e9a616c542552417eece14fc (diff) |
* GUI resource
* MemIf interface for VPP
* Better netmodel integration
* Draft documentation
* New tutorials
* Improved monitoring and error handling
* Refactored IP addresses and prefixes representation
* Improved image mgmt for LXD
* Various bugfixes and code refactoring
Change-Id: I90da6cf7b5716bc7deb6bf4e24d3f9f01b5a9b0f
Signed-off-by: Marcel Enguehard <mengueha+fdio@cisco.com>
Diffstat (limited to 'vicn/resource/ns3/emulated_channel.py')
-rw-r--r-- | vicn/resource/ns3/emulated_channel.py | 65 |
1 files changed, 39 insertions, 26 deletions
diff --git a/vicn/resource/ns3/emulated_channel.py b/vicn/resource/ns3/emulated_channel.py index 5f61960c..3c090a9e 100644 --- a/vicn/resource/ns3/emulated_channel.py +++ b/vicn/resource/ns3/emulated_channel.py @@ -16,30 +16,33 @@ # limitations under the License. # +import functools import logging import random +from netmodel.model.key import Key from netmodel.model.type import Integer from netmodel.util.socket import check_port from vicn.core.address_mgr import AddressManager -from vicn.core.attribute import Attribute, Multiplicity +from vicn.core.attribute import Attribute, Multiplicity from vicn.core.exception import ResourceNotFound from vicn.core.requirement import Requirement from vicn.core.resource import BaseResource from vicn.core.resource_mgr import wait_resources from vicn.core.task import inline_task, async_task, task from vicn.core.task import BashTask, run_task +from vicn.core.task import inherit_parent from vicn.resource.channel import Channel -from vicn.resource.linux.application import LinuxApplication as Application +from vicn.resource.linux.application import LinuxApplication from vicn.resource.linux.net_device import NetDevice from vicn.resource.linux.tap_device import TapDevice -from vicn.resource.linux.veth_pair import VethPair +from vicn.resource.linux.veth_pair_lxc import VethPairLxc from vicn.resource.lxd.lxc_container import LxcContainer from vicn.resource.node import Node log = logging.getLogger(__name__) -class EmulatedChannel(Channel, Application): +class EmulatedChannel(Channel, LinuxApplication): """EmulatedChannel resource This resources serves as a base class for wireless channels emulated by @@ -56,7 +59,7 @@ class EmulatedChannel(Channel, Application): traffic and prevent loops on the bridge. - We also need that all interfaces related to ap and stations are created before we run the commandline (currently, dynamically adding/removing - AP and stations is not supported by the emulator). This is made + AP and stations is not supported by the emulator). This is made possible thanks to the key=True parameter, which makes sure the attributes are processed before the __create__ is called. @@ -66,11 +69,15 @@ class EmulatedChannel(Channel, Application): __resource_type__ = BaseResource - ap = Attribute(Node, description = 'AP', key = True) + ap = Attribute(Node, description = 'AP') stations = Attribute(Node, description = 'List of stations', - multiplicity = Multiplicity.OneToMany, key = True) + multiplicity = Multiplicity.OneToMany) control_port = Attribute(Integer, description = 'Control port for the simulation') + nb_base_stations = Attribute(Integer, description='Number of nodes emulated by the AP', + default=1) + + __key__ = Key(ap, stations) # Overloaded attributes node = Attribute(requirements = [ @@ -101,20 +108,29 @@ class EmulatedChannel(Channel, Application): # Resource lifecycle #-------------------------------------------------------------------------- + @inherit_parent + def __initialize__(self): + return self.__set_ap() > self.__set_stations() + + @inherit_parent @inline_task def __get__(self): raise ResourceNotFound + + @inherit_parent def __create__(self): # NOTE: http://stackoverflow.com/questions/21141352/python-subprocess- # calling-a-script-which-runs-a-background-process-hanging # The output of the background scripts is still going to the same file # descriptor as the child script, thus the parent script waits for it # to finish. - cmd = '(' + self.__app_name__ + ' ' + self._get_cmdline_params() + \ - '>/dev/null 2>&1) &' - return BashTask(self.node, cmd) + def get_cmdline(channel): + return '(' + channel.__app_name__ + ' ' + \ + channel._get_cmdline_params() + '>/dev/null 2>&1) &' + return BashTask(self.node, functools.partial(get_cmdline, self)) + @inherit_parent def __delete__(self): raise NotImplementedError @@ -123,9 +139,8 @@ class EmulatedChannel(Channel, Application): #-------------------------------------------------------------------------- @async_task - async def _set_ap(self, ap=None): - if ap is None: - ap = self.ap + async def __set_ap(self): + ap = self.ap if ap is None: log.info('Ignored setting ap to None...') return @@ -133,13 +148,13 @@ class EmulatedChannel(Channel, Application): # Add a WiFi interface for the AP... interfaces = list() if isinstance(ap, LxcContainer): - # Ideally, We need to create a VethPair for each station + # Ideally, We need to create a VethPairLxc for each station # This should be monitored for the total channel bw host = NetDevice(node = ap.node, device_name='vhh-' + ap.name + '-' + self.name, monitored = False, managed = False) - self._ap_if = VethPair(node = self.ap, + self._ap_if = VethPairLxc(node = self.ap, name = 'vh-' + ap.name + '-' + self.name, device_name = 'vh-' + ap.name + '-' + self.name, host = host, @@ -171,37 +186,35 @@ class EmulatedChannel(Channel, Application): # Add interfaces to bridge vlan = AddressManager().get('vlan', self, tag='ap') - # AS the container has created the VethPair already without Vlan, we + # AS the container has created the VethPairLxc already without Vlan, we # need to delete and recreate it task = self.node.bridge._remove_interface(self._ap_bridged) await run_task(task, self._state.manager) task = self.node.bridge._add_interface(self._ap_bridged, vlan = vlan) await run_task(task, self._state.manager) + task = self.node.bridge._remove_interface(self._ap_tap) + await run_task(task, self._state.manager) task = self.node.bridge._add_interface(self._ap_tap, vlan = vlan) await run_task(task, self._state.manager) @inline_task - def _get_ap(self): + def __get_ap(self): return {'ap': None} @inline_task - def _get_stations(self): + def __get_stations(self): return {'stations': list()} @async_task - async def _set_stations(self, stations=None): - print('adding stations...') - if stations is None: - stations = self.stations - - for station in stations: + async def __set_stations(self): + for station in self.stations: await self._add_station(station) - def _add_stations(self, stations): + def __add_stations(self, stations): raise NotImplementedError @inline_task - def _remove_stations(self, station): + def __remove_stations(self, station): raise NotImplementedError |