mgmt: support LpReliability flag in faces/create and faces/update

refs #4003

Change-Id: Iddf94ea55c630b038187c2503783591b118230ec
diff --git a/daemon/face/ethernet-channel.cpp b/daemon/face/ethernet-channel.cpp
index 44fb03c..bc149d2 100644
--- a/daemon/face/ethernet-channel.cpp
+++ b/daemon/face/ethernet-channel.cpp
@@ -55,12 +55,13 @@
 void
 EthernetChannel::connect(const ethernet::Address& remoteEndpoint,
                          ndn::nfd::FacePersistency persistency,
+                         bool wantLpReliability,
                          const FaceCreatedCallback& onFaceCreated,
                          const FaceCreationFailedCallback& onConnectFailed)
 {
   shared_ptr<Face> face;
   try {
-    face = createFace(remoteEndpoint, persistency).second;
+    face = createFace(remoteEndpoint, persistency, wantLpReliability).second;
   }
   catch (const boost::system::system_error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << remoteEndpoint << " failed: " << e.what());
@@ -165,7 +166,7 @@
   bool isCreated = false;
   shared_ptr<Face> face;
   try {
-    std::tie(isCreated, face) = createFace(sender, ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+    std::tie(isCreated, face) = createFace(sender, ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, false);
   }
   catch (const EthernetTransport::Error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << sender << " failed: " << e.what());
@@ -186,7 +187,8 @@
 
 std::pair<bool, shared_ptr<Face>>
 EthernetChannel::createFace(const ethernet::Address& remoteEndpoint,
-                            ndn::nfd::FacePersistency persistency)
+                            ndn::nfd::FacePersistency persistency,
+                            bool wantLpReliability)
 {
   auto it = m_channelFaces.find(remoteEndpoint);
   if (it != m_channelFaces.end()) {
@@ -196,7 +198,9 @@
   }
 
   // else, create a new face
-  auto linkService = make_unique<GenericLinkService>();
+  GenericLinkService::Options options;
+  options.reliabilityOptions.isEnabled = wantLpReliability;
+  auto linkService = make_unique<GenericLinkService>(options);
   auto transport = make_unique<UnicastEthernetTransport>(*m_localEndpoint, remoteEndpoint,
                                                          persistency, m_idleFaceTimeout);
   auto face = make_shared<Face>(std::move(linkService), std::move(transport));
diff --git a/daemon/face/ethernet-channel.hpp b/daemon/face/ethernet-channel.hpp
index 8ad2432..5847af5 100644
--- a/daemon/face/ethernet-channel.hpp
+++ b/daemon/face/ethernet-channel.hpp
@@ -79,12 +79,14 @@
    *
    * \param remoteEndpoint The remote Ethernet endpoint
    * \param persistency Persistency of the newly created face
+   * \param wantLpReliability whether LpReliability should be enabled
    * \param onFaceCreated Callback to notify successful creation of the face
    * \param onConnectFailed Callback to notify errors
    */
   void
   connect(const ethernet::Address& remoteEndpoint,
           ndn::nfd::FacePersistency persistency,
+          bool wantLpReliability,
           const FaceCreatedCallback& onFaceCreated,
           const FaceCreationFailedCallback& onConnectFailed);
 
@@ -122,7 +124,8 @@
 
   std::pair<bool, shared_ptr<Face>>
   createFace(const ethernet::Address& remoteEndpoint,
-             ndn::nfd::FacePersistency persistency);
+             ndn::nfd::FacePersistency persistency,
+             bool wantLpReliability);
 
   void
   updateFilter();
diff --git a/daemon/face/ethernet-factory.cpp b/daemon/face/ethernet-factory.cpp
index b00fa5f..36f7c45 100644
--- a/daemon/face/ethernet-factory.cpp
+++ b/daemon/face/ethernet-factory.cpp
@@ -193,7 +193,7 @@
     return;
   }
 
