def test_dnat(): """ Title: Tests DNAT on ping messages. Scenario 1: When: a VM sends ICMP echo request with ping command to an unassigned IP address. Then: the router performs DNAT on the message according to the rule chain set to the router, And: the receiver VM should receive the ICMP echo packet, And: the ping command succeeds """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) f2 = async_assert_that( receiver, should_NOT_receive('dst host 172.16.2.1 and icmp', within_sec(5))) f1 = sender.ping_ipv4_addr('100.100.100.100', suppress_failure=True) wait_on_futures([f1, f2]) # Set DNAT rule chains to the router set_filters('router-000-001', 'pre_filter_001', 'post_filter_001') f2 = async_assert_that( receiver, receives('dst host 172.16.2.1 and icmp', within_sec(5))) f3 = async_assert_that( sender, receives('src host 100.100.100.100 and icmp', within_sec(5))) f1 = sender.ping_ipv4_addr('100.100.100.100') wait_on_futures([f1, f2, f3])
def test_floating_ip(): """ Title: Tests a floating IP. Scenario 1: When: a VM sends an ICMP echo request to a floating IP address (100.100.100.100). Then: the router performs DNAT on the message according to the rule chain set to the router, And: the receiver VM should receive the ICMP echo packet, And: the receiver sends back an ICMP reply with its original IP address as a source address. And: the router applies SNAT to the reply packet. And: the sender receives the reply with src address NATed to the floating IP address. """ sender = BM.get_iface_for_port("bridge-000-001", 2) receiver = BM.get_iface_for_port("bridge-000-002", 2) # Reset in-/out-bound filters. unset_filters("router-000-001") feed_receiver_mac(receiver) f2 = async_assert_that(receiver, should_NOT_receive("dst host 172.16.2.1 and icmp", within_sec(5))) f1 = sender.ping_ipv4_addr("100.100.100.100", suppress_failure=True) wait_on_futures([f1, f2]) # Configure floating IP address with the router set_filters("router-000-001", "pre_filter_floating_ip", "post_filter_floating_ip") f2 = async_assert_that(receiver, receives("dst host 172.16.2.1 and icmp", within_sec(5))) f3 = async_assert_that(sender, receives("src host 100.100.100.100 and icmp", within_sec(5))) f1 = sender.ping_ipv4_addr("100.100.100.100") wait_on_futures([f1, f2, f3])
def test_snat(): """ Title: Tests SNAT on ping messages. Scenario: When: a VM sends ICMP echo request with ping command to a different subnet, Then: the router performs SNAT on the message according to the rule chain set to the router, And: the receiver VM should receive the ICMP echo packet, with src address NATted, And: the ping command succeeds. """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) f1 = sender.ping4(receiver) # No SNAT configured. Should not receive SNATed messages. assert_that(receiver, should_NOT_receive('src host 172.16.1.100 and icmp', within_sec(5))) wait_on_futures([f1]) # Set SNAT rule chains to the router set_filters('router-000-001', 'pre_filter_002', 'post_filter_002') f1 = sender.ping4(receiver) # The receiver should receive SNATed messages. f2 = async_assert_that(receiver, receives('src host 172.16.1.100 and icmp', within_sec(5))) f3 = async_assert_that(sender, receives('dst host 172.16.1.1 and icmp', within_sec(5))) wait_on_futures([f1, f2, f3])
def test_dnat(): """ Title: Tests DNAT on ping messages. Scenario 1: When: a VM sends ICMP echo request with ping command to an unassigned IP address. Then: the router performs DNAT on the message according to the rule chain set to the router, And: the receiver VM should receive the ICMP echo packet, And: the ping command succeeds """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) f1 = sender.ping_ipv4_addr('100.100.100.100', suppress_failure=True) assert_that(receiver, should_NOT_receive('dst host 172.16.2.1 and icmp', within_sec(5))) wait_on_futures([f1]) # Set DNAT rule chains to the router set_filters('router-000-001', 'pre_filter_001', 'post_filter_001') f1 = sender.ping_ipv4_addr('100.100.100.100') f2 = async_assert_that(receiver, receives('dst host 172.16.2.1 and icmp', within_sec(5))) f3 = async_assert_that(sender, receives('src host 100.100.100.100 and icmp', within_sec(5))) wait_on_futures([f1, f2, f3])
def test_filtering_by_dl(): ''' Title: Tests dl-based packet filtering. Scenario: When: A VM sends UDP packets to another host on the same bridge. Then: The UDP packets reach the receiver without filtering rule chains. Then: A filtering rule chain based on mac address is set on the bridge. And: UDP packets from the same host do NOT reach the same destination host. ''' outside = BM.get_iface_for_port('bridge-000-001', 2) inside = BM.get_iface_for_port('bridge-000-001', 3) # Reset an in-bound filter. unset_bridge_port_filters('bridge-000-001', 3) port_num = get_random_port_num() f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(inside, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'No filtering: inside receives UDP packets from outside.') wait_on_futures([f1]) # Set a filtering rule based on mac addresses set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_dl_in', 'connection_tracking_dl_out') f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(inside, should_NOT_receive('dst host 172.16.1.2 and udp', within_sec(5)), 'Packets are filtered based on mac address.') wait_on_futures([f1])
def test_connection_tracking_with_drop_by_dl(): ''' Title: Tests dl-based connection tracking. Scenario: When: A VM inside a FW sends UDP packets to a VM outside. And: The outside receives the UDP packets. Then: A connection-tracking-based peep hole is established. And: The outside now can send UDP packets to the inside. ''' outside = BM.get_iface_for_port('bridge-000-001', 2) inside = BM.get_iface_for_port('bridge-000-001', 3) # Set a filtering rule based on mac addresses set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_dl_in', 'connection_tracking_dl_out') # Send forward packets to set up a connection-tracking based peep hole in # the filter. port_num = get_random_port_num() f1 = inside.send_udp('aa:bb:cc:00:01:01', '172.16.1.1', 41, src_port=port_num, dst_port=port_num) assert_that(outside, receives('dst host 172.16.1.1 and udp', within_sec(5)), 'The outside host receives forward packets from the inside.') wait_on_futures([f1]) # Verify the peep hole. f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(inside, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'The outside host can now send packets to the inside via a ' 'peep hole.') wait_on_futures([f1])
def test_connection_tracking_by_network_addres(): ''' Title: Tests NW address based connection tracking. Scenario: When: A VM, supposedly inside a FW, sends UDP packets to another host, supposedly outside the FS, on the same bridge. And: The host outside the FW receives the UDP packets. Then: A connection-tracking-based peep hole is established. And: The outside host now can send UDP packets to the inside host. ''' outside = BM.get_iface_for_port('bridge-000-001', 2) inside = BM.get_iface_for_port('bridge-000-001', 3) # Set a filtering rule based on ip address. set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_nw_in', 'connection_tracking_nw_out') # Send forward packets to set up a connection-tracking based peep hole in # the filter. port_num = get_random_port_num() f1 = inside.send_udp('aa:bb:cc:00:01:01', '172.16.1.1', 41, src_port=port_num, dst_port=port_num) assert_that(outside, receives('dst host 172.16.1.1 and udp', within_sec(5)), 'Outside host receives forward packets from inside.') wait_on_futures([f1]) # Verify the peep hole. f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(inside, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'Outside host can send packets to inside via a peep hole.') wait_on_futures([f1])
def test_filtering_by_network_address(): ''' Title: Tests packets filtering based on network address Scenario: When: A VM sends UDP packets to another host on the same bridge. Then: The UDP packets reaches the receiver. Then: Filtering rule chains based on network address (IP address) are set on the bridge port that the receiver host is connected to. And: The UDP packets from the same sender do NOT reach the receiver. ''' sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-001', 3) # Reset in/out-bound filters. unset_bridge_port_filters('bridge-000-001', 3) port_num = get_random_port_num() f1 = sender.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(receiver, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'No filtering: receiver receives UDP packets from sender.') wait_on_futures([f1]) # Set a filtering rule based on network address. set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_nw_in', 'connection_tracking_nw_out') f1 = sender.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(receiver, should_NOT_receive('dst host 172.16.1.2 and udp', within_sec(5)), 'Packets are filtered based on IP address.') wait_on_futures([f1])
def check_forward_flow(src_port_no): dst_mac = mac_for(downlink_port()) fs = expect_forward() f = downlink_iface().send_udp(dst_mac, '21.42.84.168', 41, src_port=src_port_no, dst_port=1080) wait_on_futures([f, fs])
def check_forward_flow(src_port_no): dst_mac = mac_for(downlink_port()) f = downlink_iface().send_udp(dst_mac, '21.42.84.168', 41, src_port=src_port_no, dst_port=1080) expect_forward() wait_on_futures([f])
def check_return_flow(port, iface, dst_port_no, dropped = False): dst_mac = mac_for(port); f = iface.send_udp(dst_mac, '192.168.0.1', 41, src_port=80, dst_port=dst_port_no, src_ipv4 = '172.16.42.1') if dropped: expect_return_dropped(dst_port_no) else: expect_return(dst_port_no) wait_on_futures([f])
def test_snat_for_udp(): """ Title: Tests SNAT on UDP packets. Scenario: When: a VM sends UDP packets to an unassigned IP address. Then: the router performs SNAT on the message according to the rule chain set to the router, And: the UDP packets reach the receiver VM, with src address NATted, And: because the UDP port is not open, the receiver VM returns ICMP error responses. """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) # Target hardware is a router's incoming port. router_port = VTM.get_router('router-000-001').get_port(1) router_mac = router_port.get_mn_resource().get_port_mac() # No SNAT configured. Should not receive SNATed messages. f2 = async_assert_that( receiver, should_NOT_receive('src host 172.16.1.100 and udp', within_sec(5))) f1 = sender.send_udp(router_mac, '172.16.2.1', 29, src_port=9, dst_port=65000) wait_on_futures([f1, f2]) # Set SNAT rule chains to the router set_filters('router-000-001', 'pre_filter_002', 'post_filter_002') # The receiver should receive SNATed messages. f2 = async_assert_that( receiver, receives('src host 172.16.1.100 and udp', within_sec(5))) # Sender should receive ICMP unreachable as the receiver port is not open. f3 = async_assert_that( sender, receives_icmp_unreachable_for_udp('172.16.1.1', '172.16.2.1', udp_src_port=9, udp_dst_port=65000, timeout=within_sec(5))) f1 = sender.send_udp(router_mac, '172.16.2.1', 29, src_port=9, dst_port=65000) wait_on_futures([f1, f2, f3])
def check_return_flow(port, iface, dst_port_no, dropped=False): dst_mac = mac_for(port) f = iface.send_udp(dst_mac, '192.168.0.1', 41, src_port=80, dst_port=dst_port_no, src_ipv4='172.16.42.1') if dropped: expect_return_dropped(dst_port_no) else: expect_return(dst_port_no) wait_on_futures([f])
def assert_traffic_to(vip, assertion): backend_if = get_backend_if(1) source_ports = {NON_STICKY_VIP: 10108, STICKY_VIP:10109} source_port = source_ports[vip] recv_filter = 'dst host 10.0.2.1 and src port %s and tcp' % source_port dst_ip, dst_port = vip sender_router_port = VTM.get_router('router-000-001').get_port(1) sender_router_mac = sender_router_port.get_mn_resource().get_port_mac() # 41 bytes = 20 min IPv4 header + 20 min TCP header + 1 "trivial-test-udp" f1 = SENDER.send_tcp(sender_router_mac, dst_ip, 41, src_port=source_port, dst_port=dst_port) f2 = async_assert_that(backend_if, assertion(recv_filter, within_sec(5))) wait_on_futures([f1, f2])
def check_return_flow(port, iface, dst_port_no, dropped=False, retries=0): dst_mac = mac_for(port) if dropped: fs = expect_return_dropped(dst_port_no) else: fs = expect_return(dst_port_no) f = iface.send_udp(dst_mac, "192.168.0.1", 41, src_port=80, dst_port=dst_port_no, src_ipv4="172.16.42.1") try: wait_on_futures([f, fs]) except: if retries > 0: time.sleep(5) check_return_flow(port, iface, dst_port_no, dropped, retries - 1) else: raise
def assert_traffic_to(vip, assertion): backend_if = get_backend_if(1) source_ports = {NON_STICKY_VIP: 10108, STICKY_VIP: 10109} source_port = source_ports[vip] recv_filter = 'dst host 10.0.2.1 and src port %s and tcp' % source_port dst_ip, dst_port = vip sender_router_port = VTM.get_router('router-000-001').get_port(1) sender_router_mac = sender_router_port.get_mn_resource().get_port_mac() # 41 bytes = 20 min IPv4 header + 20 min TCP header + 1 "trivial-test-udp" f1 = SENDER.send_tcp(sender_router_mac, dst_ip, 41, src_port=source_port, dst_port=dst_port) f2 = async_assert_that(backend_if, assertion(recv_filter, within_sec(5))) wait_on_futures([f1, f2])
def check_return_flow(port, iface, dst_port_no, dropped = False, retries=0): dst_mac = mac_for(port) if dropped: fs = expect_return_dropped(dst_port_no) else: fs = expect_return(dst_port_no) f = iface.send_udp(dst_mac, '192.168.0.1', 41, src_port=80, dst_port=dst_port_no, src_ipv4 = '172.16.42.1') try: wait_on_futures([f, fs]) except: if retries > 0: time.sleep(5) check_return_flow(port, iface, dst_port_no, dropped, retries - 1) else: raise
def test_snat_for_udp(): """ Title: Tests SNAT on UDP packets. Scenario: When: a VM sends UDP packets to an unassigned IP address. Then: the router performs SNAT on the message according to the rule chain set to the router, And: the UDP packets reach the receiver VM, with src address NATted, And: because the UDP port is not open, the receiver VM returns ICMP error responses. """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) # Target hardware is a router's incoming port. router_port = VTM.get_router('router-000-001').get_port(1) router_mac = router_port.get_mn_resource().get_port_mac() f1 = sender.send_udp(router_mac, '172.16.2.1', 29, src_port=9, dst_port=65000) # No SNAT configured. Should not receive SNATed messages. assert_that(receiver, should_NOT_receive('src host 172.16.1.100 and udp', within_sec(5))) wait_on_futures([f1]) # Set SNAT rule chains to the router set_filters('router-000-001', 'pre_filter_002', 'post_filter_002') f1 = sender.send_udp(router_mac, '172.16.2.1', 29, src_port=9, dst_port=65000) # The receiver should receive SNATed messages. f2 = async_assert_that(receiver, receives('src host 172.16.1.100 and udp', within_sec(5))) # Sender should receive ICMP unreachable as the receiver port is not open. f3 = async_assert_that(sender, receives_icmp_unreachable_for_udp( '172.16.1.1', '172.16.2.1', udp_src_port=9, udp_dst_port=65000, timeout=within_sec(5))) wait_on_futures([f1, f2, f3])
def test_filtering_by_network_address(): ''' Title: Tests packets filtering based on network address Scenario: When: A VM sends UDP packets to another host on the same bridge. Then: The UDP packets reaches the receiver. Then: Filtering rule chains based on network address (IP address) are set on the bridge port that the receiver host is connected to. And: The UDP packets from the same sender do NOT reach the receiver. ''' sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-001', 3) # Reset in/out-bound filters. unset_bridge_port_filters('bridge-000-001', 3) port_num = get_random_port_num() f1 = sender.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(receiver, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'No filtering: receiver receives UDP packets from sender.') wait_on_futures([f1]) # Set a filtering rule based on network address. set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_nw_in', 'connection_tracking_nw_out') f1 = sender.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that( receiver, should_NOT_receive('dst host 172.16.1.2 and udp', within_sec(5)), 'Packets are filtered based on IP address.') wait_on_futures([f1])
def destroy(self): LOG.debug('-' * 80) LOG.debug("destroy") LOG.debug('-' * 80) for h in self._hosts: host = h['host'] # Delete TZ if host.get('tunnel_zone'): tz_data = host.get('tunnel_zone') tzs = self._api.get_tunnel_zones() tz = filter(lambda x: x.get_name() == tz_data['name'], tzs) # Delete tz, which has(have) the name in the config map(lambda x: x.delete(), tz) if host['provided'] == True: LOG.info('Skipped destroying host=%r', host) else: #TODO(tomoe): when we support provisioning Midolman host with # this tool. pass interfaces = host['interfaces'] futures = [] for i in interfaces: iface = Interface(i['interface'], host) f = iface.delete() futures.append(f) wait_on_futures(futures) for b in self._bridges: bridge = b['bridge'] # TODO(tomohiko) Need to do something when !host['provided']? if host['provided']: LOG.info('Skipped destroying bridge=%r', bridge) LOG.debug('-' * 80) LOG.debug("end destroy") LOG.debug('-' * 80)
def destroy(self): LOG.debug("-" * 80) LOG.debug("destroy") LOG.debug("-" * 80) for h in self._hosts: host = h["host"] # Delete TZ if host.get("tunnel_zone"): tz_data = host.get("tunnel_zone") tzs = self._api.get_tunnel_zones() tz = filter(lambda x: x.get_name() == tz_data["name"], tzs) # Delete tz, which has(have) the name in the config map(lambda x: x.delete(), tz) if host["provided"] == True: LOG.info("Skipped destroying host=%r", host) else: # TODO(tomoe): when we support provisioning Midolman host with # this tool. pass interfaces = host["interfaces"] futures = [] for i in interfaces: iface = Interface(i["interface"], host) f = iface.delete() futures.append(f) wait_on_futures(futures) for b in self._bridges: bridge = b["bridge"] # TODO(tomohiko) Need to do something when !host['provided']? if host["provided"]: LOG.info("Skipped destroying bridge=%r", bridge) LOG.debug("-" * 80) LOG.debug("end destroy") LOG.debug("-" * 80)
def test_connection_tracking_with_drop_by_dl(): ''' Title: Tests dl-based connection tracking. Scenario: When: A VM inside a FW sends UDP packets to a VM outside. And: The outside receives the UDP packets. Then: A connection-tracking-based peep hole is established. And: The outside now can send UDP packets to the inside. ''' outside = BM.get_iface_for_port('bridge-000-001', 2) inside = BM.get_iface_for_port('bridge-000-001', 3) # Set a filtering rule based on mac addresses set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_dl_in', 'connection_tracking_dl_out') # Send forward packets to set up a connection-tracking based peep hole in # the filter. port_num = get_random_port_num() f1 = inside.send_udp('aa:bb:cc:00:01:01', '172.16.1.1', 41, src_port=port_num, dst_port=port_num) assert_that(outside, receives('dst host 172.16.1.1 and udp', within_sec(5)), 'The outside host receives forward packets from the inside.') wait_on_futures([f1]) # Verify the peep hole. f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that( inside, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'The outside host can now send packets to the inside via a ' 'peep hole.') wait_on_futures([f1])
def test_filtering_by_dl(): ''' Title: Tests dl-based packet filtering. Scenario: When: A VM sends UDP packets to another host on the same bridge. Then: The UDP packets reach the receiver without filtering rule chains. Then: A filtering rule chain based on mac address is set on the bridge. And: UDP packets from the same host do NOT reach the same destination host. ''' outside = BM.get_iface_for_port('bridge-000-001', 2) inside = BM.get_iface_for_port('bridge-000-001', 3) # Reset an in-bound filter. unset_bridge_port_filters('bridge-000-001', 3) port_num = get_random_port_num() f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that(inside, receives('dst host 172.16.1.2 and udp', within_sec(5)), 'No filtering: inside receives UDP packets from outside.') wait_on_futures([f1]) # Set a filtering rule based on mac addresses set_bridge_port_filters('bridge-000-001', 3, 'connection_tracking_dl_in', 'connection_tracking_dl_out') f1 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41, src_port=port_num, dst_port=port_num) assert_that( inside, should_NOT_receive('dst host 172.16.1.2 and udp', within_sec(5)), 'Packets are filtered based on mac address.') wait_on_futures([f1])
def test_dnat_for_udp(): """ Title: Tests DNAT on UDP packets. Scenario: When: a VM sends UDP packets to an unassigned IP address. Then: the router performs DNAT on the message according to the rule chain set to the router, And: the UDP packets reach the receiver VM. And: because the UDP port is not open, the receiver VM returns ICMP error responses. """ sender = BM.get_iface_for_port("bridge-000-001", 2) receiver = BM.get_iface_for_port("bridge-000-002", 2) # Reset in-/out-bound filters. unset_filters("router-000-001") feed_receiver_mac(receiver) # Target hardware is a router's incoming port. router_port = VTM.get_router("router-000-001").get_port(1) router_mac = router_port.get_mn_resource().get_port_mac() f2 = async_assert_that(receiver, should_NOT_receive("dst host 172.16.2.1 and udp", within_sec(5))) f1 = sender.send_udp(router_mac, "100.100.100.100", 29, src_port=9, dst_port=9) wait_on_futures([f1, f2]) # Set DNAT rule chains to the router set_filters("router-000-001", "pre_filter_001", "post_filter_001") f2 = async_assert_that(receiver, receives("dst host 172.16.2.1 and udp", within_sec(5))) # Sender should receive ICMP unreachable as the receiver port is not open. f3 = async_assert_that( sender, receives_icmp_unreachable_for_udp( "172.16.1.1", "100.100.100.100", udp_src_port=9, udp_dst_port=9, timeout=within_sec(5) ), ) f1 = sender.send_udp(router_mac, "100.100.100.100", 29, src_port=9, dst_port=9) wait_on_futures([f1, f2, f3])
def start_web_servers(): global web_servers global NUM_BACKENDS # Start web servers, send gratuitous arp replies # then wait for arp replies to propagate and web servers to start router_port = VTM.get_router('router-000-001').get_port(2) router_mac = router_port.get_mn_resource().get_port_mac() for backend_num in range(1, NUM_BACKENDS + 1): backend_ip, backend_port = backend_ip_port(backend_num) backend_if = get_backend_if(backend_num) # When we switch bindings, router's ARP table will still keep # the IP <> Mac mapping from previous test, so we send gratuitous # ARP from receiver to avoid this issue f = backend_if.send_arp_reply(backend_if.get_mac_addr(), router_mac, backend_ip, '10.0.2.254') wait_on_futures([f]) ws = backend_if.start_web_server(backend_port) web_servers.append(ws) time.sleep(2)
def test_floating_ip(): """ Title: Tests a floating IP. Scenario 1: When: a VM sends an ICMP echo request to a floating IP address (100.100.100.100). Then: the router performs DNAT on the message according to the rule chain set to the router, And: the receiver VM should receive the ICMP echo packet, And: the receiver sends back an ICMP reply with its original IP address as a source address. And: the router applies SNAT to the reply packet. And: the sender receives the reply with src address NATed to the floating IP address. """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) f2 = async_assert_that( receiver, should_NOT_receive('dst host 172.16.2.1 and icmp', within_sec(5))) f1 = sender.ping_ipv4_addr('100.100.100.100', suppress_failure=True) wait_on_futures([f1, f2]) # Configure floating IP address with the router set_filters('router-000-001', 'pre_filter_floating_ip', 'post_filter_floating_ip') f2 = async_assert_that( receiver, receives('dst host 172.16.2.1 and icmp', within_sec(5))) f3 = async_assert_that( sender, receives('src host 100.100.100.100 and icmp', within_sec(5))) f1 = sender.ping_ipv4_addr('100.100.100.100') wait_on_futures([f1, f2, f3])
def test_snat(): """ Title: Tests SNAT on ping messages. Scenario: When: a VM sends ICMP echo request with ping command to a different subnet, Then: the router performs SNAT on the message according to the rule chain set to the router, And: the receiver VM should receive the ICMP echo packet, with src address NATted, And: the ping command succeeds. """ sender = BM.get_iface_for_port('bridge-000-001', 2) receiver = BM.get_iface_for_port('bridge-000-002', 2) # Reset in-/out-bound filters. unset_filters('router-000-001') feed_receiver_mac(receiver) # No SNAT configured. Should not receive SNATed messages. f2 = async_assert_that( receiver, should_NOT_receive('src host 172.16.1.100 and icmp', within_sec(5))) f1 = sender.ping4(receiver) wait_on_futures([f1, f2]) # Set SNAT rule chains to the router set_filters('router-000-001', 'pre_filter_002', 'post_filter_002') # The receiver should receive SNATed messages. f2 = async_assert_that( receiver, receives('src host 172.16.1.100 and icmp', within_sec(5))) f3 = async_assert_that( sender, receives('dst host 172.16.1.1 and icmp', within_sec(5))) f1 = sender.ping4(receiver) wait_on_futures([f1, f2, f3])
def build(self): """ Build physical topology from the data. Args: filename: filename that defines physical topology data: python dictionary object to represent the physical topology """ LOG.debug('-' * 80) LOG.debug("build") LOG.debug('-' * 80) for b in self._bridges: bridge = b['bridge'] # TODO(tomohiko) Need to something when not bridge['provided']? if bridge['provided']: LOG.info('Skipped building bridge=%r', bridge) for h in self._hosts: host = h['host'] if host.get('tunnel_zone'): tz_data = host.get('tunnel_zone') tzs = self._api.get_tunnel_zones() # Ensure that TZ exists tz = [t for t in tzs if t.get_name() == tz_data['name']] if tz == []: if is_vxlan_enabled(): tz = self._api.add_vxlan_tunnel_zone() else: tz = self._api.add_gre_tunnel_zone() tz.name(tz_data['name']) tz.create() else: tz = tz[0] # Ensure that the host is in the TZ tz_hosts = tz.get_hosts() tz_host = filter( lambda x: x.get_host_id() == host['mn_host_id'], tz_hosts) if tz_host == []: tz_host = tz.add_tunnel_zone_host() tz_host.ip_address(tz_data['ip_addr']) tz_host.host_id(host['mn_host_id']) tz_host.create() if host['provided'] == True: LOG.info('Skipped building host=%r', host) else: #TODO(tomoe): when we support provisioning Midolman host with # this tool. pass interfaces = host['interfaces'] futures = [] for i in interfaces: iface = Interface(i['interface'], host) self._interfaces[(host['id'], i['interface']['id'])] = iface f = iface.create() futures.append(f) wait_on_futures(futures) LOG.debug('-' * 80) LOG.debug("end build") LOG.debug('-' * 80)
def build(self): """ Build physical topology from the data. Args: filename: filename that defines physical topology data: python dictionary object to represent the physical topology """ LOG.debug("-" * 80) LOG.debug("build") LOG.debug("-" * 80) for b in self._bridges: bridge = b["bridge"] # TODO(tomohiko) Need to something when not bridge['provided']? if bridge["provided"]: LOG.info("Skipped building bridge=%r", bridge) for h in self._hosts: host = h["host"] if host.get("tunnel_zone"): tz_data = host.get("tunnel_zone") tzs = self._api.get_tunnel_zones() # Ensure that TZ exists tz = [t for t in tzs if t.get_name() == tz_data["name"]] if tz == []: if is_vxlan_enabled(): tz = self._api.add_vxlan_tunnel_zone() else: tz = self._api.add_gre_tunnel_zone() tz.name(tz_data["name"]) tz.create() else: tz = tz[0] # Ensure that the host is in the TZ tz_hosts = tz.get_hosts() tz_host = filter(lambda x: x.get_host_id() == host["mn_host_id"], tz_hosts) if tz_host == []: tz_host = tz.add_tunnel_zone_host() tz_host.ip_address(tz_data["ip_addr"]) tz_host.host_id(host["mn_host_id"]) tz_host.create() if host["provided"] == True: LOG.info("Skipped building host=%r", host) else: # TODO(tomoe): when we support provisioning Midolman host with # this tool. pass interfaces = host["interfaces"] futures = [] for i in interfaces: iface = Interface(i["interface"], host) self._interfaces[(host["id"], i["interface"]["id"])] = iface f = iface.create() futures.append(f) wait_on_futures(futures) LOG.debug("-" * 80) LOG.debug("end build") LOG.debug("-" * 80)