fib: fix route unregister bug during update
refs: #5179 Change-Id: I19952ebcb0c78c405f3d820694a7b0f1cf7a3fe6
This commit is contained in:
1 parent
3781c7ebc1
commit
6f0f35d96d
6 files changed
+259
-171
No files matched your search
+16
-14
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Copyright (c) 2014-2021, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -54,7 +54,7 @@ Fib::remove(const ndn::Name& name)
|
||||
|
||||
// Only unregister the prefix if it ISN'T a neighbor.
|
||||
if (it != m_table.end() && isNotNeighbor((it->second).name)) {
|
||||
for (const auto& nexthop : (it->second).nexthopList.getNextHops()) {
|
||||
for (const auto& nexthop : (it->second).nexthopSet) {
|
||||
unregisterPrefix((it->second).name, nexthop.getConnectingFaceUri());
|
||||
}
|
||||
m_table.erase(it);
|
||||
@@ -62,16 +62,17 @@ Fib::remove(const ndn::Name& name)
|
||||
}
|
||||
|
||||
void
|
||||
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, const NexthopList& hopsToAdd)
|
||||
Fib::addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd)
|
||||
{
|
||||
const ndn::Name& name = entry.name;
|
||||
|
||||
bool shouldRegister = isNotNeighbor(name);
|
||||
|
||||
for (const auto& hop : hopsToAdd.getNextHops())
|
||||
for (const auto& hop : hopsToAdd)
|
||||
{
|
||||
// Add nexthop to FIB entry
|
||||
entry.nexthopList.addNextHop(hop);
|
||||
NLSR_LOG_DEBUG("Adding " << hop.getConnectingFaceUri() << " to " << entry.name);
|
||||
entry.nexthopSet.addNextHop(hop);
|
||||
|
||||
if (shouldRegister) {
|
||||
// Add nexthop to NDN-FIB
|
||||
@@ -92,7 +93,7 @@ Fib::update(const ndn::Name& name, const NexthopList& allHops)
|
||||
// the length of the list of all next hops.
|
||||
unsigned int maxFaces = getNumberOfFacesForName(allHops);
|
||||
|
||||
NexthopList hopsToAdd;
|
||||
NextHopsUriSortedSet hopsToAdd;
|
||||
unsigned int nFaces = 0;
|
||||
|
||||
// Create a list of next hops to be installed with length == maxFaces
|
||||
@@ -129,10 +130,11 @@ Fib::update(const ndn::Name& name, const NexthopList& allHops)
|
||||
FibEntry& entry = (entryIt->second);
|
||||
addNextHopsToFibEntryAndNfd(entry, hopsToAdd);
|
||||
|
||||
std::set<NextHop, NextHopComparator> hopsToRemove;
|
||||
std::set_difference(entry.nexthopList.begin(), entry.nexthopList.end(),
|
||||
std::set<NextHop, NextHopUriSortedComparator> hopsToRemove;
|
||||
std::set_difference(entry.nexthopSet.begin(), entry.nexthopSet.end(),
|
||||
hopsToAdd.begin(), hopsToAdd.end(),
|
||||
std::inserter(hopsToRemove, hopsToRemove.end()), NextHopComparator());
|
||||
std::inserter(hopsToRemove, hopsToRemove.begin()),
|
||||
NextHopUriSortedComparator());
|
||||
|
||||
bool isUpdatable = isNotNeighbor(entry.name);
|
||||
// Remove the uninstalled next hops from NFD and FIB entry
|
||||
@@ -141,7 +143,7 @@ Fib::update(const ndn::Name& name, const NexthopList& allHops)
|
||||
unregisterPrefix(entry.name, hop.getConnectingFaceUri());
|
||||
}
|
||||
NLSR_LOG_DEBUG("Removing " << hop.getConnectingFaceUri() << " from " << entry.name);
|
||||
entry.nexthopList.removeNextHop(hop);
|
||||
entry.nexthopSet.removeNextHop(hop);
|
||||
}
|
||||
|
||||
// Increment sequence number
|
||||
@@ -161,7 +163,7 @@ Fib::clean()
|
||||
{
|
||||
NLSR_LOG_DEBUG("Clean called");
|
||||
for (const auto& it : m_table) {
|
||||
for (const auto& hop : it.second.nexthopList.getNextHops()) {
|
||||
for (const auto& hop : it.second.nexthopSet) {
|
||||
unregisterPrefix(it.second.name, hop.getConnectingFaceUri());
|
||||
}
|
||||
}
|
||||
@@ -339,7 +341,7 @@ Fib::refreshEntry(const ndn::Name& name, afterRefreshCallback refreshCb)
|
||||
|
||||
entry.seqNo += 1;
|
||||
|
||||
for (const NextHop& hop : entry.nexthopList) {
|
||||
for (const NextHop& hop : entry.nexthopSet) {
|
||||
registerPrefix(entry.name,
|
||||
ndn::FaceUri(hop.getConnectingFaceUri()),
|
||||
hop.getRouteCostAsAdjustedInteger(),
|
||||
@@ -355,9 +357,9 @@ Fib::writeLog()
|
||||
{
|
||||
NLSR_LOG_DEBUG("-------------------FIB-----------------------------");
|
||||
for (const auto& entry : m_table) {
|
||||
NLSR_LOG_DEBUG("Name Prefix: " << entry.second.name);
|
||||
NLSR_LOG_DEBUG("Name prefix: " << entry.first);
|
||||
NLSR_LOG_DEBUG("Seq No: " << entry.second.seqNo);
|
||||
NLSR_LOG_DEBUG(entry.second.nexthopList);
|
||||
NLSR_LOG_DEBUG("Nexthop List: \n" << entry.second.nexthopSet);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Copyright (c) 2014-2021, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -31,11 +31,13 @@
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
typedef NexthopListT<NextHopUriSortedComparator> NextHopsUriSortedSet;
|
||||
|
||||
struct FibEntry {
|
||||
ndn::Name name;
|
||||
ndn::scheduler::ScopedEventId refreshEventId;
|
||||
int32_t seqNo = 1;
|
||||
NexthopList nexthopList;
|
||||
NextHopsUriSortedSet nexthopSet;
|
||||
};
|
||||
|
||||
typedef std::function<void(FibEntry&)> afterRefreshCallback;
|
||||
@@ -153,7 +155,7 @@ private:
|
||||
* \sa Fib::removeOldNextHopsFromFibEntryAndNfd
|
||||
*/
|
||||
void
|
||||
addNextHopsToFibEntryAndNfd(FibEntry& entry, const NexthopList& hopsToAdd);
|
||||
addNextHopsToFibEntryAndNfd(FibEntry& entry, const NextHopsUriSortedSet& hopsToAdd);
|
||||
|
||||
unsigned int
|
||||
getNumberOfFacesForName(const NexthopList& nextHopList);
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
* See AUTHORS.md for complete list of NLSR authors and contributors.
|
||||
*
|
||||
* NLSR is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "nexthop-list.hpp"
|
||||
#include "common.hpp"
|
||||
#include "nexthop.hpp"
|
||||
|
||||
#include <ndn-cxx/util/ostream-joiner.hpp>
|
||||
|
||||
namespace nlsr {
|
||||
|
||||
static bool
|
||||
nexthopAddCompare(const NextHop& nh1, const NextHop& nh2)
|
||||
{
|
||||
return nh1.getConnectingFaceUri() == nh2.getConnectingFaceUri();
|
||||
}
|
||||
|
||||
static bool
|
||||
nexthopRemoveCompare(const NextHop& nh1, const NextHop& nh2)
|
||||
{
|
||||
return (nh1.getConnectingFaceUri() == nh2.getConnectingFaceUri() &&
|
||||
nh1.getRouteCostAsAdjustedInteger() == nh2.getRouteCostAsAdjustedInteger()) ;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const NexthopList& lhs, const NexthopList& rhs)
|
||||
{
|
||||
if (lhs.size() != rhs.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NexthopList slhs = lhs;
|
||||
NexthopList srhs = rhs;
|
||||
|
||||
for (struct {std::set<NextHop>::iterator lItr;
|
||||
std::set<NextHop>::iterator rItr;} pair = {slhs.begin(), srhs.begin()};
|
||||
(pair.lItr != slhs.end() || pair.rItr != srhs.end());
|
||||
pair.rItr++, pair.lItr++) {
|
||||
if (!((*pair.lItr) == (*pair.rItr))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
operator!=(const NexthopList& lhs, const NexthopList& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NexthopList& nhl)
|
||||
{
|
||||
os << " ";
|
||||
std::copy(nhl.cbegin(), nhl.cend(), ndn::make_ostream_joiner(os, "\n "));
|
||||
return os;
|
||||
}
|
||||
|
||||
void
|
||||
NexthopList::addNextHop(const NextHop& nh)
|
||||
{
|
||||
auto it = std::find_if(m_nexthopList.begin(), m_nexthopList.end(),
|
||||
std::bind(&nexthopAddCompare, _1, nh));
|
||||
if (it == m_nexthopList.end()) {
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
else if (it->getRouteCost() > nh.getRouteCost()) {
|
||||
removeNextHop(*it);
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NexthopList::removeNextHop(const NextHop& nh)
|
||||
{
|
||||
auto it = std::find_if(m_nexthopList.begin(), m_nexthopList.end(),
|
||||
std::bind(&nexthopRemoveCompare, _1, nh));
|
||||
if (it != m_nexthopList.end()) {
|
||||
m_nexthopList.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
+72
-17
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Copyright (c) 2014-2021, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "adjacent.hpp"
|
||||
|
||||
#include <ndn-cxx/face.hpp>
|
||||
#include <ndn-cxx/util/ostream-joiner.hpp>
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace nlsr {
|
||||
@@ -44,10 +46,31 @@ struct NextHopComparator {
|
||||
}
|
||||
};
|
||||
|
||||
class NexthopList
|
||||
struct NextHopUriSortedComparator {
|
||||
bool
|
||||
operator() (const NextHop& nh1, const NextHop& nh2) const {
|
||||
return nh1.getConnectingFaceUri() < nh2.getConnectingFaceUri();
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool
|
||||
nexthopAddCompare(const NextHop& nh1, const NextHop& nh2)
|
||||
{
|
||||
return nh1.getConnectingFaceUri() == nh2.getConnectingFaceUri();
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nexthopRemoveCompare(const NextHop& nh1, const NextHop& nh2)
|
||||
{
|
||||
return (nh1.getConnectingFaceUri() == nh2.getConnectingFaceUri() &&
|
||||
nh1.getRouteCostAsAdjustedInteger() == nh2.getRouteCostAsAdjustedInteger()) ;
|
||||
}
|
||||
|
||||
template<typename T = NextHopComparator>
|
||||
class NexthopListT
|
||||
{
|
||||
public:
|
||||
NexthopList() = default;
|
||||
NexthopListT() = default;
|
||||
|
||||
/*! \brief Adds a next hop to the list.
|
||||
\param nh The next hop.
|
||||
@@ -57,7 +80,18 @@ public:
|
||||
hop's route cost is updated.
|
||||
*/
|
||||
void
|
||||
addNextHop(const NextHop& nh);
|
||||
addNextHop(const NextHop& nh)
|
||||
{
|
||||
auto it = std::find_if(m_nexthopList.begin(), m_nexthopList.end(),
|
||||
std::bind(&nexthopAddCompare, _1, nh));
|
||||
if (it == m_nexthopList.end()) {
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
else if (it->getRouteCost() > nh.getRouteCost()) {
|
||||
removeNextHop(*it);
|
||||
m_nexthopList.insert(nh);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Remove a next hop from the Next Hop list
|
||||
\param nh The NextHop we want to remove.
|
||||
@@ -65,7 +99,14 @@ public:
|
||||
The next hop gets removed only if both next hop face and route cost are same.
|
||||
*/
|
||||
void
|
||||
removeNextHop(const NextHop& nh);
|
||||
removeNextHop(const NextHop& nh)
|
||||
{
|
||||
auto it = std::find_if(m_nexthopList.begin(), m_nexthopList.end(),
|
||||
std::bind(&nexthopRemoveCompare, _1, nh));
|
||||
if (it != m_nexthopList.end()) {
|
||||
m_nexthopList.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
size() const
|
||||
@@ -79,24 +120,25 @@ public:
|
||||
m_nexthopList.clear();
|
||||
}
|
||||
|
||||
const std::set<NextHop, NextHopComparator>&
|
||||
const std::set<NextHop, T>&
|
||||
getNextHops() const
|
||||
{
|
||||
return m_nexthopList;
|
||||
}
|
||||
|
||||
typedef std::set<NextHop, NextHopComparator>::iterator iterator;
|
||||
typedef std::set<NextHop, NextHopComparator>::const_iterator const_iterator;
|
||||
typedef std::set<NextHop, NextHopComparator>::reverse_iterator reverse_iterator;
|
||||
typedef T value_type;
|
||||
typedef typename std::set<NextHop, T>::iterator iterator;
|
||||
typedef typename std::set<NextHop, T>::const_iterator const_iterator;
|
||||
typedef typename std::set<NextHop, T>::reverse_iterator reverse_iterator;
|
||||
|
||||
iterator
|
||||
begin()
|
||||
begin() const
|
||||
{
|
||||
return m_nexthopList.begin();
|
||||
}
|
||||
|
||||
iterator
|
||||
end()
|
||||
end() const
|
||||
{
|
||||
return m_nexthopList.end();
|
||||
}
|
||||
@@ -126,20 +168,33 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<NextHop, NextHopComparator> m_nexthopList;
|
||||
std::set<NextHop, T> m_nexthopList;
|
||||
};
|
||||
|
||||
bool
|
||||
operator==(NexthopList& lhs, NexthopList& rhs);
|
||||
typedef NexthopListT<> NexthopList;
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
operator==(const NexthopList& lhs, const NexthopList& rhs);
|
||||
operator==(const NexthopListT<T>& lhs, const NexthopListT<T>& rhs)
|
||||
{
|
||||
return lhs.getNextHops() == rhs.getNextHops();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool
|
||||
operator!=(const NexthopList& lhs, const NexthopList& rhs);
|
||||
operator!=(const NexthopListT<T>& lhs, const NexthopListT<T>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const NexthopList& nhl);
|
||||
operator<<(std::ostream& os, const NexthopListT<T>& nhl)
|
||||
{
|
||||
os << " ";
|
||||
std::copy(nhl.cbegin(), nhl.cend(), ndn::make_ostream_joiner(os, "\n "));
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace nlsr
|
||||
|
||||
|
||||
+117
-34
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Copyright (c) 2014-2021, The University of Memphis,
|
||||
* Regents of the University of California
|
||||
*
|
||||
* This file is part of NLSR (Named-data Link State Routing).
|
||||
@@ -29,16 +29,19 @@
|
||||
namespace nlsr {
|
||||
namespace test {
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
class FibFixture : public UnitTestTimeFixture
|
||||
{
|
||||
public:
|
||||
FibFixture()
|
||||
: face(std::make_shared<ndn::util::DummyClientFace>(m_ioService, m_keyChain))
|
||||
, conf(*face, m_keyChain)
|
||||
, interests(face->sentInterests)
|
||||
: face(m_ioService, m_keyChain)
|
||||
, conf(face, m_keyChain)
|
||||
, adjacencies(conf.getAdjacencyList())
|
||||
, fib(face, m_scheduler, adjacencies, conf, m_keyChain)
|
||||
, interests(face.sentInterests)
|
||||
{
|
||||
enableRegistrationReplyWithFaceId();
|
||||
advanceClocks(1_s);
|
||||
|
||||
Adjacent neighbor1(router1Name, ndn::FaceUri(router1FaceUri), 0, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
|
||||
adjacencies.insert(neighbor1);
|
||||
|
||||
@@ -50,16 +53,44 @@ public:
|
||||
|
||||
conf.setMaxFacesPerPrefix(2);
|
||||
|
||||
fib = std::make_shared<Fib>(*face, m_scheduler, adjacencies, conf, m_keyChain);
|
||||
fib->setEntryRefreshTime(1);
|
||||
fib.setEntryRefreshTime(1);
|
||||
}
|
||||
|
||||
void
|
||||
enableRegistrationReplyWithFaceId() {
|
||||
face.onSendInterest.connect([this] (const ndn::Interest& interest) {
|
||||
static const ndn::Name localhostRegistration("/localhost/nfd/rib");
|
||||
if (!localhostRegistration.isPrefixOf(interest.getName()))
|
||||
return;
|
||||
|
||||
ndn::nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
|
||||
if (!params.hasFaceId()) {
|
||||
params.setFaceId(1);
|
||||
}
|
||||
params.setOrigin(ndn::nfd::ROUTE_ORIGIN_APP);
|
||||
if (interest.getName().get(3) == ndn::name::Component("register")) {
|
||||
params.setCost(0);
|
||||
}
|
||||
|
||||
ndn::nfd::ControlResponse resp;
|
||||
resp.setCode(200);
|
||||
resp.setBody(params.wireEncode());
|
||||
|
||||
ndn::Data data(interest.getName());
|
||||
data.setContent(resp.wireEncode());
|
||||
|
||||
m_keyChain.sign(data, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_SHA256));
|
||||
|
||||
face.getIoService().post([this, data] { face.receive(data); });
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<ndn::util::DummyClientFace> face;
|
||||
std::shared_ptr<Fib> fib;
|
||||
ndn::util::DummyClientFace face;
|
||||
|
||||
AdjacencyList adjacencies;
|
||||
ConfParameter conf;
|
||||
AdjacencyList& adjacencies;
|
||||
Fib fib;
|
||||
std::vector<ndn::Interest>& interests;
|
||||
|
||||
static const ndn::Name router1Name;
|
||||
@@ -98,8 +129,8 @@ BOOST_AUTO_TEST_CASE(NextHopsAdd)
|
||||
hops.addNextHop(hop1);
|
||||
hops.addNextHop(hop2);
|
||||
|
||||
fib->update("/ndn/name", hops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", hops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
// Should register faces 1 and 2 for /ndn/name
|
||||
BOOST_REQUIRE_EQUAL(interests.size(), 2);
|
||||
@@ -122,7 +153,6 @@ BOOST_AUTO_TEST_CASE(NextHopsAdd)
|
||||
verb == ndn::Name::Component("register"));
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(NextHopsNoChange)
|
||||
{
|
||||
NextHop hop1(router1FaceUri, 10);
|
||||
@@ -132,14 +162,14 @@ BOOST_AUTO_TEST_CASE(NextHopsNoChange)
|
||||
oldHops.addNextHop(hop1);
|
||||
oldHops.addNextHop(hop2);
|
||||
|
||||
fib->update("/ndn/name", oldHops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", oldHops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
BOOST_REQUIRE_EQUAL(interests.size(), 2);
|
||||
interests.clear();
|
||||
|
||||
fib->update("/ndn/name", oldHops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", oldHops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
// Should register face 1 and 2 for /ndn/name
|
||||
BOOST_REQUIRE_EQUAL(interests.size(), 2);
|
||||
@@ -171,16 +201,16 @@ BOOST_AUTO_TEST_CASE(NextHopsRemoveAll)
|
||||
oldHops.addNextHop(hop1);
|
||||
oldHops.addNextHop(hop2);
|
||||
|
||||
fib->update("/ndn/name", oldHops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", oldHops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
BOOST_REQUIRE_EQUAL(interests.size(), 2);
|
||||
interests.clear();
|
||||
|
||||
NexthopList empty;
|
||||
|
||||
fib->update("/ndn/name", empty);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", empty);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
// Should unregister faces 1 and 2 for /ndn/name
|
||||
BOOST_CHECK_EQUAL(interests.size(), 2);
|
||||
@@ -214,8 +244,8 @@ BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixes)
|
||||
hops.addNextHop(hop2);
|
||||
hops.addNextHop(hop3);
|
||||
|
||||
fib->update("/ndn/name", hops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", hops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
// Should only register faces 1 and 2 for /ndn/name
|
||||
BOOST_CHECK_EQUAL(interests.size(), 2);
|
||||
@@ -247,8 +277,8 @@ BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
|
||||
hops.addNextHop(hop1);
|
||||
hops.addNextHop(hop2);
|
||||
|
||||
fib->update("/ndn/name", hops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", hops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
// FIB
|
||||
// Name NextHops
|
||||
@@ -260,8 +290,8 @@ BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
|
||||
NextHop hop3(router3FaceUri, 5);
|
||||
hops.addNextHop(hop3);
|
||||
|
||||
fib->update("/ndn/name", hops);
|
||||
face->processEvents(ndn::time::milliseconds(-1));
|
||||
fib.update("/ndn/name", hops);
|
||||
face.processEvents(ndn::time::milliseconds(-1));
|
||||
|
||||
// To maintain a max 2 face requirement, face 3 should be registered and face 2 should be
|
||||
// unregistered. Face 1 will also be re-registered.
|
||||
@@ -279,14 +309,14 @@ BOOST_AUTO_TEST_CASE(NextHopsMaxPrefixesAfterRecalculation)
|
||||
extractRibCommandParameters(*it, verb, extractedParameters);
|
||||
|
||||
BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
|
||||
extractedParameters.getFaceId() == router3FaceId &&
|
||||
extractedParameters.getFaceId() == router1FaceId &&
|
||||
verb == ndn::Name::Component("register"));
|
||||
|
||||
++it;
|
||||
extractRibCommandParameters(*it, verb, extractedParameters);
|
||||
|
||||
BOOST_CHECK(extractedParameters.getName() == "/ndn/name" &&
|
||||
extractedParameters.getFaceId() == router1FaceId &&
|
||||
extractedParameters.getFaceId() == router3FaceId &&
|
||||
verb == ndn::Name::Component("register"));
|
||||
|
||||
++it;
|
||||
@@ -303,9 +333,9 @@ BOOST_FIXTURE_TEST_CASE(ScheduleFibEntryRefresh, FibFixture)
|
||||
FibEntry fe;
|
||||
fe.name = name1;
|
||||
int origSeqNo = fe.seqNo;
|
||||
fib->m_table.emplace(name1, std::move(fe));
|
||||
fib.m_table.emplace(name1, std::move(fe));
|
||||
|
||||
fib->scheduleEntryRefresh(fe,
|
||||
fib.scheduleEntryRefresh(fe,
|
||||
[&] (FibEntry& entry) {
|
||||
BOOST_CHECK_EQUAL(origSeqNo + 1, entry.seqNo);
|
||||
});
|
||||
@@ -321,11 +351,64 @@ BOOST_AUTO_TEST_CASE(ShouldNotRefreshNeighborRoute) // #4799
|
||||
hops.addNextHop(hop1);
|
||||
|
||||
// Simulate update for this neighbor from name prefix table
|
||||
fib->update(router1Name, hops);
|
||||
fib.update(router1Name, hops);
|
||||
this->advanceClocks(ndn::time::seconds(1));
|
||||
|
||||
// Should not send the register interest
|
||||
BOOST_CHECK_EQUAL(face->sentInterests.size(), 0);
|
||||
BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(PrefixWithdrawalFibUpdateBug) // #5179
|
||||
{
|
||||
fib.setEntryRefreshTime(3600);
|
||||
conf.setMaxFacesPerPrefix(3);
|
||||
|
||||
// Three adjacencies of Neu
|
||||
Adjacent neighbor1("/ndn/memphis/router-memphis",
|
||||
ndn::FaceUri("udp4://10.0.0.9:6363"), 21, Adjacent::STATUS_ACTIVE, 0, router1FaceId);
|
||||
adjacencies.insert(neighbor1);
|
||||
|
||||
Adjacent neighbor2("/ndn/michigan/router-michigan",
|
||||
ndn::FaceUri("udp4://10.0.0.13:6363"), 14, Adjacent::STATUS_ACTIVE, 0, router2FaceId);
|
||||
adjacencies.insert(neighbor2);
|
||||
|
||||
Adjacent neighbor3("/ndn/savi/router-savi",
|
||||
ndn::FaceUri("udp4://10.0.0.26:6363"), 15, Adjacent::STATUS_ACTIVE, 0, router3FaceId);
|
||||
adjacencies.insert(neighbor3);
|
||||
|
||||
// Wustl advertises /test
|
||||
NexthopList nhl1;
|
||||
nhl1.addNextHop(NextHop("udp4://10.0.0.13:6363", 28));
|
||||
nhl1.addNextHop(NextHop("udp4://10.0.0.9:6363", 38));
|
||||
nhl1.addNextHop(NextHop("udp4://10.0.0.26:6363", 44));
|
||||
fib.update("/test", nhl1);
|
||||
|
||||
// Memphis advertises /test
|
||||
NexthopList nhl2;
|
||||
nhl2.addNextHop(NextHop("udp4://10.0.0.9:6363", 21));
|
||||
nhl2.addNextHop(NextHop("udp4://10.0.0.13:6363", 26));
|
||||
nhl2.addNextHop(NextHop("udp4://10.0.0.26:6363", 42));
|
||||
fib.update("/test", nhl2);
|
||||
|
||||
advanceClocks(10_ms);
|
||||
face.sentInterests.clear();
|
||||
// Memphis withdraws /test
|
||||
// NamePrefixTable calls this saying we need to install the Wu routes
|
||||
// instead of the existing Memphis' cheaper routes
|
||||
fib.update("/test", nhl1);
|
||||
|
||||
advanceClocks(10_ms);
|
||||
int numRegister = 0;
|
||||
// Do not expect any unregisters, just registers which will update the cost in NFD
|
||||
for (const auto& i : face.sentInterests) {
|
||||
if (i.getName().getPrefix(4) == "/localhost/nfd/rib/unregister/") {
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
else {
|
||||
++numRegister;
|
||||
}
|
||||
}
|
||||
BOOST_CHECK_EQUAL(numRegister, 3);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The University of Memphis,
|
||||
* Copyright (c) 2014-2021, The University of Memphis,
|
||||
* Regents of the University of California,
|
||||
* Arizona Board of Regents.
|
||||
*
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "route/nexthop-list.hpp"
|
||||
#include "route/nexthop.hpp"
|
||||
#include "route/fib.hpp"
|
||||
#include "tests/boost-test.hpp"
|
||||
|
||||
namespace nlsr {
|
||||
@@ -180,6 +181,53 @@ BOOST_AUTO_TEST_CASE(UseCheaperNextHop)
|
||||
}
|
||||
}
|
||||
|
||||
/* Fib needs a NexthopList to be sorted by FaceUri when updating
|
||||
to avoid removing prefixes that were just installed. The above
|
||||
test does not apply to this scenario as the NexthopList
|
||||
sorted by cost is given to the Fib::update.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE(NextHopListDiffForFibUpdate) // #5179
|
||||
{
|
||||
// If default sorter is used then difference results in
|
||||
// the same hops to remove as those that were added
|
||||
NexthopList nhl1;
|
||||
nhl1.addNextHop(NextHop("udp4://10.0.0.13:6363", 28));
|
||||
nhl1.addNextHop(NextHop("udp4://10.0.0.9:6363", 38));
|
||||
nhl1.addNextHop(NextHop("udp4://10.0.0.26:6363", 44));
|
||||
|
||||
NexthopList nhl2;
|
||||
nhl2.addNextHop(NextHop("udp4://10.0.0.9:6363", 21));
|
||||
nhl2.addNextHop(NextHop("udp4://10.0.0.13:6363", 26));
|
||||
nhl2.addNextHop(NextHop("udp4://10.0.0.26:6363", 42));
|
||||
|
||||
std::set<NextHop, NextHopComparator> hopsToRemove;
|
||||
std::set_difference(nhl2.begin(), nhl2.end(),
|
||||
nhl1.begin(), nhl1.end(),
|
||||
std::inserter(hopsToRemove, hopsToRemove.begin()),
|
||||
NextHopComparator());
|
||||
|
||||
BOOST_CHECK_EQUAL(hopsToRemove.size(), 3);
|
||||
|
||||
// Sorted by FaceUri
|
||||
NextHopsUriSortedSet nhs1;
|
||||
nhs1.addNextHop(NextHop("udp4://10.0.0.13:6363", 28));
|
||||
nhs1.addNextHop(NextHop("udp4://10.0.0.9:6363", 38));
|
||||
nhs1.addNextHop(NextHop("udp4://10.0.0.26:6363", 44));
|
||||
|
||||
NextHopsUriSortedSet nhs2;
|
||||
nhs2.addNextHop(NextHop("udp4://10.0.0.9:6363", 21));
|
||||
nhs2.addNextHop(NextHop("udp4://10.0.0.13:6363", 26));
|
||||
nhs2.addNextHop(NextHop("udp4://10.0.0.26:6363", 42));
|
||||
|
||||
std::set<NextHop, NextHopUriSortedComparator> hopsToRemove2;
|
||||
std::set_difference(nhs2.begin(), nhs2.end(),
|
||||
nhs1.begin(), nhs1.end(),
|
||||
std::inserter(hopsToRemove2, hopsToRemove2.begin()),
|
||||
NextHopUriSortedComparator());
|
||||
|
||||
BOOST_CHECK_EQUAL(hopsToRemove2.size(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
} // namespace test
|
||||
|
||||
Reference in new issue
Block a user