-  if (params.wantLocalFieldsEnabled) {
+  if (params.wantLocalFields) {
     // Ethernet faces are never local
     NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
     onFailure(406, "Local fields can only be enabled on faces with local scope");
@@ -202,7 +202,8 @@
 
   for (const auto& i : m_channels) {
     if (i.first == localEndpoint) {
-      i.second->connect(remoteEndpoint, params.persistency, onCreated, onFailure);
+      i.second->connect(remoteEndpoint, params.persistency, params.wantLpReliability,
+                        onCreated, onFailure);
       return;
     }
   }
diff --git a/daemon/face/protocol-factory.hpp b/daemon/face/protocol-factory.hpp
index 0eee552..e0c62a1 100644
--- a/daemon/face/protocol-factory.hpp
+++ b/daemon/face/protocol-factory.hpp
@@ -139,7 +139,8 @@
     FaceUri remoteUri;
     ndn::optional<FaceUri> localUri;
     ndn::nfd::FacePersistency persistency;
-    bool wantLocalFieldsEnabled;
+    bool wantLocalFields;
+    bool wantLpReliability;
   };
 
   /** \brief Try to create face using the supplied parameters
diff --git a/daemon/face/tcp-channel.cpp b/daemon/face/tcp-channel.cpp
index dee9fa6..4c4c290 100644
--- a/daemon/face/tcp-channel.cpp
+++ b/daemon/face/tcp-channel.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -69,7 +69,8 @@
 void
 TcpChannel::connect(const tcp::Endpoint& remoteEndpoint,
                     ndn::nfd::FacePersistency persistency,
-                    bool wantLocalFieldsEnabled,
+                    bool wantLocalFields,
+                    bool wantLpReliability,
                     const FaceCreatedCallback& onFaceCreated,
                     const FaceCreationFailedCallback& onConnectFailed,
                     time::nanoseconds timeout)
@@ -88,15 +89,18 @@
   NFD_LOG_CHAN_TRACE("Connecting to " << remoteEndpoint);
   clientSocket->async_connect(remoteEndpoint,
                               bind(&TcpChannel::handleConnect, this,
-                                   boost::asio::placeholders::error, remoteEndpoint,
-                                   clientSocket, persistency, wantLocalFieldsEnabled,
+                                   boost::asio::placeholders::error, remoteEndpoint, clientSocket,
+                                   // Creating a parameters struct works around limit on number of
+                                   // parameters to bind
+                                   ConnectParams{persistency, wantLocalFields, wantLpReliability},
                                    timeoutEvent, onFaceCreated, onConnectFailed));
 }
 
 void
 TcpChannel::createFace(ip::tcp::socket&& socket,
                        ndn::nfd::FacePersistency persistency,
-                       bool wantLocalFieldsEnabled,
+                       bool wantLocalFields,
+                       bool wantLpReliability,
                        const FaceCreatedCallback& onFaceCreated)
 {
   shared_ptr<Face> face;
@@ -104,10 +108,10 @@
 
   auto it = m_channelFaces.find(remoteEndpoint);
   if (it == m_channelFaces.end()) {
-    auto linkService = make_unique<GenericLinkService>();
-    auto options = linkService->getOptions();
-    options.allowLocalFields = wantLocalFieldsEnabled;
-    linkService->setOptions(options);
+    GenericLinkService::Options options;
+    options.allowLocalFields = wantLocalFields;
+    options.reliabilityOptions.isEnabled = wantLpReliability;
+    auto linkService = make_unique<GenericLinkService>(options);
 
     auto transport = make_unique<TcpTransport>(std::move(socket), persistency);
     face = make_shared<Face>(std::move(linkService), std::move(transport));
@@ -154,7 +158,7 @@
   }
 
   NFD_LOG_CHAN_TRACE("Incoming connection from " << m_socket.remote_endpoint());
-  createFace(std::move(m_socket), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, false, onFaceCreated);
+  createFace(std::move(m_socket), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, false, false, onFaceCreated);
 
   // prepare accepting the next connection
   accept(onFaceCreated, onAcceptFailed);
@@ -164,8 +168,7 @@
 TcpChannel::handleConnect(const boost::system::error_code& error,
                           const tcp::Endpoint& remoteEndpoint,
                           const shared_ptr<ip::tcp::socket>& socket,
-                          ndn::nfd::FacePersistency persistency,
-                          bool wantLocalFieldsEnabled,
+                          TcpChannel::ConnectParams params,
                           const scheduler::EventId& connectTimeoutEvent,
                           const FaceCreatedCallback& onFaceCreated,
                           const FaceCreationFailedCallback& onConnectFailed)
@@ -190,7 +193,8 @@
   }
 
   NFD_LOG_CHAN_TRACE("Connected to " << socket->remote_endpoint());
-  createFace(std::move(*socket), persistency, wantLocalFieldsEnabled, onFaceCreated);
+  createFace(std::move(*socket), params.persistency, params.wantLocalFields,
+             params.wantLpReliability, onFaceCreated);
 }
 
 void
diff --git a/daemon/face/tcp-channel.hpp b/daemon/face/tcp-channel.hpp
index 129587e..ca4c522 100644
--- a/daemon/face/tcp-channel.hpp
+++ b/daemon/face/tcp-channel.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -88,16 +88,26 @@
   void
   connect(const tcp::Endpoint& remoteEndpoint,
           ndn::nfd::FacePersistency persistency,
-          bool wantLocalFieldsEnabled,
+          bool wantLocalFields,
+          bool wantLpReliability,
           const FaceCreatedCallback& onFaceCreated,
           const FaceCreationFailedCallback& onConnectFailed,
           time::nanoseconds timeout = time::seconds(4));
 
 private:
+  struct ConnectParams
+  {
+    ndn::nfd::FacePersistency persistency;
+    bool wantLocalFields;
+    bool wantLpReliability;
+  };
+
+private:
   void
   createFace(boost::asio::ip::tcp::socket&& socket,
              ndn::nfd::FacePersistency persistency,
-             bool wantLocalFieldsEnabled,
+             bool wantLocalFields,
+             bool wantLpReliability,
              const FaceCreatedCallback& onFaceCreated);
 
   void
@@ -113,8 +123,7 @@
   handleConnect(const boost::system::error_code& error,
                 const tcp::Endpoint& remoteEndpoint,
                 const shared_ptr<boost::asio::ip::tcp::socket>& socket,
-                ndn::nfd::FacePersistency persistency,
-                bool wantLocalFieldsEnabled,
+                ConnectParams params,
                 const scheduler::EventId& connectTimeoutEvent,
                 const FaceCreatedCallback& onFaceCreated,
                 const FaceCreationFailedCallback& onConnectFailed);
diff --git a/daemon/face/tcp-factory.cpp b/daemon/face/tcp-factory.cpp
index a53721c..8214969 100644
--- a/daemon/face/tcp-factory.cpp
+++ b/daemon/face/tcp-factory.cpp
@@ -149,7 +149,7 @@
   // a canonical tcp4/tcp6 FaceUri cannot have a multicast address
   BOOST_ASSERT(!endpoint.address().is_multicast());
 
-  if (params.wantLocalFieldsEnabled && !endpoint.address().is_loopback()) {
+  if (params.wantLocalFields && !endpoint.address().is_loopback()) {
     NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
     onFailure(406, "Local fields can only be enabled on faces with local scope");
     return;
@@ -159,8 +159,8 @@
   for (const auto& i : m_channels) {
     if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
         (i.first.address().is_v6() && endpoint.address().is_v6())) {
-      i.second->connect(endpoint, params.persistency, params.wantLocalFieldsEnabled,
-                        onCreated, onFailure);
+      i.second->connect(endpoint, params.persistency, params.wantLocalFields,
+                        params.wantLpReliability, onCreated, onFailure);
       return;
     }
   }
diff --git a/daemon/face/udp-channel.cpp b/daemon/face/udp-channel.cpp
index 3ab9e1f..6ecaeaf 100644
--- a/daemon/face/udp-channel.cpp
+++ b/daemon/face/udp-channel.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -48,12 +48,13 @@
 void
 UdpChannel::connect(const udp::Endpoint& remoteEndpoint,
                     ndn::nfd::FacePersistency persistency,
+                    bool wantLpReliability,
                     const FaceCreatedCallback& onFaceCreated,
                     const FaceCreationFailedCallback& onConnectFailed)
 {
   shared_ptr<Face> face;
   try {
-    face = createFace(remoteEndpoint, persistency).second;
+    face = createFace(remoteEndpoint, persistency, wantLpReliability).second;
   }
   catch (const boost::system::system_error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << remoteEndpoint << " failed: " << e.what());
@@ -118,7 +119,8 @@
   bool isCreated = false;
   shared_ptr<Face> face;
   try {
-    std::tie(isCreated, face) = createFace(m_remoteEndpoint, ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+    std::tie(isCreated, face) = createFace(m_remoteEndpoint, ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
+                                           false);
   }
   catch (const boost::system::system_error& e) {
     NFD_LOG_CHAN_DEBUG("Face creation for " << m_remoteEndpoint << " failed: " << e.what());
@@ -141,7 +143,8 @@
 
 std::pair<bool, shared_ptr<Face>>
 UdpChannel::createFace(const udp::Endpoint& remoteEndpoint,
-                       ndn::nfd::FacePersistency persistency)
+                       ndn::nfd::FacePersistency persistency,
+                       bool wantLpReliability)
 {
   auto it = m_channelFaces.find(remoteEndpoint);
   if (it != m_channelFaces.end()) {
@@ -156,7 +159,9 @@
   socket.bind(m_localEndpoint);
   socket.connect(remoteEndpoint);
 
-  auto linkService = make_unique<GenericLinkService>();
+  GenericLinkService::Options options;
+  options.reliabilityOptions.isEnabled = wantLpReliability;
+  auto linkService = make_unique<GenericLinkService>(options);
   auto transport = make_unique<UnicastUdpTransport>(std::move(socket), persistency, m_idleFaceTimeout);
   auto face = make_shared<Face>(std::move(linkService), std::move(transport));
 
diff --git a/daemon/face/udp-channel.hpp b/daemon/face/udp-channel.hpp
index b239157..471a971 100644
--- a/daemon/face/udp-channel.hpp
+++ b/daemon/face/udp-channel.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -67,12 +67,14 @@
    *
    * \param remoteEndpoint The remote UDP endpoint
    * \param persistency Persistency of the newly created face
+   * \param wantLpReliability whether LpReliability should be enabled
    * \param onFaceCreated Callback to notify successful creation of the face
    * \param onConnectFailed Callback to notify errors
    */
   void
   connect(const udp::Endpoint& remoteEndpoint,
           ndn::nfd::FacePersistency persistency,
+          bool wantLpReliability,
           const FaceCreatedCallback& onFaceCreated,
           const FaceCreationFailedCallback& onConnectFailed);
 
@@ -108,7 +110,8 @@
 
   std::pair<bool, shared_ptr<Face>>
   createFace(const udp::Endpoint& remoteEndpoint,
-             ndn::nfd::FacePersistency persistency);
+             ndn::nfd::FacePersistency persistency,
+             bool wantLpReliability);
 
 private:
   const udp::Endpoint m_localEndpoint;
