tools: visualize RIB dataset in nfd-status
refs #1749
Change-Id: Ia11b88187635ffa4eda4b829afd6a20120765d58
diff --git a/tools/nfd-status.cpp b/tools/nfd-status.cpp
index d06e8fb..affd2d8 100644
--- a/tools/nfd-status.cpp
+++ b/tools/nfd-status.cpp
@@ -36,6 +36,7 @@
#include <ndn-cxx/management/nfd-channel-status.hpp>
#include <ndn-cxx/management/nfd-face-status.hpp>
#include <ndn-cxx/management/nfd-fib-entry.hpp>
+#include <ndn-cxx/management/nfd-rib-entry.hpp>
#include <ndn-cxx/management/nfd-strategy-choice.hpp>
#include <boost/algorithm/string/replace.hpp>
@@ -53,6 +54,7 @@
, m_needChannelStatusRetrieval(false)
, m_needFaceStatusRetrieval(false)
, m_needFibEnumerationRetrieval(false)
+ , m_needRibStatusRetrieval(false)
, m_needStrategyChoiceRetrieval(false)
, m_isOutputXml(false)
{
@@ -69,6 +71,7 @@
" [-c] - retrieve channel status information\n"
" [-f] - retrieve face status information\n"
" [-b] - retrieve FIB information\n"
+ " [-r] - retrieve RIB information\n"
" [-s] - retrieve configured strategy choice for NDN namespaces\n"
" [-x] - output NFD status information in XML format\n"
"\n"
@@ -110,6 +113,12 @@
}
void
+ enableRibStatusRetrieval()
+ {
+ m_needRibStatusRetrieval = true;
+ }
+
+ void
enableXmlOutput()
{
m_isOutputXml = true;
@@ -381,13 +390,13 @@
std::cout << "<incomingPackets>";
std::cout << "<nInterests>" << faceStatus.getNInInterests()
<< "</nInterests>";
- std::cout << "<nDatas>" << faceStatus.getNInInterests()
+ std::cout << "<nDatas>" << faceStatus.getNInDatas()
<< "</nDatas>";
std::cout << "</incomingPackets>";
std::cout << "<outgoingPackets>";
std::cout << "<nInterests>" << faceStatus.getNOutInterests()
<< "</nInterests>";
- std::cout << "<nDatas>" << faceStatus.getNOutInterests()
+ std::cout << "<nDatas>" << faceStatus.getNOutDatas()
<< "</nDatas>";
std::cout << "</outgoingPackets>";
std::cout << "</packetCounters>";
@@ -629,6 +638,118 @@
}
void
+ fetchRibStatusInformation()
+ {
+ m_buffer = make_shared<OBufferStream>();
+
+ Interest interest("/localhost/nfd/rib/list");
+ interest.setChildSelector(1);
+ interest.setMustBeFresh(true);
+
+ m_face.expressInterest(interest,
+ bind(&NfdStatus::fetchSegments, this, _2,
+ &NfdStatus::afterFetchedRibStatusInformation),
+ bind(&NfdStatus::onTimeout, this));
+ }
+
+ void
+ afterFetchedRibStatusInformation()
+ {
+ ConstBufferPtr buf = m_buffer->buf();
+ if (m_isOutputXml)
+ {
+ std::cout << "<rib>";
+
+ Block block;
+ size_t offset = 0;
+ while (offset < buf->size())
+ {
+ bool ok = Block::fromBuffer(buf, offset, block);
+ if (!ok)
+ {
+ std::cerr << "ERROR: cannot decode RibEntry TLV";
+ break;
+ }
+ offset += block.size();
+
+ nfd::RibEntry ribEntry(block);
+
+ std::cout << "<ribEntry>";
+ std::string prefix(ribEntry.getName().toUri());
+ escapeSpecialCharacters(&prefix);
+ std::cout << "<prefix>" << prefix << "</prefix>";
+ std::cout << "<routes>";
+ for (std::list<nfd::Route>::const_iterator
+ nextRoute = ribEntry.begin();
+ nextRoute != ribEntry.end();
+ ++nextRoute)
+ {
+ std::cout << "<route>" ;
+ std::cout << "<faceId>" << nextRoute->getFaceId() << "</faceId>";
+ std::cout << "<origin>" << nextRoute->getOrigin() << "</origin>";
+ std::cout << "<cost>" << nextRoute->getCost() << "</cost>";
+ std::cout << "<flags>" << nextRoute->getFlags() << "</flags>";
+ if (!nextRoute->hasInfiniteExpirationPeriod()) {
+ std::cout << "<expirationPeriod>PT"
+ << time::duration_cast<time::seconds>(nextRoute->getExpirationPeriod())
+ .count() << "S"
+ << "</expirationPeriod>";
+ }
+ std::cout << "</route>";
+ }
+ std::cout << "</routes>";
+ std::cout << "</ribEntry>";
+ }
+
+ std::cout << "</rib>";
+ }
+ else
+ {
+ std::cout << "Rib:" << std::endl;
+
+ Block block;
+ size_t offset = 0;
+ while (offset < buf->size())
+ {
+ bool ok = Block::fromBuffer(buf, offset, block);
+ if (!ok)
+ {
+ std::cerr << "ERROR: cannot decode RibEntry TLV" << std::endl;
+ break;
+ }
+
+ offset += block.size();
+
+ nfd::RibEntry ribEntry(block);
+
+ std::cout << " " << ribEntry.getName().toUri() << " route={";
+ for (std::list<nfd::Route>::const_iterator
+ nextRoute = ribEntry.begin();
+ nextRoute != ribEntry.end();
+ ++nextRoute)
+ {
+ if (nextRoute != ribEntry.begin())
+ std::cout << ", ";
+ std::cout << "faceid=" << nextRoute->getFaceId()
+ << " (origin=" << nextRoute->getOrigin()
+ << " cost=" << nextRoute->getCost()
+ << " flags=" << nextRoute->getFlags();
+ if (!nextRoute->hasInfiniteExpirationPeriod()) {
+ std::cout << " expires="
+ << time::duration_cast<time::seconds>(nextRoute->getExpirationPeriod())
+ .count() << "s";
+ }
+ std::cout << ")";
+ }
+ std::cout << "}" << std::endl;
+ }
+ }
+
+ runNextStep();
+ }
+
+
+ void
fetchInformation()
{
if (m_isOutputXml ||
@@ -636,12 +757,14 @@
!m_needChannelStatusRetrieval &&
!m_needFaceStatusRetrieval &&
!m_needFibEnumerationRetrieval &&
+ !m_needRibStatusRetrieval &&
!m_needStrategyChoiceRetrieval))
{
enableVersionRetrieval();
enableChannelStatusRetrieval();
enableFaceStatusRetrieval();
enableFibEnumerationRetrieval();
+ enableRibStatusRetrieval();
enableStrategyChoiceRetrieval();
}
@@ -660,6 +783,9 @@
if (m_needFibEnumerationRetrieval)
m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));
+ if (m_needRibStatusRetrieval)
+ m_fetchSteps.push_back(bind(&NfdStatus::fetchRibStatusInformation, this));
+
if (m_needStrategyChoiceRetrieval)
m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));
@@ -705,6 +831,7 @@
bool m_needChannelStatusRetrieval;
bool m_needFaceStatusRetrieval;
bool m_needFibEnumerationRetrieval;
+ bool m_needRibStatusRetrieval;
bool m_needStrategyChoiceRetrieval;
bool m_isOutputXml;
Face m_face;
@@ -721,7 +848,7 @@
int option;
ndn::NfdStatus nfdStatus(argv[0]);
- while ((option = getopt(argc, argv, "hvcfbsxV")) != -1) {
+ while ((option = getopt(argc, argv, "hvcfbrsxV")) != -1) {
switch (option) {
case 'h':
nfdStatus.usage();
@@ -738,6 +865,9 @@
case 'b':
nfdStatus.enableFibEnumerationRetrieval();
break;
+ case 'r':
+ nfdStatus.enableRibStatusRetrieval();
+ break;
case 's':
nfdStatus.enableStrategyChoiceRetrieval();
break;