lsdb: emit signals when modified
RoutingTable and NamePrefixTable consume the signal
and behave accordingly.
refs: #4127
Change-Id: I6540f30f0222f804b01dc7d9640831c84e5264cc
diff --git a/src/route/name-prefix-table.cpp b/src/route/name-prefix-table.cpp
index 91e6210..deb9af7 100644
--- a/src/route/name-prefix-table.cpp
+++ b/src/route/name-prefix-table.cpp
@@ -33,26 +33,88 @@
INIT_LOGGER(route.NamePrefixTable);
-NamePrefixTable::NamePrefixTable(Fib& fib, RoutingTable& routingTable,
- std::unique_ptr<AfterRoutingChange>& afterRoutingChangeSignal)
- : m_fib(fib)
+NamePrefixTable::NamePrefixTable(const ndn::Name& ownRouterName, Fib& fib,
+ RoutingTable& routingTable,
+ AfterRoutingChange& afterRoutingChangeSignal,
+ Lsdb::AfterLsdbModified& afterLsdbModifiedSignal)
+ : m_ownRouterName(ownRouterName)
+ , m_fib(fib)
, m_routingTable(routingTable)
{
- m_afterRoutingChangeConnection = afterRoutingChangeSignal->connect(
+ m_afterRoutingChangeConnection = afterRoutingChangeSignal.connect(
[this] (const std::list<RoutingTableEntry>& entries) {
updateWithNewRoute(entries);
});
+
+ m_afterLsdbModified = afterLsdbModifiedSignal.connect(
+ [this] (std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
+ const auto& namesToAdd, const auto& namesToRemove) {
+ updateFromLsdb(lsa, updateType, namesToAdd, namesToRemove);
+ }
+ );
}
NamePrefixTable::~NamePrefixTable()
{
m_afterRoutingChangeConnection.disconnect();
+ m_afterLsdbModified.disconnect();
+}
+
+void
+NamePrefixTable::updateFromLsdb(std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
+ const std::list<ndn::Name>& namesToAdd,
+ const std::list<ndn::Name>& namesToRemove)
+{
+ if (m_ownRouterName == lsa->getOriginRouter()) {
+ return;
+ }
+ NLSR_LOG_TRACE("Got update from Lsdb for router: " << lsa->getOriginRouter());
+
+ if (updateType == LsdbUpdate::INSTALLED) {
+ addEntry(lsa->getOriginRouter(), lsa->getOriginRouter());
+
+ if (lsa->getType() == Lsa::Type::NAME) {
+ auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
+ for (const auto& name : nlsa->getNpl().getNames()) {
+ if (name != m_ownRouterName) {
+ addEntry(name, lsa->getOriginRouter());
+ }
+ }
+ }
+ }
+ else if (updateType == LsdbUpdate::UPDATED) {
+ if (lsa->getType() != Lsa::Type::NAME) {
+ return;
+ }
+
+ for (const auto& name : namesToAdd) {
+ if (name != m_ownRouterName) {
+ addEntry(name, lsa->getOriginRouter());
+ }
+ }
+
+ for (const auto& name : namesToRemove) {
+ if (name != m_ownRouterName) {
+ removeEntry(name, lsa->getOriginRouter());
+ }
+ }
+ }
+ else {
+ removeEntry(lsa->getOriginRouter(), lsa->getOriginRouter());
+ if (lsa->getType() == Lsa::Type::NAME) {
+ auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
+ for (const auto& name : nlsa->getNpl().getNames()) {
+ if (name != m_ownRouterName) {
+ removeEntry(name, lsa->getOriginRouter());
+ }
+ }
+ }
+ }
}
void
NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
{
-
// Check if the advertised name prefix is in the table already.
NptEntryList::iterator nameItr =
std::find_if(m_table.begin(),
diff --git a/src/route/name-prefix-table.hpp b/src/route/name-prefix-table.hpp
index 370e515..449b928 100644
--- a/src/route/name-prefix-table.hpp
+++ b/src/route/name-prefix-table.hpp
@@ -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.
*
@@ -17,7 +17,7 @@
*
* 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/>.
- **/
+ */
#ifndef NLSR_NAME_PREFIX_TABLE_HPP
#define NLSR_NAME_PREFIX_TABLE_HPP
@@ -27,6 +27,7 @@
#include "signals.hpp"
#include "test-access-control.hpp"
#include "route/fib.hpp"
+#include "lsdb.hpp"
#include <list>
#include <unordered_map>
@@ -41,11 +42,23 @@
using NptEntryList = std::list<std::shared_ptr<NamePrefixTableEntry>>;
using const_iterator = NptEntryList::const_iterator;
- NamePrefixTable(Fib& fib, RoutingTable& routingTable,
- std::unique_ptr<AfterRoutingChange>& afterRoutingChangeSignal);
+ NamePrefixTable(const ndn::Name& ownRouterName, Fib& fib, RoutingTable& routingTable,
+ AfterRoutingChange& afterRoutingChangeSignal,
+ Lsdb::AfterLsdbModified& afterLsdbModifiedSignal);
~NamePrefixTable();
+ /*! \brief Add, update, or remove Names according to the Lsdb update
+ \param lsa The LSA class pointer
+ \param updateType Update type from Lsdb (INSTALLED, UPDATED, REMOVED)
+ \param namesToAdd If LSA is UPDATED, then these are the names to add
+ \param namesToRemove If LSA is UPDATED, then these are the names to remove
+ */
+ void
+ updateFromLsdb(std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
+ const std::list<ndn::Name>& namesToAdd,
+ const std::list<ndn::Name>& namesToRemove);
+
/*! \brief Adds a destination to the specified name prefix.
\param name The name prefix
\param destRouter The destination router prefix
@@ -125,9 +138,11 @@
NptEntryList m_table;
private:
+ const ndn::Name& m_ownRouterName;
Fib& m_fib;
RoutingTable& m_routingTable;
ndn::util::signal::Connection m_afterRoutingChangeConnection;
+ ndn::util::signal::Connection m_afterLsdbModified;
};
inline NamePrefixTable::const_iterator
diff --git a/src/route/routing-table.cpp b/src/route/routing-table.cpp
index b600882..c06b429 100644
--- a/src/route/routing-table.cpp
+++ b/src/route/routing-table.cpp
@@ -24,93 +24,85 @@
#include "conf-parameter.hpp"
#include "routing-table-calculator.hpp"
#include "routing-table-entry.hpp"
-#include "name-prefix-table.hpp"
#include "logger.hpp"
#include "tlv-nlsr.hpp"
-#include <list>
-#include <string>
-
namespace nlsr {
INIT_LOGGER(route.RoutingTable);
-RoutingTable::RoutingTable(ndn::Scheduler& scheduler, Fib& fib, Lsdb& lsdb,
- NamePrefixTable& namePrefixTable, ConfParameter& confParam)
- : afterRoutingChange{std::make_unique<AfterRoutingChange>()}
- , m_scheduler(scheduler)
- , m_fib(fib)
+RoutingTable::RoutingTable(ndn::Scheduler& scheduler, Lsdb& lsdb, ConfParameter& confParam)
+ : m_scheduler(scheduler)
, m_lsdb(lsdb)
- , m_namePrefixTable(namePrefixTable)
, m_routingCalcInterval{confParam.getRoutingCalcInterval()}
, m_isRoutingTableCalculating(false)
, m_isRouteCalculationScheduled(false)
, m_confParam(confParam)
+ , m_hyperbolicState(m_confParam.getHyperbolicState())
{
+ m_afterLsdbModified = lsdb.onLsdbModified.connect(
+ [this] (std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
+ const auto& namesToAdd, const auto& namesToRemove) {
+ auto type = lsa->getType();
+ bool updateForOwnAdjacencyLsa = lsa->getOriginRouter() == m_confParam.getRouterPrefix() &&
+ type == Lsa::Type::ADJACENCY;
+ bool scheduleCalculation = false;
+
+ if (updateType == LsdbUpdate::REMOVED && updateForOwnAdjacencyLsa) {
+ // If own Adjacency LSA is removed then we have no ACTIVE neighbors.
+ // (Own Coordinate LSA is never removed. But routing table calculation is scheduled
+ // in HelloProtocol. The routing table calculator for HR takes into account
+ // the INACTIVE status of the link).
+ NLSR_LOG_DEBUG("No Adj LSA of router itself, routing table can not be calculated :(");
+ clearRoutingTable();
+ clearDryRoutingTable();
+ NLSR_LOG_DEBUG("Calling Update NPT With new Route");
+ afterRoutingChange(m_rTable);
+ NLSR_LOG_DEBUG(*this);
+ m_ownAdjLsaExist = false;
+ }
+
+ if (updateType == LsdbUpdate::INSTALLED && updateForOwnAdjacencyLsa) {
+ m_ownAdjLsaExist = true;
+ }
+
+ // Don;t do anything on removal, wait for HelloProtocol to confirm and then react
+ if (updateType == LsdbUpdate::INSTALLED || updateType == LsdbUpdate::UPDATED) {
+ if ((type == Lsa::Type::ADJACENCY && m_hyperbolicState != HYPERBOLIC_STATE_ON) ||
+ (type == Lsa::Type::COORDINATE && m_hyperbolicState != HYPERBOLIC_STATE_OFF)) {
+ scheduleCalculation = true;
+ }
+ }
+
+ if (scheduleCalculation) {
+ scheduleRoutingTableCalculation();
+ }
+ }
+ );
}
void
RoutingTable::calculate()
{
m_lsdb.writeLog();
- m_namePrefixTable.writeLog();
+ NLSR_LOG_TRACE("Calculating routing table");
+
if (m_isRoutingTableCalculating == false) {
- // setting routing table calculation
m_isRoutingTableCalculating = true;
- bool isHrEnabled = m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF;
-
- if ((!isHrEnabled &&
- m_lsdb.doesLsaExist(m_confParam.getRouterPrefix(), Lsa::Type::ADJACENCY))
- ||
- (isHrEnabled &&
- m_lsdb.doesLsaExist(m_confParam.getRouterPrefix(), Lsa::Type::COORDINATE))) {
- if (m_lsdb.getIsBuildAdjLsaSheduled() != 1) {
- NLSR_LOG_TRACE("Clearing old routing table");
- clearRoutingTable();
- // for dry run options
- clearDryRoutingTable();
-
- NLSR_LOG_DEBUG("Calculating routing table");
-
- // calculate Link State routing
- if ((m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_OFF) ||
- (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_DRY_RUN)) {
- calculateLsRoutingTable();
- }
- // calculate hyperbolic routing
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
- calculateHypRoutingTable(false);
- }
- // calculate dry hyperbolic routing
- if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_DRY_RUN) {
- calculateHypRoutingTable(true);
- }
- // Inform the NPT that updates have been made
- NLSR_LOG_DEBUG("Calling Update NPT With new Route");
- (*afterRoutingChange)(m_rTable);
- NLSR_LOG_DEBUG(*this);
- m_namePrefixTable.writeLog();
- m_fib.writeLog();
- }
- else {
- NLSR_LOG_DEBUG("Adjacency building is scheduled, so routing table can not be calculated :(");
- }
+ if (m_hyperbolicState == HYPERBOLIC_STATE_OFF) {
+ calculateLsRoutingTable();
}
- else {
- NLSR_LOG_DEBUG("No Adj LSA of router itself, so Routing table can not be calculated :(");
- clearRoutingTable();
- clearDryRoutingTable(); // for dry run options
- // need to update NPT here
- NLSR_LOG_DEBUG("Calling Update NPT With new Route");
- (*afterRoutingChange)(m_rTable);
- NLSR_LOG_DEBUG(*this);
- m_namePrefixTable.writeLog();
- m_fib.writeLog();
- // debugging purpose end
+ else if (m_hyperbolicState == HYPERBOLIC_STATE_DRY_RUN) {
+ calculateLsRoutingTable();
+ calculateHypRoutingTable(true);
}
- m_isRouteCalculationScheduled = false; // clear scheduled flag
- m_isRoutingTableCalculating = false; // unsetting routing table calculation
+ else if (m_hyperbolicState == HYPERBOLIC_STATE_ON) {
+ calculateHypRoutingTable(false);
+ }
+
+ m_isRouteCalculationScheduled = false;
+ m_isRoutingTableCalculating = false;
}
else {
scheduleRoutingTableCalculation();
@@ -122,6 +114,19 @@
{
NLSR_LOG_TRACE("CalculateLsRoutingTable Called");
+ if (m_lsdb.getIsBuildAdjLsaScheduled()) {
+ NLSR_LOG_DEBUG("Adjacency build is scheduled, routing table can not be calculated :(");
+ return;
+ }
+
+ // We only check this in LS since we never remove our own Coordinate LSA,
+ // whereas we remove our own Adjacency LSA if we don't have any neighbors
+ if (!m_ownAdjLsaExist) {
+ return;
+ }
+
+ clearRoutingTable();
+
Map map;
auto lsaRange = m_lsdb.getLsdbIterator<AdjLsa>();
map.createFromAdjLsdb(lsaRange.first, lsaRange.second);
@@ -132,11 +137,22 @@
LinkStateRoutingTableCalculator calculator(nRouters);
calculator.calculatePath(map, *this, m_confParam, m_lsdb);
+
+ NLSR_LOG_DEBUG("Calling Update NPT With new Route");
+ afterRoutingChange(m_rTable);
+ NLSR_LOG_DEBUG(*this);
}
void
RoutingTable::calculateHypRoutingTable(bool isDryRun)
{
+ if (isDryRun) {
+ clearDryRoutingTable();
+ }
+ else {
+ clearRoutingTable();
+ }
+
Map map;
auto lsaRange = m_lsdb.getLsdbIterator<CoordinateLsa>();
map.createFromCoordinateLsdb(lsaRange.first, lsaRange.second);
@@ -147,6 +163,12 @@
HyperbolicRoutingCalculator calculator(nRouters, isDryRun, m_confParam.getRouterPrefix());
calculator.calculatePath(map, *this, m_lsdb, m_confParam.getAdjacencyList());
+
+ if (!isDryRun) {
+ NLSR_LOG_DEBUG("Calling Update NPT With new Route");
+ afterRoutingChange(m_rTable);
+ NLSR_LOG_DEBUG(*this);
+ }
}
void
@@ -179,6 +201,7 @@
else {
rteChk->getNexthopList().addNextHop(nh);
}
+ m_wire.reset();
}
RoutingTableEntry*
@@ -207,22 +230,21 @@
else {
it->getNexthopList().addNextHop(nh);
}
+ m_wire.reset();
}
void
RoutingTable::clearRoutingTable()
{
- if (m_rTable.size() > 0) {
- m_rTable.clear();
- }
+ m_rTable.clear();
+ m_wire.reset();
}
void
RoutingTable::clearDryRoutingTable()
{
- if (m_dryTable.size() > 0) {
- m_dryTable.clear();
- }
+ m_dryTable.clear();
+ m_wire.reset();
}
template<ndn::encoding::Tag TAG>
diff --git a/src/route/routing-table.hpp b/src/route/routing-table.hpp
index 4a0ebd2..f7e0525 100644
--- a/src/route/routing-table.hpp
+++ b/src/route/routing-table.hpp
@@ -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).
@@ -27,6 +27,7 @@
#include "lsdb.hpp"
#include "route/fib.hpp"
#include "test-access-control.hpp"
+#include "route/name-prefix-table.hpp"
#include <ndn-cxx/util/scheduler.hpp>
@@ -89,8 +90,12 @@
{
public:
explicit
- RoutingTable(ndn::Scheduler& scheduler, Fib& fib, Lsdb& lsdb,
- NamePrefixTable& namePrefixTable, ConfParameter& confParam);
+ RoutingTable(ndn::Scheduler& scheduler, Lsdb& lsdb, ConfParameter& confParam);
+
+ ~RoutingTable()
+ {
+ m_afterLsdbModified.disconnect();
+ }
/*! \brief Calculates a list of next hops for each router in the network.
*
@@ -122,24 +127,6 @@
void
scheduleRoutingTableCalculation();
- void
- setRoutingCalcInterval(uint32_t interval)
- {
- m_routingCalcInterval = ndn::time::seconds(interval);
- }
-
- const ndn::time::seconds&
- getRoutingCalcInterval() const
- {
- return m_routingCalcInterval;
- }
-
- uint64_t
- getRtSize()
- {
- return m_rTable.size();
- }
-
private:
/*! \brief Calculates a link-state routing table. */
void
@@ -156,21 +143,21 @@
clearDryRoutingTable();
public:
- std::unique_ptr<AfterRoutingChange> afterRoutingChange;
+ AfterRoutingChange afterRoutingChange;
private:
ndn::Scheduler& m_scheduler;
- Fib& m_fib;
Lsdb& m_lsdb;
- NamePrefixTable& m_namePrefixTable;
-
- ndn::time::seconds m_routingCalcInterval;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+ ndn::time::seconds m_routingCalcInterval;
bool m_isRoutingTableCalculating;
bool m_isRouteCalculationScheduled;
ConfParameter& m_confParam;
+ ndn::util::signal::Connection m_afterLsdbModified;
+ int32_t m_hyperbolicState;
+ bool m_ownAdjLsaExist = false;
};
} // namespace nlsr