30 #include <boost/multi_array.hpp>
37 constexpr
int EMPTY_PARENT = -12345;
38 constexpr
double INF_DISTANCE = 2147483647;
39 constexpr
int NO_NEXT_HOP = -12345;
47 using AdjMatrix = boost::multi_array<double, 2>;
59 operator<<(std::ostream& os,
const PrintAdjMatrix& p)
61 size_t nRouters = p.map.size();
63 os <<
"-----------Legend (routerName -> index)------\n";
64 for (
size_t i = 0; i < nRouters; ++i) {
65 os <<
"Router:" << *p.map.getRouterNameByMappingNo(i)
66 <<
" Index:" << i <<
"\n";
69 for (
size_t i = 0; i < nRouters; ++i) {
74 for (
size_t i = 0; i < nRouters; ++i) {
79 for (
size_t i = 0; i < nRouters; i++) {
81 for (
size_t j = 0; j < nRouters; j++) {
82 double cost = p.matrix[i][j];
83 if (
cost == NO_NEXT_HOP) {
105 makeAdjMatrix(
const Lsdb& lsdb, NameMap&
map)
109 AdjMatrix
matrix(boost::extents[nRouters][nRouters]);
115 auto lsaRange = lsdb.getLsdbIterator<AdjLsa>();
116 for (
auto lsaIt = lsaRange.first; lsaIt != lsaRange.second; ++lsaIt) {
117 auto adjLsa = std::static_pointer_cast<AdjLsa>(*lsaIt);
120 std::list<Adjacent> adl = adjLsa->getAdl().getAdjList();
122 for (
const auto& adjacent : adl) {
124 double cost = adjacent.getLinkCost();
126 if (row && col && *row <
static_cast<int32_t
>(nRouters)
127 && *col <
static_cast<int32_t
>(nRouters)) {
144 for (
size_t row = 0; row < nRouters; ++row) {
145 for (
size_t col = 0; col < nRouters; ++col) {
146 double& toCost =
matrix[row][col];
147 double& fromCost =
matrix[col][row];
149 if (fromCost == toCost) {
155 if (toCost >= 0 && fromCost >= 0) {
156 correctedCost = std::max(toCost, fromCost);
159 NLSR_LOG_WARN(
"Cost between [" << row <<
"][" << col <<
"] and [" << col <<
"][" << row <<
160 "] are not the same (" << toCost <<
" != " << fromCost <<
"). " <<
161 "Correcting to cost: " << correctedCost);
163 toCost = correctedCost;
164 fromCost = correctedCost;
172 sortQueueByDistance(std::vector<int>& q,
const std::vector<double>& dist,
size_t start)
174 for (
size_t i = start; i < q.size(); ++i) {
175 for (
size_t j = i + 1; j < q.size(); ++j) {
176 if (dist[q[j]] < dist[q[i]]) {
177 std::swap(q[i], q[j]);
184 isNotExplored(std::vector<int>& q,
int u,
size_t start)
186 for (
size_t i = start; i < q.size(); i++) {
204 gatherLinks(
const AdjMatrix&
matrix,
int sourceRouter)
206 size_t nRouters =
matrix.size();
207 std::vector<Link> result;
208 result.reserve(nRouters);
209 for (
size_t i = 0; i < nRouters; ++i) {
210 if (i ==
static_cast<size_t>(sourceRouter)) {
215 result.emplace_back(Link{i,
cost});
225 simulateOneNeighbor(AdjMatrix&
matrix,
int sourceRouter,
const Link& accessibleNeighbor)
227 size_t nRouters =
matrix.size();
228 for (
size_t i = 0; i < nRouters; ++i) {
229 if (i == accessibleNeighbor.index) {
230 matrix[sourceRouter][i] = accessibleNeighbor.cost;
243 getNextHop(
int dest,
int source)
const
245 int nextHop = NO_NEXT_HOP;
246 while (
parent[dest] != EMPTY_PARENT) {
250 if (dest != source) {
251 nextHop = NO_NEXT_HOP;
265 calculateDijkstraPath(
const AdjMatrix&
matrix,
int sourceRouter)
267 size_t nRouters =
matrix.size();
268 std::vector<int>
parent(nRouters, EMPTY_PARENT);
270 std::vector<double>
distance(nRouters, INF_DISTANCE);
272 std::vector<int> q(nRouters);
273 for (
size_t i = 0 ; i < nRouters; ++i) {
274 q[i] =
static_cast<int>(i);
280 sortQueueByDistance(q,
distance, head);
282 while (head < nRouters) {
288 for (
size_t v = 0; v < nRouters; ++v) {
290 if (
matrix[u][v] >= 0 && isNotExplored(q, v, head + 1)) {
305 sortQueueByDistance(q,
distance, head);
315 addNextHopsToRoutingTable(
RoutingTable& rt,
const NameMap&
map,
int sourceRouter,
316 const AdjacencyList& adjacencies,
const DijkstraResult& dr)
319 int nRouters =
static_cast<int>(
map.
size());
322 for (
int i = 0; i < nRouters; ++i) {
323 if (i == sourceRouter) {
328 int nextHopRouter = dr.getNextHop(i, sourceRouter);
329 if (nextHopRouter == NO_NEXT_HOP) {
335 double routeCost = dr.distance[i];
338 BOOST_ASSERT(nextHopRouterName.has_value());
339 auto nextHopFace = adjacencies.getAdjacent(*nextHopRouterName).getFaceUri();
341 NextHop nh(nextHopFace, routeCost);
360 AdjMatrix
matrix = makeAdjMatrix(lsdb,
map);
365 auto dr = calculateDijkstraPath(
matrix, *sourceRouter);
372 auto links = gatherLinks(
matrix, *sourceRouter);
373 for (
const auto& link : links) {
375 simulateOneNeighbor(
matrix, *sourceRouter, link);
378 auto dr = calculateDijkstraPath(
matrix, *sourceRouter);
static constexpr double NON_ADJACENT_COST
A class to house all the configuration parameters for NLSR.
const ndn::Name & getRouterPrefix() const
AdjacencyList & getAdjacencyList()
uint32_t getMaxFacesPerPrefix() const
Assigning numbers to router names.
std::optional< ndn::Name > getRouterNameByMappingNo(int32_t mn) const
Find router name by its mapping number.
std::optional< int32_t > getMappingNoByRouterName(const ndn::Name &rtrName) const
Find mapping number of a router name.
size_t size() const
Return number of entries in this container.
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define NLSR_LOG_DEBUG(x)
#define INIT_LOGGER(name)
Copyright (c) 2014-2020, The University of Memphis, Regents of the University of California.
std::ostream & operator<<(std::ostream &os, const Adjacent &adjacent)
void calculateLinkStateRoutingPath(NameMap &map, RoutingTable &rt, ConfParameter &confParam, const Lsdb &lsdb)
std::vector< double > distance
std::vector< int > parent