Example #1
0
def stream(request, drone, ports):
    global proto_number

    # add a stream
    stream_id = ost_pb.StreamIdList()
    stream_id.port_id.CopyFrom(ports.tx.port_id[0])
    stream_id.stream_id.add().id = 1
    log.info('adding tx_stream %d' % stream_id.stream_id[0].id)
    drone.addStream(stream_id)

    # configure the stream
    stream_cfg = ost_pb.StreamConfigList()
    stream_cfg.port_id.CopyFrom(ports.tx.port_id[0])
    s = stream_cfg.stream.add()
    s.stream_id.id = stream_id.stream_id[0].id
    s.core.is_enabled = True
    s.control.packets_per_sec = 100
    s.control.num_packets = 10

    # setup stream protocols as mac:eth2:ip:udp:payload
    s.ClearField("protocol")
    protos = request.param.split()
    for p in protos:
        s.protocol.add().protocol_id.id = proto_number[p]

    def fin():
        # delete streams
        log.info('deleting tx_stream %d' % stream_id.stream_id[0].id)
        drone.deleteStream(stream_id)

    request.addfinalizer(fin)

    return stream_cfg
Example #2
0
def stream(request, drone, ports):
    global proto_number

    # add a stream
    stream_id = ost_pb.StreamIdList()
    stream_id.port_id.CopyFrom(ports.tx.port_id[0])
    stream_id.stream_id.add().id = 1
    log.info('adding tx_stream %d' % stream_id.stream_id[0].id)
    drone.addStream(stream_id)

    # configure the stream
    stream_cfg = ost_pb.StreamConfigList()
    stream_cfg.port_id.CopyFrom(ports.tx.port_id[0])
    s = stream_cfg.stream.add()
    s.stream_id.id = stream_id.stream_id[0].id
    s.core.is_enabled = True
    s.control.packets_per_sec = 100
    s.control.num_packets = 10

    # XXX: don't setup any stream protocols

    def fin():
        # delete streams
        log.info('deleting tx_stream %d' % stream_id.stream_id[0].id)
        drone.deleteStream(stream_id)

    request.addfinalizer(fin)

    return stream_cfg
Example #3
0
            rx_port_number = port.port_id.id

    if tx_port_number < 0 or rx_port_number < 0:
        log.warning('loopback port not found')
        sys.exit(1)

    print('Using port %d as tx/rx port(s)' % tx_port_number)

    tx_port = ost_pb.PortIdList()
    tx_port.port_id.add().id = tx_port_number

    rx_port = ost_pb.PortIdList()
    rx_port.port_id.add().id = rx_port_number

    # add a stream
    stream_id = ost_pb.StreamIdList()
    stream_id.port_id.CopyFrom(tx_port.port_id[0])
    stream_id.stream_id.add().id = 1
    log.info('adding tx_stream %d' % stream_id.stream_id[0].id)
    drone.addStream(stream_id)

    # configure the stream
    stream_cfg = ost_pb.StreamConfigList()
    stream_cfg.port_id.CopyFrom(tx_port.port_id[0])
    s = stream_cfg.stream.add()
    s.stream_id.id = stream_id.stream_id[0].id
    s.core.is_enabled = True
    s.control.num_packets = 10

    # setup stream protocols as mac:eth2:ip4:udp:payload
    p = s.protocol.add()
