Пример #1
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])
Пример #2
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')
    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])
Пример #3
0
def ping_to_vtep(bridge_name, port_index, dest_ip,
                 interval=0.5, count=4, retries=1):
    try:
        time.sleep(2)
        sender = BM.get_iface_for_port(bridge_name, port_index)
        f1 = sender.ping_ipv4_addr(dest_ip, interval=interval, count=count)
        wait_on_futures([f1])
        output_stream, exec_id = f1.result()
        exit_status = sender.compute_host.check_exit_status(exec_id,
                                                            output_stream,
                                                            timeout=60)

        assert_that(exit_status, equal_to(0),
                    "Ping to from {0}.{1} to {2} failed.".format(bridge_name,
                                                                 port_index,
                                                                 dest_ip))
    except Exception:
        if retries == 0:
            assert_that(-1, equal_to(0),
                        "Ping to from {0}.{1} to {2} failed.".format(bridge_name,
                                                                     port_index,
                                                                     dest_ip))

        ping_to_vtep(bridge_name, port_index, dest_ip, count, interval,
                     retries - 1)
Пример #4
0
def ping(src, dst, expected_failure=False, retries=3):
    try:
        # src and dst could be the vm object
        # or the port name where the vm is bound
        LOG.info("VPNaaS: pinging from %s to %s" % (src, dst))
        src_vm = src if not isinstance(src, str) \
            else BM.get_interface_on_vport(src)
        dst_vm = dst if not isinstance(dst, str) \
            else BM.get_interface_on_vport(dst)
        f1 = src_vm.ping_ipv4_addr(dst_vm.get_ip(update=True),
                                   interval=1, count=5)

        wait_on_futures([f1])
        output_stream, exec_id = f1.result()
        exit_status = src_vm.compute_host.check_exit_status(exec_id,
                                                            output_stream,
                                                            timeout=10)

        assert_that(exit_status, equal_to(0), "Ping did not return any data")
    except AssertionError:
        if retries == 0:
            if expected_failure:
                return
            raise AssertionError("Ping failed after max retries. Giving up.")
        LOG.debug("VPNaaS: failed ping from %s to %s... (%d retries left)" %
                  (src, dst, retries))
        ping(src, dst, expected_failure, retries=retries - 1)
Пример #5
0
def test_fragmented_packets():
    """
    Title: L3 connectivity over bridge and router
           (MN-L3-ICMP-2) with large packets that will be fragmented

    Scenario 1:
    When: a VM sends a ICMP echo request with size >MTU uwing ping command
          to a different subnet
    Then: 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)

    # The receiver VM needs to send some frames so the MN Router learns
    # the VM's mac address. Otherwise this test would fail with binding2
    # because the MidoNet Router forwards the ICMP with the previous mac
    # found in bindings1 in ethernet headers.
    # Issue: https://midobugs.atlassian.net/browse/MN-79
    receiver.ping4(sender, 0.5, 3, True, 2000, do_arp=True)

    f1 = async_assert_that(receiver,
                           receives('dst host 172.16.2.1 and icmp', within_sec(5)))

    f2 = sender.ping4(receiver, 0.5, 3, False, 2000)

    wait_on_futures([f1, f2])
Пример #6
0
def _ping_from_mn(midoVmIface, exHostIface, count=3, do_arp=False):

    f1 = async_assert_that(exHostIface,
                           receives('dst host 172.16.0.224 and icmp',
                                    within_sec(20)))
    f2 = midoVmIface.ping4(exHostIface, count=count, do_arp=do_arp)
    wait_on_futures([f1, f2])
Пример #7
0
def _ping_to_mn(midoVmIface, exHostIface, count=3, do_arp=False):

    exHostIface.clear_arp()
    f1 = async_assert_that(midoVmIface,
                           receives('dst host 172.16.0.1 and icmp',
                                    within_sec(5)))
    f2 = exHostIface.ping4(midoVmIface, count=count, do_arp=do_arp)
    wait_on_futures([f1, f2])
Пример #8
0
def check_return_flow(src_vm, dst_vm, snat_ip, snat_port, dst_port, src_port):
    # And expect: Internal VM receives return traffic
    recv_filter = 'udp and port %d and ip dst %s' % (dst_port, dst_vm.get_ip())
    f = async_assert_that(dst_vm, receives(recv_filter, within_sec(10)))
    # When: sending return flows
    src_vm.execute('hping3 -c 1 -q -2 -s %s -p %s %s' %
                   (src_port, snat_port, snat_ip))
    wait_on_futures([f])
Пример #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])
Пример #10
0
def test_icmp_autobind_vm_in_binding():
    vm1 = BM2.get_interface_on_vport('port1')
    vm2 = BM2.get_interface_on_vport('port2')
    # Test ping works
    f1 = async_assert_that(vm2,
                           receives('dst host %s and icmp' % vm2.get_ip(),
                                    within_sec(10)))
    f2 = vm1.ping4(vm2)

    wait_on_futures([f1, f2])
Пример #11
0
def feed_receiver_mac(receiver):
    """Feeds the receiver's mac address to the MidoNet router."""
    try:
        router_port = VTM.get_router('router-000-001').get_port(2)
        router_ip = router_port.get_mn_resource().get_port_address()
        receiver_ip = receiver.get_ip()
        f1 = async_assert_that(receiver, receives('dst host %s' % receiver_ip,
                                                  within_sec(10)))
        receiver.send_arp_request(router_ip)
        wait_on_futures([f1])
    except Exception:
        LOG.warn('Oops, sending ARP from the receiver VM failed.')
Пример #12
0
def send_udp(sender, receiver, hw_dst, dst_p, src_p, mirror=None):
    sender.get_mac_addr()
    sender.get_ip()
    ip_dst = receiver.get_ip()

    udp_filter = "dst host %s and dst port %d" % (ip_dst, dst_p)
    futures = []
    futures.append(async_assert_that(receiver, receives(udp_filter, within_sec(15))))
    if mirror is not None:
        futures.append(async_assert_that(mirror, receives(udp_filter, within_sec(15))))

    sender.send_udp(hw_dst, ip_dst, src_port=src_p, dst_port=dst_p)
    wait_on_futures(futures)
Пример #13
0
def test_mac_learning():
    """
    Title: Bridge mac learning

    Scenario 1:
    When: the destination ethernet address has never been seen before.
    Then: the bridge should flood the ethernet unicast

    Scenario 2:
    When: the destination ethernet address has been seen before.
    Then: the bridge should not flood the ethernet frame, instaed it should
          forward to only the port that is connected to the interface with
          the mac address.
    """
    sender = BM.get_iface_for_port('bridge-000-001', 1)
    iface_with_the_hw_addr = BM.get_iface_for_port('bridge-000-001', 2)
    iface_x = BM.get_iface_for_port('bridge-000-001', 3)

    hw_addr = iface_with_the_hw_addr.get_mac_addr()
    match_on_the_hw_addr = 'ether dst ' + hw_addr

    ethernet_unicast_to_the_hw_addr = '%s-7e:1f:ff:ff:ff:ff-aa:bb' % (hw_addr)

    # Scenario 1:
    # Both interfaces should get the frname as the bridge should flood it.

    f1 = async_assert_that(iface_with_the_hw_addr,
                           receives(match_on_the_hw_addr, within_sec(5)))
    f2 = async_assert_that(iface_x,
                           receives(match_on_the_hw_addr, within_sec(5)))
    time.sleep(1)

    sender.send_ether(ethernet_unicast_to_the_hw_addr, count=3)
    wait_on_futures([f1, f2])

    # Scenario 2:

    # Get the bridge to learn the mac address
    iface_with_the_hw_addr.ping4(sender, sync=True)

    time.sleep(1)

    # only iface_with_the_hw_addr should receives the ehternet unicast
    f1 = async_assert_that(iface_with_the_hw_addr,
                           receives(match_on_the_hw_addr, within_sec(5)))
    f2 = async_assert_that(iface_x,
                           should_NOT_receive(match_on_the_hw_addr,
                                              within_sec(5)))
    sender.send_ether(ethernet_unicast_to_the_hw_addr, count=1)
    wait_on_futures([f1, f2])
