BREAKING: Change Name LSAs to propagate cost which are applied to remote routes
This is a stopgap change to address a lack of functionality in the NDN testbed.
Current restrictions:
-Cost must be set from NFD readvertisement
-Cost is applied after routing calculations but before FIB insertion; lowest cost
nexthop will be chosen but may not be the optimal path given this cost.
Further work will be required to move the application of cost as part of routing
and to make this functionality more easily accessible.
Refs #5349
Change-Id: I914dc5c2d5d3cb6bfa13f5730df0eae66d115c60
diff --git a/src/lsa/adj-lsa.cpp b/src/lsa/adj-lsa.cpp
index f143499..9b58098 100644
--- a/src/lsa/adj-lsa.cpp
+++ b/src/lsa/adj-lsa.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -126,7 +126,7 @@
}
}
-std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
AdjLsa::update(const std::shared_ptr<Lsa>& lsa)
{
auto alsa = std::static_pointer_cast<AdjLsa>(lsa);
@@ -135,9 +135,9 @@
for (const auto& adjacent : alsa->getAdl()) {
addAdjacent(adjacent);
}
- return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
+ return {true, std::list<PrefixInfo>{}, std::list<PrefixInfo>{}};
}
- return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
+ return {false, std::list<PrefixInfo>{}, std::list<PrefixInfo>{}};
}
} // namespace nlsr
diff --git a/src/lsa/adj-lsa.hpp b/src/lsa/adj-lsa.hpp
index 8c6354d..5fc3903 100644
--- a/src/lsa/adj-lsa.hpp
+++ b/src/lsa/adj-lsa.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -107,7 +107,7 @@
void
wireDecode(const ndn::Block& wire);
- std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+ std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
update(const std::shared_ptr<Lsa>& lsa) override;
private:
diff --git a/src/lsa/coordinate-lsa.cpp b/src/lsa/coordinate-lsa.cpp
index 11428f8..3008915 100644
--- a/src/lsa/coordinate-lsa.cpp
+++ b/src/lsa/coordinate-lsa.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -129,7 +129,7 @@
}
}
-std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
CoordinateLsa::update(const std::shared_ptr<Lsa>& lsa)
{
auto clsa = std::static_pointer_cast<CoordinateLsa>(lsa);
@@ -139,9 +139,9 @@
for (const auto& angle : clsa->getTheta()) {
m_hyperbolicAngles.push_back(angle);
}
- return {true, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
+ return {true, std::list<PrefixInfo>{}, std::list<PrefixInfo>{}};
}
- return {false, std::list<ndn::Name>{}, std::list<ndn::Name>{}};
+ return {false, std::list<PrefixInfo>{}, std::list<PrefixInfo>{}};
}
} // namespace nlsr
diff --git a/src/lsa/coordinate-lsa.hpp b/src/lsa/coordinate-lsa.hpp
index 3e7f0a1..60ef965 100644
--- a/src/lsa/coordinate-lsa.hpp
+++ b/src/lsa/coordinate-lsa.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -106,7 +106,7 @@
void
wireDecode(const ndn::Block& wire);
- std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+ std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
update(const std::shared_ptr<Lsa>& lsa) override;
private:
diff --git a/src/lsa/lsa.hpp b/src/lsa/lsa.hpp
index e482a92..a52a4f7 100644
--- a/src/lsa/lsa.hpp
+++ b/src/lsa/lsa.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -23,12 +23,14 @@
#define NLSR_LSA_LSA_HPP
#include "common.hpp"
+#include "name-prefix-list.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/util/scheduler.hpp>
#include <list>
+
namespace nlsr {
/**
@@ -112,7 +114,7 @@
m_expiringEventId = eid;
}
- virtual std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+ virtual std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
update(const std::shared_ptr<Lsa>& lsa) = 0;
virtual const ndn::Block&
diff --git a/src/lsa/name-lsa.cpp b/src/lsa/name-lsa.cpp
index 7867b68..2efe86e 100644
--- a/src/lsa/name-lsa.cpp
+++ b/src/lsa/name-lsa.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -29,7 +29,7 @@
const NamePrefixList& npl)
: Lsa(originRouter, seqNo, timepoint)
{
- for (const auto& name : npl.getNames()) {
+ for (const auto& name : npl.getPrefixInfo()) {
addName(name);
}
}
@@ -45,7 +45,7 @@
{
size_t totalLength = 0;
- auto names = m_npl.getNames();
+ auto names = m_npl.getPrefixInfo();
for (auto it = names.rbegin(); it != names.rend(); ++it) {
totalLength += it->wireEncode(block);
@@ -102,8 +102,9 @@
NamePrefixList npl;
for (; val != m_wire.elements_end(); ++val) {
- if (val->type() == ndn::tlv::Name) {
- npl.insert(ndn::Name(*val));
+ if (val->type() == nlsr::tlv::PrefixInfo) {
+ //TODO: Implement this structure as a type instead and add decoding
+ npl.insert(PrefixInfo(*val));
}
else {
NDN_THROW(Error("Name", val->type()));
@@ -117,12 +118,14 @@
{
os << " Names:\n";
int i = 0;
- for (const auto& name : m_npl.getNames()) {
- os << " Name " << i++ << ": " << name << "\n";
+ for (const auto& name : m_npl.getPrefixInfo()) {
+ os << " Name " << i << ": " << name.getName()
+ << " | Cost: " << name.getCost() << "\n";
+ i++;
}
}
-std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
NameLsa::update(const std::shared_ptr<Lsa>& lsa)
{
auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
@@ -130,25 +133,31 @@
// Obtain the set difference of the current and the incoming
// name prefix sets, and add those.
+
std::list<ndn::Name> newNames = nlsa->getNpl().getNames();
std::list<ndn::Name> oldNames = m_npl.getNames();
- std::list<ndn::Name> namesToAdd;
+ std::list<ndn::Name> nameRefToAdd;
+ std::list<PrefixInfo> namesToAdd;
+
std::set_difference(newNames.begin(), newNames.end(), oldNames.begin(), oldNames.end(),
- std::inserter(namesToAdd, namesToAdd.begin()));
- for (const auto& name : namesToAdd) {
- addName(name);
+ std::inserter(nameRefToAdd, nameRefToAdd.begin()));
+ for (const auto& name : nameRefToAdd) {
+ namesToAdd.push_back(nlsa->getNpl().getPrefixInfoForName(name));
+ addName(nlsa->getNpl().getPrefixInfoForName(name));
updated = true;
}
// Also remove any names that are no longer being advertised.
- std::list<ndn::Name> namesToRemove;
+ std::list<ndn::Name> nameRefToRemove;
+ std::list<PrefixInfo> namesToRemove;
std::set_difference(oldNames.begin(), oldNames.end(), newNames.begin(), newNames.end(),
- std::inserter(namesToRemove, namesToRemove.begin()));
- for (const auto& name : namesToRemove) {
- removeName(name);
+ std::inserter(nameRefToRemove, nameRefToRemove.begin()));
+ for (const auto& name : nameRefToRemove) {
+ namesToRemove.push_back(m_npl.getPrefixInfoForName(name));
+ removeName(m_npl.getPrefixInfoForName(name));
+
updated = true;
}
-
return {updated, namesToAdd, namesToRemove};
}
diff --git a/src/lsa/name-lsa.hpp b/src/lsa/name-lsa.hpp
index 625bbb7..27f46b1 100644
--- a/src/lsa/name-lsa.hpp
+++ b/src/lsa/name-lsa.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -76,17 +76,17 @@
}
void
- addName(const ndn::Name& name)
+ addName(const PrefixInfo& name)
{
m_wire.reset();
m_npl.insert(name);
}
void
- removeName(const ndn::Name& name)
+ removeName(const PrefixInfo& name)
{
m_wire.reset();
- m_npl.erase(name);
+ m_npl.erase(name.getName());
}
template<ndn::encoding::Tag TAG>
@@ -99,7 +99,7 @@
void
wireDecode(const ndn::Block& wire);
- std::tuple<bool, std::list<ndn::Name>, std::list<ndn::Name>>
+ std::tuple<bool, std::list<PrefixInfo>, std::list<PrefixInfo>>
update(const std::shared_ptr<Lsa>& lsa) override;
private:
diff --git a/src/lsdb.hpp b/src/lsdb.hpp
index 7e1d9ad..ba7052d 100644
--- a/src/lsdb.hpp
+++ b/src/lsdb.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2024, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -335,7 +335,7 @@
ndn::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
ndn::signal::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
using AfterLsdbModified = ndn::signal::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
- std::list<ndn::Name>, std::list<ndn::Name>>;
+ std::list<nlsr::PrefixInfo>, std::list<nlsr::PrefixInfo>>;
AfterLsdbModified onLsdbModified;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
diff --git a/src/name-prefix-list.cpp b/src/name-prefix-list.cpp
index 0323896..8012306 100644
--- a/src/name-prefix-list.cpp
+++ b/src/name-prefix-list.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2023, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -21,6 +21,7 @@
#include "name-prefix-list.hpp"
#include "common.hpp"
+#include "tlv-nlsr.hpp"
namespace nlsr {
@@ -34,10 +35,19 @@
}
bool
-NamePrefixList::insert(const ndn::Name& name, const std::string& source)
+NamePrefixList::insert(const ndn::Name& name, const std::string& source, double cost)
{
- auto& sources = m_namesSources[name];
- return sources.insert(source).second;
+ auto& soucePrefixInfo = m_namesSources[name];
+ soucePrefixInfo.costObj = PrefixInfo(name, cost);
+ return soucePrefixInfo.sources.insert(source).second;
+}
+
+bool
+NamePrefixList::insert(const PrefixInfo& nameCost)
+{
+ auto& soucePrefixInfo = m_namesSources[nameCost.getName()];
+ soucePrefixInfo.costObj = nameCost;
+ return soucePrefixInfo.sources.insert("").second;
}
bool
@@ -48,30 +58,48 @@
return false;
}
- bool isRemoved = it->second.erase(source);
- if (it->second.empty()) {
+ bool isRemoved = it->second.sources.erase(source);
+ if (it->second.sources.empty()) {
m_namesSources.erase(it);
}
return isRemoved;
}
+const PrefixInfo&
+NamePrefixList::getPrefixInfoForName(const ndn::Name& name) const
+{
+ auto it = m_namesSources.find(name);
+ BOOST_ASSERT(it != m_namesSources.end());
+ return it->second.costObj;
+}
+
std::list<ndn::Name>
NamePrefixList::getNames() const
{
std::list<ndn::Name> names;
for (const auto& [name, sources] : m_namesSources) {
- names.push_back(name);
+ names.emplace_back(name);
}
return names;
}
+std::list<PrefixInfo>
+NamePrefixList::getPrefixInfo() const
+{
+ std::list<PrefixInfo> nameCosts;
+ for (const auto& [name, soucePrefixInfo] : m_namesSources) {
+ nameCosts.emplace_back(name, soucePrefixInfo.costObj.getCost());
+ }
+ return nameCosts;
+}
+
#ifdef WITH_TESTS
std::set<std::string>
NamePrefixList::getSources(const ndn::Name& name) const
{
if (auto it = m_namesSources.find(name); it != m_namesSources.end()) {
- return it->second;
+ return it->second.sources;
}
return {};
}
@@ -84,7 +112,7 @@
os << "Name prefix list: {\n";
for (const auto& [name, sources] : list.m_namesSources) {
os << name << "\nSources:\n";
- for (const auto& source : sources) {
+ for (const auto& source : sources.sources) {
os << " " << source << "\n";
}
}
@@ -92,4 +120,70 @@
return os;
}
+template<ndn::encoding::Tag TAG>
+size_t
+PrefixInfo::wireEncode(ndn::EncodingImpl<TAG>& encoder) const
+{
+ size_t totalLength = 0;
+
+ totalLength += prependDoubleBlock(encoder, nlsr::tlv::Cost, m_prefixCost);
+
+ totalLength += m_prefixName.wireEncode(encoder);
+
+ totalLength += encoder.prependVarNumber(totalLength);
+ totalLength += encoder.prependVarNumber(nlsr::tlv::PrefixInfo);
+
+ return totalLength;
+}
+
+NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(PrefixInfo);
+
+const ndn::Block&
+PrefixInfo::wireEncode() const
+{
+ if (m_wire.hasWire()) {
+ return m_wire;
+ }
+
+ ndn::EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
+
+ ndn::EncodingBuffer buffer(estimatedSize, 0);
+ wireEncode(buffer);
+
+ m_wire = buffer.block();
+
+ return m_wire;
+}
+
+void
+PrefixInfo::wireDecode(const ndn::Block& wire)
+{
+ m_wire = wire;
+
+ if (m_wire.type() != nlsr::tlv::PrefixInfo) {
+ NDN_THROW(Error("PrefixInfo", m_wire.type()));
+ }
+
+ m_wire.parse();
+
+ auto val = m_wire.elements_begin();
+
+ if (val != m_wire.elements_end() && val->type() == ndn::tlv::Name) {
+ m_prefixName.wireDecode(*val);
+ ++val;
+ }
+ else {
+ NDN_THROW(Error("Missing required Name field"));
+ }
+
+ if (val != m_wire.elements_end() && val->type() == nlsr::tlv::Cost) {
+ m_prefixCost = ndn::encoding::readDouble(*val);
+ ++val;
+ }
+ else {
+ NDN_THROW(Error("Missing required Cost field"));
+ }
+}
+
} // namespace nlsr
diff --git a/src/name-prefix-list.hpp b/src/name-prefix-list.hpp
index 8adaf24..9ea814a 100644
--- a/src/name-prefix-list.hpp
+++ b/src/name-prefix-list.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2023, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -36,6 +36,69 @@
namespace nlsr {
+class PrefixInfo : private boost::equality_comparable<PrefixInfo>
+{
+public:
+ class Error : public ndn::tlv::Error
+ {
+ public:
+ using ndn::tlv::Error::Error;
+ };
+
+ PrefixInfo() = default;
+
+ PrefixInfo(const ndn::Block& block)
+ {
+ wireDecode(block);
+ }
+
+ PrefixInfo(const ndn::Name& name, double cost)
+ : m_prefixName(name),
+ m_prefixCost(cost)
+ {
+ }
+
+ const ndn::Name& getName() const
+ {
+ return m_prefixName;
+ }
+
+ double getCost() const
+ {
+ return m_prefixCost;
+ }
+
+ template<ndn::encoding::Tag TAG>
+ size_t
+ wireEncode(ndn::EncodingImpl<TAG>& block) const;
+
+ const ndn::Block&
+ wireEncode() const;
+
+ void
+ wireDecode(const ndn::Block& wire);
+
+private:
+ friend bool
+ operator==(const PrefixInfo& lhs, const PrefixInfo& rhs)
+ {
+ return (lhs.getName() == rhs.getName()) && (lhs.getCost() == rhs.getCost());
+ }
+
+ friend std::ostream&
+ operator<<(std::ostream& os, const PrefixInfo& info)
+ {
+ os << "Prefix Info: (" << info.getName() << ", " << info.getCost() << ")\n";
+ return os;
+ }
+
+private:
+ ndn::Name m_prefixName;
+ double m_prefixCost;
+
+ mutable ndn::Block m_wire;
+};
+
class NamePrefixList : private boost::equality_comparable<NamePrefixList>
{
public:
@@ -49,7 +112,10 @@
\retval false Name and source combination already exists.
*/
bool
- insert(const ndn::Name& name, const std::string& source = "");
+ insert(const ndn::Name& name, const std::string& source = "", double cost = 0);
+
+ bool
+ insert(const PrefixInfo& nameCost);
/*! \brief Deletes name and source combination
\retval true Name and source combination is deleted.
@@ -64,9 +130,15 @@
return m_namesSources.size();
}
+ const PrefixInfo&
+ getPrefixInfoForName(const ndn::Name& name) const;
+
std::list<ndn::Name>
getNames() const;
+ std::list<PrefixInfo>
+ getPrefixInfo() const;
+
#ifdef WITH_TESTS
/*! Returns the sources that this name has.
If the name does not exist, returns an empty container.
@@ -89,16 +161,26 @@
friend bool
operator==(const NamePrefixList& lhs, const NamePrefixList& rhs)
{
- return lhs.getNames() == rhs.getNames();
+ return lhs.getPrefixInfo() == rhs.getPrefixInfo();
}
+ struct PrefixInfoSource
+ {
+ std::set<std::string> sources;
+ // Because NFD only readvertises each prefix once, this will be the first cost
+ // announced via NFD
+ PrefixInfo costObj;
+ };
+
private:
- std::map<ndn::Name, std::set<std::string>> m_namesSources;
+ std::map<ndn::Name, PrefixInfoSource> m_namesSources;
friend std::ostream&
operator<<(std::ostream& os, const NamePrefixList& list);
};
+NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(PrefixInfo);
+
} // namespace nlsr
#endif // NLSR_NAME_PREFIX_LIST_HPP
diff --git a/src/route/name-prefix-table-entry.hpp b/src/route/name-prefix-table-entry.hpp
index c298e97..d808018 100644
--- a/src/route/name-prefix-table-entry.hpp
+++ b/src/route/name-prefix-table-entry.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-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -24,6 +24,7 @@
#include "routing-table-pool-entry.hpp"
#include "test-access-control.hpp"
+#include "nexthop.hpp"
#include <list>
#include <utility>
@@ -80,6 +81,12 @@
return m_nexthopList;
}
+ NexthopList&
+ getNexthopListForModification()
+ {
+ return m_nexthopList;
+ }
+
/*! \brief Collect all next-hops that are advertised by this entry's
* routing entries.
*/
diff --git a/src/route/name-prefix-table.cpp b/src/route/name-prefix-table.cpp
index 3ee9132..ea4fc16 100644
--- a/src/route/name-prefix-table.cpp
+++ b/src/route/name-prefix-table.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -62,8 +62,8 @@
void
NamePrefixTable::updateFromLsdb(std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
- const std::list<ndn::Name>& namesToAdd,
- const std::list<ndn::Name>& namesToRemove)
+ const std::list<nlsr::PrefixInfo>& namesToAdd,
+ const std::list<nlsr::PrefixInfo>& namesToRemove)
{
if (m_ownRouterName == lsa->getOriginRouter()) {
return;
@@ -75,9 +75,10 @@
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());
+ for (const auto &prefix : nlsa->getNpl().getPrefixInfo()) {
+ if (prefix.getName() != m_ownRouterName) {
+ m_nexthopCost[DestNameKey(lsa->getOriginRouter(), prefix.getName())] = prefix.getCost();
+ addEntry(prefix.getName(), lsa->getOriginRouter());
}
}
}
@@ -87,15 +88,17 @@
return;
}
- for (const auto& name : namesToAdd) {
- if (name != m_ownRouterName) {
- addEntry(name, lsa->getOriginRouter());
+ for (const auto &prefix : namesToAdd) {
+ if (prefix.getName() != m_ownRouterName) {
+ m_nexthopCost[DestNameKey(lsa->getOriginRouter(), prefix.getName())] = prefix.getCost();
+ addEntry(prefix.getName(), lsa->getOriginRouter());
}
}
- for (const auto& name : namesToRemove) {
- if (name != m_ownRouterName) {
- removeEntry(name, lsa->getOriginRouter());
+ for (const auto &prefix : namesToRemove) {
+ if (prefix.getName() != m_ownRouterName) {
+ m_nexthopCost.erase(m_nexthopCost.find(DestNameKey(lsa->getOriginRouter(), prefix.getName())));
+ removeEntry(prefix.getName(), lsa->getOriginRouter());
}
}
}
@@ -105,6 +108,7 @@
auto nlsa = std::static_pointer_cast<NameLsa>(lsa);
for (const auto& name : nlsa->getNpl().getNames()) {
if (name != m_ownRouterName) {
+ m_nexthopCost.erase(m_nexthopCost.find(DestNameKey(lsa->getOriginRouter(), name)));
removeEntry(name, lsa->getOriginRouter());
}
}
@@ -112,6 +116,18 @@
}
}
+NexthopList
+NamePrefixTable::adjustNexthopCosts(const NexthopList& nhlist, const ndn::Name& nameToCheck, const ndn::Name& destRouterName)
+{
+ NexthopList new_nhList;
+ for (const auto& nh : nhlist.getNextHops()) {
+ const NextHop newNextHop = NextHop(nh.getConnectingFaceUri(), nh.getRouteCost() +
+ m_nexthopCost[DestNameKey(destRouterName, nameToCheck)]);
+ new_nhList.addNextHop(newNextHop);
+ }
+ return new_nhList;
+}
+
void
NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
{
@@ -161,7 +177,7 @@
// If this entry has next hops, we need to inform the FIB
if (npte->getNexthopList().size() > 0) {
NLSR_LOG_TRACE("Updating FIB with next hops for " << npte->getNamePrefix());
- m_fib.update(name, npte->getNexthopList());
+ m_fib.update(name, adjustNexthopCosts(npte->getNexthopList(), name, destRouter));
}
// The routing table may recalculate and add a routing table entry
// with no next hops to replace an existing routing table entry. In
@@ -183,7 +199,7 @@
if ((*nameItr)->getNexthopList().size() > 0) {
NLSR_LOG_TRACE("Updating FIB with next hops for " << (**nameItr));
- m_fib.update(name, (*nameItr)->getNexthopList());
+ m_fib.update(name, adjustNexthopCosts((*nameItr)->getNexthopList(), name, destRouter));
}
else {
NLSR_LOG_TRACE(npte->getNamePrefix() << " has no next hops; removing from FIB");
@@ -251,7 +267,7 @@
NLSR_LOG_TRACE(**nameItr << " has other routing table entries;"
<< " updating FIB with next hops");
(*nameItr)->generateNhlfromRteList();
- m_fib.update(name, (*nameItr)->getNexthopList());
+ m_fib.update(name, adjustNexthopCosts((*nameItr)->getNexthopList(), name, destRouter));
}
}
else {
diff --git a/src/route/name-prefix-table.hpp b/src/route/name-prefix-table.hpp
index 5ac8345..8fca574 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-2023, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -41,6 +41,7 @@
std::unordered_map<ndn::Name, std::shared_ptr<RoutingTablePoolEntry>>;
using NptEntryList = std::list<std::shared_ptr<NamePrefixTableEntry>>;
using const_iterator = NptEntryList::const_iterator;
+ using DestNameKey = std::tuple<ndn::Name, ndn::Name>;
NamePrefixTable(const ndn::Name& ownRouterName, Fib& fib, RoutingTable& routingTable,
AfterRoutingChange& afterRoutingChangeSignal,
@@ -48,6 +49,9 @@
~NamePrefixTable();
+ NexthopList
+ adjustNexthopCosts(const NexthopList& nhlist, const ndn::Name& nameToCheck, const ndn::Name& destRouterName);
+
/*! \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)
@@ -56,8 +60,8 @@
*/
void
updateFromLsdb(std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
- const std::list<ndn::Name>& namesToAdd,
- const std::list<ndn::Name>& namesToRemove);
+ const std::list<nlsr::PrefixInfo>& namesToAdd,
+ const std::list<nlsr::PrefixInfo>& namesToRemove);
/*! \brief Adds a destination to the specified name prefix.
\param name The name prefix
@@ -143,6 +147,7 @@
RoutingTable& m_routingTable;
ndn::signal::Connection m_afterRoutingChangeConnection;
ndn::signal::Connection m_afterLsdbModified;
+ std::map<std::tuple<ndn::Name, ndn::Name>, double> m_nexthopCost;
};
inline NamePrefixTable::const_iterator
diff --git a/src/tlv-nlsr.hpp b/src/tlv-nlsr.hpp
index 224c452..102e49f 100644
--- a/src/tlv-nlsr.hpp
+++ b/src/tlv-nlsr.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2014-2022, The University of Memphis,
+ * Copyright (c) 2014-2025, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
@@ -46,6 +46,7 @@
NextHop = 143,
RoutingTable = 144,
RoutingTableEntry = 145,
+ PrefixInfo = 146
};
} // namespace nlsr::tlv
diff --git a/src/update/command-processor.cpp b/src/update/command-processor.cpp
index 67f58cc..f260bd6 100644
--- a/src/update/command-processor.cpp
+++ b/src/update/command-processor.cpp
@@ -50,7 +50,8 @@
? responseParams.getFaceId() : m_defaultResponseFaceId;
responseParams.setFaceId(responseFaceId);
// Only build a Name LSA if the added name is new
- if (m_namePrefixList.insert(castParams.getName())) {
+ double castParamCost = (castParams.hasCost() ? castParams.getCost() : 0);
+ if (m_namePrefixList.insert(castParams.getName(), "", castParamCost)) {
NLSR_LOG_INFO("Advertising name: " << castParams.getName());
m_lsdb.buildAndInstallOwnNameLsa();
if (castParams.hasFlags() && castParams.getFlags() == PREFIX_FLAG) {