HostDev: Return smac/dmac resolve failure via RPC

This commit is contained in:
Srivats P 2019-02-09 17:16:31 +05:30
parent 90d93d52e1
commit 8b9cceb7ed
6 changed files with 102 additions and 27 deletions

View File

@ -667,6 +667,11 @@ void PortGroup::processModifyStreamAck(int portIndex,
qDebug("apply completed"); qDebug("apply completed");
logInfo(id(), mPorts[portIndex]->id(), QString("All port changes applied")); logInfo(id(), mPorts[portIndex]->id(), QString("All port changes applied"));
OstProto::Ack *ack = static_cast<OstProto::Ack*>(controller->response());
if (ack->status())
logError(id(), mPorts[portIndex]->id(),
QString::fromStdString(ack->notes()));
mPorts[portIndex]->when_syncComplete(); mPorts[portIndex]->when_syncComplete();
mainWindow->setEnabled(true); mainWindow->setEnabled(true);
@ -803,6 +808,7 @@ void PortGroup::modifyPort(int portIndex, OstProto::Port portConfig)
void PortGroup::processModifyPortAck(bool restoreUi,PbRpcController *controller) void PortGroup::processModifyPortAck(bool restoreUi,PbRpcController *controller)
{ {
qDebug("In %s", __FUNCTION__); qDebug("In %s", __FUNCTION__);
if (controller->Failed()) if (controller->Failed())
@ -813,6 +819,10 @@ void PortGroup::processModifyPortAck(bool restoreUi,PbRpcController *controller)
.arg(controller->ErrorString())); .arg(controller->ErrorString()));
} }
OstProto::Ack *ack = static_cast<OstProto::Ack*>(controller->response());
if (ack->status())
logError(id(), QString::fromStdString(ack->notes()));
if (restoreUi) { if (restoreUi) {
mainWindow->setEnabled(true); mainWindow->setEnabled(true);
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
@ -1339,6 +1349,9 @@ void PortGroup::processStartTxAck(PbRpcController *controller)
{ {
qDebug("In %s", __FUNCTION__); qDebug("In %s", __FUNCTION__);
OstProto::Ack *ack = static_cast<OstProto::Ack*>(controller->response());
if (ack->status())
logError(id(), QString::fromStdString(ack->notes()));
delete controller; delete controller;
} }

View File

@ -175,7 +175,12 @@ message Void {
} }
message Ack { message Ack {
//! \todo (LOW) do we need any fields in 'Ack' enum RpcStatus {
kRpcSuccess = 0;
kRpcFail = 1;
}
optional RpcStatus status = 1; // FIXME: make required
optional string notes = 2;
} }
message PortId { message PortId {

View File

@ -202,23 +202,24 @@ bool AbstractPort::setRateAccuracy(Accuracy accuracy)
return true; return true;
} }
void AbstractPort::updatePacketList() int AbstractPort::updatePacketList()
{ {
switch(data_.transmit_mode()) switch(data_.transmit_mode())
{ {
case OstProto::kSequentialTransmit: case OstProto::kSequentialTransmit:
updatePacketListSequential(); return updatePacketListSequential();
break; break;
case OstProto::kInterleavedTransmit: case OstProto::kInterleavedTransmit:
updatePacketListInterleaved(); return updatePacketListInterleaved();
break; break;
default: default:
Q_ASSERT(false); // Unreachable!!! Q_ASSERT(false); // Unreachable!!!
break; break;
} }
return 0;
} }
void AbstractPort::updatePacketListSequential() int AbstractPort::updatePacketListSequential()
{ {
FrameValueAttrib packetListAttrib; FrameValueAttrib packetListAttrib;
long sec = 0; long sec = 0;
@ -397,11 +398,12 @@ void AbstractPort::updatePacketListSequential()
_stop_no_more_pkts: _stop_no_more_pkts:
isSendQueueDirty_ = false; isSendQueueDirty_ = false;
// FIXME: send attrib back in Ack qDebug("PacketListAttrib = %x",
qDebug("PacketListAttrib = %x", (int)packetListAttrib.errorFlags); static_cast<int>(packetListAttrib.errorFlags));
return static_cast<int>(packetListAttrib.errorFlags);
} }
void AbstractPort::updatePacketListInterleaved() int AbstractPort::updatePacketListInterleaved()
{ {
FrameValueAttrib packetListAttrib; FrameValueAttrib packetListAttrib;
int numStreams = 0; int numStreams = 0;
@ -432,7 +434,7 @@ void AbstractPort::updatePacketListInterleaved()
if (activeStreamCount == 0) if (activeStreamCount == 0)
{ {
isSendQueueDirty_ = false; isSendQueueDirty_ = false;
return; return 0;
} }
// First sort the streams by ordinalValue // First sort the streams by ordinalValue
@ -643,8 +645,9 @@ void AbstractPort::updatePacketListInterleaved()
setPacketListLoopMode(true, delaySec, delayNsec); setPacketListLoopMode(true, delaySec, delayNsec);
isSendQueueDirty_ = false; isSendQueueDirty_ = false;
// FIXME: send attrib back in Ack qDebug("PacketListAttrib = %x",
qDebug("PacketListAttrib = %x", (int)packetListAttrib.errorFlags); static_cast<int>(packetListAttrib.errorFlags));
return static_cast<int>(packetListAttrib.errorFlags);
} }
void AbstractPort::stats(PortStats *stats) void AbstractPort::stats(PortStats *stats)