Пример #14
0
def _send_icmp(sender, receiver, payload, target_ipv4,
               expect, expect_icmp_frag_needed=False):
    f1 = async_assert_that(receiver,
                           expect('dst host %s and icmp' % target_ipv4,
                                  within_sec(5)))

    f2 = _async_assert_receives_icmp_frag_needed(sender,
                                                 expect_icmp_frag_needed)

    time.sleep(1)

    f3 = sender.ping4(receiver, 0.5, 3, False, payload)

    wait_on_futures([f1, f2, f3])
Пример #15
0
def test_src_mac_masking():
    """
    Title: Test source MAC masking in chain rules

    Scenario 1:
    When: There's a rule dropping any traffic with an even source MAC
    Then: Traffic from if2 to if1 is blocked because if2's MAC ends with 2
    And:  Traffic from if1 to if2 goes through because if1's MAC ends with 1

    FIXME: moving to the new bindings mechanisms should allow removing
    this restriction.
    Only running this with the one-host binding, because:
    1. The multi-host binding breaks the assumptions that if1 will have
       an odd MAC address and if2 an even one.
    2. This is basically just a sanity test to make sure dl_src_mask is
       wired up. Unit tests and test_dst_mac_masking provide enough
       coverage of the other aspects.
    3. These tests are slow enough as it is.
    """

    bridge = VTM.get_bridge('bridge-000-001')

    if1 = BM.get_iface_for_port('bridge-000-001', 1)
    if2 = BM.get_iface_for_port('bridge-000-001', 2)

    if1_hw_addr = if1.interface['hw_addr']
    if2_hw_addr = if2.interface['hw_addr']

    if1_ip_addr = if1.get_ip()
    if2_ip_addr = if2.get_ip()

    if1_rcv_filter = 'udp and ether dst %s' % if1_hw_addr
    if2_rcv_filter = 'udp and ether dst %s' % if2_hw_addr

    bridge.set_inbound_filter(VTM.get_chain('drop_even_src_mac'))

    # If2 has an even MAC (ends with 2), so traffic from if2 to if1
    # should be dropped.
    f1 = async_assert_that(if1, should_NOT_receive(if1_rcv_filter, within_sec(5)))
    time.sleep(1)
    f2 = if2.send_udp(if1_hw_addr, if1_ip_addr, 41)
    wait_on_futures([f1, f2])

    # If1 has an odd MAC (ends with 1), so traffic from if1 to if2
    # should go through.
    f1 = async_assert_that(if2, receives(if2_rcv_filter, within_sec(5)))
    time.sleep(1)
    f2 = if1.send_udp(if2_hw_addr, if2_ip_addr, 41)
    wait_on_futures([f1, f2])
Пример #16
0
def send_udp(sender, receiver, hw_dst, dst_p, src_p, mirror=None):
    sender.get_mac_addr()
    sender.get_ip()
    ip_dst = receiver.get_ip()

    udp_filter = "dst host %s and dst port %d" % (ip_dst, dst_p)
    futures = []
    futures.append(
        async_assert_that(receiver, receives(udp_filter, within_sec(15))))
    if mirror is not None:
        futures.append(
            async_assert_that(mirror, receives(udp_filter, within_sec(15))))

    sender.send_udp(hw_dst, ip_dst, src_port=src_p, dst_port=dst_p)
    wait_on_futures(futures)
Пример #17
0
def _send_udp(sender, receiver, target_hw, target_ipv4, parms, payload,
              expect, expect_icmp_frag_needed=False):
    f1 = async_assert_that(receiver,
                           expect('dst host %s and udp' % target_ipv4,
                                  within_sec(5)))

    f2 = _async_assert_receives_icmp_frag_needed(sender,
                                                 expect_icmp_frag_needed)

    time.sleep(1)

    f3 = sender.send_packet(target_hw, target_ipv4, 'udp', parms, payload,
                            1, 3, False)

    wait_on_futures([f1, f2, f3])
Пример #18
0
def ping_to_inet(count=5, interval=1, port=2, retries=3):
    try:
        sender = BM.get_iface_for_port('bridge-000-001', port)
        f1 = sender.ping_ipv4_addr('1.1.1.1', interval=interval, count=count)
        wait_on_futures([f1])
        output_stream, exec_id = f1.result()
        exit_status = sender.compute_host.check_exit_status(exec_id,
                                                            output_stream,
                                                            timeout=20)

        assert_that(exit_status, equal_to(0), "Ping did not return any data")
    except Exception:
        if retries == 0:
            raise RuntimeError("Ping did not return any data and returned -1")
        LOG.debug("BGP: failed ping to inet... (%d retries left)" % retries)
        ping_to_inet(count, interval, port, retries - 1)
Пример #19
0
def _send_icmp(sender,
               receiver,
               payload,
               target_ipv4,
               expect,
               expect_icmp_frag_needed=False):
    f1 = async_assert_that(
        receiver, expect('dst host %s and icmp' % target_ipv4, within_sec(5)))

    f2 = _async_assert_receives_icmp_frag_needed(sender,
                                                 expect_icmp_frag_needed)

    time.sleep(1)

    f3 = sender.ping4(receiver, 0.5, 3, False, payload)

    wait_on_futures([f1, f2, f3])
Пример #20
0
def check_forward_flow(src_vm, dst_vm, fip, src_port, dst_port):
    # Expect: Both vms (with fip) receive the packet
    recv_filter = 'udp and port %d and ip dst %s' % (dst_port, dst_vm.get_ip())
    f = async_assert_that(dst_vm, receives(recv_filter, within_sec(10)))
    # When: Sending udp packet
    #  src_vm (internal) -> dst_vm (fip)
    src_vm.execute('hping3 -c 1 -q -2 -s %s -p %s %s' %
                   (src_port, dst_port, fip))
    wait_on_futures([f])

    # tcpdump format:
    # date net_proto src_ip.src_port > dst_ip.dst_port: transp_proto [...]
    output = dst_vm.get_last_tcpdump_output()
    snat_ip = output.split(' ')[2].rsplit('.', 1)[0]
    snat_port = output.split(' ')[2].rsplit('.', 1)[1]

    return {'ip': snat_ip, 'port': snat_port}
Пример #21
0
def test_two_isolated_bridges():
    """
    Title: Two isolated bridges

    All traffic between two VMs in different and
    unconnected bridges should be independent, so
    receiver shouldn't get any packets
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-002', 1)

    f2 = async_assert_that(receiver, should_NOT_receive('icmp', within_sec(5)))

    f1 = sender.ping4(receiver, 0.5, 3, False, 100)

    wait_on_futures([f1, f2])
Пример #22
0
def check_forward_flow(src_vm, dst_vm, fip, src_port, dst_port):
    # Expect: VM with fip to receive the packet
    recv_filter = 'udp and port %d and ip dst %s' % (dst_port, dst_vm.get_ip())
    f = async_assert_that(dst_vm, receives(recv_filter, within_sec(10)))
    # When: Sending udp packet
    #  src_vm (internal) -> dst_vm (fip)
    src_vm.execute('hping3 -c 1 -q -2 -s %s -p %s %s' %
                   (src_port, dst_port, fip))
    wait_on_futures([f])

    # tcpdump format:
    # date net_proto src_ip.src_port > dst_ip.dst_port: transp_proto [...]
    output = dst_vm.get_last_tcpdump_output()
    snat_ip = output.split(' ')[2].rsplit('.', 1)[0]
    snat_port = output.split(' ')[2].rsplit('.', 1)[1]

    return {'ip': snat_ip, 'port': snat_port}
Пример #23
0
def test_icmp():
    """
    Title: ICMP reachability over bridge

    Scenario 1:
    When: a VM sends ICMP echo request with ping command
    Then: the receiver VM should receive the ICMP echo packet.
    And: the ping command succeeds
    """
    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 3)

    f1 = async_assert_that(receiver,
                           receives('dst host %s and icmp' % receiver.get_ip(),
                                    within_sec(5)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])
Пример #24
0
def test_two_isolated_bridges():
    """
    Title: Two isolated bridges

    All traffic between two VMs in different and
    unconnected bridges should be independent, so
    receiver shouldn't get any packets
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-002', 1)

    f2 = async_assert_that(receiver,
                           should_NOT_receive('icmp', within_sec(5)))

    f1 = sender.ping4(receiver, 0.5, 3, False, 100)

    wait_on_futures([f1, f2])
