tools: add congestion marking parameters to nfdc face create
refs #4465
Change-Id: I5df5d6136f4729ad836a72f55531208d868da5f7
diff --git a/tools/nfd-status-http-server-files/nfd-status.xsl b/tools/nfd-status-http-server-files/nfd-status.xsl
index d9b8885..9620cba 100644
--- a/tools/nfd-status-http-server-files/nfd-status.xsl
+++ b/tools/nfd-status-http-server-files/nfd-status.xsl
@@ -36,7 +36,26 @@
<xsl:template name="formatDuration">
<xsl:param name="duration" />
- <xsl:variable name="seconds"><xsl:value-of select="substring($duration, 3, string-length($duration)-3)" /></xsl:variable>
+ <xsl:variable name="milliseconds">
+ <xsl:choose>
+ <xsl:when test="contains($duration, '.')">
+ <xsl:value-of select="substring($duration, string-length($duration)-4, 3)" />
+ </xsl:when>
+ <xsl:otherwise>
+ 0
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="seconds">
+ <xsl:choose>
+ <xsl:when test="contains($duration, '.')">
+ <xsl:value-of select="substring($duration, 3, string-length($duration)-7)" />
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="substring($duration, 3, string-length($duration)-3)" />
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
<xsl:variable name="days"><xsl:value-of select="floor($seconds div 86400)" /></xsl:variable>
<xsl:variable name="hours"><xsl:value-of select="floor($seconds div 3600)" /></xsl:variable>
<xsl:variable name="minutes"><xsl:value-of select="floor($seconds div 60)" /></xsl:variable>
@@ -65,6 +84,12 @@
<xsl:otherwise>
<xsl:value-of select="$seconds"/> seconds
</xsl:otherwise>
+ <xsl:when test="$milliseconds > 1">
+ <xsl:value-of select="$milliseconds"/> milliseconds
+ </xsl:when>
+ <xsl:when test="$milliseconds = 1">
+ <xsl:value-of select="$milliseconds"/> millisecond
+ </xsl:when>
</xsl:choose>
</xsl:template>
@@ -183,6 +208,12 @@
<xsl:when test="nfd:flags/nfd:localFieldsEnabled">
local-fields
</xsl:when>
+ <xsl:when test="nfd:flags/nfd:lpReliabilityEnabled">
+ reliability
+ </xsl:when>
+ <xsl:when test="nfd:flags/nfd:congestionMarkingEnabled">
+ congestion-marking
+ </xsl:when>
</xsl:choose>
</td>
<td>
diff --git a/tools/nfdc/face-module.cpp b/tools/nfdc/face-module.cpp
index 1a88229..560b223 100644
--- a/tools/nfdc/face-module.cpp
+++ b/tools/nfdc/face-module.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,7 +25,6 @@
#include "face-module.hpp"
#include "find-face.hpp"
-#include "format-helpers.hpp"
namespace nfd {
namespace tools {
@@ -54,7 +53,10 @@
.addArg("remote", ArgValueType::FACE_URI, Required::YES, Positional::YES)
.addArg("persistency", ArgValueType::FACE_PERSISTENCY, Required::NO, Positional::YES)
.addArg("local", ArgValueType::FACE_URI, Required::NO, Positional::NO)
- .addArg("reliability", ArgValueType::BOOLEAN, Required::NO, Positional::NO);
+ .addArg("reliability", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
+ .addArg("congestion-marking", ArgValueType::BOOLEAN, Required::NO, Positional::NO)
+ .addArg("congestion-marking-interval", ArgValueType::UNSIGNED, Required::NO, Positional::NO)
+ .addArg("default-congestion-threshold", ArgValueType::UNSIGNED, Required::NO, Positional::NO);
parser.addCommand(defFaceCreate, &FaceModule::create);
CommandDefinition defFaceDestroy("face", "destroy");
@@ -153,6 +155,9 @@
auto localUri = ctx.args.getOptional<FaceUri>("local");
auto persistency = ctx.args.get<FacePersistency>("persistency", FacePersistency::FACE_PERSISTENCY_PERSISTENT);
auto lpReliability = ctx.args.getTribool("reliability");
+ auto congestionMarking = ctx.args.getTribool("congestion-marking");
+ auto baseCongestionMarkingIntervalMs = ctx.args.getOptional<uint64_t>("congestion-marking-interval");
+ auto defaultCongestionThreshold = ctx.args.getOptional<uint64_t>("default-congestion-threshold");
FaceUri canonicalRemote;
ndn::optional<FaceUri> canonicalLocal;
@@ -168,9 +173,8 @@
<< ia("id") << resp.getFaceId()
<< ia("local") << resp.getLocalUri()
<< ia("remote") << resp.getUri()
- << ia("persistency") << resp.getFacePersistency()
- << ia("reliability") << (resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) ? "on" : "off")
- << '\n';
+ << ia("persistency") << resp.getFacePersistency();
+ printFaceParams(ctx.out, ia, resp);
};
auto updateFace = [&printPositiveResult] (ControlParameters respParams, ControlParameters resp) {
@@ -200,24 +204,36 @@
ctx.makeCommandFailureHandler("upgrading face persistency"),
ctx.makeCommandOptions());
}
- else if (lpReliability && !respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
- // enable reliability
+ else if ((!boost::logic::indeterminate(lpReliability) &&
+ lpReliability != respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) ||
+ (!boost::logic::indeterminate(congestionMarking) &&
+ congestionMarking != respParams.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) ||
+ baseCongestionMarkingIntervalMs ||
+ defaultCongestionThreshold) {
ControlParameters params;
- params.setFaceId(respParams.getFaceId()).setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+ params.setFaceId(respParams.getFaceId());
+
+ if (!boost::logic::indeterminate(lpReliability) &&
+ lpReliability != respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
+ params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, lpReliability);
+ }
+ if (!boost::logic::indeterminate(congestionMarking) &&
+ congestionMarking != respParams.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
+ params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, congestionMarking);
+ }
+
+ if (baseCongestionMarkingIntervalMs) {
+ params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
+ }
+
+ if (defaultCongestionThreshold) {
+ params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
+ }
+
ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
params,
bind(updateFace, respParams, _1),
- ctx.makeCommandFailureHandler("enabling reliability"),
- ctx.makeCommandOptions());
- }
- else if (!lpReliability && respParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
- // disable reliability
- ControlParameters params;
- params.setFaceId(respParams.getFaceId()).setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
- ctx.controller.start<ndn::nfd::FaceUpdateCommand>(
- params,
- bind(updateFace, respParams, _1),
- ctx.makeCommandFailureHandler("disabling reliability"),
+ ctx.makeCommandFailureHandler("updating face"),
ctx.makeCommandOptions());
}
else {
@@ -237,6 +253,15 @@
if (!boost::logic::indeterminate(lpReliability)) {
params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, lpReliability);
}
+ if (!boost::logic::indeterminate(congestionMarking)) {
+ params.setFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED, congestionMarking);
+ }
+ if (baseCongestionMarkingIntervalMs) {
+ params.setBaseCongestionMarkingInterval(time::milliseconds(*baseCongestionMarkingIntervalMs));
+ }
+ if (defaultCongestionThreshold) {
+ params.setDefaultCongestionThreshold(*defaultCongestionThreshold);
+ }
ctx.controller.start<ndn::nfd::FaceCreateCommand>(
params,
@@ -309,9 +334,8 @@
ctx.out << ia("id") << face.getFaceId()
<< ia("local") << face.getLocalUri()
<< ia("remote") << face.getRemoteUri()
- << ia("persistency") << face.getFacePersistency()
- << ia("reliability") << (resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) ? "on" : "off")
- << '\n';
+ << ia("persistency") << face.getFacePersistency();
+ printFaceParams(ctx.out, ia, resp);
},
ctx.makeCommandFailureHandler("destroying face"),
ctx.makeCommandOptions());
@@ -360,6 +384,21 @@
os << "<facePersistency>" << item.getFacePersistency() << "</facePersistency>";
os << "<linkType>" << item.getLinkType() << "</linkType>";
+ if (!item.hasBaseCongestionMarkingInterval() && !item.hasDefaultCongestionThreshold()) {
+ os << "<congestion/>";
+ }
+ else {
+ os << "<congestion>";
+ if (item.hasBaseCongestionMarkingInterval()) {
+ os << "<baseMarkingInterval>" << xml::formatDuration(item.getBaseCongestionMarkingInterval())
+ << "</baseMarkingInterval>";
+ }
+ if (item.hasDefaultCongestionThreshold()) {
+ os << "<defaultThreshold>" << item.getDefaultCongestionThreshold() << "</defaultThreshold>";
+ }
+ os << "</congestion>";
+ }
+
if (item.getFlags() == 0) {
os << "<flags/>";
}
@@ -371,6 +410,9 @@
if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
os << "<lpReliabilityEnabled/>";
}
+ if (item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
+ os << "<congestionMarkingEnabled/>";
+ }
os << "</flags>";
}
@@ -409,14 +451,27 @@
void
FaceModule::formatItemText(std::ostream& os, const FaceStatus& item, bool wantMultiLine)
{
- text::ItemAttributes ia(wantMultiLine, 8);
+ text::ItemAttributes ia(wantMultiLine, 10);
os << ia("faceid") << item.getFaceId();
os << ia("remote") << item.getRemoteUri();
os << ia("local") << item.getLocalUri();
if (item.hasExpirationPeriod()) {
- os << ia("expires") << text::formatDuration(item.getExpirationPeriod());
+ os << ia("expires") << text::formatDuration<time::seconds>(item.getExpirationPeriod());
+ }
+
+ if (item.hasBaseCongestionMarkingInterval() || item.hasDefaultCongestionThreshold()) {
+ os << ia("congestion") << "{";
+ text::Separator congestionSep("", " ");
+ if (item.hasBaseCongestionMarkingInterval()) {
+ os << congestionSep << "base-marking-interval="
+ << text::formatDuration<time::milliseconds>(item.getBaseCongestionMarkingInterval());
+ }
+ if (item.hasDefaultCongestionThreshold()) {
+ os << congestionSep << "default-threshold=" << item.getDefaultCongestionThreshold() << "B";
+ }
+ os << "}";
}
os << ia("counters")
@@ -442,11 +497,29 @@
if (item.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
os << flagSep << "lp-reliability";
}
+ if (item.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED)) {
+ os << flagSep << "congestion-marking";
+ }
os << '}';
os << ia.end();
}
+void
+FaceModule::printFaceParams(std::ostream& os, text::ItemAttributes& ia, const ControlParameters& resp)
+{
+ os << ia("reliability") << (resp.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) ? "on" : "off")
+ << ia("congestion-marking") << (resp.getFlagBit(ndn::nfd::BIT_CONGESTION_MARKING_ENABLED) ? "on" : "off");
+ if (resp.hasBaseCongestionMarkingInterval()) {
+ os << ia("congestion-marking-interval")
+ << text::formatDuration<time::milliseconds>(resp.getBaseCongestionMarkingInterval());
+ }
+ if (resp.hasDefaultCongestionThreshold()) {
+ os << ia("default-congestion-threshold") << resp.getDefaultCongestionThreshold() << "B";
+ }
+ os << '\n';
+}
+
} // namespace nfdc
} // namespace tools
} // namespace nfd
diff --git a/tools/nfdc/face-module.hpp b/tools/nfdc/face-module.hpp
index 6c190a1..9f0ac2a 100644
--- a/tools/nfdc/face-module.hpp
+++ b/tools/nfdc/face-module.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -28,6 +28,7 @@
#include "module.hpp"
#include "command-parser.hpp"
+#include "format-helpers.hpp"
namespace nfd {
namespace tools {
@@ -93,6 +94,14 @@
static void
formatItemText(std::ostream& os, const FaceStatus& item, bool wantMultiLine);
+ /** \brief print face response parameters to specified ostream
+ * \param os output stream
+ * \param ia ItemAttributes used to format output
+ * \param resp response control parameters to print
+ */
+ static void
+ printFaceParams(std::ostream& os, text::ItemAttributes& ia, const ControlParameters& resp);
+
private:
std::vector<FaceStatus> m_status;
};
diff --git a/tools/nfdc/format-helpers.cpp b/tools/nfdc/format-helpers.cpp
index 3d851dd..6d5a983 100644
--- a/tools/nfdc/format-helpers.cpp
+++ b/tools/nfdc/format-helpers.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -25,6 +25,9 @@
#include "format-helpers.hpp"
+#include <iomanip>
+#include <sstream>
+
namespace nfd {
namespace tools {
namespace nfdc {
@@ -73,9 +76,28 @@
}
std::string
-formatSeconds(time::seconds d)
+formatDuration(time::nanoseconds d)
{
- return "PT" + to_string(d.count()) + "S";
+ std::ostringstream str;
+
+ if (d < 0_ns) {
+ str << "-";
+ }
+
+ str << "PT";
+
+ time::seconds seconds(time::duration_cast<time::seconds>(time::abs(d)));
+ time::milliseconds ms(time::duration_cast<time::milliseconds>(time::abs(d) - seconds));
+
+ str << seconds.count();
+
+ if (ms >= 1_ms) {
+ str << "." << std::setfill('0') << std::setw(3) << ms.count();
+ }
+
+ str << "S";
+
+ return str.str();
}
std::string
@@ -156,12 +178,6 @@
}
std::string
-formatSeconds(time::seconds d, bool isLong)
-{
- return to_string(d.count()) + (isLong ? " seconds" : "s");
-}
-
-std::string
formatTimestamp(time::system_clock::TimePoint t)
{
return time::toIsoString(t);
diff --git a/tools/nfdc/format-helpers.hpp b/tools/nfdc/format-helpers.hpp
index 9283855..c0f8fd1 100644
--- a/tools/nfdc/format-helpers.hpp
+++ b/tools/nfdc/format-helpers.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -50,16 +50,17 @@
std::ostream&
operator<<(std::ostream& os, const Text& text);
+/** \return duration in XML duration format
+ *
+ * Definition of this format: https://www.w3.org/TR/xmlschema11-2/#duration
+ */
std::string
-formatSeconds(time::seconds d);
+formatDuration(time::nanoseconds d);
-template<typename DURATION>
-std::string
-formatDuration(DURATION d)
-{
- return formatSeconds(time::duration_cast<time::seconds>(d));
-}
-
+/** \return timestamp in XML dateTime format
+ *
+ * Definition of this format: https://www.w3.org/TR/xmlschema11-2/#dateTime
+ */
std::string
formatTimestamp(time::system_clock::TimePoint t);
@@ -164,14 +165,69 @@
std::ostream&
operator<<(std::ostream& os, const ItemAttributes::Attribute& attr);
-std::string
-formatSeconds(time::seconds d, bool isLong = false);
+namespace detail {
-template<typename DURATION>
+template<typename DurationT>
std::string
-formatDuration(DURATION d, bool isLong = false)
+getTimeUnit(bool isLong);
+
+template<>
+inline std::string
+getTimeUnit<time::nanoseconds>(bool isLong)
{
- return formatSeconds(time::duration_cast<time::seconds>(d), isLong);
+ return isLong ? "nanoseconds" : "ns";
+}
+
+template<>
+inline std::string
+getTimeUnit<time::microseconds>(bool isLong)
+{
+ return isLong ? "microseconds" : "us";
+}
+
+template<>
+inline std::string
+getTimeUnit<time::milliseconds>(bool isLong)
+{
+ return isLong ? "milliseconds" : "ms";
+}
+
+template<>
+inline std::string
+getTimeUnit<time::seconds>(bool isLong)
+{
+ return isLong ? "seconds" : "s";
+}
+
+template<>
+inline std::string
+getTimeUnit<time::minutes>(bool isLong)
+{
+ return isLong ? "minutes" : "m";
+}
+
+template<>
+inline std::string
+getTimeUnit<time::hours>(bool isLong)
+{
+ return isLong ? "hours" : "h";
+}
+
+template<>
+inline std::string
+getTimeUnit<time::days>(bool isLong)
+{
+ return isLong ? "days" : "d";
+}
+
+} // namespace detail
+
+template<typename OutputPrecision>
+std::string
+formatDuration(time::nanoseconds d, bool isLong = false)
+{
+ return to_string(time::duration_cast<OutputPrecision>(d).count()) +
+ (isLong ? " " : "") + detail::getTimeUnit<OutputPrecision>(isLong);
}
std::string
diff --git a/tools/nfdc/forwarder-general-module.cpp b/tools/nfdc/forwarder-general-module.cpp
index e490892..4a85cdd 100644
--- a/tools/nfdc/forwarder-general-module.cpp
+++ b/tools/nfdc/forwarder-general-module.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2017, Regents of the University of California,
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -64,7 +64,8 @@
os << "<version>" << xml::Text{item.getNfdVersion()} << "</version>";
os << "<startTime>" << xml::formatTimestamp(item.getStartTimestamp()) << "</startTime>";
os << "<currentTime>" << xml::formatTimestamp(item.getCurrentTimestamp()) << "</currentTime>";
- os << "<uptime>" << xml::formatDuration(calculateUptime(item)) << "</uptime>";
+ os << "<uptime>" << xml::formatDuration(time::duration_cast<time::seconds>(calculateUptime(item)))
+ << "</uptime>";
os << "<nNameTreeEntries>" << item.getNNameTreeEntries() << "</nNameTreeEntries>";
os << "<nFibEntries>" << item.getNFibEntries() << "</nFibEntries>";
@@ -101,7 +102,7 @@
os << " version=" << item.getNfdVersion() << "\n";
os << " startTime=" << text::formatTimestamp(item.getStartTimestamp()) << "\n";
os << " currentTime=" << text::formatTimestamp(item.getCurrentTimestamp()) << "\n";
- os << " uptime=" << text::formatDuration(calculateUptime(item), true) << "\n";
+ os << " uptime=" << text::formatDuration<time::seconds>(calculateUptime(item), true) << "\n";
os << " nNameTreeEntries=" << item.getNNameTreeEntries() << "\n";
os << " nFibEntries=" << item.getNFibEntries() << "\n";
diff --git a/tools/nfdc/rib-module.cpp b/tools/nfdc/rib-module.cpp
index 5ca7195..f9d888f 100644
--- a/tools/nfdc/rib-module.cpp
+++ b/tools/nfdc/rib-module.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017, Regents of the University of California,
+/*
+ * Copyright (c) 2014-2018, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
@@ -195,7 +195,7 @@
<< ia("cost") << resp.getCost()
<< ia("flags") << static_cast<ndn::nfd::RouteFlags>(resp.getFlags());
if (resp.hasExpirationPeriod()) {
- ctx.out << ia("expires") << resp.getExpirationPeriod().count() << "ms\n";
+ ctx.out << ia("expires") << text::formatDuration<time::milliseconds>(resp.getExpirationPeriod()) << "\n";
}
else {
ctx.out<< ia("expires") << "never\n";
@@ -307,7 +307,7 @@
}
if (route.hasExpirationPeriod()) {
os << "<expirationPeriod>"
- << xml::formatDuration(route.getExpirationPeriod())
+ << xml::formatDuration(time::duration_cast<time::seconds>(route.getExpirationPeriod()))
<< "</expirationPeriod>";
}
os << "</route>";
@@ -356,7 +356,7 @@
os << ia("cost") << route.getCost();
os << ia("flags") << static_cast<ndn::nfd::RouteFlags>(route.getFlags());
if (route.hasExpirationPeriod()) {
- os << ia("expires") << text::formatDuration(route.getExpirationPeriod());
+ os << ia("expires") << text::formatDuration<time::seconds>(route.getExpirationPeriod());
}
else {
os << ia("expires") << "never";