diff --git a/daemon/face/udp-factory.cpp b/daemon/face/udp-factory.cpp
index da42416..f44e4e9 100644
--- a/daemon/face/udp-factory.cpp
+++ b/daemon/face/udp-factory.cpp
@@ -236,7 +236,7 @@
     return;
   }
 
-  if (params.wantLocalFieldsEnabled) {
+  if (params.wantLocalFields) {
     // UDP faces are never local
     NFD_LOG_TRACE("createFace cannot create non-local face with local fields enabled");
     onFailure(406, "Local fields can only be enabled on faces with local scope");
@@ -247,7 +247,8 @@
   for (const auto& i : m_channels) {
     if ((i.first.address().is_v4() && endpoint.address().is_v4()) ||
         (i.first.address().is_v6() && endpoint.address().is_v6())) {
-      i.second->connect(endpoint, params.persistency, onCreated, onFailure);
+      i.second->connect(endpoint, params.persistency, params.wantLpReliability,
+                        onCreated, onFailure);
       return;
     }
   }
diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 8966d9d..c3cd1bd 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -118,7 +118,9 @@
   try {
     factory->createFace({remoteUri, localUri, parameters.getFacePersistency(),
         parameters.hasFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED) &&
-        parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED)},
+        parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
+        parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED) &&
+        parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)},
       bind(&FaceManager::afterCreateFaceSuccess, this, parameters, _1, done),
       bind(&FaceManager::afterCreateFaceFailure, this, _1, _2, done));
   }