Пример #25
0
def test_icmp():
    """
    Title: ICMP reachability over bridge

    Scenario 1:
    When: a VM sends ICMP echo request with ping command
    Then: the receiver VM should receive the ICMP echo packet.
    And: the ping command succeeds
    """
    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 3)

    f1 = async_assert_that(
        receiver,
        receives('dst host %s and icmp' % receiver.get_ip(), within_sec(5)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])
Пример #26
0
def test_fragmented_packets():
    """
    Title: Fragmented IP packets through a bridge

    Scenario 1:
    When: a VM sends large PING packets (> MTU)
    Then: the receiver should receive the ICMP echo packet
    And: the ping command succeeds
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 3)

    f2 = async_assert_that(
        receiver, receives('dst host 172.16.1.3 and icmp', within_sec(5)))
    f1 = sender.ping4(receiver, 0.5, 3, False, 2000)

    wait_on_futures([f1, f2])
Пример #27
0
def ping_to_inet(count=5, interval=1, port=2, retries=3):
    try:
        sender = BM.get_iface_for_port('bridge-000-001', port)
        f1 = sender.ping_ipv4_addr('1.1.1.1',
                                   interval=interval,
                                   count=count)
        wait_on_futures([f1])
        output_stream, exec_id = f1.result()
        exit_status = sender.compute_host.check_exit_status(exec_id,
                                                            output_stream,
                                                            timeout=20)

        assert_that(exit_status, equal_to(0), "Ping did not return any data")
    except Exception:
        if retries == 0:
            raise RuntimeError("Ping did not return any data and returned -1")
        LOG.debug("BGP: failed ping to inet... (%d retries left)" % retries)
        ping_to_inet(count, interval, port, retries - 1)
Пример #28
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])
Пример #29
0
def test_icmp_topology_out_test_two_computes():
    # Query resources created on the managers
    vm1 = PTM2.get_resource('vm1_host1')
    vm2 = PTM2.get_resource('vm2_host2')

    port1 = VTM2.get_resource('port1')
    port2 = VTM2.get_resource('port2')

    # Bind virtual and physical topology
    vm1.compute_host.bind_port(vm1, port1['port']['id'])
    vm2.compute_host.bind_port(vm2, port2['port']['id'])

    # Test ping works
    f1 = async_assert_that(vm2,
                           receives('dst host %s and icmp' % vm2.get_ip(),
                                    within_sec(10)))
    f2 = vm1.ping4(vm2)

    wait_on_futures([f1, f2])
Пример #30
0
def test_dst_mac_masking():
    """
    Title: Test destination MAC masking in chain rules

    Scenario 1:
    When: There's a rule dropping any traffic with the multicast bit on
    Then: Multicast traffic is blocked and unicast traffic goes through

    Scenario 2:
    When: There's a rule dropping any traffic with the multicast bit off
    Then: Multicast traffic goes through and unicast traffic is blocked
    """

    bridge = VTM.get_bridge('bridge-000-001')

    if1 = BM.get_iface_for_port('bridge-000-001', 1)
    if2 = BM.get_iface_for_port('bridge-000-001', 2)

    if1_hw_addr = if1.get_mac_addr()  # interface['hw_addr']
    if2_hw_addr = if2.get_mac_addr()  # interface['hw_addr']

    if2_ip_addr = if2.get_ip()

    rcv_filter = 'udp and ether src %s' % if1_hw_addr

    bridge.set_inbound_filter(VTM.get_chain('drop_multicast'))
    # Send a frame to an arbitrary multicast address. Bridge doesn't
    # recognize it and will try to flood it to the other port, but the
    # masked MAC rule should drop it since it has the multicast bit set.
    f1 = async_assert_that(if2, should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = if1.send_udp("01:23:45:67:89:ab", if2_ip_addr)
    wait_on_futures([f1, f2])

    # If2's actual MAC address should work, since it doesn't have the bit set.
    f1 = async_assert_that(if2, receives(rcv_filter, within_sec(10)))
    f2 = if1.send_udp(if2_hw_addr, if2_ip_addr)
    wait_on_futures([f1, f2])

    # Change to the chain that allows only multicast addresses.
    bridge.set_inbound_filter(VTM.get_chain('allow_only_multicast'))

    # Send another frame to the multicast address. Bridge doesn't
    # recognize it and will try to flood it to the other port. This
    # time the rule should allow it through.
    f1 = async_assert_that(if2, receives(rcv_filter, within_sec(10)))
    f2 = if1.send_udp("01:23:45:67:89:ab", if2_ip_addr)
    wait_on_futures([f1, f2])

    # If2's actual MAC address should be blocked, since it doesn't
    # have the multicast bit set.
    f1 = async_assert_that(if2, should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = if1.send_udp(if2_hw_addr, if2_ip_addr)
    wait_on_futures([f1, f2])
Пример #31
0
def test_fragmented_packets():
    """
    Title: Fragmented IP packets through a bridge

    Scenario 1:
    When: a VM sends large PING packets (> MTU)
    Then: the receiver should receive the ICMP echo packet
    And: the ping command succeeds
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 3)

    f2 = async_assert_that(receiver,
                           receives('dst host 172.16.1.3 and icmp',
                                    within_sec(5)))
    f1 = sender.ping4(receiver, 0.5, 3, False, 2000)

    wait_on_futures([f1, f2])
Пример #32
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()
    # FIXME: do not use harcoded values!
    f1 = async_assert_that(
        receiver, receives('dst host 172.16.1.2 and udp', within_sec(5)),
        'No filtering: receives UDP packets from sender.')
    f2 = sender.send_udp('aa:bb:cc:00:01:02',
                         '172.16.1.2',
                         41,
                         src_port=port_num,
                         dst_port=port_num)
    wait_on_futures([f1, f2])

    # 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 = async_assert_that(
        receiver,
        should_NOT_receive('dst host 172.16.1.2 and udp', within_sec(5)),
        'Packets are filtered based on IP address.')
    f2 = sender.send_udp('aa:bb:cc:00:01:02',
                         '172.16.1.2',
                         41,
                         src_port=port_num,
                         dst_port=port_num)
    wait_on_futures([f1, f2])
