Exemple #1
0
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])
Exemple #2
0
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])
Exemple #9
0
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])
Exemple #10
0
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])
Exemple #11
0
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])
Exemple #12
0
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])
Exemple #13
0
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])
Exemple #14
0
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])
Exemple #15
0
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
Exemple #16
0
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])
Exemple #17
0
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])
Exemple #19
0
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])
Exemple #20
0
    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)
Exemple #22
0
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])
Exemple #23
0
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])
Exemple #24
0
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])
Exemple #25
0
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])
Exemple #26
0
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)
Exemple #27
0
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)
Exemple #28
0
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])
Exemple #29
0
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])
Exemple #30
0
    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)