def test_inbound_ip_match(self): """ Inbound ip match test, checks that packets are properly matched when the inbound traffic matches an ip in the blacklist. Assert: Both packets are matched Ip match flows are added """ # Set up subscribers sub = SubContextConfig('IMSI001010000000013', '192.168.128.74', self._tbl_num) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub).build_requests(), self.testing_controller, ) # Set up packets pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ self._build_default_ip_packet(self.INBOUND_TEST_IP, sub.ip), self._build_default_ip_packet(self.BOTH_DIR_TEST_IP, sub.ip), ] # Check if these flows were added (queries should return flows) inbound_flow_queries = [ FlowQuery(self._tbl_num, self.testing_controller, match=MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, direction=Direction.OUT, ipv4_dst=self.INBOUND_TEST_IP)), FlowQuery(self._tbl_num, self.testing_controller, match=MagmaMatch(eth_type=ether_types.ETH_TYPE_IP, direction=Direction.OUT, ipv4_dst=self.BOTH_DIR_TEST_IP)), ] # =========================== Verification =========================== # packets matched, ip match flows installed flow_verifier = FlowVerifier([ FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 2), ] + [ FlowTest(query, 1, flow_count=1) for query in inbound_flow_queries ], lambda: wait_after_send(self.testing_controller)) with isolator, flow_verifier: for packet in packets: pkt_sender.send(packet) flow_verifier.verify() assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_gre_peer_rules(self): """ Inbound ip match test, checks that packets are properly matched when the inbound traffic matches an ip in the blocklist. Assert: Both packets are matched Ip match flows are added """ assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def testFlowSnapshotMatch(self): cls = self.__class__ assert_bridge_snapshot_match( self, self.UPLINK_BRIDGE, self.service_manager, include_stats=False, ) self.assertIn(cls.SGi_IP, get_iface_ipv4(cls.UPLINK_BRIDGE), "ip not found") self.assertIn(cls.SGi_IPv6, get_iface_ipv6(cls.UPLINK_BRIDGE), "ipv6 not found")
def testFlowSnapshotMatch(self): cls = self.__class__ # after Non NAT init, router shld be accessible. # manually start DHCP client on up-br check_connectivity(cls.ROUTER_IP, cls.UPLINK_BRIDGE, False) check_connectivity_v6(cls.ROUTER_IPV6) assert_bridge_snapshot_match( self, self.UPLINK_BRIDGE, self.service_manager, include_stats=False, ) self.assertEqual(get_ovsdb_port_tag(cls.UPLINK_BRIDGE), '[]')
def test_remove_app_rules(self): """ Test DPI classifier flows are properly removed Assert: Remove the facebook match flow """ flow_match1 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP, ipv4_dst='45.10.0.0/24', ipv4_src='1.2.3.0/24', tcp_dst=80, tcp_src=51115, direction=FlowMatch.UPLINK) self.dpi_controller.remove_classify_flow(flow_match1) hub.sleep(5) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_add_valid_quota_subscriber(self): """ Add flows for two subscribers """ imsi_1 = 'IMSI010000000088888' mac_1 = '5e:cc:cc:b1:49:4b' # Add subscriber with UE MAC address """ self.check_quota_controller.update_subscriber_quota_state( SubscriberQuotaUpdate( sid=SubscriberID(id=imsi_1), mac_addr=mac_1, update_type=SubscriberQuotaUpdate.VALID_QUOTA)) wait_after_send(self.testing_controller) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_remove_app_rules(self): """ Test DPI classifier flows are properly removed Assert: Initial state has (`facebook` and `instagram`), remove (`facebook`) App type matches on (`instagram`) """ flow_match1 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP, ipv4_dst='45.10.0.0/24', ipv4_src='1.2.3.0/24', tcp_dst=80, tcp_src=51115, direction=FlowMatch.UPLINK) self.dpi_controller.remove_classify_flow(flow_match1) hub.sleep(5) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_add_app_rules(self): """ Test DPI classifier flows are properly added Assert: 1 App not tracked -> no rule installed(`notanAPP`) 3 App types are matched on: facebook other google_docs other viber audio """ flow_match1 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP, ipv4_dst='45.10.0.0/24', ipv4_src='1.2.3.0/24', tcp_dst=80, tcp_src=51115, direction=FlowMatch.UPLINK) flow_match2 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP, ipv4_dst='1.10.0.0/24', ipv4_src='6.2.3.0/24', tcp_dst=111, tcp_src=222, direction=FlowMatch.UPLINK) flow_match3 = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP, ipv4_dst='22.2.2.24', ipv4_src='15.22.32.0/24', udp_src=111, udp_dst=222, direction=FlowMatch.UPLINK) flow_match_for_no_proto = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP, ipv4_dst='1.1.1.1') self.dpi_controller.add_classify_flow(flow_match_for_no_proto, 'notanAPP', 'null') self.dpi_controller.add_classify_flow(flow_match1, 'base.ip.http.facebook', 'NotReal') self.dpi_controller.add_classify_flow( flow_match2, 'base.ip.https.google_gen.google_docs', 'MAGMA') self.dpi_controller.add_classify_flow(flow_match3, 'base.ip.udp.viber', 'AudioTransfer Receiving') hub.sleep(5) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_blocking_ip_match(self): """ Inbound ip match test, checks that packets are properly matched when the inbound traffic matches an ip in the blocklist. Assert: Both packets are matched Ip match flows are added """ # Set up subscribers sub = SubContextConfig( 'IMSI001010000000013', '192.168.128.74', default_ambr_config, self._tbl_num, ) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub).build_requests(), self.testing_controller, ) # Set up packets pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ _build_default_ip_packet(self.MAC_DEST, self.OUTBOUND_TEST_IP1, sub.ip), _build_default_ip_packet(self.MAC_DEST, self.OUTBOUND_TEST_IP2, sub.ip), _build_default_ip_packet(self.MAC_DEST, self.BOTH_DIR_TEST_IP, sub.ip), ] with isolator: for packet in packets: pkt_sender.send(packet) assert_bridge_snapshot_match( self, self.BRIDGE, self.service_manager, )
def testFlowSnapshotMatch(self): """ Ensure 2 IMSIs sample flows are installed Assert: Snapshots match """ imsi1 = 'IMSI010000000088888' imsi2 = 'IMSI010000000011111' msidn = 'BigTower' apn_mac = '08-00-27-cd-32-07' apn_name = 'MagmaBox' self.ipfix_controller.add_ue_sample_flow(imsi1, msidn, apn_mac, apn_name) self.ipfix_controller.add_ue_sample_flow(imsi2, msidn, apn_mac, apn_name) # Big rule wait a bit for it to appear hub.sleep(2) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_add_three_subscribers(self): """ Add flows for two subscribers """ imsi_1 = 'IMSI010000000088888' imsi_2 = 'IMSI010000111111118' imsi_3 = 'IMSI010002222222222' mac_1 = '5e:cc:cc:b1:49:4b' mac_2 = '5e:a:cc:af:aa:fe' mac_3 = '5e:bb:cc:aa:aa:fe' # Add subscriber with UE MAC address """ self.check_quota_controller.update_subscriber_quota_state( SubscriberQuotaUpdate(sid=SubscriberID(id=imsi_1), mac_addr=mac_1, update_type=SubscriberQuotaUpdate.NO_QUOTA)) self.check_quota_controller.update_subscriber_quota_state( SubscriberQuotaUpdate(sid=SubscriberID(id=imsi_2), mac_addr=mac_2, update_type=SubscriberQuotaUpdate.NO_QUOTA)) self.check_quota_controller.update_subscriber_quota_state( SubscriberQuotaUpdate( sid=SubscriberID(id=imsi_3), mac_addr=mac_3, update_type=SubscriberQuotaUpdate.VALID_QUOTA)) wait_after_send(self.testing_controller) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager) self.check_quota_controller.update_subscriber_quota_state( SubscriberQuotaUpdate(sid=SubscriberID(id=imsi_2), mac_addr=mac_2, update_type=SubscriberQuotaUpdate.TERMINATE)) self.check_quota_controller.update_subscriber_quota_state( SubscriberQuotaUpdate(sid=SubscriberID(id=imsi_3), mac_addr=mac_3, update_type=SubscriberQuotaUpdate.TERMINATE))
def test_add_app_rules(self): """ Test DPI classifier flows are properly added Assert: 2 App types are matched on (`facebook` and `instagram`) """ flow_match1 = FlowMatch(ip_proto=FlowMatch.IPPROTO_TCP, ipv4_dst='45.10.0.0/24', ipv4_src='1.2.3.0/24', tcp_dst=80, tcp_src=51115, direction=FlowMatch.UPLINK) flow_match2 = FlowMatch(ip_proto=FlowMatch.IPPROTO_UDP, ipv4_dst='45.10.0.0/24', ipv4_src='1.2.3.0/24', udp_src=111, udp_dst=222, direction=FlowMatch.UPLINK) self.dpi_controller.add_classify_flow(flow_match1, 'facebook') self.dpi_controller.add_classify_flow(flow_match2, 'instagram') hub.sleep(5) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_blocking_ip_match(self): """ Inbound ip match test, checks that packets are properly matched when the inbound traffic matches an ip in the blocklist. Assert: Both packets are matched Ip match flows are added """ sub = self._setup_subscribers_ipv6() isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub).build_requests(), self.testing_controller, ) # Set up packets pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ _build_default_ipv6_packet(self.MAC_DEST, self.OUTBOUND_TEST_IP1, sub.ip), _build_default_ipv6_packet(self.MAC_DEST, self.OUTBOUND_TEST_IP2, sub.ip), _build_default_ipv6_packet(self.MAC_DEST, self.OUTBOUND_TEST_IP3, sub.ip), ] with isolator: for packet in packets: pkt_sender.send(packet) assert_bridge_snapshot_match( self, self.BRIDGE, self.service_manager, ipv6_prefix_only=True, )
def testFlowSnapshotMatch(self): fake_inout_setup(self.inout_controller) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def testFlowSnapshotMatch(self): cls = self.__class__ assert_bridge_snapshot_match(self, self.UPLINK_BRIDGE, self.service_manager) self.assertIn(cls.SGi_IP, get_iface_ipv4(cls.BRIDGE_ETH_PORT), "ip not found")
def test_url_redirect(self): """ Partial redirection test, checks if flows were added properly for url based redirection. Assert: 1 Packet is matched Packet bypass flows are added Flow learn action is triggered - another flow is added to the table """ fake_controller_setup(self.enforcement_controller) redirect_ips = ["185.128.101.5", "185.128.121.4"] self.enforcement_controller._redirect_manager._dns_cache.get( "about.sha.ddih.org", lambda: redirect_ips, max_age=42) imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' flow_list = [FlowDescription(match=FlowMatch())] policy = PolicyRule(id='redir_test', priority=3, flow_list=flow_list, redirect=RedirectInformation( support=1, address_type=2, server_address="http://about.sha.ddih.org/")) # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._tbl_num).add_dynamic_rule(policy) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context.cfg).build_requests(), self.testing_controller) pkt_sender = ScapyPacketInjector(self.IFACE) packet = TCPPacketBuilder()\ .set_tcp_layer(42132, 80, 321)\ .set_tcp_flags("S")\ .set_ip_layer('151.42.41.122', sub_ip)\ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\ .build() # Check if these flows were added (queries should return flows) permit_outbound, permit_inbound = [], [] for ip in redirect_ips: permit_outbound.append( FlowQuery(self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( FlowMatch(ipv4_dst=ip, direction=FlowMatch.UPLINK)))) permit_inbound.append( FlowQuery(self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( FlowMatch(ipv4_src=ip, direction=FlowMatch.DOWNLINK)))) learn_action_flow = flow_match_to_magma_match( FlowMatch(ip_proto=6, direction=FlowMatch.DOWNLINK, ipv4_src=self.BRIDGE_IP_ADDRESS, ipv4_dst=sub_ip)) learn_action_query = FlowQuery(self._tbl_num, self.testing_controller, learn_action_flow) # =========================== Verification =========================== # 1 packet sent, permit rules installed, learn action installed. Since # the enforcement table is entered via the DPI table and the scratch # enforcement table, the number of packets handled by the table is 2. flow_verifier = FlowVerifier( [ FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 2), FlowTest(learn_action_query, 0, flow_count=1) ] + [FlowTest(query, 0, flow_count=1) for query in permit_outbound] + [FlowTest(query, 0, flow_count=1) for query in permit_inbound], lambda: wait_after_send(self.testing_controller)) with isolator, sub_context, flow_verifier: pkt_sender.send(packet) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager) flow_verifier.verify()
def testFlowSnapshotMatch(self): cls = self.__class__ assert_bridge_snapshot_match(self, self.UPLINK_BRIDGE, self.service_manager, include_stats=False)
def testFlowSnapshotMatch(self): # time.sleep(100) assert_bridge_snapshot_match(self, self.UPLINK_BRIDGE, self.service_manager, include_stats=False)
def test_outbound_ip_match(self): """ Outbound ip match test, checks that packets are properly matched when the outbound traffic matches an ip in the blocklist. Assert: Both packets are matched Ip match flows are added """ sub = self._setup_subscribers() isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub).build_requests(), self.testing_controller, ) # Set up packets pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ _build_default_ip_packet(self.MAC_DEST, sub.ip, self.OUTBOUND_TEST_IP), _build_default_ip_packet(self.MAC_DEST, sub.ip, self.BOTH_DIR_TEST_IP), ] # Check if these flows were added (queries should return flows) outbound_flow_queries = [ FlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch( eth_type=ether_types.ETH_TYPE_IP, direction=Direction.IN, ipv4_src=self.OUTBOUND_TEST_IP, ), ), FlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch( eth_type=ether_types.ETH_TYPE_IP, direction=Direction.IN, ipv4_src=self.BOTH_DIR_TEST_IP, ), ), ] # =========================== Verification =========================== # packets matched, ip match flows installed flow_verifier = FlowVerifier( [ FlowTest( FlowQuery(self._tbl_num, self.testing_controller), 2, ), ] + [ FlowTest(query, 1, flow_count=1) for query in outbound_flow_queries ], lambda: wait_after_send(self.testing_controller, ), ) with isolator, flow_verifier: for packet in packets: pkt_sender.send(packet) flow_verifier.verify() assert_bridge_snapshot_match( self, self.BRIDGE, self.service_manager, )
def testFlowSnapshotMatch(self): fake_mandatory_controller_setup(self.ingress_controller) fake_mandatory_controller_setup(self.middle_controller) fake_mandatory_controller_setup(self.egress_controller) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_no_match(self): """ No match test, checks that packets are not matched when the there is no match to the ip and direction in the blocklist. Assert: Both packets are not matched Ip match flows are added """ # Set up subscribers sub = SubContextConfig( 'IMSI001010000000013', '192.168.128.74', default_ambr_config, self._tbl_num, ) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub).build_requests(), self.testing_controller, ) # Set up packets. The directions of the packets are opposite of the # installed match flow, so there should not matches. pkt_sender = ScapyPacketInjector(self.BRIDGE) packets = [ _build_default_ip_packet(self.MAC_DEST, self.OUTBOUND_TEST_IP, sub.ip), _build_default_ip_packet(self.MAC_DEST, sub.ip, self.INBOUND_TEST_IP), ] # Check if these flows were added (queries should return flows) outbound_flow_queries = [ FlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch( eth_type=ether_types.ETH_TYPE_IP, direction=Direction.OUT, ipv4_dst=self.INBOUND_TEST_IP, ), ), FlowQuery( self._tbl_num, self.testing_controller, match=MagmaMatch( eth_type=ether_types.ETH_TYPE_IP, direction=Direction.IN, ipv4_src=self.OUTBOUND_TEST_IP, ), ), ] # =========================== Verification =========================== # packets are not matched, ip match flows installed flow_verifier = FlowVerifier( [ FlowTest( FlowQuery(self._tbl_num, self.testing_controller), 2, ), ] + [ FlowTest(query, 0, flow_count=1) for query in outbound_flow_queries ], lambda: wait_after_send( self.testing_controller, ), ) with isolator, flow_verifier: for packet in packets: pkt_sender.send(packet) flow_verifier.verify() assert_bridge_snapshot_match( self, self.BRIDGE, self.service_manager, )
def testFlowSnapshotMatch(self): assert_bridge_snapshot_match(self, self.UPLINK_BRIDGE, self.service_manager)
def testFlowSnapshotMatch(self): cls = self.__class__ assert_bridge_snapshot_match(self, self.UPLINK_BRIDGE, self.service_manager, include_stats=False) self.assertEqual(get_ovsdb_port_tag(cls.UPLINK_BRIDGE), cls.VLAN_TAG)
def testFlowSnapshotMatch(self): hub.sleep(2) assert_bridge_snapshot_match(self, self.BRIDGE, self.service_manager)
def test_ipv4_redirect(self): """ Partial redirection test, checks if flows were added properly for ipv4 based redirection. Assert: 1 Packet is matched Packet bypass flows are added Flow learn action is triggered - another flow is added to the table """ fake_controller_setup(self.enforcement_controller) redirect_ip = "54.12.31.42" imsi = 'IMSI012000000088888' sub_ip = '192.168.128.74' flow_list = [FlowDescription(match=FlowMatch())] policy = VersionedPolicy( rule=PolicyRule( id='redir_ip_test', priority=3, flow_list=flow_list, redirect=RedirectInformation( support=1, address_type=0, server_address=redirect_ip, ), ), version=1, ) # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._tbl_num, ).add_policy(policy) isolator = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber(sub_context.cfg) .build_requests(), self.testing_controller, ) pkt_sender = ScapyPacketInjector(self.IFACE) packet = TCPPacketBuilder()\ .set_tcp_layer(42132, 80, 321)\ .set_tcp_flags("S")\ .set_ip_layer('151.42.41.122', sub_ip)\ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\ .build() # Check if these flows were added (queries should return flows) permit_outbound = FlowQuery( self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( FlowMatch( ip_dst=convert_ipv4_str_to_ip_proto(redirect_ip), direction=FlowMatch.UPLINK, ), ), ) permit_inbound = FlowQuery( self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( FlowMatch( ip_src=convert_ipv4_str_to_ip_proto(redirect_ip), direction=FlowMatch.DOWNLINK, ), ), ) learn_action_flow = flow_match_to_magma_match( FlowMatch( ip_proto=6, direction=FlowMatch.DOWNLINK, ip_src=convert_ipv4_str_to_ip_proto(self.BRIDGE_IP_ADDRESS), ip_dst=convert_ipv4_str_to_ip_proto(sub_ip), ), ) learn_action_query = FlowQuery( self._tbl_num, self.testing_controller, learn_action_flow, ) # =========================== Verification =========================== # 1 packet sent, permit rules installed, learn action installed. Since # the enforcement table is entered via the DPI table and the scratch # enforcement table, the number of packets handled by the table is 2. flow_verifier = FlowVerifier( [ FlowTest(FlowQuery(self._tbl_num, self.testing_controller), 2), FlowTest(permit_outbound, 0, flow_count=1), FlowTest(permit_inbound, 0, flow_count=1), FlowTest(learn_action_query, 0, flow_count=1), ], lambda: wait_after_send(self.testing_controller), ) with isolator, sub_context, flow_verifier: pkt_sender.send(packet) assert_bridge_snapshot_match( self, self.BRIDGE, self.service_manager, ) flow_verifier.verify()