Esempio n. 1
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])
Esempio n. 2
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])
Esempio n. 3
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])
Esempio n. 4
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])
Esempio n. 5
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])
Esempio n. 6
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])
Esempio n. 7
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])
Esempio n. 8
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])
Esempio n. 9
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])
Esempio n. 10
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])
Esempio n. 11
0
def _async_assert_receives_icmp_frag_needed(sender, should_receive):
    icmp_filter = 'icmp[icmptype] == icmp-unreach and icmp[icmpcode] == 4'
    if should_receive:
        return async_assert_that(sender,
                                 receives(icmp_filter,
                                          within_sec(5)))
    else:
        return async_assert_that(sender,
                                 should_NOT_receive(icmp_filter,
                                                    within_sec(5)))
Esempio n. 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])
Esempio n. 13
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])
Esempio n. 14
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])
Esempio n. 15
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])
Esempio n. 16
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])
Esempio n. 17
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])
Esempio n. 18
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])
Esempio n. 19
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])
Esempio n. 20
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('', within_sec(5)))

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

    wait_on_futures([f1, f2])
Esempio n. 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('', within_sec(5)))

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

    wait_on_futures([f1, f2])
Esempio n. 22
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])
Esempio n. 23
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])
Esempio n. 24
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])
Esempio n. 25
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])
Esempio n. 26
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])
Esempio n. 27
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])
Esempio n. 28
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])
Esempio n. 29
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])
Esempio n. 30
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])
Esempio n. 31
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])
Esempio n. 32
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])
Esempio n. 33
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()
Esempio n. 34
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()
Esempio n. 35
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()
Esempio n. 36
0
def test_multi_l2insertion():
    """
    Title: Multiple insertions on a port

    2 L2 insertions on a port, each with a different bad pattern.
    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()

    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)

        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 = 'ether dst %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr()
        rcv_filter_ret = 'ether src %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr()

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

        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])

        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])

        LOG.info("Sending cafe food the other way")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(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="cafef00d", should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending another good packet the other way")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter_ret, within_sec(10)))
        f3 = async_assert_that(other_port,
                               receives(rcv_filter_ret, within_sec(10)))
        ping_port(insertion_port, other_port, data="beeff00d")
        wait_on_futures([f1, f2, f3])

    finally:
        fakesnort1.kill()
        fakesnort2.kill()
Esempio n. 37
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()
Esempio n. 38
0
def test_multi_l2insertion():
    """
    Title: Multiple insertions on a port

    2 L2 insertions on a port, each with a different bad pattern.
    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()

    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)

        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 = 'ether dst %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr(
        )
        rcv_filter_ret = 'ether src %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr(
        )

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

        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])

        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])

        LOG.info("Sending cafe food the other way")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(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="cafef00d",
                  should_succeed=False)
        wait_on_futures([f1, f2, f3])

        LOG.info("Sending another good packet the other way")
        f1 = async_assert_that(service_port1,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = async_assert_that(service_port2,
                               receives(rcv_filter_ret, within_sec(10)))
        f3 = async_assert_that(other_port,
                               receives(rcv_filter_ret, within_sec(10)))
        ping_port(insertion_port, other_port, data="beeff00d")
        wait_on_futures([f1, f2, f3])

    finally:
        fakesnort1.kill()
        fakesnort2.kill()
Esempio n. 39
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()
Esempio n. 40
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()
Esempio n. 41
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")
Esempio n. 42
0
def test_spoofed_arp_reply():
    """
    Title: Test spoofed ARP reply

    Given: Sender is bridge-000-001, port 2, at 176.16.1.1
           Receiver is bridge-000-002, port 2, at 176.16.2.1

    Scenario 1:
    When: Sender pings 176.16.2.2
    Then: The ping fails.

    Scenario 2:
    When: Receiver sends an unsolicited ARP reply to its gateway (172.16.2.254)
          with source IP 176.16.2.2 and its own MAC address as source MAC.
    Then: The router maps 176.16.2.2 to receiver's MAC address.
    And:  Sender pings 176.16.2.2
    Then: The ping succeeds.

    Scenario 3:
    When: Receiver sends an unsolicited ARP reply to its gateway (172.16.2.254)
          with source IP 176.16.1.2 and its own MAC address as source MAC.
    Then: The router ignores it because 176.16.1.2 is not in the subnet
          (172.16.2.254/24) of the port through which the ARP reply came in.
    And:  Sender pings 176.16.1.2
    Then: The ping fails.
    """
    sender = BM.get_iface_for_port('bridge-000-001', 2)
    receiver = BM.get_iface_for_port('bridge-000-002', 2)

    # 176.16.2.2 is not in the router's ARP table. Ping fails.
    f1 = async_assert_that(receiver,
                           should_NOT_receive('dst host 172.16.2.2 and icmp',
                                              within_sec(5)))
    sender.ping_ipv4_addr('172.16.2.2')
    wait_on_futures([f1])

    # Sender sends an unsolicited ARP reply with source IP 172.16.2.2,
    # which the router maps to sender's MAC address.
    router_port = VTM.get_router('router-000-001').get_port(2)
    router_mac = router_port.get_mn_resource().get_port_mac()

    receiver.send_arp_reply(receiver.get_mac_addr(), router_mac,
                            '172.16.2.2', '172.16.2.254')

    # wait for the arp reply effect to be propagated
    time.sleep(20)

    # Ping now succeeds.
    f1 = async_assert_that(receiver,
                           receives('dst host 172.16.2.2 and icmp',
                                    within_sec(5)))
    sender.ping_ipv4_addr('172.16.2.2')
    wait_on_futures([f1])

    # This ARP reply is ignored because 172.16.1.2 is not in the subnet of
    # router port 2, so a ping to 172.16.1.2 is ignored.
    f1 = async_assert_that(receiver,
                           should_NOT_receive('dst host 172.16.1.2 and icmp',
                                              within_sec(5)))
    receiver.send_arp_reply(receiver.get_mac_addr(), router_mac,
                            '172.16.1.2', '172.16.2.254')
    sender.ping_ipv4_addr('172.16.1.2')
    wait_on_futures([f1])
Esempio n. 43
0
def test_basic_l2insertion():
    """
    Title: Basic insertion functionallity

    L2Service insertion on 1, which redirects traffic through port 3.
    Good traffic should go through. Traffic that matches the bad pattern
    should be dropped.
    """
    api = get_midonet_api()

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

    fakesnort = FakeSnort(service_port, "deadbeef")
    fakesnort.run()
    try:
        insertion_port = BM.get_iface_for_port('bridge-000-001', 1)
        insertion = api.add_l2insertion()
        insertion.srv_port(service_port.vport_id)
        insertion.port(insertion_port.vport_id)
        insertion.position(1)
        insertion.fail_open(False)
        insertion.mac(insertion_port.get_mac_addr())
        insertion.create()

        time.sleep(5)

        other_port = BM.get_iface_for_port('bridge-000-001', 3)

        rcv_filter = 'ether dst %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr(
        )
        rcv_filter_ret = 'ether src %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr(
        )
        LOG.info("Sending good packet")
        f1 = async_assert_that(service_port,
                               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="f00b4c")
        wait_on_futures([f1, f2])

        LOG.info("Sending dead beef")
        f1 = async_assert_that(service_port,
                               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="deadbeef",
                  should_succeed=False)
        wait_on_futures([f1, f2])

        LOG.info("Sending another good packet")
        f1 = async_assert_that(service_port,
                               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="f00b4c")
        wait_on_futures([f1, f2])

        LOG.info("Sending bad packet the other way")
        f1 = async_assert_that(service_port,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = 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])

        LOG.info("Sending good packet the other way")
        f1 = async_assert_that(service_port,
                               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="b00f00")
        wait_on_futures([f1, f2])
    finally:
        fakesnort.kill()
