Feature (contd.): Device Emulation - fixed problems in code and in test case for multi-tagged vlans
This commit is contained in:
parent
cb1e16976d
commit
ad1fb5fc37
@ -324,22 +324,62 @@ void DeviceManager::enumerateDevices(
|
|||||||
OstEmul::VlanEmulation pbVlan = deviceGroup->GetExtension(OstEmul::encap)
|
OstEmul::VlanEmulation pbVlan = deviceGroup->GetExtension(OstEmul::encap)
|
||||||
.vlan();
|
.vlan();
|
||||||
int numTags = pbVlan.stack_size();
|
int numTags = pbVlan.stack_size();
|
||||||
int vlanCount = 1;
|
int n = 1;
|
||||||
|
QList<int> vlanCount;
|
||||||
|
|
||||||
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
||||||
OstEmul::Ip4Emulation ip4 = deviceGroup->GetExtension(OstEmul::ip4);
|
OstEmul::Ip4Emulation ip4 = deviceGroup->GetExtension(OstEmul::ip4);
|
||||||
|
|
||||||
for (int i = 0; i < numTags; i++)
|
/*
|
||||||
vlanCount *= pbVlan.stack(i).count();
|
* vlanCount[] stores the number of unique vlans at each tag level
|
||||||
|
* e.g. for a 3-tag config with 2, 3, 4 vlans at each level respectively
|
||||||
|
* vlanCount = [24, 12, 4]
|
||||||
|
* 0 - 0, 0, 0
|
||||||
|
* 1 - 0, 0, 1
|
||||||
|
* 2 - 0, 0, 2
|
||||||
|
* 3 - 0, 0, 3
|
||||||
|
* 4 - 0, 1, 0
|
||||||
|
* 5 - 0, 1, 1
|
||||||
|
* 6 - 0, 1, 2
|
||||||
|
* 7 - 0, 1, 3
|
||||||
|
* 8 - 0, 2, 0
|
||||||
|
* 9 - 0, 2, 1
|
||||||
|
* 10 - 0, 2, 2
|
||||||
|
* 11 - 0, 2, 3
|
||||||
|
* 12 - 1, 0, 0
|
||||||
|
* 13 - 1, 0, 1
|
||||||
|
* 14 - 1, 0, 2
|
||||||
|
* 15 - 1, 0, 3
|
||||||
|
* 16 - 1, 1, 0
|
||||||
|
* 17 - 1, 1, 1
|
||||||
|
* 18 - 1, 1, 2
|
||||||
|
* 19 - 1, 1, 3
|
||||||
|
* 21 - 1, 2, 0
|
||||||
|
* 21 - 1, 2, 1
|
||||||
|
* 22 - 1, 2, 2
|
||||||
|
* 23 - 1, 2, 3
|
||||||
|
*
|
||||||
|
* Note that vlanCount[0] repesents total-number-of-vlans
|
||||||
|
*
|
||||||
|
* Another way to think about this is that at a particular vlan tag
|
||||||
|
* level, we need to repeat a particular vlan-id as many times as the
|
||||||
|
* next level's count before we can increment the vlan-id at that level
|
||||||
|
*
|
||||||
|
* We use this list to calculate the vlan ids for each tag level for
|
||||||
|
* all the vlans.
|
||||||
|
*
|
||||||
|
* For implementation convenience we append a '1' as the last element
|
||||||
|
*/
|
||||||
|
vlanCount.append(n);
|
||||||
|
for (int i = numTags - 1; i >= 0 ; i--) {
|
||||||
|
n *= pbVlan.stack(i).count();
|
||||||
|
vlanCount.prepend(n);
|
||||||
|
}
|
||||||
|
|
||||||
// If we have no vlans, we still have the non-vlan-segmented LAN
|
for (int i = 0; i < vlanCount.at(0); i++) {
|
||||||
if (vlanCount == 0)
|
|
||||||
vlanCount = 1;
|
|
||||||
|
|
||||||
for (int i = 0; i < vlanCount; i++) {
|
|
||||||
for (int j = 0; j < numTags; j++) {
|
for (int j = 0; j < numTags; j++) {
|
||||||
OstEmul::VlanEmulation::Vlan vlan = pbVlan.stack(j);
|
OstEmul::VlanEmulation::Vlan vlan = pbVlan.stack(j);
|
||||||
quint16 vlanAdd = i*vlan.step();
|
quint16 vlanAdd = (i/vlanCount.at(j+1) % vlan.count())*vlan.step();
|
||||||
|
|
||||||
dk.setVlan(j, vlan.vlan_tag() + vlanAdd);
|
dk.setVlan(j, vlan.vlan_tag() + vlanAdd);
|
||||||
}
|
}
|
||||||
|
@ -946,7 +946,40 @@ void PcapPort::EmulationTransceiver::run()
|
|||||||
int flags = PCAP_OPENFLAG_PROMISCUOUS;
|
int flags = PCAP_OPENFLAG_PROMISCUOUS;
|
||||||
char errbuf[PCAP_ERRBUF_SIZE] = "";
|
char errbuf[PCAP_ERRBUF_SIZE] = "";
|
||||||
struct bpf_program bpf;
|
struct bpf_program bpf;
|
||||||
const char *capture_filter = "arp or (vlan and arp)";
|
#if 0
|
||||||
|
/*
|
||||||
|
Ideally we should use the below filter, but the 'vlan' capture filter
|
||||||
|
in libpcap is implemented as a kludge. From the pcap-filter man page -
|
||||||
|
|
||||||
|
vlan [vlan_id]
|
||||||
|
Note that the first vlan keyword encountered in expression changes
|
||||||
|
the decoding offsets for the remainder of expression on the
|
||||||
|
assumption that the packet is a VLAN packet.
|
||||||
|
|
||||||
|
The vlan [vlan_id] expression may be used more than once, to filter on
|
||||||
|
VLAN hierarchies. Each use of that expression increments the filter
|
||||||
|
offsets by 4.
|
||||||
|
|
||||||
|
See https://ask.wireshark.org/questions/31953/unusual-behavior-with-stacked-vlan-tags-and-capture-filter
|
||||||
|
|
||||||
|
So we use the modified filter expression that works as we intend. If ever
|
||||||
|
libpcap changes their implementation, this will need to change as well.
|
||||||
|
*/
|
||||||
|
const char *capture_filter =
|
||||||
|
"arp or "
|
||||||
|
"(vlan and arp) or "
|
||||||
|
"(vlan and vlan and arp) or "
|
||||||
|
"(vlan and vlan and vlan and arp) or "
|
||||||
|
"(vlan and vlan and vlan and vlan and arp)";
|
||||||
|
#else
|
||||||
|
const char *capture_filter =
|
||||||
|
"arp or "
|
||||||
|
"(vlan and arp) or "
|
||||||
|
"(vlan and arp) or "
|
||||||
|
"(vlan and arp) or "
|
||||||
|
"(vlan and arp)";
|
||||||
|
#endif
|
||||||
|
|
||||||
const int optimize = 1;
|
const int optimize = 1;
|
||||||
|
|
||||||
qDebug("In %s", __PRETTY_FUNCTION__);
|
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||||
|
@ -624,6 +624,7 @@ def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports, stream_id,
|
|||||||
for i in range(num_vlans):
|
for i in range(num_vlans):
|
||||||
s = stream_cfg.stream.add()
|
s = stream_cfg.stream.add()
|
||||||
s.stream_id.id = stream_id.stream_id[i].id
|
s.stream_id.id = stream_id.stream_id[i].id
|
||||||
|
s.core.name = 'stream ' + str(s.stream_id.id)
|
||||||
s.core.is_enabled = True
|
s.core.is_enabled = True
|
||||||
s.core.ordinal = i
|
s.core.ordinal = i
|
||||||
s.control.packets_per_sec = 100
|
s.control.packets_per_sec = 100
|
||||||
@ -635,10 +636,11 @@ def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports, stream_id,
|
|||||||
p.Extensions[mac].dst_mac_mode = Mac.e_mm_resolve
|
p.Extensions[mac].dst_mac_mode = Mac.e_mm_resolve
|
||||||
p.Extensions[mac].src_mac_mode = Mac.e_mm_resolve
|
p.Extensions[mac].src_mac_mode = Mac.e_mm_resolve
|
||||||
|
|
||||||
for vcfg in vlan_cfg:
|
ids = dut_vlans.vlans[i].split('.')
|
||||||
|
for id in ids:
|
||||||
p = s.protocol.add()
|
p = s.protocol.add()
|
||||||
p.protocol_id.id = ost_pb.Protocol.kVlanFieldNumber
|
p.protocol_id.id = ost_pb.Protocol.kVlanFieldNumber
|
||||||
p.Extensions[vlan].vlan_tag = vcfg['base']+(i % vcfg['count'])
|
p.Extensions[vlan].vlan_tag = int(id)
|
||||||
|
|
||||||
p = s.protocol.add()
|
p = s.protocol.add()
|
||||||
p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber
|
p.protocol_id.id = ost_pb.Protocol.kEth2FieldNumber
|
||||||
@ -658,7 +660,7 @@ def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports, stream_id,
|
|||||||
p = s.protocol.add()
|
p = s.protocol.add()
|
||||||
p.protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber
|
p.protocol_id.id = ost_pb.Protocol.kPayloadFieldNumber
|
||||||
|
|
||||||
log.info('configuring tx_stream %d' % stream_id.stream_id[0].id)
|
log.info('configuring tx_stream %d' % stream_id.stream_id[i].id)
|
||||||
|
|
||||||
drone.modifyStream(stream_cfg)
|
drone.modifyStream(stream_cfg)
|
||||||
|
|
||||||
@ -708,7 +710,7 @@ def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports, stream_id,
|
|||||||
log.info('dumping Rx capture buffer (all)')
|
log.info('dumping Rx capture buffer (all)')
|
||||||
cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
|
cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap'])
|
||||||
print(cap_pkts)
|
print(cap_pkts)
|
||||||
log.info('dumping Tx capture buffer (all pkts - vlans only)')
|
log.info('dumping Rx capture buffer (all pkts - vlans only)')
|
||||||
cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap',
|
cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap',
|
||||||
'-Tfields', '-eframe.number', '-evlan.id'])
|
'-Tfields', '-eframe.number', '-evlan.id'])
|
||||||
print(cap_pkts)
|
print(cap_pkts)
|
||||||
@ -734,6 +736,7 @@ def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports, stream_id,
|
|||||||
for dev_cfg, device in zip(device_config, devices):
|
for dev_cfg, device in zip(device_config, devices):
|
||||||
resolved = False
|
resolved = False
|
||||||
for arp in device.arp:
|
for arp in device.arp:
|
||||||
|
# TODO: print all configured vlans, not just the first
|
||||||
# TODO: pretty print ip and mac
|
# TODO: pretty print ip and mac
|
||||||
print('v%d|%08x: %08x %012x' %
|
print('v%d|%08x: %08x %012x' %
|
||||||
(dev_cfg.vlan[0] & 0xffff, dev_cfg.ip4, arp.ip4, arp.mac))
|
(dev_cfg.vlan[0] & 0xffff, dev_cfg.ip4, arp.ip4, arp.mac))
|
||||||
|
Loading…
Reference in New Issue
Block a user