Пример #33
0
def test_dst_mac_masking():
    """
    Title: Test destination MAC masking in chain rules

    Scenario 1:
    When: There's a rule dropping any traffic with the multicast bit on
    Then: Multicast traffic is blocked and unicast traffic goes through

    Scenario 2:
    When: There's a rule dropping any traffic with the multicast bit off
    Then: Multicast traffic goes through and unicast traffic is blocked
    """

    bridge = VTM.get_bridge('bridge-000-001')

    if1 = BM.get_iface_for_port('bridge-000-001', 1)
    if2 = BM.get_iface_for_port('bridge-000-001', 2)

    if1_hw_addr = if1.get_mac_addr()  # interface['hw_addr']
    if2_hw_addr = if2.get_mac_addr()  # interface['hw_addr']

    if2_ip_addr = if2.get_ip()

    rcv_filter = 'udp and ether src %s' % if1_hw_addr

    bridge.set_inbound_filter(VTM.get_chain('drop_multicast'))
    # Send a frame to an arbitrary multicast address. Bridge doesn't
    # recognize it and will try to flood it to the other port, but the
    # masked MAC rule should drop it since it has the multicast bit set.
    f1 = async_assert_that(if2, should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = if1.send_udp("01:23:45:67:89:ab", if2_ip_addr)
    wait_on_futures([f1, f2])

    # If2's actual MAC address should work, since it doesn't have the bit set.
    f1 = async_assert_that(if2, receives(rcv_filter, within_sec(10)))
    f2 = if1.send_udp(if2_hw_addr, if2_ip_addr)
    wait_on_futures([f1, f2])

    # Change to the chain that allows only multicast addresses.
    bridge.set_inbound_filter(VTM.get_chain('allow_only_multicast'))

    # Send another frame to the multicast address. Bridge doesn't
    # recognize it and will try to flood it to the other port. This
    # time the rule should allow it through.
    f1 = async_assert_that(if2, receives(rcv_filter, within_sec(10)))
    f2 = if1.send_udp("01:23:45:67:89:ab", if2_ip_addr)
    wait_on_futures([f1, f2])

    # If2's actual MAC address should be blocked, since it doesn't
    # have the multicast bit set.
    f1 = async_assert_that(if2, should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = if1.send_udp(if2_hw_addr, if2_ip_addr)
    wait_on_futures([f1, f2])
Пример #34
0
def test_tracing_egress_matching_over_nat():
    """
    Title: Tracing egress matching over nat

    Scenario 1:
    When: a VM sends ICMP echo request over nat wait for echo response
    Then: Trace data appears for the ingress and the egress host,
          but only as part of 2 flow traces (one for forward, one for return)
    """
    unset_filters('router-000-001')
    tracerequest = VTM.get_tracerequest('ping-trace-request')
    try:
        set_filters('router-000-001', 'pre_filter_001', 'post_filter_001')
        tracerequest.set_enabled(True)
        time.sleep(5)

        flowtraces = get_flow_traces(tracerequest.get_id())
        assert (len(flowtraces) == 0)

        sender = BM.get_iface_for_port('bridge-000-001', 2)
        receiver = BM.get_iface_for_port('bridge-000-002', 2)

        feed_receiver_mac(receiver)

        f2 = async_assert_that(
            receiver, receives('dst host 172.16.2.1 and icmp', within_sec(10)))
        f3 = async_assert_that(
            sender,
            receives('src host 100.100.100.100 and icmp', within_sec(10)))
        f1 = sender.ping_ipv4_addr('100.100.100.100')
        wait_on_futures([f1, f2, f3])

        time.sleep(5)

        flowtraces = get_flow_traces(tracerequest.get_id())
        assert (len(flowtraces) == 2)

        # ensure both packets were traced on both hosts
        assert (len(get_hosts(tracerequest.get_id(), flowtraces[0])) == 2)
        assert (len(get_hosts(tracerequest.get_id(), flowtraces[1])) == 2)
    finally:
        tracerequest.set_enabled(False)
        unset_filters('router-000-001')
Пример #35
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 = async_assert_that(
        outside, receives('dst host 172.16.1.1 and udp', within_sec(5)),
        'Outside host receives forward packets from inside.')
    f2 = inside.send_udp('aa:bb:cc:00:01:01',
                         '172.16.1.1',
                         41,
                         src_port=port_num,
                         dst_port=port_num)
    wait_on_futures([f1, f2])

    # Verify the peep hole.
    f1 = async_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.')
    f2 = outside.send_udp('aa:bb:cc:00:01:02',
                          '172.16.1.2',
                          41,
                          src_port=port_num,
                          dst_port=port_num)
    wait_on_futures([f1, f2])
Пример #36
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 = async_assert_that(
        outside, receives('dst host 172.16.1.1 and udp', within_sec(5)),
        'The outside host receives forward packets '
        'from the inside.')
    f2 = inside.send_udp('aa:bb:cc:00:01:01',
                         '172.16.1.1',
                         41,
                         src_port=port_num,
                         dst_port=port_num)
    wait_on_futures([f1, f2])

    # Verify the peep hole.
    f1 = async_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.')
    f2 = outside.send_udp('aa:bb:cc:00:01:02',
                          '172.16.1.2',
                          41,
                          src_port=port_num,
                          dst_port=port_num)
    wait_on_futures([f1, f2])
Пример #37
0
def _send_udp(sender,
              receiver,
              target_hw,
              target_ipv4,
              parms,
              payload,
              expect,
              expect_icmp_frag_needed=False):
    f1 = async_assert_that(
        receiver, expect('dst host %s and udp' % target_ipv4, within_sec(5)))

    f2 = _async_assert_receives_icmp_frag_needed(sender,
                                                 expect_icmp_frag_needed)

    time.sleep(1)

    f3 = sender.send_packet(target_hw, target_ipv4, 'udp', parms, payload, 1,
                            3, False)

    wait_on_futures([f1, f2, f3])
Пример #38
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 = async_assert_that(
        inside, receives('dst host 172.16.1.2 and udp', within_sec(5)),
        'No filtering: inside receives UDP packets from outside.')
    f2 = outside.send_udp('aa:bb:cc:00:01:02',
                          '172.16.1.2',
                          41,
                          src_port=port_num,
                          dst_port=port_num)
    wait_on_futures([f1, f2])

    # 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 = async_assert_that(
        inside, should_NOT_receive('dst host 172.16.1.2 and udp',
                                   within_sec(5)),
        'Packets are filtered based on mac address.')
    f2 = outside.send_udp('aa:bb:cc:00:01:02',
                          '172.16.1.2',
                          41,
                          src_port=port_num,
                          dst_port=port_num)
    wait_on_futures([f1, f2])
Пример #39
0
def test_flow_invalidation_on_mac_update():
    """
    Title: Flow invalidation, learning MACs

    The bridge learns the MACs from the traffic flowing by its ports.
    When the bridge learns a MAC that has 'moved' to another port, it should
    send traffic only to that port.
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 2)
    intruder = BM.get_iface_for_port('bridge-000-001', 3)

    receiver_MAC = receiver.get_mac_addr()
    frame = '%s-%s-aa:bb' % (receiver_MAC, receiver_MAC)

    capture = 'icmp and src host %s' % (sender.get_ip())

    # Populate ARP table
    sender.execute('arp -s %s %s' % (receiver.get_ip(), receiver_MAC))
    receiver.execute('arp -s %s %s' % (sender.get_ip(), sender.get_mac_addr()))

    # Trigger receiver MAC learning
    receiver.send_ether(frame)

    # First: packets go from sender to receiver
    f1 = async_assert_that(receiver, receives(capture, within_sec(5)))
    f2 = async_assert_that(intruder,
                           should_NOT_receive(capture, within_sec(5)))
    f3 = sender.ping4(receiver)
    wait_on_futures([f1, f2, f3])

    # Second: intruder claims to be receiver
    intruder.send_ether(frame)

    # Third: packets go from sender to intruder
    f1 = async_assert_that(receiver,
                           should_NOT_receive(capture, within_sec(5)))
    f2 = async_assert_that(intruder, receives(capture, within_sec(5)))
    f3 = sender.ping4(receiver)
    wait_on_futures([f1, f2, f3])
Пример #40
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 Exception:
        if retries > 0:
            time.sleep(5)
            check_return_flow(port, iface, dst_port_no, dropped, retries - 1)
        else:
            raise
Пример #41
0
def test_filter_ipv6():
    """
    Title: Filter IPv6 packets out on Bridge

    Scenario 1:
    When: there is no filter settings
    Then: IPv6 packets go through the bridge

    Scenario 2:
    When: the bridge has a chain in which there is a drop rule for IPv6
    Then: IPv6 packets should not go through the bridge

    Scenario 3:
    When: the chain is removed from the bridge
    Then: IPv6 packets should go through again.
    """

    iface1 = BM.get_iface_for_port('bridge-000-001', 1)
    iface2 = BM.get_iface_for_port('bridge-000-001', 2)

    iface1_hw_addr = iface1.interface['hw_addr']
    iface2_hw_addr = iface2.interface['hw_addr']

    ipv6_proto = "86:dd"
    ipv6_icmp = ("60:00:00:00:00:20:3a:ff:fe:80:00:00:00:00:00:00:1a:03:73:ff:"
                 "fe:29:a9:b1:ff:02:00:00:00:00:00:00:00:00:00:01:ff:29:a9:b2:"
                 "87:00:32:26:00:00:00:00:fe:80:00:00:00:00:00:00:1a:03:73:ff:"
                 "fe:29:a9:b2:01:01:18:03:73:29:a9:b1")

    packet = '%s-%s-%s-%s' % (iface2_hw_addr, iface1_hw_addr, ipv6_proto,
                              ipv6_icmp)

    rcv_filter = 'ether dst %s' % iface2_hw_addr

    # Sceneario 1:
    f1 = async_assert_that(iface2, receives(rcv_filter, within_sec(10)))
    # async_assert_that expects only 1 packet. Send only one, because the next
    # tcpdump might capture it (and fail the test) in case it takes some time
    # to arrive.
    # FIXME: make the tcpdump listener configurable
    f2 = iface1.send_ether(packet, count=1)
    wait_on_futures([f1, f2])

    # Scenario 2:
    # setting chain and make sure it's dropped
    chain = VTM.get_chain('drop_ipv6')
    VTM.get_bridge('bridge-000-001').set_inbound_filter(chain)

    f1 = async_assert_that(iface2,
                           should_NOT_receive(
                               rcv_filter, within_sec(10)))
    f2 = iface1.send_ether(packet, count=1)
    wait_on_futures([f1, f2])

    # Remove the filter and verify that packets go through again.
    VTM.get_bridge('bridge-000-001').set_inbound_filter(None)
    time.sleep(1)
    f1 = async_assert_that(iface2, receives(rcv_filter, within_sec(10)))
    f2 = iface1.send_ether(packet, count=1)
    wait_on_futures([f1, f2])
Пример #42
0
def test_ping_delete_port():
    """
    Title: L3 connectivity over bridge and router, then deletes a port
    and verifies that there is no connectivity. Implemented to cover the
    old DeletePortTest.

    Scenario 1:
    When: a VM sends ICMP echo request with ping command to a different subnet
    Then: the receiver VM should receive the ICMP echo packet.
    And: the ping command succeeds
    When: the destination port on the router is deleted
    Then: the receiver VM should NOT receive the ICMP echo packet
    """

    sender = BM.get_iface_for_port('bridge-000-001', 2)
    receiver = BM.get_iface_for_port('bridge-000-002', 2)

    # The receiver VM needs to send some frames so the MN Router learns
    # the VM's mac address. Otherwise this test would fail with binding2
    # because the MidoNet Router forwards the ICMP with the previous mac
    # found in bindings1 in ethernet headers.
    # Issue: https://midobugs.atlassian.net/browse/MN-79
    receiver.ping4(sender)

    f1 = async_assert_that(receiver,
                           receives('dst host 172.16.2.1 and icmp',
                                    within_sec(5)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])

    port = VTM.get_device_port('router-000-001', 2)
    port.destroy()

    f1 = async_assert_that(receiver,
                           should_NOT_receive('dst host 172.16.2.1 and icmp',
                                              within_sec(5)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])
Пример #43
0
def test_filter_ipv6():
    """
    Title: Filter IPv6 packets out on Bridge

    Scenario 1:
    When: there is no filter settings
    Then: IPv6 packets go through the bridge

    Scenario 2:
    When: the bridge has a chain in which there is a drop rule for IPv6
    Then: IPv6 packets should not go through the bridge

    Scenario 3:
    When: the chain is removed from the bridge
    Then: IPv6 packets should go through again.
    """

    iface1 = BM.get_iface_for_port('bridge-000-001', 1)
    iface2 = BM.get_iface_for_port('bridge-000-001', 2)

    iface1_hw_addr = iface1.interface['hw_addr']
    iface2_hw_addr = iface2.interface['hw_addr']

    ipv6_proto = "86:dd"
    ipv6_icmp = ("60:00:00:00:00:20:3a:ff:fe:80:00:00:00:00:00:00:1a:03:73:ff:"
                 "fe:29:a9:b1:ff:02:00:00:00:00:00:00:00:00:00:01:ff:29:a9:b2:"
                 "87:00:32:26:00:00:00:00:fe:80:00:00:00:00:00:00:1a:03:73:ff:"
                 "fe:29:a9:b2:01:01:18:03:73:29:a9:b1")

    packet = '%s-%s-%s-%s' % (iface2_hw_addr, iface1_hw_addr, ipv6_proto,
                              ipv6_icmp)

    rcv_filter = 'ether dst %s' % iface2_hw_addr

    # Sceneario 1:
    f1 = async_assert_that(iface2, receives(rcv_filter, within_sec(10)))
    # async_assert_that expects only 1 packet. Send only one, because the next
    # tcpdump might capture it (and fail the test) in case it takes some time
    # to arrive.
    # FIXME: make the tcpdump listener configurable
    f2 = iface1.send_ether(packet, count=1)
    wait_on_futures([f1, f2])

    # Scenario 2:
    # setting chain and make sure it's dropped
    chain = VTM.get_chain('drop_ipv6')
    VTM.get_bridge('bridge-000-001').set_inbound_filter(chain)

    f1 = async_assert_that(iface2,
                           should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = iface1.send_ether(packet, count=1)
    wait_on_futures([f1, f2])

    # Remove the filter and verify that packets go through again.
    VTM.get_bridge('bridge-000-001').set_inbound_filter(None)
    time.sleep(1)
    f1 = async_assert_that(iface2, receives(rcv_filter, within_sec(10)))
    f2 = iface1.send_ether(packet, count=1)
    wait_on_futures([f1, f2])
Пример #44
0
def test_flow_invalidation_on_mac_update():
    """
    Title: Flow invalidation, learning MACs

    The bridge learns the MACs from the traffic flowing by its ports.
    When the bridge learns a MAC that has 'moved' to another port, it should
    send traffic only to that port.
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 2)
    intruder = BM.get_iface_for_port('bridge-000-001', 3)

    receiver_MAC = receiver.get_mac_addr()
    frame = '%s-%s-aa:bb' % (receiver_MAC, receiver_MAC)

    capture = 'icmp and src host %s' % (sender.get_ip())

    # Populate ARP table
    sender.execute('arp -s %s %s' % (receiver.get_ip(), receiver_MAC))
    receiver.execute('arp -s %s %s' % (sender.get_ip(), sender.get_mac_addr()))

    # Trigger receiver MAC learning
    receiver.send_ether(frame)

    # First: packets go from sender to receiver
    f1 = async_assert_that(receiver, receives(capture, within_sec(5)))
    f2 = async_assert_that(intruder, should_NOT_receive(capture, within_sec(5)))
    f3 = sender.ping4(receiver)
    wait_on_futures([f1, f2, f3])

    # Second: intruder claims to be receiver
    intruder.send_ether(frame)

    # Third: packets go from sender to intruder
    f1 = async_assert_that(receiver, should_NOT_receive(capture, within_sec(5)))
    f2 = async_assert_that(intruder, receives(capture, within_sec(5)))
    f3 = sender.ping4(receiver)
    wait_on_futures([f1, f2, f3])
