def _setup_non_nat_monitoring(self, datapath): """ Setup egress flow to forward traffic to internet GW. Start a thread to figure out MAC address of uplink NAT gw. :param datapath: datapath to install flows. :return: None """ if self._gw_mac_monitor is not None: # No need to multiple probes here. return if self.config.enable_nat is True: self.logger.info("Nat is on") return elif self.config.setup_type != 'LTE': self.logger.info("No GW MAC probe for %s", self.config.setup_type) return else: self.logger.info("Non nat conf: Frequency:%s, egress port: %s, uplink: %s", self.config.non_mat_gw_probe_frequency, self.config.non_nat_arp_egress_port, self._uplink_port) self._dhcp_gw_info = UplinkGatewayInfo(store.GatewayInfoMap()) self._gw_mac_monitor = Thread(target=self._monitor_and_update, args=(datapath,)) self._gw_mac_monitor.setDaemon(True) self._gw_mac_monitor.start() threading.Event().wait(1)
def __init__(self, *, config, recycling_interval: int = DEFAULT_IP_RECYCLE_INTERVAL): """ Initializes a new IP allocator Args: recycling_interval (number): minimum time, in seconds, before a released IP is recycled and freed into the pool of available IPs. Default: None, no recycling will occur automatically. """ persist_to_redis = config.get('persist_to_redis', True) redis_port = config.get('redis_port', 6379) if 'allocator_type' in config: if config['allocator_type'] == 'ip_pool': self.allocator_type = IPAllocatorType.IP_POOL elif config['allocator_type'] == 'dhcp': self.allocator_type = IPAllocatorType.DHCP else: raise ArgumentError("unknown allocator config {}" .format(config['allocator_type'])) else: self.allocator_type = IPAllocatorType.IP_POOL logging.debug('Persist to Redis: %s', persist_to_redis) self._lock = threading.RLock() # re-entrant locks self._recycle_timer = None # reference to recycle timer self._recycling_interval_seconds = recycling_interval if not persist_to_redis: self._assigned_ip_blocks = set() # {ip_block} self.sid_ips_map = defaultdict(IPDesc) # {SID=>IPDesc} else: if not redis_port: raise ValueError( 'Must specify a redis_port in mobilityd config.') client = get_default_client() self._assigned_ip_blocks = store.AssignedIpBlocksSet(client) self.sid_ips_map = store.IPDescDict(client) self.ip_state_map = IpDescriptorMap(persist_to_redis, redis_port) if self.allocator_type == IPAllocatorType.IP_POOL: self.ip_allocator = IpAllocatorStatic(self._assigned_ip_blocks, self.ip_state_map, self.sid_ips_map) elif self.allocator_type == IPAllocatorType.DHCP: dhcp_store = store.MacToIP() # mac => DHCP_State dhcp_gw_info = UplinkGatewayInfo(store.GatewayInfoMap()) iface = config.get('dhcp_iface', 'dhcp0') retry_limit = config.get('retry_limit', 300) self.ip_allocator = IPAllocatorDHCP(self._assigned_ip_blocks, self.ip_state_map, iface=iface, retry_limit=retry_limit, dhcp_store=dhcp_store, gw_info=dhcp_gw_info)
def setUp(self): self._dhcp_gw_info_mock = store.GatewayInfoMap() self._dhcp_gw_info_mock[DHCP_Router_key] = '192.168.128.211' logging.info("set router key [{}]".format(self._dhcp_gw_info_mock[DHCP_Router_key])) """ Starts the thread which launches ryu apps Create a testing bridge, add a port, setup the port interfaces. Then launch the ryu apps for testing pipelined. Gets the references to apps launched by using futures. """ cls = self.__class__ super(InOutNonNatTest, cls).setUpClass() warnings.simplefilter('ignore') cls.setup_uplink_br() cls.service_manager = create_service_manager([]) inout_controller_reference = Future() testing_controller_reference = Future() test_setup = TestSetup( apps=[PipelinedController.InOut, PipelinedController.Testing, PipelinedController.StartupFlows], references={ PipelinedController.InOut: inout_controller_reference, PipelinedController.Testing: testing_controller_reference, PipelinedController.StartupFlows: Future(), }, config={ 'setup_type': 'LTE', 'bridge_name': cls.BRIDGE, 'bridge_ip_address': cls.BRIDGE_IP, 'ovs_gtp_port_number': 32768, 'clean_restart': True, 'enable_nat': False, 'non_mat_gw_probe_frequency': .2, 'non_nat_arp_egress_port': 't_dhcp0', 'ovs_uplink_port_name': 'patch-up' }, mconfig=None, loop=None, service_manager=cls.service_manager, integ_test=False ) BridgeTools.create_bridge(cls.BRIDGE, cls.IFACE) cls.thread = start_ryu_app_thread(test_setup) cls.inout_controller = inout_controller_reference.result() cls.testing_controller = testing_controller_reference.result()
def list_all_record(self, args): """ Print list DHCP and GW records. Args: args: None Returns: None """ for k, v in self.dhcp_client_state.items(): print("mac: %s DHCP state: %s" % (k.replace('_', ':'), str(v))) gw_info = UplinkGatewayInfo(store.GatewayInfoMap()) print("Default GW: %s" % gw_info.get_gw_ip()) print("GW Mac address: %s" % gw_info.get_gw_mac())
def __init__(self, *, config, mconfig, subscriberdb_rpc_stub=None, recycling_interval: int = DEFAULT_IP_RECYCLE_INTERVAL): """ Initializes a new IP allocator Args: recycling_interval (number): minimum time, in seconds, before a released IP is recycled and freed into the pool of available IPs. Default: None, no recycling will occur automatically. """ persist_to_redis = config.get('persist_to_redis', True) redis_port = config.get('redis_port', 6379) self.allocator_type = mconfig.ip_allocator_type logging.debug('Persist to Redis: %s', persist_to_redis) self._lock = threading.RLock() # re-entrant locks self._recycle_timer = None # reference to recycle timer self._recycling_interval_seconds = recycling_interval self.static_ip_enabled = mconfig.static_ip_enabled if not persist_to_redis: self._assigned_ip_blocks = set() # {ip_block} self.sid_ips_map = defaultdict(IPDesc) # {SID=>IPDesc} self._dhcp_gw_info = UplinkGatewayInfo(defaultdict(str)) self._dhcp_store = {} # mac => DHCP_State else: if not redis_port: raise ValueError( 'Must specify a redis_port in mobilityd config.') client = get_default_client() self._assigned_ip_blocks = store.AssignedIpBlocksSet(client) self.sid_ips_map = store.IPDescDict(client) self._dhcp_gw_info = UplinkGatewayInfo(store.GatewayInfoMap()) self._dhcp_store = store.MacToIP() # mac => DHCP_State self.ip_state_map = IpDescriptorMap(persist_to_redis, redis_port) logging.info("Using allocator: %s static ip: %s", self.allocator_type, self.static_ip_enabled) if self.allocator_type == MobilityD.IP_POOL: self._dhcp_gw_info.read_default_gw() ip_allocator = IpAllocatorPool(self._assigned_ip_blocks, self.ip_state_map, self.sid_ips_map) elif self.allocator_type == MobilityD.DHCP: iface = config.get('dhcp_iface', 'dhcp0') retry_limit = config.get('retry_limit', 300) ip_allocator = IPAllocatorDHCP(self._assigned_ip_blocks, self.ip_state_map, iface=iface, retry_limit=retry_limit, dhcp_store=self._dhcp_store, gw_info=self._dhcp_gw_info) if self.static_ip_enabled: self.ip_allocator = IPAllocatorStaticWrapper( subscriberdb_rpc_stub=subscriberdb_rpc_stub, ip_allocator=ip_allocator) else: self.ip_allocator = ip_allocator
def test_ip_alloc(self): sid1 = "IMSI02917" ip1 = self._dhcp_allocator.alloc_ip_address(sid1) threading.Event().wait(2) gw_map = store.GatewayInfoMap() dhcp_gw_info = UplinkGatewayInfo(gw_map) dhcp_store = store.MacToIP() # mac => DHCP_State self.assertEqual(str(dhcp_gw_info.getIP()), "192.168.128.211") self._dhcp_allocator.release_ip_address(sid1, ip1) # wait for DHCP release threading.Event().wait(7) mac1 = create_mac_from_sid(sid1) dhcp_state1 = dhcp_store.get(mac1.as_redis_key()) self.assertEqual(dhcp_state1.state, DHCPState.RELEASE) ip1_1 = self._dhcp_allocator.alloc_ip_address(sid1) threading.Event().wait(2) self.assertEqual(str(ip1), str(ip1_1)) self._dhcp_allocator.release_ip_address(sid1, ip1_1) threading.Event().wait(5) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), []) ip1 = self._dhcp_allocator.alloc_ip_address("IMSI02918") self.assertEqual(str(ip1), "192.168.128.146") self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')]) ip2 = self._dhcp_allocator.alloc_ip_address("IMSI029192") self.assertNotEqual(ip1, ip2) ip3 = self._dhcp_allocator.alloc_ip_address("IMSI0432") self.assertNotEqual(ip1, ip3) self.assertNotEqual(ip2, ip3) # release unallocated IP of SID self._dhcp_allocator.ip_allocator.release_ip("IMSI033", ip3, ip_network("1.1.1.0/24")) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')]) sid4 = "IMSI54321" ip4 = self._dhcp_allocator.alloc_ip_address(sid4) threading.Event().wait(1) self._dhcp_allocator.release_ip_address(sid4, ip4) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')]) # wait for DHCP release threading.Event().wait(7) mac4 = create_mac_from_sid(sid4) dhcp_state = dhcp_store.get(mac4.as_redis_key()) self.assertEqual(dhcp_state.state, DHCPState.RELEASE) ip4_2 = self._dhcp_allocator.alloc_ip_address(sid4) self.assertEqual(ip4, ip4_2) try: self._dhcp_allocator.release_ip_address(sid1, ip1) self.assertEqual("should not", "reach here") except MappingNotFoundError: pass