View File

@ -105,7 +105,7 @@ public:
int length) = 0; int length) = 0;
virtual void setPacketListLoopMode(bool loop, virtual void setPacketListLoopMode(bool loop,
quint64 secDelay, quint64 nsecDelay) = 0; quint64 secDelay, quint64 nsecDelay) = 0;
void updatePacketList(); int updatePacketList();
virtual void startTransmit() = 0; virtual void startTransmit() = 0;
virtual void stopTransmit() = 0; virtual void stopTransmit() = 0;
@ -140,8 +140,8 @@ protected:
void addNote(QString note); void addNote(QString note);
void updatePacketListSequential(); int updatePacketListSequential();
void updatePacketListInterleaved(); int updatePacketListInterleaved();
bool isUsable_; bool isUsable_;
OstProto::Port data_; OstProto::Port data_;

View File

@ -31,6 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "../common/abstractprotocol.h" #include "../common/abstractprotocol.h"
#endif #endif
#include "../common/framevalueattrib.h"
#include "../common/streambase.h" #include "../common/streambase.h"
#include "../rpc/pbrpccontroller.h" #include "../rpc/pbrpccontroller.h"
#include "device.h" #include "device.h"
@ -116,9 +117,11 @@ void MyService::getPortConfig(::google::protobuf::RpcController* /*controller*/,
void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/, void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/,
const ::OstProto::PortConfigList* request, const ::OstProto::PortConfigList* request,
::OstProto::Ack* /*response*/, ::OstProto::Ack *response,
::google::protobuf::Closure* done) ::google::protobuf::Closure* done)
{ {
bool fail = false;
QString notes;
// notification needs to be on heap because signal/slot is across threads! // notification needs to be on heap because signal/slot is across threads!
OstProto::Notification *notif = new OstProto::Notification; OstProto::Notification *notif = new OstProto::Notification;
@ -127,7 +130,7 @@ void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/,
for (int i = 0; i < request->port_size(); i++) for (int i = 0; i < request->port_size(); i++)
{ {
OstProto::Port port; OstProto::Port port;
int id; int id, err = 0;
port = request->port(i); port = request->port(i);
id = port.port_id().id(); id = port.port_id().id();
@ -143,15 +146,22 @@ void MyService::modifyPort(::google::protobuf::RpcController* /*controller*/,
portLock[id]->lockForWrite(); portLock[id]->lockForWrite();
portInfo[id]->modify(port); portInfo[id]->modify(port);
if (dirty) if (dirty)
portInfo[id]->updatePacketList(); err = portInfo[id]->updatePacketList();
portLock[id]->unlock(); portLock[id]->unlock();
if (err) {
notes += frameValueErrorNotes(id, err);
fail = true;
}
notif->mutable_port_id_list()->add_port_id()->set_id(id); notif->mutable_port_id_list()->add_port_id()->set_id(id);
} }
} }
//! \todo (LOW): fill-in response "Ack"???? if (fail) {
response->set_status(OstProto::Ack::kRpcFail);
response->set_notes(notes.toStdString());
}
else
response->set_status(OstProto::Ack::kRpcSuccess);
done->Run(); done->Run();
if (notif->port_id_list().port_id_size()) { if (notif->port_id_list().port_id_size()) {
@ -318,10 +328,11 @@ _exit:
void MyService::modifyStream(::google::protobuf::RpcController* controller, void MyService::modifyStream(::google::protobuf::RpcController* controller,
const ::OstProto::StreamConfigList* request, const ::OstProto::StreamConfigList* request,
::OstProto::Ack* /*response*/, ::OstProto::Ack* response,
::google::protobuf::Closure* done) ::google::protobuf::Closure* done)
{ {
int portId; int portId;
int err = 0;
qDebug("In %s", __PRETTY_FUNCTION__); qDebug("In %s", __PRETTY_FUNCTION__);
@ -346,11 +357,16 @@ void MyService::modifyStream(::google::protobuf::RpcController* controller,
} }
if (portInfo[portId]->isDirty()) if (portInfo[portId]->isDirty())
portInfo[portId]->updatePacketList(); err = portInfo[portId]->updatePacketList();
portLock[portId]->unlock(); portLock[portId]->unlock();
//! \todo(LOW): fill-in response "Ack"???? if (err) {
QString notes = frameValueErrorNotes(portId, err);
response->set_status(OstProto::Ack::kRpcFail);
response->set_notes(notes.toStdString());
}
else
response->set_status(OstProto::Ack::kRpcSuccess);
done->Run(); done->Run();
return; return;
@ -365,14 +381,18 @@ _exit:
void MyService::startTransmit(::google::protobuf::RpcController* /*controller*/, void MyService::startTransmit(::google::protobuf::RpcController* /*controller*/,
const ::OstProto::PortIdList* request, const ::OstProto::PortIdList* request,
::OstProto::Ack* /*response*/, ::OstProto::Ack* response,
::google::protobuf::Closure* done) ::google::protobuf::Closure* done)
{ {
bool fail = false;
QString notes;
qDebug("In %s", __PRETTY_FUNCTION__); qDebug("In %s", __PRETTY_FUNCTION__);
for (int i = 0; i < request->port_id_size(); i++) for (int i = 0; i < request->port_id_size(); i++)
{ {
int portId; int portId;
int err = 0;
portId = request->port_id(i).id(); portId = request->port_id(i).id();
if ((portId < 0) || (portId >= portInfo.size())) if ((portId < 0) || (portId >= portInfo.size()))
@ -380,12 +400,21 @@ void MyService::startTransmit(::google::protobuf::RpcController* /*controller*/,
portLock[portId]->lockForWrite(); portLock[portId]->lockForWrite();
if (portInfo[portId]->isDirty()) if (portInfo[portId]->isDirty())
portInfo[portId]->updatePacketList(); err = portInfo[portId]->updatePacketList();
portInfo[portId]->startTransmit(); portInfo[portId]->startTransmit();
portLock[portId]->unlock(); portLock[portId]->unlock();
if (err) {
notes += frameValueErrorNotes(portId, err);
fail = true;
}
} }
//! \todo (LOW): fill-in response "Ack"???? if (fail) {
response->set_status(OstProto::Ack::kRpcFail);
response->set_notes(notes.toStdString());
}
else
response->set_status(OstProto::Ack::kRpcSuccess);
done->Run(); done->Run();
} }
@ -1000,6 +1029,29 @@ _invalid_port:
done->Run(); done->Run();
} }
QString MyService::frameValueErrorNotes(int portId, int error)
{
if (!error)
return QString();
QString pfx = QString("Port %1: ").arg(portId);
auto errorFlags = static_cast<FrameValueAttrib::ErrorFlags>(error);
// If smac resolve fails, dmac will always fail - so check that first
// and report only that so as not to confuse users (they may not realize
// that without a source device, we have no ARP table to lookup for dmac)
if (errorFlags & FrameValueAttrib::UnresolvedSrcMacError)
return pfx + "Source mac resolve failed for one or more "
"streams - Device matching stream's source ip not found\n";
if (errorFlags & FrameValueAttrib::UnresolvedDstMacError)
return pfx + "Destination mac resolve failed for one or more "
"streams - possible ARP/ND failure\n";
return QString();
}
/* /*
* =================================================================== * ===================================================================
* Friends * Friends

View File

@ -172,6 +172,8 @@ signals:
void notification(int notifType, SharedProtobufMessage notifData); void notification(int notifType, SharedProtobufMessage notifData);
private: private:
QString frameValueErrorNotes(int portId, int error);
/* /*
* NOTES: * NOTES:
* - AbstractPort::id() and index into portInfo[] are same! * - AbstractPort::id() and index into portInfo[] are same!