mgmt: LpFace faces/enable-local-control workaround
In this temporary workaround,
faces/enable-local-control enables all local fields in GenericLinkService,
and faces/disable-local-control disables all local fields in GenericLinkService.
This commit also modifies FaceTable::remove to retain shared_ptr<Face>
until signal execution is complete.
refs #3226
Change-Id: I3513e97ec2af87df94dbf57a7256b895ed9d2103
diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp
index 1884203..a8a8053 100644
--- a/daemon/fw/face-table.cpp
+++ b/daemon/fw/face-table.cpp
@@ -25,6 +25,7 @@
#include "face-table.hpp"
#include "forwarder.hpp"
+#include "core/global-io.hpp"
#include "core/logger.hpp"
namespace nfd {
@@ -111,6 +112,9 @@
" (" << reason << ")");
m_forwarder.getFib().removeNextHopFromAllEntries(face);
+
+ // defer Face deallocation, so that Transport isn't deallocated during afterStateChange signal
+ getGlobalIoService().post([face] {});
}
FaceTable::ForwardRange
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index b49b752..29cac39 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -26,6 +26,7 @@
#include "face-manager.hpp"
#include "core/network-interface.hpp"
+#include "face/generic-link-service.hpp"
#include "face/lp-face-wrapper.hpp"
#include "face/tcp-factory.hpp"
#include "face/udp-factory.hpp"
@@ -133,43 +134,6 @@
}
void
-FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
- const ControlParameters& parameters,
- const ndn::mgmt::CommandContinuation& done)
-{
- shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
- if (target) {
- target->close();
- }
-
- done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
-}
-
-void
-FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
- const ControlParameters& parameters,
- const ndn::mgmt::CommandContinuation& done)
-{
- auto result = extractLocalControlParameters(interest, parameters, done);
- if (result.isValid) {
- result.face->setLocalControlHeaderFeature(result.feature, true);
- return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
- }
-}
-
-void
-FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
- const ControlParameters& parameters,
- const ndn::mgmt::CommandContinuation& done)
-{
- auto result = extractLocalControlParameters(interest, parameters, done);
- if (result.isValid) {
- result.face->setLocalControlHeaderFeature(result.feature, false);
- return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
- }
-}
-
-void
FaceManager::afterCreateFaceSuccess(ControlParameters& parameters,
const shared_ptr<Face>& newFace,
const ndn::mgmt::CommandContinuation& done)
@@ -183,6 +147,19 @@
}
void
+FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
+ const ControlParameters& parameters,
+ const ndn::mgmt::CommandContinuation& done)
+{
+ shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
+ if (target) {
+ target->close();
+ }
+
+ done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+}
+
+void
FaceManager::afterCreateFaceFailure(const std::string& reason,
const ndn::mgmt::CommandContinuation& done)
{
@@ -191,6 +168,68 @@
done(ControlResponse(408, "Failed to create face: " + reason));
}
+void
+FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
+ const ControlParameters& parameters,
+ const ndn::mgmt::CommandContinuation& done)
+{
+ auto result = extractLocalControlParameters(interest, parameters, done);
+ if (!result.isValid) {
+ return;
+ }
+
+ if (result.face) {
+ result.face->setLocalControlHeaderFeature(result.feature, true);
+ return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+ }
+
+ // TODO#3226 redesign enable-local-control
+ // For now, enable-local-control will enable all local fields in GenericLinkService.
+ BOOST_ASSERT(result.lpFace != nullptr);
+ auto service = dynamic_cast<face::GenericLinkService*>(result.lpFace->getLinkService());
+ if (service == nullptr) {
+ return done(ControlResponse(503, "LinkService type not supported"));
+ }
+
+ face::GenericLinkService::Options options = service->getOptions();
+ options.allowLocalFields = true;
+ service->setOptions(options);
+
+ return done(ControlResponse(200, "OK: enable all local fields on GenericLinkService")
+ .setBody(parameters.wireEncode()));
+}
+
+void
+FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
+ const ControlParameters& parameters,
+ const ndn::mgmt::CommandContinuation& done)
+{
+ auto result = extractLocalControlParameters(interest, parameters, done);
+ if (!result.isValid) {
+ return;
+ }
+
+ if (result.face) {
+ result.face->setLocalControlHeaderFeature(result.feature, false);
+ return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+ }
+
+ // TODO#3226 redesign disable-local-control
+ // For now, disable-local-control will disable all local fields in GenericLinkService.
+ BOOST_ASSERT(result.lpFace != nullptr);
+ auto service = dynamic_cast<face::GenericLinkService*>(result.lpFace->getLinkService());
+ if (service == nullptr) {
+ return done(ControlResponse(503, "LinkService type not supported"));
+ }
+
+ face::GenericLinkService::Options options = service->getOptions();
+ options.allowLocalFields = false;
+ service->setOptions(options);
+
+ return done(ControlResponse(200, "OK: disable all local fields on GenericLinkService")
+ .setBody(parameters.wireEncode()));
+}
+
FaceManager::ExtractLocalControlParametersResult
FaceManager::extractLocalControlParameters(const Interest& request,
const ControlParameters& parameters,
@@ -198,6 +237,7 @@
{
ExtractLocalControlParametersResult result;
result.isValid = false;
+ result.lpFace = nullptr;
auto face = m_faceTable.get(request.getIncomingFaceId());
if (!static_cast<bool>(face)) {
@@ -215,6 +255,11 @@
result.isValid = true;
result.face = dynamic_pointer_cast<LocalFace>(face);
+ if (result.face == nullptr) {
+ auto lpFaceW = dynamic_pointer_cast<face::LpFaceWrapper>(face);
+ BOOST_ASSERT(lpFaceW != nullptr);
+ result.lpFace = lpFaceW->getLpFace();
+ }
result.feature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
return result;
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index f5283d6..e3c955f 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -36,6 +36,10 @@
class NetworkInterfaceInfo;
class ProtocolFactory;
+namespace face {
+class LpFace;
+} // namespace face
+
/**
* @brief implement the Face Management of NFD Management Protocol.
* @sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt
@@ -88,6 +92,7 @@
{
bool isValid;
shared_ptr<LocalFace> face;
+ face::LpFace* lpFace;
LocalControlFeature feature;
};