Пример #45
0
def test_ping_delete_port():
    """
    Title: L3 connectivity over bridge and router, then deletes a port
    and verifies that there is no connectivity. Implemented to cover the
    old DeletePortTest.

    Scenario 1:
    When: a VM sends ICMP echo request with ping command to a different subnet
    Then: the receiver VM should receive the ICMP echo packet.
    And: the ping command succeeds
    When: the destination port on the router is deleted
    Then: the receiver VM should NOT receive the ICMP echo packet
    """

    sender = BM.get_iface_for_port('bridge-000-001', 2)
    receiver = BM.get_iface_for_port('bridge-000-002', 2)

    # The receiver VM needs to send some frames so the MN Router learns
    # the VM's mac address. Otherwise this test would fail with binding2
    # because the MidoNet Router forwards the ICMP with the previous mac
    # found in bindings1 in ethernet headers.
    # Issue: https://midobugs.atlassian.net/browse/MN-79
    receiver.ping4(sender)

    f1 = async_assert_that(
        receiver, receives('dst host 172.16.2.1 and icmp', within_sec(5)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])

    port = VTM.get_device_port('router-000-001', 2)
    port.destroy()

    f1 = async_assert_that(
        receiver,
        should_NOT_receive('dst host 172.16.2.1 and icmp', within_sec(5)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])
