def setUp(self): """ Creates and sets up ICMP monitor """ self.loop = asyncio.get_event_loop() self.subscribers = SubscriberIPTable() self._monitor = ICMPMonitoring(polling_interval=5, service_loop=self.loop, mtr_interface=LOCALHOST)
def GetSubscriberIPTable(self, void, context): """ Get the full subscriber table """ logging.debug("Listing subscriber IP table") resp = SubscriberIPTable() sid_ip_pairs = self._ipv4_allocator.get_sid_ip_table() for subscriber_id, ip in sid_ip_pairs: sid = SIDUtils.to_pb(subscriber_id) version = IPAddress.IPV4 if ip.version == 4 else IPAddress.IPV6 ip_msg = IPAddress(version=version, address=ip.packed) resp.entries.add(sid=sid, ip=ip_msg) return resp
def GetSubscriberIPTable(self, void, context): """ Get the full subscriber table """ logging.debug("Listing subscriber IP table") resp = SubscriberIPTable() csid_ip_pairs = self._ipv4_allocator.get_sid_ip_table() for composite_sid, ip in csid_ip_pairs: #handle composite sid to sid and apn mapping sid, _, apn = composite_sid.partition('.') sid_pb = SIDUtils.to_pb(sid) version = IPAddress.IPV4 if ip.version == 4 else IPAddress.IPV6 ip_msg = IPAddress(version=version, address=ip.packed) resp.entries.add(sid=sid_pb, ip=ip_msg, apn=apn) return resp
def GetSubscriberIPTable(self, request, context): """ Get the full subscriber table """ logging.debug("Received GetSubscriberIPTable") self._print_grpc(request) resp = SubscriberIPTable() csid_ip_pairs = self._ip_address_man.get_sid_ip_table() for composite_sid, ip in csid_ip_pairs: # handle composite sid to sid and apn mapping sid, _, apn_part = composite_sid.partition('.') apn, *_ = apn_part.split(',') sid_pb = SIDUtils.to_pb(sid) version = IPAddress.IPV4 if ip.version == 4 else IPAddress.IPV6 ip_msg = IPAddress(version=version, address=ip.packed) resp.entries.add(sid=sid_pb, ip=ip_msg, apn=apn) self._print_grpc(resp) return resp
def test_process_deleted_subscriber(self): """ With usage polling on, send packets to install metering flows and delete one of them by removing the subscriber from the subscriber ip table. Verifies that the metering flows for the subscriber is deleted after the correct usage is reported. """ # Set up subscribers sub1 = SubContextConfig('IMSI001010000000013', '192.168.128.74', self._tbl_num) sub2 = SubContextConfig('IMSI001010000000014', '192.168.128.75', self._tbl_num) isolator1 = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub1).build_requests(), self.testing_controller, ) isolator2 = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub2).build_requests(), self.testing_controller, ) # Set up packets pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ _make_default_pkt(self.MAC_DEST, '45.10.0.1', sub1.ip), _make_default_pkt(self.MAC_DEST, '45.10.0.3', sub2.ip), ] # Initialize subscriber list in subscriber controller. subscriber_ip_table = SubscriberIPTable() subscriber_ip_table.entries.extend([ SubscriberIPTableEntry(sid=SubscriberID(id='IMSI001010000000013')), SubscriberIPTableEntry(sid=SubscriberID(id='IMSI001010000000014')), ]) fut = Future() fut.set_result(subscriber_ip_table) self.subscriber_controller._poll_subscriber_list_done(fut) # Verify that after the poll, flows for subscriber 1 and 2 are # installed and the second pair of packets sent are matched. sub1_query = RyuDirectFlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch(imsi=encode_imsi('IMSI001010000000013'))) sub2_query = RyuDirectFlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch(imsi=encode_imsi('IMSI001010000000014'))) flow_verifier = FlowVerifier([ FlowTest(sub1_query, 1, 2), FlowTest(sub2_query, 1, 2), ], lambda: None) # Send packets through pipeline and wait. with isolator1, isolator2, flow_verifier: # Send packets to create the metering flows. Note that these # packets will not be matched because the test setup does not # support outputting to port. for pkt in packets: pkt_sender.send(pkt) wait_after_send(self.testing_controller) # Update the subscriber list to delete subscriber 2. subscriber_ip_table = SubscriberIPTable() subscriber_ip_table.entries.extend([ SubscriberIPTableEntry(sid=SubscriberID( id='IMSI001010000000013')), ]) fut = Future() fut.set_result(subscriber_ip_table) self.subscriber_controller._poll_subscriber_list_done(fut) # Send another pair of packets which will be matched. for pkt in packets: pkt_sender.send(pkt) wait_after_send(self.testing_controller) # Temporarily mock out _handle_flow_stats because flow_verifier # sends a stats request to the meter table, which will trigger # the deletion prematurely. handle_flow_stats = self.subscriber_controller._handle_flow_stats self.subscriber_controller._handle_flow_stats = MagicMock() flow_verifier.verify() self.subscriber_controller._handle_flow_stats = handle_flow_stats # Verify that after the usage is reported, the flows for subscriber 2 # are deleted. sub1_record = UsageRecord() sub1_record.bytes_tx = len(packets[0]) sub2_record = UsageRecord() sub2_record.bytes_tx = len(packets[1]) target_usage = { 'IMSI001010000000013': sub1_record, 'IMSI001010000000014': sub2_record, } flow_verifier = FlowVerifier([ FlowTest(sub1_query, 0, 2), FlowTest(sub2_query, 0, 0), ], lambda: wait_for_meter_stats(self.stats_controller, target_usage)) with flow_verifier: self._poll_stats() flow_verifier.verify()
def test_process_deleted_subscriber(self): """ With usage polling off, send packets to install metering flows and delete one of them by removing the subscriber from the subscriber ip table. Verifies that the metering flows for the subscriber is deleted when the subscriber is deleted. """ # Set up subscribers sub1 = SubContextConfig('IMSI001010000000013', '192.168.128.74', self._tbl_num) sub2 = SubContextConfig('IMSI001010000000014', '192.168.128.75', self._tbl_num) isolator1 = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub1).build_requests(), self.testing_controller, ) isolator2 = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub2).build_requests(), self.testing_controller, ) # Set up packets pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ _make_default_pkt(self.MAC_DEST, '45.10.0.1', sub1.ip), _make_default_pkt(self.MAC_DEST, '45.10.0.3', sub2.ip), ] # Initialize subscriber list in subscriber controller. subscriber_ip_table = SubscriberIPTable() subscriber_ip_table.entries.extend([ SubscriberIPTableEntry(sid=SubscriberID(id='IMSI001010000000013')), SubscriberIPTableEntry(sid=SubscriberID(id='IMSI001010000000014')), ]) fut = Future() fut.set_result(subscriber_ip_table) self.subscriber_controller._poll_subscriber_list_done(fut) # Verify that after the poll, subscriber 2 flows are deleted while # subscriber 1 flows remain. sub1_query = RyuDirectFlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch(imsi=encode_imsi('IMSI001010000000013'))) sub2_query = RyuDirectFlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch(imsi=encode_imsi('IMSI001010000000014'))) flow_verifier = FlowVerifier([ FlowTest(sub1_query, 0, 2), FlowTest(sub2_query, 0, 0), ], lambda: None) # Send packets through pipeline and wait. with isolator1, isolator2, flow_verifier: # Send packets to create the metering flows. Note that these # packets will not be matched because the test setup does not # support outputting to port. for pkt in packets: pkt_sender.send(pkt) wait_after_send(self.testing_controller) # Update the subscriber list to delete subscriber 2. subscriber_ip_table = SubscriberIPTable() subscriber_ip_table.entries.extend([ SubscriberIPTableEntry(sid=SubscriberID( id='IMSI001010000000013')), ]) fut = Future() fut.set_result(subscriber_ip_table) self.subscriber_controller._poll_subscriber_list_done(fut) flow_verifier.verify()