Example #1
0
 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)
Example #2
0
    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
Example #3
0
    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
Example #4
0
    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
Example #5
0
    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()
Example #6
0
    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()