Esempio n. 44
0
def test_spoofed_arp_reply():
    """
    Title: Test spoofed ARP reply

    Given: Sender is bridge-000-001, port 2, at 176.16.1.1
           Receiver is bridge-000-002, port 2, at 176.16.2.1

    Scenario 1:
    When: Sender pings 176.16.2.2
    Then: The ping fails.

    Scenario 2:
    When: Receiver sends an unsolicited ARP reply to its gateway (172.16.2.254)
          with source IP 176.16.2.2 and its own MAC address as source MAC.
    Then: The router maps 176.16.2.2 to receiver's MAC address.
    And:  Sender pings 176.16.2.2
    Then: The ping succeeds.

    Scenario 3:
    When: Receiver sends an unsolicited ARP reply to its gateway (172.16.2.254)
          with source IP 176.16.1.2 and its own MAC address as source MAC.
    Then: The router ignores it because 176.16.1.2 is not in the subnet
          (172.16.2.254/24) of the port through which the ARP reply came in.
    And:  Sender pings 176.16.1.2
    Then: The ping fails.
    """
    sender = BM.get_iface_for_port('bridge-000-001', 2)
    receiver = BM.get_iface_for_port('bridge-000-002', 2)

    # 176.16.2.2 is not in the router's ARP table. Ping fails.
    f1 = async_assert_that(
        receiver,
        should_NOT_receive('dst host 172.16.2.2 and icmp', within_sec(5)))
    sender.ping_ipv4_addr('172.16.2.2')
    wait_on_futures([f1])

    # Sender sends an unsolicited ARP reply with source IP 172.16.2.2,
    # which the router maps to sender's MAC address.
    router_port = VTM.get_router('router-000-001').get_port(2)
    router_mac = router_port.get_mn_resource().get_port_mac()

    receiver.send_arp_reply(receiver.get_mac_addr(), router_mac, '172.16.2.2',
                            '172.16.2.254')

    # wait for the arp reply effect to be propagated
    time.sleep(20)

    # Ping now succeeds.
    f1 = async_assert_that(
        receiver, receives('dst host 172.16.2.2 and icmp', within_sec(5)))
    sender.ping_ipv4_addr('172.16.2.2')
    wait_on_futures([f1])

    # This ARP reply is ignored because 172.16.1.2 is not in the subnet of
    # router port 2, so a ping to 172.16.1.2 is ignored.
    f1 = async_assert_that(
        receiver,
        should_NOT_receive('dst host 172.16.1.2 and icmp', within_sec(5)))
    receiver.send_arp_reply(receiver.get_mac_addr(), router_mac, '172.16.1.2',
                            '172.16.2.254')
    sender.ping_ipv4_addr('172.16.1.2')
    wait_on_futures([f1])
