def test_004_docker_network_access(self): home = CirqueHome() logger = home.logger ping_cmd = 'ping -w 2 -c 2 -i 0.5' home.create_home({ 'device0': { 'type': 'generic_node_image', }, 'device1': { 'type': 'generic_node_image', }, }) devices = home.get_home_devices() device_ids = list(devices.keys()) device0_id = device_ids[0] device1_id = device_ids[1] device0_ip = \ home.home['devices'][device0_id].description['ipv4_addr'] device1_ip = \ home.home['devices'][device1_id].description['ipv4_addr'] self.assertEqual( host_run(logger, '{} {}'.format(ping_cmd, device0_ip)).returncode, 0) self.__verify_ping_in_container(device0_id, device1_ip, ping_cmd=ping_cmd, should_succeed=False) self.__verify_ping_in_container(device0_id, '8.8.8.8', ping_cmd=ping_cmd, should_succeed=True) internal_node_id = home.add_device({ 'type': 'generic_node_image', 'docker_network': 'internal', }) internal_node_ip = \ home.home['devices'][internal_node_id].description['ipv4_addr'] self.assertEqual( host_run(logger, '{} {}'.format(ping_cmd, internal_node_ip)).returncode, 0) self.__verify_ping_in_container(internal_node_id, '8.8.8.8', ping_cmd=ping_cmd, should_succeed=False) home.destroy_home()
def __add_phy_device_to_container_namespace(self, docker_node): ret = utils.host_run(docker_node.logger, "iw phy {} set netns name {}".format( docker_node.wlan_phy_device, docker_node.name) ) if ret.returncode != 0: raise NameSpaceOperatingError( "failed adding {} to container namespace: {}".format( docker_node.wlan_phy_device, docker_node.name))
def load_kernel_mac80211_hwsim(radios=DEFAULT_RADIOS): logger = CirqueLog.get_cirque_logger() logger.info( "kernel module mac80211_hwsim is not loaded, loading now...") ret = utils.host_run(logger, "modprobe mac80211_hwsim \ radios={}".format(radios)) if ret.returncode != 0: raise LoadKernelError("unable to load module mac80211_hwsim!!") utils.sleep_time(logger, 5, "loading mac80211_hwsim module")
def __create_docker_network(self): # The docker-py library will add a weird route which disconnects # the host when creating networks. The `docker network inspect`isn't # supported neither so we use bash commands directly. cmd = ['docker', 'network', 'create', self.__name] if self.__internal: cmd.append('--internal') ret = host_run(self.logger, cmd) if ret.returncode != 0: self.logger.error('Failed to create home lan %s', self.__name)
def close(self): if self.subnet: cmd = ['docker', 'network', 'rm', self.__name] if host_run(self.logger, cmd).returncode != 0: self.logger.error('Failed to remove home lan %s', self.__name) manipulate_iptable_src_dst_rule( self.logger, self.subnet, self.subnet, 'DROP', add=False) manipulate_iptable_src_dst_rule( self.logger, self.gateway, self.subnet, 'ACCEPT', add=False) manipulate_iptable_src_dst_rule( self.logger, self.subnet, self.gateway, 'ACCEPT', add=False) self.subnet = None self.gateway = None
def __phy_namespace_restore(self, docker_node): self.logger.debug("running phy device namespace restore...") if os.path.isfile(os.path.join(self.RUNTIME_NAMESPACE, docker_node.name)): if hasattr(docker_node, 'phy_device') and docker_node.phy_device: namespace = NetNS(docker_node.name) # return a list ifidx = namespace.link_lookup(ifname='wlan0') # find wlan0 in netns if len(ifidx) != 0: phy_device = docker_node.phy_device commands = [ "ip addr flush dev wlan0", "ip link set wlan0 down", "ip link set wlan0 name {}".format( docker_node.wlan_interface), ] for command in commands: ret = utils.netns_run(docker_node.logger, command, docker_node.name) if ret.returncode != 0: raise IpNetnsExecError( "Error: {} on command: {}".format( ret.stderr, command)) self.logger.debug( "moving out {} device from namespace:{}".format( phy_device, docker_node.name)) ret = utils.netns_run(docker_node.logger, "iw phy {} set netns 1".format( phy_device), docker_node.name) if ret.returncode != 0: raise IpNetnsExecError( "Error: {} on removing {} out of namespace".format( ret.stderr, phy_device)) # del created namespace self.logger.debug( "removing explored namespace: {}".format(docker_node.name)) ret = utils.host_run(docker_node.logger, 'ip netns del {}'.format(docker_node.name)) if ret.returncode != 0: raise NameSpaceOperatingError( "Error: {} on delete netns: {}".format( ret.stderr, docker_node.name))
def __get_available_phy_device(self, docker_node): ret = utils.host_run(self.logger, "iw dev") if ret.stderr != b'': raise PHYDeviceError("Error:{}".format(ret.stderr)) if ret.returncode == 1: raise PHYDeviceError("run out of all the phy devices!") lines = ret.stdout.decode('utf-8').split('\n') lines = [line.strip() for line in lines] lines = [line for line in lines if line.startswith('phy') or line.startswith('Interface')] devices = [(l1, l2.split()[-1]) for l1, l2 in zip(lines, lines[1:]) if l1.startswith('phy')] phy_device, interface = devices.pop() phy_device = ''.join(phy_device.split('#')) docker_node.wlan_phy_device = phy_device docker_node.wlan_interface = interface self.logger.info("container {}: phy device {} interface {}".format( docker_node.name, docker_node.wlan_phy_device, docker_node.wlan_interface))
def __disable_container_mutual_access(self): ret = host_run( self.logger, [ 'docker', 'network', 'inspect', self.__name]) if ret.returncode != 0: self.logger.error('Failed to inspect home lan %s', self.__name) return network_info = json.loads(ret.stdout.decode()) if not network_info: self.logger.error('Failed to inspect home lan %s', self.__name) return network_configs = network_info[0]['IPAM']['Config'] if len(network_configs) != 1: self.logger.error( 'Unexpected network behavior on home lan %s', self.__name) self.subnet = network_configs[0]['Subnet'] self.gateway = network_configs[0]['Gateway'] manipulate_iptable_src_dst_rule( self.logger, self.subnet, self.subnet, 'DROP') manipulate_iptable_src_dst_rule( self.logger, self.gateway, self.subnet, 'ACCEPT') manipulate_iptable_src_dst_rule( self.logger, self.subnet, self.gateway, 'ACCEPT')
def is_mac80211_hwsim_loaded(): ret = utils.host_run(CirqueLog.get_cirque_logger(), "lsmod | grep mac80211_hwsim") return ret.returncode == 0