Пример #46
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()
    # FIXME: do not use harcoded values!
    f1 = async_assert_that(receiver,
                           receives('dst host 172.16.1.2 and udp',
                                    within_sec(5)),
                           'No filtering: receives UDP packets from sender.')
    f2 = sender.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41,
                         src_port=port_num, dst_port=port_num)
    wait_on_futures([f1, f2])

    # 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 = async_assert_that(receiver, should_NOT_receive(
        'dst host 172.16.1.2 and udp',
        within_sec(5)),
        'Packets are filtered based on IP address.')
    f2 = sender.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41,
                         src_port=port_num, dst_port=port_num)
    wait_on_futures([f1, f2])
Пример #47
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)

    f1 = async_assert_that(
        receiver,
        should_NOT_receive('dst host 172.16.2.1 and icmp', within_sec(10)))
    sender.ping_ipv4_addr('100.100.100.100')
    wait_on_futures([f1])

    # Configure floating IP address with the router
    set_filters('router-000-001', 'pre_filter_floating_ip',
                'post_filter_floating_ip')

    f1 = async_assert_that(
        receiver, receives('dst host 172.16.2.1 and icmp', within_sec(10)))
    f2 = async_assert_that(
        sender, receives('src host 100.100.100.100 and icmp', within_sec(10)))
    sender.ping_ipv4_addr('100.100.100.100')
    wait_on_futures([f1, f2])
Пример #48
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 = async_assert_that(outside,
                           receives('dst host 172.16.1.1 and udp',
                                    within_sec(5)),
                           'The outside host receives forward packets '
                           'from the inside.')
    f2 = inside.send_udp('aa:bb:cc:00:01:01', '172.16.1.1', 41,
                         src_port=port_num, dst_port=port_num)
    wait_on_futures([f1, f2])

    # Verify the peep hole.
    f1 = async_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.')
    f2 = outside.send_udp('aa:bb:cc:00:01:02', '172.16.1.2', 41,
                          src_port=port_num, dst_port=port_num)
    wait_on_futures([f1, f2])