Example #4
0
def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports,
                             stream_clear, emul_ports, dgid_list, vlan_cfg,
                             ip_ver):
    # ----------------------------------------------------------------- #
    # TESTCASE: Emulate multiple IPv4 device per multiple single-tag VLANs
    #
    #          +- DUT -+
    #       .1/         \.1
    #        /           \
    # 10.1.1/24        10.1.2/24
    # 1234:1/96        1234:2/96
    #  [vlans]          [vlans]
    #     /                  \
    #    /.101-103            \.101-103
    # Host1(s)              Host2(s)
    # ----------------------------------------------------------------- #

    num_vlans = 1
    for vcfg in vlan_cfg:
        num_vlans = num_vlans * vcfg['count']
    test_multiEmulDevPerVlan.vlan_cfg = vlan_cfg
    num_devs_per_vlan = 3
    has_ip4 = True if 4 in ip_ver else False
    has_ip6 = True if 6 in ip_ver else False
    if has_ip4:
        tx_ip4_base = 0x0a010165
        rx_ip4_base = 0x0a010265
    if has_ip6:
        tx_ip6_base = ip6_address('1234:1::65/96')
        rx_ip6_base = ip6_address('1234:2::65/96')

    # configure vlans on the DUT
    dut_vlans(request, dut_ports)

    assert len(dut_vlans.vlans) == num_vlans
    vlan_filter = []
    for i in range(len(dut_vlans.vlans)):
        vlan_filter.append('')
        ids = dut_vlans.vlans[i].split('.')
        for j in range(len(ids)):
            filter = '(frame[<ofs>:4]==<tpid>:<id>)' \
                        .replace('<ofs>', str(12+j*4)) \
                        .replace('<tpid>', '{:04x}'.format(
                            vlan_cfg[j].get('tpid', 0x8100))) \
                        .replace('<id>', '{:04x}'.format(int(ids[j])))
            if len(vlan_filter[i]) > 0:
                vlan_filter[i] += ' && '
            vlan_filter[i] += filter
        print i, vlan_filter[i]

    # configure the tx device(s)
    devgrp_cfg = ost_pb.DeviceGroupConfigList()
    devgrp_cfg.port_id.CopyFrom(ports.tx.port_id[0])
    dg = devgrp_cfg.device_group.add()
    dg.device_group_id.id = dgid_list.tx.device_group_id[0].id
    dg.core.name = "Host1"
    for vcfg in vlan_cfg:
        v = dg.encap.Extensions[emul.vlan].stack.add()
        v.vlan_tag = vcfg['base']
        v.count = vcfg['count']
        if 'tpid' in vcfg:
            v.tpid = vcfg['tpid']
        if 'step' in vcfg:
            v.step = vcfg['step']
    dg.device_count = num_devs_per_vlan
    dg.Extensions[emul.mac].address = 0x000102030a01
    if has_ip4:
        ip = dg.Extensions[emul.ip4]
        ip.address = tx_ip4_base
        ip.prefix_length = 24
        ip.default_gateway = (tx_ip4_base & 0xffffff00) | 0x01
    if has_ip6:
        ip = dg.Extensions[emul.ip6]
        ip.address.CopyFrom(tx_ip6_base.ip6)
        ip.prefix_length = tx_ip6_base.prefixlen
        ip.default_gateway.CopyFrom(tx_ip6_base.gateway)

    drone.modifyDeviceGroup(devgrp_cfg)

    # configure the rx device(s)
    devgrp_cfg = ost_pb.DeviceGroupConfigList()
    devgrp_cfg.port_id.CopyFrom(ports.rx.port_id[0])
    dg = devgrp_cfg.device_group.add()
    dg.device_group_id.id = dgid_list.rx.device_group_id[0].id
    dg.core.name = "Host1"
    for vcfg in vlan_cfg:
        v = dg.encap.Extensions[emul.vlan].stack.add()
        v.vlan_tag = vcfg['base']
        v.count = vcfg['count']
        if 'tpid' in vcfg:
            v.tpid = vcfg['tpid']
        if 'step' in vcfg:
            v.step = vcfg['step']
    dg.device_count = num_devs_per_vlan
    dg.Extensions[emul.mac].address = 0x000102030b01
    if has_ip4:
        ip = dg.Extensions[emul.ip4]
        ip.address = rx_ip4_base
        ip.prefix_length = 24
        ip.default_gateway = (rx_ip4_base & 0xffffff00) | 0x01
    if has_ip6:
        ip = dg.Extensions[emul.ip6]
        ip.address.CopyFrom(rx_ip6_base.ip6)
        ip.prefix_length = rx_ip6_base.prefixlen
        ip.default_gateway.CopyFrom(rx_ip6_base.gateway)

    drone.modifyDeviceGroup(devgrp_cfg)

    # add the tx stream(s) - we need more than one stream
    stream_id = ost_pb.StreamIdList()
    stream_id.port_id.CopyFrom(ports.tx.port_id[0])
    for i in range(num_vlans * len(ip_ver)):
        stream_id.stream_id.add().id = i
        log.info('adding tx_stream %d' % stream_id.stream_id[i].id)

    drone.addStream(stream_id)

    # configure the tx stream(s)
    stream_cfg = ost_pb.StreamConfigList()
    stream_cfg.port_id.CopyFrom(ports.tx.port_id[0])
    for i in range(num_vlans):
        for j in range(len(ip_ver)):
            idx = i * len(ip_ver) + j
            s = stream_cfg.stream.add()
            s.stream_id.id = stream_id.stream_id[idx].id
            s.core.name = 'stream ' + str(s.stream_id.id)
            s.core.is_enabled = True
            s.core.ordinal = idx
            s.core.frame_len = 1024
            s.control.packets_per_sec = 100
            s.control.num_packets = num_devs_per_vlan

            # setup stream protocols as mac:vlan:eth2:ip4:udp:payload
            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kMacFieldNumber
            p.Extensions[mac].dst_mac_mode = Mac.e_mm_resolve
            p.Extensions[mac].src_mac_mode = Mac.e_mm_resolve

            ids = dut_vlans.vlans[i].split('.')
            for id, idx in zip(ids, range(len(ids))):
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kVlanFieldNumber
                p.Extensions[vlan].vlan_tag = int(id)
                if 'tpid' in vlan_cfg[idx]:
                    p.Extensions[vlan].tpid = vlan_cfg[idx]['tpid']
                    p.Extensions[vlan].is_override_tpid = True

            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber

            if ip_ver[j] == 4:
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber
                ip = p.Extensions[ip4]
                ip.src_ip = tx_ip4_base
                ip.src_ip_mode = Ip4.e_im_inc_host
                ip.src_ip_count = num_devs_per_vlan
                ip.dst_ip = rx_ip4_base
                ip.dst_ip_mode = Ip4.e_im_inc_host
                ip.dst_ip_count = num_devs_per_vlan
            elif ip_ver[j] == 6:
                p = s.protocol.add()
                p.protocol_id.id = ost_pb.Protocol.kIp6FieldNumber
                ip = p.Extensions[ip6]

                ip.src_addr_hi = tx_ip6_base.ip6.hi
                ip.src_addr_lo = tx_ip6_base.ip6.lo
                ip.src_addr_mode = Ip6.kIncHost
                ip.src_addr_count = num_devs_per_vlan
                ip.src_addr_prefix = tx_ip6_base.prefixlen

                ip.dst_addr_hi = rx_ip6_base.ip6.hi
                ip.dst_addr_lo = rx_ip6_base.ip6.lo
                ip.dst_addr_mode = Ip6.kIncHost
                ip.dst_addr_count = num_devs_per_vlan
                ip.dst_addr_prefix = rx_ip6_base.prefixlen
            else:
                assert false  # unreachable

            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kUdpFieldNumber
            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber

            log.info('configuring tx_stream %d' % stream_id.stream_id[idx].id)

    drone.modifyStream(stream_cfg)

    # clear arp/ndp on DUT
    for i in range(num_vlans):
        vrf = 'vrf' + str(i + 1)

        sudo('ip netns exec ' + vrf + ' ip neigh flush all')
        arp_cache = sudo('ip netns exec ' + vrf + ' ip neigh show')
        assert re.search('10.1.[1-2].20[1-5].*lladdr', arp_cache) == None
        assert re.search('1234:[1-2]::\[\da-f]+.*lladdr', arp_cache) == None

    # wait for interface to do DAD? Otherwise we don't get replies for NS
    # FIXME: find alternative to sleep
    if has_ip6:
        time.sleep(5)

    # clear ARP/NDP cache
    log.info('clearing ARP/NDP cache on tx/rx port')
    drone.clearDeviceNeighbors(emul_ports)

    log.info('retrieving ARP/NDP entries on tx port to verify clear')
    device_list = drone.getDeviceList(emul_ports.port_id[0])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[0])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on tx port')
    for devcfg, device in zip(device_config, devices):
        if has_ip4:
            for arp in device.arp:
                print('%s: %s %012x' % (str(ipaddress.ip_address(
                    devcfg.ip4)), str(ipaddress.ip_address(arp.ip4)), arp.mac))
            assert (len(device.arp) == 0)
        if has_ip6:
            for ndp in device.ndp:
                print('%s: %s %012x' % (str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
            assert (len(device.ndp) == 0)

    log.info('retrieving ARP/NDP entries on rx port to verify clear')
    device_list = drone.getDeviceList(emul_ports.port_id[1])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[1])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on rx port')
    for devcfg, device in zip(device_config, devices):
        if has_ip4:
            for arp in device.arp:
                print('%s: %s %012x' % (str(ipaddress.ip_address(
                    devcfg.ip4)), str(ipaddress.ip_address(arp.ip4)), arp.mac))
            assert (len(device.arp) == 0)
        if has_ip6:
            for ndp in device.ndp:
                print('%s: %s %012x' % (str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
            assert (len(device.ndp) == 0)

    # resolve ARP/NDP on tx/rx ports
    log.info('resolving Neighbors on tx/rx ports ...')
    drone.startCapture(emul_ports)
    drone.resolveDeviceNeighbors(emul_ports)
    time.sleep(3)
    drone.stopCapture(emul_ports)

    # verify ARP/NDP Requests sent out from tx port
    buff = drone.getCaptureBuffer(emul_ports.port_id[0])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    log.info('dumping Tx capture buffer (all)')
    cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
    print(cap_pkts)
    log.info('dumping Tx capture buffer (all pkts - vlans only)')
    cap_pkts = subprocess.check_output([
        tshark, '-nr', 'capture.pcap', '-Tfields', '-eframe.number',
        '-eieee8021ad.id', '-evlan.id'
    ])
    print(cap_pkts)
    log.info('dumping Tx capture buffer (filtered)')
    for i in range(num_vlans):
        for j in range(len(ip_ver)):
            if ip_ver[j] == 4:
                filter = vlan_filter[i] + ' && (arp.opcode == 1)' \
                    ' && (arp.src.proto_ipv4 == 10.1.1.<x>)' \
                    ' && (arp.dst.proto_ipv4 == 10.1.1.1)' \
                    ' && !expert.severity'
            elif ip_ver[j] == 6:
                filter = vlan_filter[i] + ' && (icmpv6.type == 135)' \
                    ' && (ipv6.src == 1234:1::<x>)' \
                    ' && (icmpv6.nd.ns.target_address == 1234:1::1)' \
                    ' && !expert.severity'
            for k in range(num_devs_per_vlan):
                if ip_ver[j] == 4:
                    filter = filter.replace('<x>', str(101 + k))
                elif ip_ver[j] == 6:
                    filter = filter.replace('<x>', format(0x65 + k, 'x'))
                print filter
                cap_pkts = subprocess.check_output(
                    [tshark, '-nr', 'capture.pcap', '-Y', filter])
                print(cap_pkts)
                assert cap_pkts.count('\n') == 1

    # verify ARP/NDP Requests sent out from rx port
    buff = drone.getCaptureBuffer(emul_ports.port_id[1])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    log.info('dumping Rx capture buffer (all)')
    cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
    print(cap_pkts)
    log.info('dumping Rx capture buffer (all pkts - vlans only)')
    cap_pkts = subprocess.check_output([
        tshark, '-nr', 'capture.pcap', '-Tfields', '-eframe.number',
        '-eieee8021ad.id', '-evlan.id'
    ])
    print(cap_pkts)
    log.info('dumping Rx capture buffer (filtered)')
    for i in range(num_vlans):
        for j in range(len(ip_ver)):
            if ip_ver[j] == 4:
                filter = vlan_filter[i] + ' && (arp.opcode == 1)' \
                    ' && (arp.src.proto_ipv4 == 10.1.2.<x>)' \
                    ' && (arp.dst.proto_ipv4 == 10.1.2.1)' \
                    ' && !expert.severity'
            elif ip_ver[j] == 6:
                filter = vlan_filter[i] + ' && (icmpv6.type == 135)' \
                    ' && (ipv6.src == 1234:2::<x>)' \
                    ' && (icmpv6.nd.ns.target_address == 1234:2::1)' \
                    ' && !expert.severity'
            for k in range(num_devs_per_vlan):
                if ip_ver[j] == 4:
                    filter = filter.replace('<x>', str(101 + k))
                elif ip_ver[j] == 6:
                    filter = filter.replace('<x>', format(0x65 + k, 'x'))
                print filter
                cap_pkts = subprocess.check_output(
                    [tshark, '-nr', 'capture.pcap', '-Y', filter])
                print(cap_pkts)
                assert cap_pkts.count('\n') == 1

    # retrieve and verify ARP/NDP Table on tx/rx ports
    log.info('retrieving ARP/NDP entries on tx port')
    device_list = drone.getDeviceList(emul_ports.port_id[0])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[0])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on tx port')
    for devcfg, device in zip(device_config, devices):
        vlans = ''
        for v in devcfg.vlan:
            vlans += str(v & 0xffff) + ' '
        if has_ip4:
            resolved = False
            for arp in device.arp:
                print('%s%s: %s %012x' %
                      (vlans, str(ipaddress.ip_address(devcfg.ip4)),
                       str(ipaddress.ip_address(arp.ip4)), arp.mac))
                if (arp.ip4 == devcfg.ip4_default_gateway) and (arp.mac):
                    resolved = True
            assert resolved
        if has_ip6:
            resolved = False
            for ndp in device.ndp:
                print('%s%s: %s %012x' % (vlans, str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
                if (ndp.ip6 == devcfg.ip6_default_gateway) and (ndp.mac):
                    resolved = True
            assert resolved

    log.info('retrieving ARP entries on rx port')
    device_list = drone.getDeviceList(emul_ports.port_id[1])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[1])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on rx port')
    for devcfg, device in zip(device_config, devices):
        vlans = ''
        for v in devcfg.vlan:
            vlans += str(v & 0xffff) + ' '
        if has_ip4:
            resolved = False
            for arp in device.arp:
                print('%s%s: %s %012x' %
                      (vlans, str(ipaddress.ip_address(devcfg.ip4)),
                       str(ipaddress.ip_address(arp.ip4)), arp.mac))
                if (arp.ip4 == devcfg.ip4_default_gateway) and (arp.mac):
                    resolved = True
            assert resolved
        if has_ip6:
            resolved = False
            for ndp in device.ndp:
                print('%s%s: %s %012x' % (vlans, str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
                if (ndp.ip6 == devcfg.ip6_default_gateway) and (ndp.mac):
                    resolved = True
            assert resolved

    # ping the tx devices from the DUT
    for i in range(num_vlans):
        vrf = 'vrf' + str(i + 1)
        for j in range(num_devs_per_vlan):
            if has_ip4:
                out = sudo('ip netns exec ' + vrf + ' ping -c3 10.1.1.' +
                           str(101 + j),
                           warn_only=True)
                assert '100% packet loss' not in out
            if has_ip6:
                out = sudo('ip netns exec ' + vrf + ' ping -6 -c3 1234:1::' +
                           format(101 + j, 'x'),
                           warn_only=True)
                assert '100% packet loss' not in out

    # ping the rx devices from the DUT
    for i in range(num_vlans):
        vrf = 'vrf' + str(i + 1)
        for j in range(num_devs_per_vlan):
            if has_ip4:
                out = sudo('ip netns exec ' + vrf + ' ping -c3 10.1.2.' +
                           str(101 + j),
                           warn_only=True)
                assert '100% packet loss' not in out
            if has_ip6:
                out = sudo('ip netns exec ' + vrf + ' ping -6 -c3 1234:2::' +
                           format(101 + j, 'x'),
                           warn_only=True)
                assert '100% packet loss' not in out

    # we are all set - send data stream(s)
    drone.startCapture(ports.rx)
    drone.startTransmit(ports.tx)
    log.info('waiting for transmit to finish ...')
    time.sleep(5)
    drone.stopTransmit(ports.tx)
    drone.stopCapture(ports.rx)

    # verify data packets received on rx port
    buff = drone.getCaptureBuffer(ports.rx.port_id[0])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    log.info('dumping Rx capture buffer (all)')
    cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
    print(cap_pkts)
    log.info('dumping Rx capture buffer (all pkts - vlans only)')
    cap_pkts = subprocess.check_output([
        tshark, '-nr', 'capture.pcap', '-Tfields', '-eframe.number',
        '-eieee8021ad.id', '-evlan.id'
    ])
    print(cap_pkts)
    log.info('dumping Rx capture buffer (filtered)')
    for i in range(num_vlans):
        for j in range(num_devs_per_vlan):
            if has_ip4:
                filter = vlan_filter[i] + \
                      ' && (ip.src == 10.1.1.' + str(101+j) + ')' \
                      ' && (ip.dst == 10.1.2.' + str(101+j) + ')' \
                      ' && (eth.dst == 00:01:02:03:0b:' + format(1+j, '02x')+')'
                print('filter: %s' % filter)
                cap_pkts = subprocess.check_output(
                    [tshark, '-nr', 'capture.pcap', '-Y', filter])
                print(cap_pkts)
                assert cap_pkts.count('\n') == 1
            if has_ip6:
                filter = vlan_filter[i] \
                    + ' && (ipv6.src == 1234:1::' + format(101+j, 'x') + ')' \
                    + ' && (ipv6.dst == 1234:2::' + format(101+j, 'x') + ')' \
                    + ' && (eth.dst == 00:01:02:03:0b:' \
                                        + format(1+j, '02x') + ')'
                print('filter: %s' % filter)
                cap_pkts = subprocess.check_output(
                    [tshark, '-nr', 'capture.pcap', '-Y', filter])
                print(cap_pkts)
                assert cap_pkts.count('\n') == 1
    os.remove('capture.pcap')
Example #5
0
def test_multiEmulDevNoVlan(drone, ports, dut, dut_ports, dut_ip, stream_clear,
                            emul_ports, dgid_list, dev_cfg):
    # ----------------------------------------------------------------- #
    # TESTCASE: Emulate multiple IPv4 devices (no vlans)
    #          DUT
    #        /.1   \.1
    #       /       \
    # 10.10.1/24  10.10.2/24
    # 1234::1/96  1234::2/96
    #     /           \
    #    /.101-105     \.101-105
    #  Host1(s)      Host2(s)
    # ----------------------------------------------------------------- #

    num_devs = 5
    has_ip4 = True if 4 in dev_cfg['ip_ver'] else False
    has_ip6 = True if 6 in dev_cfg['ip_ver'] else False
    mac_step = dev_cfg['mac_step']
    ip_step = dev_cfg['ip_step']

    # configure the tx device(s)
    devgrp_cfg = ost_pb.DeviceGroupConfigList()
    devgrp_cfg.port_id.CopyFrom(ports.tx.port_id[0])
    dg = devgrp_cfg.device_group.add()
    dg.device_group_id.id = dgid_list.tx.device_group_id[0].id
    dg.core.name = "Host1"
    dg.device_count = num_devs
    dg.Extensions[emul.mac].address = 0x000102030a01
    if (mac_step != 1):
        dg.Extensions[emul.mac].step = mac_step
    if has_ip4:
        ip = dg.Extensions[emul.ip4]
        ip.address = 0x0a0a0165
        ip.prefix_length = 24
        if (ip_step != 1):
            ip.step = ip_step
        ip.default_gateway = 0x0a0a0101
    if has_ip6:
        ip = dg.Extensions[emul.ip6]
        ip6addr = ip6_address('1234:1::65/96')
        ip.address.CopyFrom(ip6addr.ip6)
        ip.prefix_length = ip6addr.prefixlen
        if (ip_step != 1):
            ip.step.CopyFrom(ip6_address(ip_step).ip6)
        ip.default_gateway.CopyFrom(ip6addr.gateway)

    drone.modifyDeviceGroup(devgrp_cfg)

    # configure the rx device(s)
    devgrp_cfg = ost_pb.DeviceGroupConfigList()
    devgrp_cfg.port_id.CopyFrom(ports.rx.port_id[0])
    dg = devgrp_cfg.device_group.add()
    dg.device_group_id.id = dgid_list.rx.device_group_id[0].id
    dg.core.name = "Host1"
    dg.device_count = num_devs
    dg.Extensions[emul.mac].address = 0x000102030b01
    if (mac_step != 1):
        dg.Extensions[emul.mac].step = mac_step
    if has_ip4:
        ip = dg.Extensions[emul.ip4]
        ip.address = 0x0a0a0265
        ip.prefix_length = 24
        if (ip_step != 1):
            ip.step = ip_step
        ip.default_gateway = 0x0a0a0201
    if has_ip6:
        ip = dg.Extensions[emul.ip6]
        ip6addr = ip6_address('1234:2::65/96')
        ip.address.CopyFrom(ip6addr.ip6)
        ip.prefix_length = ip6addr.prefixlen
        if (ip_step != 1):
            ip.step.CopyFrom(ip6_address(ip_step).ip6)
        ip.default_gateway.CopyFrom(ip6addr.gateway)

    drone.modifyDeviceGroup(devgrp_cfg)

    # add the tx stream(s) - we may need more than one
    stream_id = ost_pb.StreamIdList()
    stream_id.port_id.CopyFrom(ports.tx.port_id[0])
    for i in range(len(dev_cfg['ip_ver'])):
        stream_id.stream_id.add().id = i
        log.info('adding tx_stream %d' % stream_id.stream_id[i].id)

    drone.addStream(stream_id)

    # configure the tx stream(s)
    stream_cfg = ost_pb.StreamConfigList()
    stream_cfg.port_id.CopyFrom(ports.tx.port_id[0])
    for i in range(len(dev_cfg['ip_ver'])):
        s = stream_cfg.stream.add()
        s.stream_id.id = stream_id.stream_id[i].id
        s.core.is_enabled = True
        s.core.frame_len = 1024
        s.control.packets_per_sec = 100
        s.control.num_packets = 10

        # setup stream protocols as mac:eth2:ip:udp:payload
        p = s.protocol.add()
        p.protocol_id.id = ost_pb.Protocol.kMacFieldNumber
        p.Extensions[mac].dst_mac_mode = Mac.e_mm_resolve
        p.Extensions[mac].src_mac_mode = Mac.e_mm_resolve

        p = s.protocol.add()
        p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber

        if dev_cfg['ip_ver'][i] == 4:
            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber
            ip = None
            ip = p.Extensions[ip4]
            ip.src_ip = 0x0a0a0165
            if ip_step == 1:
                ip.src_ip_mode = Ip4.e_im_inc_host
                ip.src_ip_count = num_devs
            else:
                vf = p.variable_field.add()
                vf.type = ost_pb.VariableField.kCounter32
                vf.offset = 12
                vf.mask = 0x000000FF
                vf.value = 0x00000065
                vf.step = ip_step
                vf.mode = ost_pb.VariableField.kIncrement
                vf.count = num_devs
            ip.dst_ip = 0x0a0a0265
            if ip_step == 1:
                ip.dst_ip_mode = Ip4.e_im_inc_host
                ip.dst_ip_count = num_devs
            else:
                vf = p.variable_field.add()
                vf.type = ost_pb.VariableField.kCounter32
                vf.offset = 16
                vf.mask = 0x000000FF
                vf.value = 0x00000065
                vf.step = ip_step
                vf.mode = ost_pb.VariableField.kIncrement
                vf.count = num_devs
        elif dev_cfg['ip_ver'][i] == 6:
            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kIp6FieldNumber
            ip = p.Extensions[ip6]
            ip6addr = ip6_address('1234:1::65/96')
            ip.src_addr_hi = ip6addr.ip6.hi
            ip.src_addr_lo = ip6addr.ip6.lo
            if ip_step == 1:
                ip.src_addr_mode = Ip6.kIncHost
                ip.src_addr_count = num_devs
                ip.src_addr_prefix = ip6addr.prefixlen
            else:
                vf = p.variable_field.add()
                vf.type = ost_pb.VariableField.kCounter32
                vf.offset = 20
                vf.mask = 0xFFFFFFFF
                vf.value = 0x00000065
                vf.step = ip_step
                vf.mode = ost_pb.VariableField.kIncrement
                vf.count = num_devs
            ip6addr = ip6_address('1234:2::65/96')
            ip.dst_addr_hi = ip6addr.ip6.hi
            ip.dst_addr_lo = ip6addr.ip6.lo
            if ip_step == 1:
                ip.dst_addr_mode = Ip6.kIncHost
                ip.dst_addr_count = num_devs
                ip.dst_addr_prefix = ip6addr.prefixlen
            else:
                vf = p.variable_field.add()
                vf.type = ost_pb.VariableField.kCounter32
                vf.offset = 36
                vf.mask = 0xFFFFFFFF
                vf.value = 0x00000065
                vf.step = ip_step
                vf.mode = ost_pb.VariableField.kIncrement
                vf.count = num_devs
        else:
            assert False  # unreachable

        s.protocol.add().protocol_id.id = ost_pb.Protocol.kUdpFieldNumber
        s.protocol.add().protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber

        log.info('configuring tx_stream %d' % stream_id.stream_id[i].id)

    drone.modifyStream(stream_cfg)

    # FIXME(needed?): clear tx/rx stats
    log.info('clearing tx/rx stats')
    drone.clearStats(ports.tx)
    drone.clearStats(ports.rx)

    # clear arp/ndp on DUT
    sudo('ip neigh flush all')
    arp_cache = run('ip neigh show')
    assert re.search('10.10.[1-2].1\d\d.*lladdr', arp_cache) == None
    assert re.search('1234:[1-2]::\[\da-f]+.*lladdr', arp_cache) == None

    # wait for interface to do DAD? Otherwise we don't get replies for NS
    # FIXME: find alternative to sleep
    time.sleep(5)

    # clear ARP/NDP cache
    log.info('clearing ARP/NDP cache on tx/rx port')
    drone.clearDeviceNeighbors(emul_ports)

    log.info('retrieving ARP/NDP entries on tx port to verify clear')
    device_list = drone.getDeviceList(emul_ports.port_id[0])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[0])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on tx port')
    for devcfg, device in zip(device_config, devices):
        if has_ip4:
            for arp in device.arp:
                print('%s: %s %012x' % (str(ipaddress.ip_address(
                    devcfg.ip4)), str(ipaddress.ip_address(arp.ip4)), arp.mac))
            assert (len(device.arp) == 0)
        if has_ip6:
            for ndp in device.ndp:
                print('%s: %s %012x' % (str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
            assert (len(device.ndp) == 0)

    log.info('retrieving ARP/NDP entries on rx port to verify clear')
    device_list = drone.getDeviceList(emul_ports.port_id[1])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[1])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on rx port')
    for devcfg, device in zip(device_config, devices):
        if has_ip4:
            for arp in device.arp:
                print('%s: %s %012x' % (str(ipaddress.ip_address(
                    devcfg.ip4)), str(ipaddress.ip_address(arp.ip4)), arp.mac))
            assert (len(device.arp) == 0)
        if has_ip6:
            for ndp in device.ndp:
                print('%s: %s %012x' % (str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
            assert (len(device.ndp) == 0)

    # resolve ARP/NDP on tx/rx ports
    log.info('resolving Neighbors on tx/rx ports ...')
    drone.startCapture(emul_ports)
    drone.resolveDeviceNeighbors(emul_ports)
    time.sleep(3)
    drone.stopCapture(emul_ports)

    # verify ARP/NDP Requests sent out from tx port
    buff = drone.getCaptureBuffer(emul_ports.port_id[0])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    log.info('dumping Tx capture buffer (all)')
    cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
    print(cap_pkts)
    log.info('dumping Tx capture buffer (filtered)')
    for i in range(len(dev_cfg['ip_ver'])):
        if dev_cfg['ip_ver'][i] == 4:
            filter = '(arp.opcode == 1)' \
                ' && (arp.src.proto_ipv4 == 10.10.1.<x>)' \
                ' && (arp.dst.proto_ipv4 == 10.10.1.1)' \
                ' && !expert.severity'
        elif dev_cfg['ip_ver'][i] == 6:
            filter = '(icmpv6.type == 135)' \
                ' && (ipv6.src == 1234:1::<x>)' \
                ' && (icmpv6.nd.ns.target_address == 1234:1::1)' \
                ' && !expert.severity'
        for j in range(num_devs):
            if dev_cfg['ip_ver'][i] == 4:
                filter = filter.replace('<x>', str(101 + j * ip_step))
            elif dev_cfg['ip_ver'][i] == 6:
                filter = filter.replace('<x>', format(0x65 + j * ip_step, 'x'))
            #print filter
            cap_pkts = subprocess.check_output(
                [tshark, '-nr', 'capture.pcap', '-Y', filter])
            print(cap_pkts)
            assert cap_pkts.count('\n') == 1

    # verify ARP/NDP Requests sent out from rx port
    buff = drone.getCaptureBuffer(emul_ports.port_id[1])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    log.info('dumping Rx capture buffer (all)')
    cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
    print(cap_pkts)
    log.info('dumping Rx capture buffer (filtered)')
    for i in range(len(dev_cfg['ip_ver'])):
        if dev_cfg['ip_ver'][i] == 4:
            filter = '(arp.opcode == 1)' \
                ' && (arp.src.proto_ipv4 == 10.10.2.<x>)' \
                ' && (arp.dst.proto_ipv4 == 10.10.2.1)' \
                ' && !expert.severity'
        elif dev_cfg['ip_ver'][i] == 6:
            filter = '(icmpv6.type == 135)' \
                ' && (ipv6.src == 1234:2::<x>)' \
                ' && (icmpv6.nd.ns.target_address == 1234:2::1)' \
                ' && !expert.severity'
        for j in range(num_devs):
            if dev_cfg['ip_ver'][i] == 4:
                filter = filter.replace('<x>', str(101 + j * ip_step))
            elif dev_cfg['ip_ver'][i] == 6:
                filter = filter.replace('<x>', format(0x65 + j * ip_step, 'x'))
            print filter
            cap_pkts = subprocess.check_output(
                [tshark, '-nr', 'capture.pcap', '-Y', filter])
            print(cap_pkts)
            assert cap_pkts.count('\n') == 1

    # retrieve and verify ARP/NDP Table on tx/rx ports
    log.info('retrieving ARP/NDP entries on tx port')
    device_list = drone.getDeviceList(emul_ports.port_id[0])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[0])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on tx port')
    for devcfg, device in zip(device_config, devices):
        if has_ip4:
            resolved = False
            for arp in device.arp:
                print('%s: %s %012x' % (str(ipaddress.ip_address(
                    devcfg.ip4)), str(ipaddress.ip_address(arp.ip4)), arp.mac))
                if (arp.ip4 == devcfg.ip4_default_gateway) and (arp.mac):
                    resolved = True
            assert resolved
        if has_ip6:
            resolved = False
            for ndp in device.ndp:
                print('%s: %s %012x' % (str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
                if (ndp.ip6 == devcfg.ip6_default_gateway) and (ndp.mac):
                    resolved = True
            assert resolved

    log.info('retrieving ARP/NDP entries on rx port')
    device_list = drone.getDeviceList(emul_ports.port_id[1])
    device_config = device_list.Extensions[emul.device]
    neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[1])
    devices = neigh_list.Extensions[emul.device_neighbor]
    log.info('ARP/NDP Table on rx port')
    for devcfg, device in zip(device_config, devices):
        if has_ip4:
            resolved = False
            for arp in device.arp:
                print('%s: %s %012x' % (str(ipaddress.ip_address(
                    devcfg.ip4)), str(ipaddress.ip_address(arp.ip4)), arp.mac))
                if (arp.ip4 == devcfg.ip4_default_gateway) and (arp.mac):
                    resolved = True
            assert resolved
        if has_ip6:
            resolved = False
            for ndp in device.ndp:
                print('%s: %s %012x' % (str(ip6_address(
                    devcfg.ip6)), str(ip6_address(ndp.ip6)), ndp.mac))
                if (ndp.ip6 == devcfg.ip6_default_gateway) and (ndp.mac):
                    resolved = True
            assert resolved

    # ping the tx devices from the DUT
    for i in range(num_devs):
        if has_ip4:
            out = run('ping -c3 10.10.1.' + str(101 + i * ip_step),
                      warn_only=True)
            assert '100% packet loss' not in out
        if has_ip6:
            out = run('ping -6 -c3 1234:1::' + format(101 + i * ip_step, 'x'),
                      warn_only=True)
            assert '100% packet loss' not in out

    # ping the rx devices from the DUT
    for i in range(num_devs):
        if has_ip4:
            out = run('ping -c3 10.10.2.' + str(101 + i * ip_step),
                      warn_only=True)
            assert '100% packet loss' not in out
        if has_ip6:
            out = run('ping -6 -c3 1234:2::' + format(101 + i * ip_step, 'x'),
                      warn_only=True)
            assert '100% packet loss' not in out

    # We are all set now - so transmit the stream now
    drone.startCapture(ports.rx)
    drone.startTransmit(ports.tx)
    log.info('waiting for transmit to finish ...')
    time.sleep(3)
    drone.stopTransmit(ports.tx)
    drone.stopCapture(ports.rx)

    buff = drone.getCaptureBuffer(ports.rx.port_id[0])
    drone.saveCaptureBuffer(buff, 'capture.pcap')
    log.info('dumping Rx capture buffer (all)')
    cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
    print(cap_pkts)
    log.info('dumping Rx capture buffer (filtered)')
    for i in range(num_devs):
        if has_ip4:
            filter = '(ip.src == 10.10.1.' + str(101+i*ip_step) + ')' \
                  ' && (ip.dst == 10.10.2.' + str(101+i*ip_step) + ')' \
                  ' && (eth.dst == 00:01:02:03:0b:' \
                            + format(1+i*mac_step, '02x')+')'
            print('filter: %s' % filter)
            cap_pkts = subprocess.check_output(
                [tshark, '-nr', 'capture.pcap', '-Y', filter])
            print(cap_pkts)
            assert cap_pkts.count('\n') == s.control.num_packets / num_devs
        if has_ip6:
            filter = '(ipv6.src == 1234:1::' \
                            + format(101+i*ip_step, 'x') + ')' \
                + ' && (ipv6.dst == 1234:2::'  \
                            + format(101+i*ip_step, 'x') + ')' \
                + ' && (eth.dst == 00:01:02:03:0b:'  \
                            + format(1+i*mac_step, '02x') + ')'
            print('filter: %s' % filter)
            cap_pkts = subprocess.check_output(
                [tshark, '-nr', 'capture.pcap', '-Y', filter])
            print(cap_pkts)
            assert cap_pkts.count('\n') == s.control.num_packets / num_devs
    os.remove('capture.pcap')

    drone.stopTransmit(ports.tx)
    run('ip neigh show')
Example #6
0
def stream(request, drone, ports, sign_stream_cfg):

    sscfg = sign_stream_cfg
    num_streams = sscfg['num_streams']

    # add stream(s)
    stream_id = ost_pb.StreamIdList()
    stream_id.port_id.CopyFrom(ports.x.port_id[0])
    for i in range(num_streams):
        stream_id.stream_id.add().id = 1 + i
    log.info('adding X stream(s) ' + str(stream_id))
    drone.addStream(stream_id)

    # configure the stream(s)
    stream_cfg = ost_pb.StreamConfigList()
    stream_cfg.port_id.CopyFrom(ports.x.port_id[0])
    for i in range(num_streams):
        s = stream_cfg.stream.add()
        s.stream_id.id = stream_id.stream_id[i].id
        s.core.is_enabled = True
        # On Win32, packets in a seq that take less than 1s to transmit
        # are transmitted in one shot using pcap_send_queue; this means that
        # stopTransmit() cannot stop them in the middle of the sequence and
        # stop will happen only at the pktSeq boundary
        # Since we want to test cases where stop is trigerred in the middle of
        # a sequence, we set pps < 1000
        # FIXME: for some reason values such as 100pps is also leading to
        # stop only at seq boundary - need to debug
        s.control.packets_per_sec = 523

        # setup stream protocols
        p = s.protocol.add()
        s.control.num_packets = sscfg['num_pkts'][i]
        p.protocol_id.id = ost_pb.Protocol.kMacFieldNumber
        p.Extensions[mac].dst_mac_mode = Mac.e_mm_resolve
        p.Extensions[mac].src_mac_mode = Mac.e_mm_resolve

        s.protocol.add().protocol_id.id = ost_pb.Protocol.kEth2FieldNumber

        p = s.protocol.add()
        if i & 0x1:  # odd numbered stream
            p.protocol_id.id = ost_pb.Protocol.kIp4FieldNumber
            ip = p.Extensions[ip4]
            ip.src_ip = 0x0a0a0165
            ip.dst_ip = 0x0a0a0265
            if sscfg['num_var_pkts'][i]:
                ip4.src_ip_mode = Ip4.e_im_inc_host
                ip4.src_ip_count = sscfg['num_var_pkts'][i]
            s.protocol.add().protocol_id.id = ost_pb.Protocol.kUdpFieldNumber
        else:  # even numbered stream
            s.core.frame_len = 96  # IPv6 needs a larger frame
            p.protocol_id.id = ost_pb.Protocol.kIp6FieldNumber
            ip = p.Extensions[ip6]
            ip6addr = ip6_address('1234:1::65/96')
            ip.src_addr_hi = ip6addr.ip6.hi
            ip.src_addr_lo = ip6addr.ip6.lo
            ip6addr = ip6_address('1234:2::65/96')
            ip.dst_addr_hi = ip6addr.ip6.hi
            ip.dst_addr_lo = ip6addr.ip6.lo
            if sscfg['num_var_pkts'][i]:
                ip.dst_addr_mode = Ip6.kIncHost
                ip.dst_addr_count = sscfg['num_var_pkts'][i]
                ip.dst_addr_prefix = ip6addr.prefixlen
            s.protocol.add().protocol_id.id = ost_pb.Protocol.kTcpFieldNumber

        s.protocol.add().protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber
        if sscfg['guid'][i] > 0:
            p = s.protocol.add()
            p.protocol_id.id = ost_pb.Protocol.kSignFieldNumber
            p.Extensions[sign].stream_guid = sscfg['guid'][i]

    if sscfg['loop']:
        stream_cfg.stream[-1].control.next = ost_pb.StreamControl.e_nw_goto_id

    drone.modifyStream(stream_cfg)

    def fin():
        # delete streams
        log.info('deleting tx_stream ' + str(stream_id))
        drone.deleteStream(stream_id)

    request.addfinalizer(fin)

    return stream_cfg