@@ -227,7 +229,7 @@
   if (parameters.hasFacePersistency()) {
     face->setPersistency(parameters.getFacePersistency());
   }
-  setLinkServiceOptions(*face, parameters, response);
+  setLinkServiceOptions(*face, parameters);
 
   // Set ControlResponse fields
   response = collectFaceProperties(*face, false);
@@ -250,8 +252,7 @@
 
 void
 FaceManager::setLinkServiceOptions(Face& face,
-                                   const ControlParameters& parameters,
-                                   ControlParameters& response)
+                                   const ControlParameters& parameters)
 {
   auto linkService = dynamic_cast<face::GenericLinkService*>(face.getLinkService());
   BOOST_ASSERT(linkService != nullptr);
@@ -261,10 +262,10 @@
       face.getScope() == ndn::nfd::FACE_SCOPE_LOCAL) {
     options.allowLocalFields = parameters.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED);
   }
+  if (parameters.hasFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED)) {
+    options.reliabilityOptions.isEnabled = parameters.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED);
+  }
   linkService->setOptions(options);
-
-  // Set Flags for ControlResponse
-  response.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
 }
 
 ControlParameters
@@ -277,7 +278,8 @@
   ControlParameters params;
   params.setFaceId(face.getId())
         .setFacePersistency(face.getPersistency())
