def test_redirect_policy(self): """ Add a redirect policy, verifies that EnforcementStatsController reports correct stats to sessiond Assert: 1 Packet is matched and reported """ fake_controller_setup(self.enforcement_controller, self.enforcement_stats_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/")) stat_name = imsi + '|redir_test' + '|' + sub_ip self.service_manager.session_rule_version_mapper.update_version( imsi, convert_ipv4_str_to_ip_proto(sub_ip), 'redir_test') """ Setup subscriber, setup table_isolation to fwd pkts """ self._static_rule_dict[policy.id] = policy sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.enforcement_controller, self._main_tbl_num, self.enforcement_stats_controller).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() # =========================== Verification =========================== snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager) """ Send packet, wait until pkts are received by ovs and enf stats """ with isolator, sub_context, snapshot_verifier: self.enforcement_stats_controller._report_usage.reset_mock() pkt_sender.send(packet) wait_for_enforcement_stats(self.enforcement_stats_controller, [stat_name]) """ Send packets, wait until pkts are received by ovs and enf stats """ stats = get_enforcement_stats( self.enforcement_stats_controller._report_usage.call_args_list) self.assertEqual(stats[stat_name].sid, imsi) self.assertEqual(stats[stat_name].rule_id, "redir_test") self.assertEqual(stats[stat_name].bytes_rx, 0) self.assertEqual(stats[stat_name].bytes_tx, len(packet))
def test_subscriber_redirect_policy(self): """ Add redirect policy to subscriber, send 4096 packets Assert: Packets are properly matched with the 'simple_match' policy Send /20 (4096) packets, match /16 (256) packets """ fake_controller_setup(self.gy_controller) imsi = 'IMSI010000000088888' sub_ip = '192.168.128.74' redirect_ips = ["185.128.101.5", "185.128.121.4"] self.gy_controller._redirect_manager._dns_cache.get( "about.sha.ddih.org", lambda: redirect_ips, max_age=42, ) flow_list = [FlowDescription(match=FlowMatch())] policy = VersionedPolicy( rule=PolicyRule( id='redir_test', priority=3, flow_list=flow_list, redirect=RedirectInformation( support=1, address_type=2, server_address="http://about.sha.ddih.org/", ), ), version=1, ) # ============================ Subscriber ============================ sub_context = RyuDirectSubscriberContext( imsi, sub_ip, self.gy_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, 2)\ .set_tcp_flags("S")\ .set_ip_layer('151.42.41.122', sub_ip)\ .set_ether_layer(self.MAC_DEST, "01:20:10:20:aa:bb")\ .build() snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, include_stats=False, ) with isolator, sub_context, snapshot_verifier: pkt_sender.send(packet)
def test_two_subscribers(self): """ Add 2 subscribers at the same time Assert: For subcriber1 the packets are matched to the proper policy For subcriber2 the packets are matched to the proper policy The total packet delta in the table is from the above matches """ fake_controller_setup(self.enforcement_controller) pkt_sender = ScapyPacketInjector(self.IFACE) ip_match = [ FlowDescription(match=FlowMatch( ip_src=convert_ipv4_str_to_ip_proto('8.8.8.0/24'), direction=1), action=1) ] tcp_match = [ FlowDescription(match=FlowMatch(ip_proto=6, direction=FlowMatch.DOWNLINK), action=FlowDescription.DENY) ] self._static_rule_dict['t'] = PolicyRule(id='t', priority=2, flow_list=ip_match) # =========================== Subscriber 1 =========================== sub_context1 = RyuDirectSubscriberContext( 'IMSI208950001111111', '192.168.128.5', self.enforcement_controller, self._tbl_num).add_static_rule('t') isolator1 = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context1.cfg).build_requests(), self.testing_controller) packet_ip = IPPacketBuilder()\ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\ .set_ip_layer(sub_context1.cfg.ip, '8.8.8.8')\ .build() s1_pkts_sent = 29 pkts_to_send = [PktsToSend(packet_ip, s1_pkts_sent)] flow_query1 = FlowQuery(self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( ip_match[0].match)) s1 = SubTest(sub_context1, isolator1, FlowTest(flow_query1, s1_pkts_sent)) # =========================== Subscriber 2 =========================== sub_context2 = RyuDirectSubscriberContext( 'IMSI911500451242001', '192.168.128.100', self.enforcement_controller, self._tbl_num).add_dynamic_rule( PolicyRule(id='qqq', priority=2, flow_list=tcp_match)) isolator2 = RyuDirectTableIsolator( RyuForwardFlowArgsBuilder.from_subscriber( sub_context2.cfg).build_requests(), self.testing_controller) packet_tcp = TCPPacketBuilder()\ .set_ether_layer(self.MAC_DEST, "00:00:00:00:00:00")\ .set_ip_layer(sub_context2.cfg.ip, '15.0.0.8')\ .build() s2_pkts_sent = 18 pkts_to_send.append(PktsToSend(packet_tcp, s2_pkts_sent)) flow_query2 = FlowQuery(self._tbl_num, self.testing_controller, match=flow_match_to_magma_match( tcp_match[0].match)) s2 = SubTest(sub_context2, isolator2, FlowTest(flow_query2, s2_pkts_sent)) # =========================== Verification =========================== # Verify aggregate table stats, subscriber 1 & 2 flows packet matches pkts = s1_pkts_sent + s2_pkts_sent flow_verifier = FlowVerifier([ FlowTest(FlowQuery(self._tbl_num, self.testing_controller), pkts), s1.flowtest_list, s2.flowtest_list ], lambda: wait_after_send(self.testing_controller)) snapshot_verifier = SnapshotVerifier(self, self.BRIDGE, self.service_manager) with s1.isolator, s1.context, s2.isolator, s2.context, flow_verifier, \ snapshot_verifier: for pkt in pkts_to_send: pkt_sender.send(pkt.pkt, pkt.num) flow_verifier.verify()
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 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( enf_controller=self.enforcement_controller, enf_stats_controller=self.enforcement_stats_controller, startup_flow_controller=self.startup_flows_contoller, ) 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, ) setup_flows_request = SetupFlowsRequest( requests=[ ActivateFlowsRequest( sid=SIDUtils.to_pb(imsi), ip_addr=sub_ip, policies=[VersionedPolicy(rule=policy, version=1)], ), ], epoch=global_epoch, ) fake_controller_setup( enf_controller=self.enforcement_controller, enf_stats_controller=self.enforcement_stats_controller, startup_flow_controller=self.startup_flows_contoller, setup_flows_request=setup_flows_request, ) 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() snapshot_verifier = SnapshotVerifier( self, self.BRIDGE, self.service_manager, ) with isolator, sub_context, snapshot_verifier: pkt_sender.send(packet)
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()