Esempio n. 45
0
def test_basic_l2insertion():
    """
    Title: Basic insertion functionallity

    L2Service insertion on 1, which redirects traffic through port 3.
    Good traffic should go through. Traffic that matches the bad pattern
    should be dropped.
    """
    api = get_midonet_api()

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

    fakesnort = FakeSnort(service_port, "deadbeef")
    fakesnort.run()
    try:
        insertion_port = BM.get_iface_for_port('bridge-000-001', 1)
        insertion = api.add_l2insertion()
        insertion.srv_port(service_port.vport_id)
        insertion.port(insertion_port.vport_id)
        insertion.position(1)
        insertion.fail_open(False)
        insertion.mac(insertion_port.get_mac_addr())
        insertion.create()

        time.sleep(5)

        other_port = BM.get_iface_for_port('bridge-000-001', 3)

        rcv_filter = 'ether dst %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr()
        rcv_filter_ret = 'ether src %s and icmp[icmptype] == 8' % insertion_port.get_mac_addr()
        LOG.info("Sending good packet")
        f1 = async_assert_that(service_port,
                               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="f00b4c")
        wait_on_futures([f1, f2])

        LOG.info("Sending dead beef")
        f1 = async_assert_that(service_port,
                               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="deadbeef",
                  should_succeed=False)
        wait_on_futures([f1, f2])

        LOG.info("Sending another good packet")
        f1 = async_assert_that(service_port,
                               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="f00b4c")
        wait_on_futures([f1, f2])

        LOG.info("Sending bad packet the other way")
        f1 = async_assert_that(service_port,
                               receives(rcv_filter_ret, within_sec(10)))
        f2 = 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])

        LOG.info("Sending good packet the other way")
        f1 = async_assert_that(service_port,
                               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="b00f00")
        wait_on_futures([f1, f2])
    finally:
        fakesnort.kill()
Esempio n. 46
0
def expect_return_dropped(dst_port_no):
    return async_assert_that(
        downlink_iface(),
        should_NOT_receive(return_filter(dst_port_no), within_sec(10)),
        'Return flow gets dropped.')
Esempio n. 47
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")