-        .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false);
+        .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, options.allowLocalFields, false)
+        .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, options.reliabilityOptions.isEnabled, false);
   if (wantUris) {
     params.setUri(face.getRemoteUri().toString())
           .setLocalUri(face.getLocalUri().toString());
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index 4e43716..bee95a3 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -79,8 +79,7 @@
 
   static void
   setLinkServiceOptions(Face& face,
-                        const ControlParameters& parameters,
-                        ControlParameters& response);
+                        const ControlParameters& parameters);
 
   static ControlParameters
   collectFaceProperties(const Face& face, bool wantUris);
diff --git a/tests/daemon/face/ethernet-channel.t.cpp b/tests/daemon/face/ethernet-channel.t.cpp
index 78f5015..3cb705a 100644
--- a/tests/daemon/face/ethernet-channel.t.cpp
+++ b/tests/daemon/face/ethernet-channel.t.cpp
@@ -78,6 +78,7 @@
   shared_ptr<nfd::Face> face;
   channel->connect({0x00, 0x00, 0x5e, 0x00, 0x53, 0x5e},
                    ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+                   false,
                    [&face] (const shared_ptr<nfd::Face>& newFace) {
                      BOOST_REQUIRE(newFace != nullptr);
                      face = newFace;
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index 5e942d2..bb0f119 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -441,6 +441,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
 
   SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
@@ -451,6 +452,7 @@
              localUri,
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -458,6 +460,7 @@
              localUri,
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -465,6 +468,15 @@
              localUri,
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+  createFace(factory,
+             FaceUri("ether://[00:00:5e:00:53:57]"),
+             localUri,
+             ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+             false,
+             true,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
@@ -475,6 +487,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
 
@@ -483,6 +496,7 @@
              FaceUri("udp4://127.0.0.1:20071"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
 
@@ -491,6 +505,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Outgoing Ethernet faces do not support on-demand persistency"});
 
@@ -499,6 +514,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Cannot create multicast Ethernet faces"});
 
@@ -507,6 +523,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              true,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Local fields can only be enabled on faces with local scope"});
 }
diff --git a/tests/daemon/face/factory-test-common.hpp b/tests/daemon/face/factory-test-common.hpp
index 046aeb2..83cf899 100644
--- a/tests/daemon/face/factory-test-common.hpp
+++ b/tests/daemon/face/factory-test-common.hpp
@@ -46,10 +46,11 @@
            const FaceUri& remoteUri,
            const ndn::optional<FaceUri>& localUri,
            ndn::nfd::FacePersistency persistency,
-           bool wantLocalFieldsEnabled,
+           bool wantLocalFields,
+           bool wantLpReliability,
            const CreateFaceExpectedResult& expected)
 {
-  factory.createFace({remoteUri, localUri, persistency, wantLocalFieldsEnabled},
+  factory.createFace({remoteUri, localUri, persistency, wantLocalFields, wantLpReliability},
                      [expected] (const shared_ptr<Face>&) {
                        BOOST_CHECK_EQUAL(CreateFaceExpectedResult::SUCCESS, expected.result);
                      },
diff --git a/tests/daemon/face/tcp-channel-fixture.hpp b/tests/daemon/face/tcp-channel-fixture.hpp
index 798fedd..a64cd48 100644
--- a/tests/daemon/face/tcp-channel-fixture.hpp
+++ b/tests/daemon/face/tcp-channel-fixture.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -50,7 +50,7 @@
   connect(TcpChannel& channel) final
   {
     g_io.post([&] {
-      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false,
+      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false, false,
         [this] (const shared_ptr<Face>& newFace) {
           BOOST_REQUIRE(newFace != nullptr);
           connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
diff --git a/tests/daemon/face/tcp-channel.t.cpp b/tests/daemon/face/tcp-channel.t.cpp
index d1a9626..3b5da41 100644
--- a/tests/daemon/face/tcp-channel.t.cpp
+++ b/tests/daemon/face/tcp-channel.t.cpp
@@ -47,7 +47,7 @@
 
   auto channel = this->makeChannel(typename IpAddressFromFamily<F::value>::type());
   channel->connect(tcp::Endpoint(address, 7040),
-    ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false,
+    ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false, false,
     [this] (const shared_ptr<nfd::Face>&) {
       BOOST_FAIL("Connect succeeded when it should have failed");
       this->limitedIo.afterOp();
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index f6307d6..c6fee2f 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -162,6 +162,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
 
   factory.createChannel("127.0.0.1", "20071");
@@ -171,6 +172,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -178,6 +180,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -185,6 +188,15 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+  createFace(factory,
+             FaceUri("tcp4://127.0.0.1:20073"),
+             {},
+             ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+             false,
+             true,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
@@ -197,6 +209,7 @@
              FaceUri("tcp4://127.0.0.1:20071"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Unicast TCP faces cannot be created with a LocalUri"});
 
@@ -205,6 +218,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Outgoing TCP faces do not support on-demand persistency"});
 
@@ -213,6 +227,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              true,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Local fields can only be enabled on faces with local scope"});
 }
@@ -247,7 +262,7 @@
   factory.createChannel("0.0.0.0", "20070");
 
   factory.createFace({FaceUri("tcp4://192.0.2.1:20070"), {},
-                      ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false},
+                      ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false, false},
                      bind(&CreateFaceTimeoutFixture::onFaceCreated, this, _1),
                      bind(&CreateFaceTimeoutFixture::onConnectFailed, this, _2));
 
diff --git a/tests/daemon/face/udp-channel-fixture.hpp b/tests/daemon/face/udp-channel-fixture.hpp
index ebb79fb..43f912d 100644
--- a/tests/daemon/face/udp-channel-fixture.hpp
+++ b/tests/daemon/face/udp-channel-fixture.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -51,7 +51,7 @@
   connect(UdpChannel& channel) final
   {
     g_io.post([&] {
-      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false,
         [this] (const shared_ptr<Face>& newFace) {
           BOOST_REQUIRE(newFace != nullptr);
           connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index 435b6d6..2747fa8 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -592,6 +592,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
 
   factory.createChannel("127.0.0.1", "20071");
@@ -601,6 +602,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -608,6 +610,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -615,6 +618,16 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+
+  createFace(factory,
+             FaceUri("udp4://127.0.0.1:20073"),
+             {},
+             ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+             false,
+             true,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
@@ -627,6 +640,7 @@
              FaceUri("udp4://127.0.0.1:20071"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Unicast UDP faces cannot be created with a LocalUri"});
 
@@ -635,6 +649,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Outgoing UDP faces do not support on-demand persistency"});
 
@@ -643,6 +658,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Cannot create multicast UDP faces"});
 
@@ -651,6 +667,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              true,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Local fields can only be enabled on faces with local scope"});
 }
diff --git a/tests/daemon/face/unix-stream-factory.t.cpp b/tests/daemon/face/unix-stream-factory.t.cpp
index 76b1cb7..8d0e484 100644
--- a/tests/daemon/face/unix-stream-factory.t.cpp
+++ b/tests/daemon/face/unix-stream-factory.t.cpp
@@ -127,6 +127,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -134,6 +135,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -141,6 +143,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 }
 
diff --git a/tests/daemon/face/websocket-factory.t.cpp b/tests/daemon/face/websocket-factory.t.cpp
index 47b1a0f..380646e 100644
--- a/tests/daemon/face/websocket-factory.t.cpp
+++ b/tests/daemon/face/websocket-factory.t.cpp
@@ -188,6 +188,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -195,6 +196,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -202,6 +204,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 }
 
diff --git a/tests/daemon/mgmt/face-manager-create-face.t.cpp b/tests/daemon/mgmt/face-manager-create-face.t.cpp
index 5a39ddb..19a10c7 100644
--- a/tests/daemon/mgmt/face-manager-create-face.t.cpp
+++ b/tests/daemon/mgmt/face-manager-create-face.t.cpp
@@ -159,6 +159,58 @@
   }
 };
 
+class TcpFaceLpReliabilityEnabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+  }
+};
+
+class TcpFaceLpReliabilityDisabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+  }
+};
+
+class UdpFaceLpReliabilityEnabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+  }
+};
+
+class UdpFaceLpReliabilityDisabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+  }
+};
+
 class FaceUriMalformed
 {
 public:
@@ -206,6 +258,10 @@
                     mpl::pair<LocalTcpFaceLocalFieldsDisabled, CommandSuccess>,
                     mpl::pair<NonLocalUdpFaceLocalFieldsEnabled, CommandFailure<406>>,
                     mpl::pair<NonLocalUdpFaceLocalFieldsDisabled, CommandSuccess>,
+                    mpl::pair<TcpFaceLpReliabilityEnabled, CommandSuccess>,
+                    mpl::pair<TcpFaceLpReliabilityDisabled, CommandSuccess>,
+                    mpl::pair<UdpFaceLpReliabilityEnabled, CommandSuccess>,
+                    mpl::pair<UdpFaceLpReliabilityDisabled, CommandSuccess>,
                     mpl::pair<FaceUriMalformed, CommandFailure<400>>,
                     mpl::pair<FaceUriNonCanonical, CommandFailure<400>>,
                     mpl::pair<FaceUriUnsupportedScheme, CommandFailure<406>>>;
@@ -239,10 +295,13 @@
         if (expectedParams.hasFlags()) {
           BOOST_CHECK_EQUAL(expectedParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
                             actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
+          BOOST_CHECK_EQUAL(expectedParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED),
+                            actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
         }
         else {
           // local fields are disabled by default
           BOOST_CHECK_EQUAL(actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED), false);
+          BOOST_CHECK_EQUAL(actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED), false);
         }
       }
       else {
diff --git a/tests/daemon/mgmt/face-manager-update-face.t.cpp b/tests/daemon/mgmt/face-manager-update-face.t.cpp
index e81e3be..1d647fc 100644
--- a/tests/daemon/mgmt/face-manager-update-face.t.cpp
+++ b/tests/daemon/mgmt/face-manager-update-face.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -54,12 +54,14 @@
   void
   createFace(const std::string& uri = "tcp4://127.0.0.1:26363",
              ndn::nfd::FacePersistency persistency = ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
-             bool enableLocalFields = false)
+             bool enableLocalFields = false,
+             bool enableReliability = false)
   {
     ControlParameters params;
     params.setUri(uri);
     params.setFacePersistency(persistency);
     params.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, enableLocalFields);
+    params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, enableReliability);
 
     createFace(params);
   }
@@ -548,6 +550,57 @@
   });
 }
 
