Feature (contd.): Device Emulation - added getDeviceList() RPC
This commit is contained in:
parent
492a207ede
commit
7daf75c95a
@ -83,24 +83,21 @@ extend OstProto.DeviceGroup {
|
|||||||
optional Ip6Emulation ip6 = 3001;
|
optional Ip6Emulation ip6 = 3001;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO
|
|
||||||
message Device {
|
message Device {
|
||||||
optional uint64 mac = 1;
|
optional uint64 mac = 1;
|
||||||
|
|
||||||
// FIXME: move vlan into encapInfo?
|
|
||||||
repeated uint32 vlan = 2; // includes tpid 'n vlan tag
|
repeated uint32 vlan = 2; // includes tpid 'n vlan tag
|
||||||
|
|
||||||
optional uint32 ip4 = 3;
|
optional uint32 ip4 = 10;
|
||||||
optional uint32 ip4_prefix_length = 4;
|
optional uint32 ip4_prefix_length = 11;
|
||||||
optional uint32 ip4_default_gateway = 5;
|
optional uint32 ip4_default_gateway = 12;
|
||||||
|
|
||||||
// TODO: IPv6 fields
|
// TODO: IPv6 fields
|
||||||
}
|
}
|
||||||
|
|
||||||
message DeviceList {
|
extend OstProto.PortDeviceList {
|
||||||
repeated Device devices = 1;
|
repeated Device port_device = 100;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
message ArpEntry {
|
message ArpEntry {
|
||||||
optional uint32 ip4 = 1;
|
optional uint32 ip4 = 1;
|
||||||
@ -120,5 +117,6 @@ message DeviceNeighborList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extend OstProto.PortNeighborList {
|
extend OstProto.PortNeighborList {
|
||||||
|
// FIXME: rename to device (singular) to be consistent with naming convention for other repeated fields
|
||||||
repeated DeviceNeighborList devices = 100;
|
repeated DeviceNeighborList devices = 100;
|
||||||
}
|
}
|
||||||
|
@ -281,6 +281,8 @@ message Notification {
|
|||||||
* FIXME: What will be the contents of a default device created by addDeviceGroup()?
|
* FIXME: What will be the contents of a default device created by addDeviceGroup()?
|
||||||
* FIXME: decide default values for device and protoEmulations
|
* FIXME: decide default values for device and protoEmulations
|
||||||
* FIXME: rename 'DeviceGroup'?
|
* FIXME: rename 'DeviceGroup'?
|
||||||
|
* FIXME: merge getDeviceList() and get DeviceNeighbors() into a single
|
||||||
|
* getDeviceInfo() RPC?
|
||||||
*/
|
*/
|
||||||
message DeviceGroupId {
|
message DeviceGroupId {
|
||||||
required uint32 id = 1;
|
required uint32 id = 1;
|
||||||
@ -308,6 +310,12 @@ message DeviceGroupConfigList {
|
|||||||
repeated DeviceGroup device_group = 2;
|
repeated DeviceGroup device_group = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message PortDeviceList {
|
||||||
|
required PortId port_id = 1;
|
||||||
|
|
||||||
|
extensions 100 to 199;
|
||||||
|
}
|
||||||
|
|
||||||
message PortNeighborList {
|
message PortNeighborList {
|
||||||
required PortId port_id = 1;
|
required PortId port_id = 1;
|
||||||
|
|
||||||
@ -344,7 +352,7 @@ service OstService {
|
|||||||
rpc deleteDeviceGroup(DeviceGroupIdList) returns (Ack);
|
rpc deleteDeviceGroup(DeviceGroupIdList) returns (Ack);
|
||||||
rpc modifyDeviceGroup(DeviceGroupConfigList) returns (Ack);
|
rpc modifyDeviceGroup(DeviceGroupConfigList) returns (Ack);
|
||||||
|
|
||||||
// TODO: rpc getDeviceList(PortId) returns (DeviceList);
|
rpc getDeviceList(PortId) returns (PortDeviceList);
|
||||||
|
|
||||||
rpc resolveDeviceNeighbors(PortIdList) returns (Ack);
|
rpc resolveDeviceNeighbors(PortIdList) returns (Ack);
|
||||||
rpc clearDeviceNeighbors(PortIdList) returns (Ack);
|
rpc clearDeviceNeighbors(PortIdList) returns (Ack);
|
||||||
|
@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#include <qendian.h>
|
#include <qendian.h>
|
||||||
|
|
||||||
const int kBaseHex = 16;
|
const int kBaseHex = 16;
|
||||||
const int kMaxVlan = 4;
|
|
||||||
const quint64 kBcastMac = 0xffffffffffffULL;
|
const quint64 kBcastMac = 0xffffffffffffULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -92,6 +91,17 @@ void Device::setIp4(quint32 address, int prefixLength, quint32 gateway)
|
|||||||
ip4Gateway_ = gateway;
|
ip4Gateway_ = gateway;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::getConfig(OstEmul::Device *deviceConfig)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numVlanTags_; i++)
|
||||||
|
deviceConfig->add_vlan(vlan_[i]);
|
||||||
|
|
||||||
|
deviceConfig->set_mac(mac_);
|
||||||
|
deviceConfig->set_ip4(ip4_);
|
||||||
|
deviceConfig->set_ip4_prefix_length(ip4PrefixLength_);
|
||||||
|
deviceConfig->set_ip4_default_gateway(ip4Gateway_);
|
||||||
|
}
|
||||||
|
|
||||||
QString Device::config()
|
QString Device::config()
|
||||||
{
|
{
|
||||||
return QString("<vlans=%1/%2/%3/%4 mac=%5 ip4=%6/%7>")
|
return QString("<vlans=%1/%2/%3/%4 mac=%5 ip4=%6/%7>")
|
||||||
|
@ -40,6 +40,7 @@ public:
|
|||||||
quint64 mac();
|
quint64 mac();
|
||||||
void setMac(quint64 mac);
|
void setMac(quint64 mac);
|
||||||
void setIp4(quint32 address, int prefixLength, quint32 gateway);
|
void setIp4(quint32 address, int prefixLength, quint32 gateway);
|
||||||
|
void getConfig(OstEmul::Device *deviceConfig);
|
||||||
QString config();
|
QString config();
|
||||||
|
|
||||||
DeviceKey key();
|
DeviceKey key();
|
||||||
@ -63,10 +64,12 @@ private: // methods
|
|||||||
void sendArpRequest(PacketBuffer *pktBuf);
|
void sendArpRequest(PacketBuffer *pktBuf);
|
||||||
|
|
||||||
private: // data
|
private: // data
|
||||||
|
static const int kMaxVlan = 4;
|
||||||
|
|
||||||
DeviceManager *deviceManager_;
|
DeviceManager *deviceManager_;
|
||||||
|
|
||||||
int numVlanTags_;
|
int numVlanTags_;
|
||||||
quint16 vlan_[4]; // FIXME: vlan tpid
|
quint16 vlan_[kMaxVlan]; // FIXME: vlan tpid
|
||||||
quint64 mac_;
|
quint64 mac_;
|
||||||
quint32 ip4_;
|
quint32 ip4_;
|
||||||
int ip4PrefixLength_;
|
int ip4PrefixLength_;
|
||||||
|
@ -134,6 +134,18 @@ int DeviceManager::deviceCount()
|
|||||||
return deviceList_.size();
|
return deviceList_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceManager::getDeviceList(
|
||||||
|
OstProto::PortDeviceList *deviceList)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
foreach(Device *device, deviceList_) {
|
||||||
|
OstEmul::Device *dev =
|
||||||
|
deviceList->AddExtension(OstEmul::port_device);
|
||||||
|
device->getConfig(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceManager::receivePacket(PacketBuffer *pktBuf)
|
void DeviceManager::receivePacket(PacketBuffer *pktBuf)
|
||||||
{
|
{
|
||||||
uchar *pktData = pktBuf->data();
|
uchar *pktData = pktBuf->data();
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
bool modifyDeviceGroup(const OstProto::DeviceGroup *deviceGroup);
|
bool modifyDeviceGroup(const OstProto::DeviceGroup *deviceGroup);
|
||||||
|
|
||||||
int deviceCount();
|
int deviceCount();
|
||||||
|
void getDeviceList(OstProto::PortDeviceList *deviceList);
|
||||||
|
|
||||||
void receivePacket(PacketBuffer *pktBuf);
|
void receivePacket(PacketBuffer *pktBuf);
|
||||||
void transmitPacket(PacketBuffer *pktBuf);
|
void transmitPacket(PacketBuffer *pktBuf);
|
||||||
@ -57,6 +58,7 @@ public:
|
|||||||
|
|
||||||
quint64 deviceMacAddress(PacketBuffer *pktBuf);
|
quint64 deviceMacAddress(PacketBuffer *pktBuf);
|
||||||
quint64 neighborMacAddress(PacketBuffer *pktBuf);
|
quint64 neighborMacAddress(PacketBuffer *pktBuf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Operation { kAdd, kDelete };
|
enum Operation { kAdd, kDelete };
|
||||||
|
|
||||||
|
@ -823,6 +823,36 @@ _exit:
|
|||||||
done->Run();
|
done->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyService::getDeviceList(
|
||||||
|
::google::protobuf::RpcController* controller,
|
||||||
|
const ::OstProto::PortId* request,
|
||||||
|
::OstProto::PortDeviceList* response,
|
||||||
|
::google::protobuf::Closure* done)
|
||||||
|
{
|
||||||
|
DeviceManager *devMgr;
|
||||||
|
int portId;
|
||||||
|
|
||||||
|
qDebug("In %s", __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
|
portId = request->id();
|
||||||
|
if ((portId < 0) || (portId >= portInfo.size()))
|
||||||
|
goto _invalid_port;
|
||||||
|
|
||||||
|
devMgr = portInfo[portId]->deviceManager();
|
||||||
|
|
||||||
|
response->mutable_port_id()->set_id(portId);
|
||||||
|
portLock[portId]->lockForRead();
|
||||||
|
devMgr->getDeviceList(response);
|
||||||
|
portLock[portId]->unlock();
|
||||||
|
|
||||||
|
done->Run();
|
||||||
|
return;
|
||||||
|
|
||||||
|
_invalid_port:
|
||||||
|
controller->SetFailed("Invalid Port Id");
|
||||||
|
done->Run();
|
||||||
|
}
|
||||||
|
|
||||||
void MyService::resolveDeviceNeighbors(
|
void MyService::resolveDeviceNeighbors(
|
||||||
::google::protobuf::RpcController* controller,
|
::google::protobuf::RpcController* controller,
|
||||||
const ::OstProto::PortIdList* request,
|
const ::OstProto::PortIdList* request,
|
||||||
@ -905,6 +935,12 @@ _invalid_port:
|
|||||||
done->Run();
|
done->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ===================================================================
|
||||||
|
* Friends
|
||||||
|
* TODO: Encap these global functions into a DeviceBroker singleton?
|
||||||
|
* ===================================================================
|
||||||
|
*/
|
||||||
quint64 getDeviceMacAddress(int portId, int streamId, int frameIndex)
|
quint64 getDeviceMacAddress(int portId, int streamId, int frameIndex)
|
||||||
{
|
{
|
||||||
MyService *service = drone->rpcService();
|
MyService *service = drone->rpcService();
|
||||||
|
@ -132,6 +132,12 @@ public:
|
|||||||
::OstProto::Ack* response,
|
::OstProto::Ack* response,
|
||||||
::google::protobuf::Closure* done);
|
::google::protobuf::Closure* done);
|
||||||
|
|
||||||
|
virtual void getDeviceList(
|
||||||
|
::google::protobuf::RpcController* controller,
|
||||||
|
const ::OstProto::PortId* request,
|
||||||
|
::OstProto::PortDeviceList* response,
|
||||||
|
::google::protobuf::Closure* done);
|
||||||
|
|
||||||
virtual void resolveDeviceNeighbors(
|
virtual void resolveDeviceNeighbors(
|
||||||
::google::protobuf::RpcController* controller,
|
::google::protobuf::RpcController* controller,
|
||||||
const ::OstProto::PortIdList* request,
|
const ::OstProto::PortIdList* request,
|
||||||
|
@ -257,8 +257,6 @@ try:
|
|||||||
|
|
||||||
drone.modifyDeviceGroup(devgrp_cfg)
|
drone.modifyDeviceGroup(devgrp_cfg)
|
||||||
|
|
||||||
s = raw_input('Press [Enter] to continue')
|
|
||||||
|
|
||||||
# configure the tx stream
|
# configure the tx stream
|
||||||
stream_cfg = ost_pb.StreamConfigList()
|
stream_cfg = ost_pb.StreamConfigList()
|
||||||
stream_cfg.port_id.CopyFrom(tx_port.port_id[0])
|
stream_cfg.port_id.CopyFrom(tx_port.port_id[0])
|
||||||
@ -348,29 +346,36 @@ try:
|
|||||||
|
|
||||||
# retrieve and verify ARP Table on tx/rx ports
|
# retrieve and verify ARP Table on tx/rx ports
|
||||||
log.info('retrieving ARP entries on tx port')
|
log.info('retrieving ARP entries on tx port')
|
||||||
|
device_list = drone.getDeviceList(emul_ports.port_id[0])
|
||||||
|
device_config = device_list.Extensions[emul.port_device]
|
||||||
neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[0])
|
neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[0])
|
||||||
devices = neigh_list.Extensions[emul.devices]
|
devices = neigh_list.Extensions[emul.devices]
|
||||||
# TODO: verify gateway IP is resolved for each device
|
|
||||||
# FIXME: needs device ip as part of neigh_list
|
|
||||||
log.info('ARP Table on tx port')
|
log.info('ARP Table on tx port')
|
||||||
for device in devices:
|
for dev_cfg, device in zip(device_config, devices):
|
||||||
|
resolved = False
|
||||||
for arp in device.arp:
|
for arp in device.arp:
|
||||||
# TODO: pretty print ip and mac
|
# TODO: pretty print ip and mac
|
||||||
print('%d: %08x %012x' %
|
print('%08x: %08x %012x' %
|
||||||
(device.device_index, arp.ip4, arp.mac))
|
(dev_cfg.ip4, arp.ip4, arp.mac))
|
||||||
|
if (arp.ip4 == dev_cfg.ip4_default_gateway) and (arp.mac):
|
||||||
|
resolved = True
|
||||||
|
if not resolved:
|
||||||
|
fail = fail + 1
|
||||||
|
|
||||||
log.info('retrieving ARP entries on rx port')
|
log.info('retrieving ARP entries on rx port')
|
||||||
|
device_list = drone.getDeviceList(emul_ports.port_id[0])
|
||||||
|
device_config = device_list.Extensions[emul.port_device]
|
||||||
neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[1])
|
neigh_list = drone.getDeviceNeighbors(emul_ports.port_id[1])
|
||||||
devices = neigh_list.Extensions[emul.devices]
|
devices = neigh_list.Extensions[emul.devices]
|
||||||
log.info('ARP Table on rx port')
|
log.info('ARP Table on rx port')
|
||||||
for device in devices:
|
for dev_cfg, device in zip(device_config, devices):
|
||||||
# verify *no* ARPs learnt on rx port
|
# verify *no* ARPs learnt on rx port
|
||||||
if len(device.arp):
|
if len(device.arp):
|
||||||
fail = fail + 1
|
fail = fail + 1
|
||||||
for arp in device.arp:
|
for arp in device.arp:
|
||||||
# TODO: pretty print ip and mac
|
# TODO: pretty print ip and mac
|
||||||
print('%d: %08x %012x' %
|
print('%08x: %08x %012x' %
|
||||||
(device.device_index, arp.ip4, arp.mac))
|
(dev_cfg.ip4, arp.ip4, arp.mac))
|
||||||
|
|
||||||
drone.startCapture(rx_port)
|
drone.startCapture(rx_port)
|
||||||
drone.startTransmit(tx_port)
|
drone.startTransmit(tx_port)
|
||||||
|
Loading…
Reference in New Issue
Block a user