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)
|
||||
.vlan();
|
||||
int numTags = pbVlan.stack_size();
|
||||
int vlanCount = 1;
|
||||
int n = 1;
|
||||
QList<int> vlanCount;
|
||||
|
||||
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
||||
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
|
||||
if (vlanCount == 0)
|
||||
vlanCount = 1;
|
||||
|
||||
for (int i = 0; i < vlanCount; i++) {
|
||||
for (int i = 0; i < vlanCount.at(0); i++) {
|
||||
for (int j = 0; j < numTags; 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);
|
||||
}
|
||||
|
@ -946,7 +946,40 @@ void PcapPort::EmulationTransceiver::run()
|
||||
int flags = PCAP_OPENFLAG_PROMISCUOUS;
|
||||
char errbuf[PCAP_ERRBUF_SIZE] = "";
|
||||
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;
|
||||
|
||||
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):
|
||||
s = stream_cfg.stream.add()
|
||||
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.ordinal = i
|
||||
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].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.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.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.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)
|
||||
|
||||
@ -708,7 +710,7 @@ def test_multiEmulDevPerVlan(request, drone, ports, dut, dut_ports, stream_id,
|
||||
log.info('dumping Rx 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)')
|
||||
log.info('dumping Rx capture buffer (all pkts - vlans only)')
|
||||
cap_pkts = subprocess.check_output([tshark, '-nr', 'capture.pcap',
|
||||
'-Tfields', '-eframe.number', '-evlan.id'])
|
||||
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):
|
||||
resolved = False
|
||||
for arp in device.arp:
|
||||
# TODO: print all configured vlans, not just the first
|
||||
# TODO: pretty print ip and mac
|
||||
print('v%d|%08x: %08x %012x' %
|
||||
(dev_cfg.vlan[0] & 0xffff, dev_cfg.ip4, arp.ip4, arp.mac))
|
||||
|
Loading…
Reference in New Issue
Block a user