+BOOST_AUTO_TEST_CASE(UpdateReliabilityEnableDisable)
+{
+  createFace("udp4://127.0.0.1:26363");
+
+  ControlParameters enableParams;
+  enableParams.setFaceId(faceId);
+  enableParams.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+
+  ControlParameters disableParams;
+  disableParams.setFaceId(faceId);
+  disableParams.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+
+  updateFace(enableParams, false, [] (const ControlResponse& actual) {
+    ControlResponse expected(200, "OK");
+    BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
+    BOOST_TEST_MESSAGE(actual.getText());
+
+    if (actual.getBody().hasWire()) {
+      ControlParameters actualParams(actual.getBody());
+
+      BOOST_CHECK(actualParams.hasFaceId());
+      BOOST_CHECK(actualParams.hasFacePersistency());
+      BOOST_REQUIRE(actualParams.hasFlags());
+      // Check if flags indicate reliability enabled
+      BOOST_CHECK(actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
+    }
+    else {
+      BOOST_ERROR("Enable: Response does not contain ControlParameters");
+    }
+  });
+
+  updateFace(disableParams, false, [] (const ControlResponse& actual) {
+    ControlResponse expected(200, "OK");
+    BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
+    BOOST_TEST_MESSAGE(actual.getText());
+
+    if (actual.getBody().hasWire()) {
+      ControlParameters actualParams(actual.getBody());
+
+      BOOST_CHECK(actualParams.hasFaceId());
+      BOOST_CHECK(actualParams.hasFacePersistency());
+      BOOST_REQUIRE(actualParams.hasFlags());
+      // Check if flags indicate reliability disabled
+      BOOST_CHECK(!actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
+    }
+    else {
+      BOOST_ERROR("Disable: Response does not contain ControlParameters");
+    }
+  });
+}
+
 BOOST_AUTO_TEST_CASE(SelfUpdating)
 {
   createFace();
diff --git a/tests/other/face-benchmark.cpp b/tests/other/face-benchmark.cpp
index 289a270..2734e31 100644
--- a/tests/other/face-benchmark.cpp
+++ b/tests/other/face-benchmark.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -130,12 +130,14 @@
       m_tcpChannel.connect(tcp::Endpoint(addr, port),
                            ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
                            false,
+                           false,
                            bind(&FaceBenchmark::onRightFaceCreated, this, faceL, _1),
                            bind(&FaceBenchmark::onFaceCreationFailed, _1, _2));
     }
     else if (uriR.getScheme() == "udp4") {
       m_udpChannel.connect(udp::Endpoint(addr, port),
                            ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+                           false,
                            bind(&FaceBenchmark::onRightFaceCreated, this, faceL, _1),
                            bind(&FaceBenchmark::onFaceCreationFailed, _1, _2));
     }