Пример #49
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])
Пример #50
0
def run_garp_scenario(BM, sender_port, target_ip, enable_vip, disable_vip):
    vip1 = BM.get_interface_on_vport('port_int1')
    vip2 = BM.get_interface_on_vport('port_int2')

    sender = BM.get_interface_on_vport(sender_port)
    # allow sender to accept gratutious arps (only makes sense if on same network)
    sender.execute('bash -c "echo 1 > /proc/sys/net/ipv4/conf/%s/arp_accept"'
                   % sender.get_ifname())
    rcv_filter = 'icmp and ip src %s' % (sender.get_ip())

    # noone responds initially
    f1 = async_assert_that(vip1, should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = async_assert_that(vip2, should_NOT_receive(rcv_filter, within_sec(10)))
    f3 = sender.ping_ipv4_addr(target_ip, count=5)
    wait_on_futures([f1, f2, f3])

    # enable for vip1
    enable_vip(vip1)
    disable_vip(vip2)
    f1 = async_assert_that(vip1, receives(rcv_filter, within_sec(10)))
    f2 = async_assert_that(vip2, should_NOT_receive(rcv_filter, within_sec(10)))
    f3 = sender.ping_ipv4_addr(target_ip, count=5)
    wait_on_futures([f1, f2, f3])

    # enable for vip2
    enable_vip(vip2)
    disable_vip(vip1)
    f1 = async_assert_that(vip1, should_NOT_receive(rcv_filter, within_sec(10)))
    f2 = async_assert_that(vip2, receives(rcv_filter, within_sec(10)))
    f3 = sender.ping_ipv4_addr(target_ip, count=5)
    wait_on_futures([f1, f2, f3])

    # enable for vip1
    enable_vip(vip1)
    disable_vip(vip2)
    f1 = async_assert_that(vip1, receives(rcv_filter, within_sec(10)))
    f2 = async_assert_that(vip2, should_NOT_receive(rcv_filter, within_sec(10)))
    f3 = sender.ping_ipv4_addr(target_ip, count=5)
    wait_on_futures([f1, f2, f3])
Пример #51
0
def test_icmp_after_interface_recovery():
    """
    Title: ICMP reachability over bridge before and after interfaces go
    down

    Scenario 1:
    When: a VM sends ICMP echo request with ping command
    Then: the receiver VM should receive the ICMP echo packet.
    And: the ping command succeeds
    Then: the receiver VM's tap goes down
    And: the ping command fails
    Then: the receiver VM's tap goes back up
    And: the ping command succeeds
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 3)

    f1 = async_assert_that(
        receiver, receives('dst host 172.16.1.3 and icmp', within_sec(5)))
    f2 = sender.ping4(receiver)
    wait_on_futures([f1, f2])

    receiver.set_down()

    f1 = async_assert_that(
        receiver,
        should_NOT_receive('icmp', within_sec(5), on_host_interface(True)))
    f2 = sender.ping4(receiver)

    wait_on_futures([f1, f2])

    receiver.set_up()

    f1 = async_assert_that(
        receiver, receives('dst host 172.16.1.3 and icmp', within_sec(5)))
    f2 = sender.ping4(receiver)
    wait_on_futures([f1, f2])
Пример #52
0
def test_rule_changes():
    """
    Title: ICMP reachability over bridge before and after adding rule
    to drop IPv4 traffic.

    Scenario 1:
    When: A VM sends ICMP echo request with ping command
    Then: The receiver VM should receive the ICMP echo packet.
    And: The ping command succeeds
    Then: The receiver adds a rule blocking IPv4 traffic.
    And: The ping command fails
    Then: the receiver removes the rule
    And: The ping succeeds again.
    """

    sender = BM.get_iface_for_port('bridge-000-001', 1)
    receiver = BM.get_iface_for_port('bridge-000-001', 2)

    # There are no filters, so the first ping should succeed.
    f1 = async_assert_that(receiver, receives('icmp', within_sec(5)))
    f2 = sender.ping4(receiver, do_arp=True)
    wait_on_futures([f1, f2])

    # Add a filter dropping all IPv4 traffic to port 2.
    chain = VTM.get_chain('drop_ipv4')
    VTM.get_device_port('bridge-000-001', 2).set_outbound_filter(chain)

    # The second ping should not reach port 2.
    f1 = async_assert_that(receiver, should_NOT_receive('icmp', within_sec(5)))
    f2 = sender.ping4(receiver, do_arp=True)
    wait_on_futures([f1, f2])

    # After removing the filter, ping should succeed again.
    VTM.get_device_port('bridge-000-001', 2).set_outbound_filter(None)
    f1 = async_assert_that(receiver, receives('icmp', within_sec(5)))
    f2 = sender.ping4(receiver, do_arp=True)
    wait_on_futures([f1, f2])
Пример #53
0
def test_l2insertion_both_ends_protected():
    """
    Title: Test insertions with both ends protected

    2 L2 insertions on 2 ports, each insertion with a different bad pattern.

    The bad packets matching the different patterns should be blocked at
    different insertions depending on the direction of the packet.

    Verify that packets are blocked in the same order regardless of the
    direction.
    """
    api = get_midonet_api()

    service_port1 = BM.get_iface_for_port('bridge-000-001', 2)
    service_port2 = BM.get_iface_for_port('bridge-000-001', 3)

    fakesnort1 = FakeSnort(service_port1, "deadbeef")
    fakesnort2 = FakeSnort(service_port2, "cafef00d")
    try:
        fakesnort1.run()
        fakesnort2.run()

        insertion_port1 = BM.get_iface_for_port('bridge-000-001', 1)
        insertion_port2 = BM.get_iface_for_port('bridge-000-001', 4)

        insertion1 = api.add_l2insertion()
        insertion1.srv_port(service_port1.vport_id)
        insertion1.port(insertion_port1.vport_id)
        insertion1.position(1)
        insertion1.fail_open(False)
        insertion1.vlan(1)
        insertion1.mac(insertion_port1.get_mac_addr())
        insertion1.create()

        insertion2 = api.add_l2insertion()
        insertion2.srv_port(service_port2.vport_id)
        insertion2.port(insertion_port1.vport_id)
        insertion2.position(2)
        insertion2.fail_open(False)
        insertion2.vlan(2)
        insertion2.mac(insertion_port1.get_mac_addr())
        insertion2.create()

        insertion3 = api.add_l2insertion()
        insertion3.srv_port(service_port1.vport_id)
        insertion3.port(insertion_port2.vport_id)
        insertion3.position(1)
        insertion3.fail_open(False)
        insertion3.vlan(3)
        insertion3.mac(insertion_port2.get_mac_addr())
        insertion3.create()

        insertion4 = api.add_l2insertion()
        insertion4.srv_port(service_port2.vport_id)
        insertion4.port(insertion_port2.vport_id)
        insertion4.position(2)
        insertion4.fail_open(False)
        insertion4.vlan(4)
        insertion4.mac(insertion_port2.get_mac_addr())
        insertion4.create()

        time.sleep(5)

        rcv_filter = 'ip dst %s and icmp[icmptype] == 8' % insertion_port2.get_ip()

        LOG.info("Sending good packet")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10), count=2))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10), count=2))
        f3 = async_assert_that(insertion_port2,
                               receives(rcv_filter, within_sec(10)))
        ping_port(insertion_port1, insertion_port2, data="f00b4c")
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending dead beef")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port2,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(insertion_port1, insertion_port2,
                  data="deadbeef", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending cafe food")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port2,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(insertion_port1, insertion_port2,
                  data="cafef00d", should_succeed=False)
        wait_on_futures([f1, f2, f3])
    finally:
        fakesnort2.kill()
        fakesnort1.kill()
Пример #54
0
def test_l2insertion_with_flowstate():
    """
    Title: Test insertions with flow state

    2 L2 insertions on a port, each with a different bad pattern.
    Packets are sent over DNAT so that flow state is generated and necessary to
    return the packet.

    The bad packets matching the different patterns should be blocked at
    different points.

    Verify that packets are blocked in the same order regardless of the
    direction.
    """
    api = get_midonet_api()

    router = VTM.get_router('router-000-001')
    conntrack_filter = VTM.get_chain('conntrack_filter_001')
    router.set_inbound_filter(conntrack_filter)

    # Sleep here to make sure that the settings have been propagated.
    time.sleep(5)

    service_port1 = BM.get_iface_for_port('bridge-000-001', 2)
    service_port2 = BM.get_iface_for_port('bridge-000-001', 3)

    fakesnort1 = FakeSnort(service_port1, "deadbeef")
    fakesnort2 = FakeSnort(service_port2, "cafef00d")
    try:
        fakesnort1.run()
        fakesnort2.run()

        insertion_port = BM.get_iface_for_port('bridge-000-001', 1)
        other_port = BM.get_iface_for_port('bridge-000-002', 1)

        insertion1 = api.add_l2insertion()
        insertion1.srv_port(service_port1.vport_id)
        insertion1.port(insertion_port.vport_id)
        insertion1.position(1)
        insertion1.fail_open(False)
        insertion1.vlan(1)
        insertion1.mac(insertion_port.get_mac_addr())
        insertion1.create()

        insertion2 = api.add_l2insertion()
        insertion2.srv_port(service_port2.vport_id)
        insertion2.port(insertion_port.vport_id)
        insertion2.position(2)
        insertion2.fail_open(False)
        insertion2.vlan(2)
        insertion2.mac(insertion_port.get_mac_addr())
        insertion2.create()

        time.sleep(5)

        rcv_filter = 'ip dst %s and icmp[icmptype] == 8' % insertion_port.get_ip()

        LOG.info("Sending good packet")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               receives(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port, data="f00b4c")
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending dead beef")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port,
                  data="deadbeef", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending cafe food")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port,
                  data="cafef00d", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending another good packet")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               receives(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port, data="beeff00d")
        wait_on_futures([f1, f2, f3])
    finally:
        fakesnort1.kill()
        fakesnort2.kill()
Пример #55
0
def test_l2insertion_fail_open():
    """
    Title: Test insertions with fail open

    2 L2 insertions on a port, each insertion with a different bad pattern.
    One of the insertions is set to fail open.

    Test both bad patterns can't get through.

    Take down the fail open insertion.
    Verify that that bad pattern can now get through.

    Take down the non fail open insertion.
    Verify that no traffic can get through.

    Also verify both directions
    """
    api = get_midonet_api()

    service_port1 = BM.get_iface_for_port('bridge-000-001', 2)
    service_port2 = BM.get_iface_for_port('bridge-000-001', 3)

    fakesnort1 = FakeSnort(service_port1, "deadbeef")
    fakesnort2 = FakeSnort(service_port2, "cafef00d")
    try:
        fakesnort1.run()
        fakesnort2.run()

        insertion_port = BM.get_iface_for_port('bridge-000-001', 1)
        other_port = BM.get_iface_for_port('bridge-000-001', 4)

        insertion1 = api.add_l2insertion()
        insertion1.srv_port(service_port1.vport_id)
        insertion1.port(insertion_port.vport_id)
        insertion1.position(1)
        insertion1.fail_open(True)
        insertion1.vlan(1)
        insertion1.mac(insertion_port.get_mac_addr())
        insertion1.create()

        insertion2 = api.add_l2insertion()
        insertion2.srv_port(service_port2.vport_id)
        insertion2.port(insertion_port.vport_id)
        insertion2.position(2)
        insertion2.fail_open(False)
        insertion2.vlan(2)
        insertion2.mac(insertion_port.get_mac_addr())
        insertion2.create()

        time.sleep(5)

        rcv_filter = 'ip dst %s and icmp[icmptype] == 8' % insertion_port.get_ip()
        rcv_filter_ret = 'ip src %s and icmp[icmptype] == 8' % insertion_port.get_ip()

        LOG.info("Sending good packet")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               receives(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port, data="f00b4c")
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending dead beef")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port,
                  data="deadbeef", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending cafe food")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f3 = async_assert_that(insertion_port,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port,
                  data="cafef00d", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending dead beef the other way")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               should_NOT_receive(rcv_filter_ret, within_sec(10)))
        f3 = async_assert_that(other_port,
                               should_NOT_receive(rcv_filter_ret, within_sec(10)))
        ping_port(insertion_port, other_port,
                  data="deadbeef", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        set_interface_admin_down(service_port1)
        time.sleep(5)  # give midolman a chance to see it

        LOG.info("Sending dead beef again")
        f1 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(insertion_port,
                               receives(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port, data="deadbeef")
        wait_on_futures([f1, f2])

        LOG.info("Sending dead beef the other way again")
        f1 = async_assert_that(service_port2,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = async_assert_that(other_port,
                               receives(rcv_filter_ret, within_sec(10)))
        ping_port(insertion_port, other_port, data="deadbeef")
        wait_on_futures([f1, f2])

        LOG.info("Sending cafe food again")
        f1 = async_assert_that(service_port2,
                               receives(rcv_filter, within_sec(10)))
        f2 = async_assert_that(insertion_port,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port,
                  data="cafef00d", should_succeed=False)
        wait_on_futures([f1, f2])

        set_interface_admin_down(service_port2)
        time.sleep(5)

        # nothing should get through
        LOG.info("Sending good packet")
        f1 = async_assert_that(insertion_port,
                               should_NOT_receive(rcv_filter, within_sec(10)))
        ping_port(other_port, insertion_port,
                  data="f00b4c", should_succeed=False)
        wait_on_futures([f1])

        LOG.info("Sending good packet the other way")
        f1 = async_assert_that(other_port,
                               should_NOT_receive(rcv_filter_ret, within_sec(10)))
        ping_port(insertion_port, other_port,
                  data="f00b4c", should_succeed=False)
        wait_on_futures([f1])
    finally:
        fakesnort2.kill()
        fakesnort1.kill()
Пример #56
0
def test_tracing_with_limit():
    """
    Title: Tracing with a limit

    Scenario 1:
    When: a VM sends 20 ICMP echo requests over a trace request with limit 10
    Then: Trace data appears for the ingress and the egress host,
          but only for the first 10.
    Then: when disabled and reenabled, new trace data shows up
    """
    tracerequest = VTM.get_tracerequest('ping-trace-request-limited')
    try:
        set_filters('router-000-001', 'pre_filter_001', 'post_filter_001')

        tracerequest.set_enabled(True)
        time.sleep(5)

        flowtraces = get_flow_traces(tracerequest.get_id())
        assert (len(flowtraces) == 0)

        sender = BM.get_iface_for_port('bridge-000-001', 2)
        receiver = BM.get_iface_for_port('bridge-000-002', 2)

        feed_receiver_mac(receiver)
        for i in range(0, 20):
            f2 = async_assert_that(
                receiver,
                receives('dst host 172.16.2.1 and icmp', within_sec(10)))
            f3 = async_assert_that(
                sender, receives('src host 172.16.2.1 and icmp',
                                 within_sec(10)))
            f1 = sender.ping_ipv4_addr('172.16.2.1')
            wait_on_futures([f1, f2, f3])

        time.sleep(5)

        flowtraces = get_flow_traces(tracerequest.get_id())
        assert (len(flowtraces) == 10)

        # ensure both packets were traced on both hosts
        for i in range(0, 10):
            assert (len(get_hosts(tracerequest.get_id(), flowtraces[i])) == 2)

        tracerequest.set_enabled(False)
        tracerequest.set_enabled(True)

        time.sleep(5)

        f2 = async_assert_that(
            receiver, receives('dst host 172.16.2.1 and icmp', within_sec(10)))
        f3 = async_assert_that(
            sender, receives('src host 172.16.2.1 and icmp', within_sec(10)))
        f1 = sender.ping_ipv4_addr('172.16.2.1')
        wait_on_futures([f1, f2, f3])

        time.sleep(5)

        flowtraces = get_flow_traces(tracerequest.get_id())
        assert (len(flowtraces) == 11)
    finally:
        unset_filters('router-000-001')
        tracerequest.set_enabled(False)
Пример #57
0
def test_compat_fip():
    """
    Title: Tests that FIP creation and deletions are backwards compatible

    We add a new FIP and test that a ping to it works. Afterwards we upgrade,
    delete the FIP, and test that the ping fails. Finally we add a new FIP, and
    test that the ping works again.
    """

    public_vm1 = BM.get_interface_on_vport('public_1')
    private_vm2 = BM.get_interface_on_vport('private_2')
    fip = VTM.get_resource('public_1_fip')['floatingip']
    fip_address = fip['floating_ip_address']

    agent1 = service.get_container_by_hostname('midolman1')
    agent2 = service.get_container_by_hostname('midolman2')
    cluster = service.get_container_by_hostname('cluster1')

    # Restart the cluster. Cluster should always be upgraded before agents.
    cluster.stop(wait=False)
    cluster.start(wait=True)

    # Pinging the FIP works
    check_forward_flow(private_vm2, public_vm1, fip_address, 50000, 80)

    # Restart the agents
    public_vm1_id = VTM.get_resource('public_1')['port']['id']
    private_vm2_id = VTM.get_resource('private_2')['port']['id']
    agent1.stop(wait=True)
    agent2.stop(wait=True)
    await_port_active(public_vm1_id, active=False)
    await_port_active(private_vm2_id, active=False)
    agent1.start(wait=True)
    agent2.start(wait=True)
    await_port_active(public_vm1_id, active=True)
    await_port_active(private_vm2_id, active=True)

    # Pinging the FIP after the update works
    check_forward_flow(private_vm2, public_vm1, fip_address, 50000, 80)

    # Disassociate FIP
    fip['port_id'] = None
    VTM.update_floating_ip(fip)
    # Ping does not reach FIP
    f = async_assert_that(
        public_vm1,
        should_NOT_receive("udp and src host %s" % private_vm2.get_ip(), 10))
    private_vm2.execute('hping3 -c 1 -q -2 -s 50000 -p 80 %s' % fip_address)
    wait_on_futures([f])

    # Before re-associating the FIP, we need to disable and enable SNAT on the
    # router so that the old router creation works with the new MN version
    # github.com/midonet/midonet/commit/4d5cb885decbb3bfacfece69639ccae2f570c5b3
    router = VTM.get_resource('router_1')['router']
    public_net = VTM.get_resource('public')['network']
    VTM.set_router_gateway(router, public_net, enable_snat=False)
    VTM.set_router_gateway(router, public_net, enable_snat=True)
    # Associate FIP again
    fip['port_id'] = public_vm1_id
    VTM.update_floating_ip(fip)
    # Afterwards ping works again
    check_forward_flow(private_vm2, public_vm1, fip_address, 50000, 80)
Пример #58
0
def test_router_service():
    """
    Title: TCP/UDP services on router

    Scenario 1:
    When: A client tries to access a TCP or UDP service on a router.
    Then: the router should redirect the traffic to a namespace.
    And: the namespace should respond correctly.
    """

    router = VTM.get_router('router-000-001')
    pre_filter = VTM.get_chain('pre_filter_001')
    router.set_local_redirect_chain(pre_filter)

    sender1 = BM.get_iface_for_port('bridge-000-001', 2)

    service1 = BM.get_iface_for_port('router-000-001', 2)
    service2 = BM.get_iface_for_port('router-000-001', 3)

    # setup extra parameters in namespaces
    service1.execute("ip a add 172.16.1.254/32 dev lo")
    service1.execute("arp -s 169.254.1.1 aa:bb:cc:00:11:33")
    service2.execute("ip a add 172.16.1.254/32 dev lo")
    service2.execute("arp -s 169.254.2.1 aa:bb:cc:00:11:33")

    # assert udp traffic goes to correct node
    f1 = async_assert_that(
        service1,
        receives('dst host 172.16.1.254 and udp port 500', within_sec(5)))
    f2 = async_assert_that(
        service2,
        should_NOT_receive('dst host 172.16.1.2 and udp port 500',
                           within_sec(5)))
    f3 = sender1.send_udp('aa:bb:cc:00:00:22',
                          '172.16.1.254',
                          41,
                          src_port=500,
                          dst_port=500)
    wait_on_futures([f1, f2, f3])

    # assert udp traffic is returned
    f1 = async_assert_that(
        sender1, receives('dst host 172.16.1.1 and udp port 500',
                          within_sec(5)))
    f2 = service1.send_udp('aa:bb:cc:00:11:22',
                           '172.16.1.1',
                           41,
                           src_port=500,
                           dst_port=500,
                           src_hw='aa:bb:cc:00:00:22',
                           src_ipv4='172.16.1.254')
    wait_on_futures([f1, f2])

    # assert tcp traffic goes both ways
    try:
        service2.execute("sh -c \"echo foobar | nc -l 1500\"")
        f1 = async_assert_that(
            service2,
            receives('dst host 172.16.1.254 and tcp port 1500', within_sec(5)))
        f2 = async_assert_that(
            sender1,
            receives('dst host 172.16.1.1 and tcp port 1500', within_sec(5)))
        f3 = async_assert_that(
            service1, should_NOT_receive('dst host 172.16.1.254',
                                         within_sec(5)))
        sender1.execute("sh -c \"echo foobar | nc 172.16.1.254 1500\"")
        wait_on_futures([f1, f2, f3])
    finally:
        service2.execute("pkill nc")