blob: 5c18b77f227a8ea2761d88e99e08d18c8472a2a0 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Muktadir R Chowdhury800833b2016-07-29 13:43:59 -05003 * Copyright (c) 2014-2016, The University of Memphis,
Vince Lehmanc2e51f62015-01-20 15:03:11 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
akmhoque3d06e792014-05-27 16:23:20 -050020 **/
Vince Lehmanc2e51f62015-01-20 15:03:11 -060021
Vince Lehmancae33b62015-06-05 09:21:30 -050022#include "name-prefix-table.hpp"
23
24#include "logger.hpp"
25#include "nlsr.hpp"
26#include "routing-table.hpp"
27
28#include <algorithm>
akmhoque53353462014-04-22 08:43:45 -050029#include <list>
30#include <utility>
akmhoque53353462014-04-22 08:43:45 -050031
32namespace nlsr {
33
akmhoque674b0b12014-05-20 14:33:28 -050034INIT_LOGGER("NamePrefixTable");
35
akmhoque53353462014-04-22 08:43:45 -050036static bool
akmhoque31d1d4b2014-05-05 22:08:14 -050037npteCompare(NamePrefixTableEntry& npte, const ndn::Name& name)
akmhoque53353462014-04-22 08:43:45 -050038{
39 return npte.getNamePrefix() == name;
40}
41
akmhoque53353462014-04-22 08:43:45 -050042void
akmhoque31d1d4b2014-05-05 22:08:14 -050043NamePrefixTable::addEntry(const ndn::Name& name, RoutingTableEntry& rte)
akmhoque53353462014-04-22 08:43:45 -050044{
Nick G97e34942016-07-11 14:46:27 -050045 // Check if the advertised name prefix is in the table already.
Vince Lehmancae33b62015-06-05 09:21:30 -050046 NptEntryList::iterator it = std::find_if(m_table.begin(),
47 m_table.end(),
48 bind(&npteCompare, _1, name));
Nick G97e34942016-07-11 14:46:27 -050049 // If not, create a new entry and add it.
akmhoque157b0a42014-05-13 00:26:37 -050050 if (it == m_table.end()) {
Vince Lehmancae33b62015-06-05 09:21:30 -050051 _LOG_TRACE("Adding origin: " << rte.getDestination() << " to new name prefix: " << name);
52
53 NamePrefixTableEntry entry(name);
Nick G97e34942016-07-11 14:46:27 -050054 entry.addRoutingTableEntry(rte); // Add this RTE to this new NPT entry.
55 entry.generateNhlfromRteList(); // Generate a list of next-hops from the RTE.
Vince Lehmancae33b62015-06-05 09:21:30 -050056
Nick G97e34942016-07-11 14:46:27 -050057 m_table.push_back(entry); // Add the new, completed entry into the main table.
Vince Lehmancae33b62015-06-05 09:21:30 -050058
Nick G97e34942016-07-11 14:46:27 -050059 // If the RTE we added has any next hops, we inform the FIB of this.
akmhoque157b0a42014-05-13 00:26:37 -050060 if (rte.getNexthopList().getSize() > 0) {
Vince Lehmancae33b62015-06-05 09:21:30 -050061 _LOG_TRACE("Updating FIB with next hops for " << entry);
62 m_nlsr.getFib().update(name, entry.getNexthopList());
akmhoque53353462014-04-22 08:43:45 -050063 }
64 }
akmhoque157b0a42014-05-13 00:26:37 -050065 else {
Vince Lehmancae33b62015-06-05 09:21:30 -050066 _LOG_TRACE("Adding origin: " << rte.getDestination() << " to existing prefix: " << *it);
Nick G97e34942016-07-11 14:46:27 -050067 // Update the existing entry with the new RTE.
Vince Lehmancae33b62015-06-05 09:21:30 -050068 it->addRoutingTableEntry(rte);
69
Vince Lehmanef21d8e2015-04-01 15:59:39 -050070 it->generateNhlfromRteList();
Vince Lehmancae33b62015-06-05 09:21:30 -050071
Nick G97e34942016-07-11 14:46:27 -050072 // As above, inform the FIB of this fact.
73 // We may possibly have a new best next-hop for this name prefix
74 // So this is a necessary step.
Vince Lehmancae33b62015-06-05 09:21:30 -050075 if (it->getNexthopList().getSize() > 0) {
76 _LOG_TRACE("Updating FIB with next hops for " << *it);
77 m_nlsr.getFib().update(name, it->getNexthopList());
akmhoque53353462014-04-22 08:43:45 -050078 }
akmhoque157b0a42014-05-13 00:26:37 -050079 else {
Nick G97e34942016-07-11 14:46:27 -050080 // The routing table may recalculate and add a routing table
81 // entry with no next hops to replace an existing routing table
82 // entry. In this case, the name prefix is no longer reachable
83 // through a next hop and should be removed from the FIB. But,
84 // the prefix should remain in the Name Prefix Table as a future
85 // routing table calculation may add next hops.
Vince Lehmancae33b62015-06-05 09:21:30 -050086 _LOG_TRACE(*it << " has no next hops; removing from FIB");
akmhoque31d1d4b2014-05-05 22:08:14 -050087 m_nlsr.getFib().remove(name);
akmhoque53353462014-04-22 08:43:45 -050088 }
89 }
90}
91
92void
akmhoque31d1d4b2014-05-05 22:08:14 -050093NamePrefixTable::removeEntry(const ndn::Name& name, RoutingTableEntry& rte)
akmhoque53353462014-04-22 08:43:45 -050094{
Vince Lehmancae33b62015-06-05 09:21:30 -050095 NptEntryList::iterator it = std::find_if(m_table.begin(),
96 m_table.end(),
97 bind(&npteCompare, _1, name));
akmhoque157b0a42014-05-13 00:26:37 -050098 if (it != m_table.end()) {
Vince Lehmancae33b62015-06-05 09:21:30 -050099 _LOG_TRACE("Removing origin: " << rte.getDestination() << " from prefix: " << *it);
100
Vince Lehman9630fbf2015-05-05 12:33:44 -0500101 it->removeRoutingTableEntry(rte);
102
Vince Lehmancae33b62015-06-05 09:21:30 -0500103 // If the prefix is a router prefix and it does not have any other routing table entries,
104 // the Adjacency/Coordinate LSA associated with that origin router has been removed from
105 // the LSDB and so the router prefix should be removed from the Name Prefix Table.
106 //
107 // If the prefix is an advertised name prefix:
108 // If another router advertises this name prefix, the RteList should have another entry
109 // for that router; the next hops should be recalculated and installed in the FIB.
110 //
111 // If no other router advertises this name prefix, the RteList should be empty and the
112 // prefix can be removed from the Name Prefix Table. Once a new Name LSA advertises this
113 // prefix, a new entry for the prefix will be created.
114 //
115 if (it->getRteListSize() == 0) {
116 _LOG_TRACE(*it << " has no routing table entries; removing from table and FIB");
akmhoquefdbddb12014-05-02 18:35:19 -0500117 m_table.erase(it);
akmhoque31d1d4b2014-05-05 22:08:14 -0500118 m_nlsr.getFib().remove(name);
akmhoque53353462014-04-22 08:43:45 -0500119 }
akmhoque157b0a42014-05-13 00:26:37 -0500120 else {
Vince Lehmancae33b62015-06-05 09:21:30 -0500121 _LOG_TRACE(*it << " has other routing table entries; updating FIB with next hops");
122 it->generateNhlfromRteList();
Vince Lehmancae33b62015-06-05 09:21:30 -0500123
124 m_nlsr.getFib().update(name, it->getNexthopList());
akmhoque53353462014-04-22 08:43:45 -0500125 }
126 }
127}
128
akmhoque53353462014-04-22 08:43:45 -0500129void
akmhoque31d1d4b2014-05-05 22:08:14 -0500130NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
akmhoque53353462014-04-22 08:43:45 -0500131{
Vince Lehmancae33b62015-06-05 09:21:30 -0500132 _LOG_DEBUG("Adding origin: " << destRouter << " to " << name);
133
134 RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
135
136 if (rteCheck != nullptr) {
137 addEntry(name, *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500138 }
akmhoque157b0a42014-05-13 00:26:37 -0500139 else {
akmhoque53353462014-04-22 08:43:45 -0500140 RoutingTableEntry rte(destRouter);
akmhoque31d1d4b2014-05-05 22:08:14 -0500141 addEntry(name, rte);
akmhoque53353462014-04-22 08:43:45 -0500142 }
143}
144
145void
akmhoque31d1d4b2014-05-05 22:08:14 -0500146NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
akmhoque53353462014-04-22 08:43:45 -0500147{
Vince Lehmancae33b62015-06-05 09:21:30 -0500148 _LOG_DEBUG("Removing origin: " << destRouter << " from " << name);
149
150 RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
151
152 if (rteCheck != nullptr) {
153 removeEntry(name, *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500154 }
akmhoque157b0a42014-05-13 00:26:37 -0500155 else {
akmhoque53353462014-04-22 08:43:45 -0500156 RoutingTableEntry rte(destRouter);
akmhoque31d1d4b2014-05-05 22:08:14 -0500157 removeEntry(name, rte);
akmhoque53353462014-04-22 08:43:45 -0500158 }
159}
160
161void
akmhoque31d1d4b2014-05-05 22:08:14 -0500162NamePrefixTable::updateWithNewRoute()
akmhoque53353462014-04-22 08:43:45 -0500163{
Vince Lehmancae33b62015-06-05 09:21:30 -0500164 _LOG_DEBUG("Updating table with newly calculated routes");
165
166 // Update each name prefix entry in the Name Prefix Table with newly calculated next hops
Nick G97e34942016-07-11 14:46:27 -0500167 // For each entry in the NPT
Vince Lehmancae33b62015-06-05 09:21:30 -0500168 for (const NamePrefixTableEntry& prefixEntry : m_table) {
Nick G97e34942016-07-11 14:46:27 -0500169 // For each routing table entry
Vince Lehmancae33b62015-06-05 09:21:30 -0500170 for (const RoutingTableEntry& routingEntry : prefixEntry.getRteList()) {
171 _LOG_TRACE("Updating next hops to origin: " << routingEntry.getDestination()
172 << " for prefix: " << prefixEntry);
173
akmhoqueb6450b12014-04-24 00:01:03 -0500174 RoutingTableEntry* rteCheck =
Vince Lehmancae33b62015-06-05 09:21:30 -0500175 m_nlsr.getRoutingTable().findRoutingTableEntry(routingEntry.getDestination());
176
Nick G97e34942016-07-11 14:46:27 -0500177 // If there is a routing table entry for this prefix, update the NPT with it.
Vince Lehmancae33b62015-06-05 09:21:30 -0500178 if (rteCheck != nullptr) {
179 addEntry(prefixEntry.getNamePrefix(), *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500180 }
akmhoque157b0a42014-05-13 00:26:37 -0500181 else {
Vince Lehmancae33b62015-06-05 09:21:30 -0500182 RoutingTableEntry rte(routingEntry.getDestination());
183 addEntry(prefixEntry.getNamePrefix(), rte);
akmhoque53353462014-04-22 08:43:45 -0500184 }
185 }
186 }
187}
188
189void
akmhoque674b0b12014-05-20 14:33:28 -0500190NamePrefixTable::writeLog()
191{
Vince Lehmancae33b62015-06-05 09:21:30 -0500192 _LOG_DEBUG(*this);
akmhoque674b0b12014-05-20 14:33:28 -0500193}
194
Vince Lehmancae33b62015-06-05 09:21:30 -0500195std::ostream&
196operator<<(std::ostream& os, const NamePrefixTable& table)
197{
198 os << "----------------NPT----------------------\n";
199
200 for (const NamePrefixTableEntry& entry : table) {
201 os << entry << std::endl;
202 }
203
204 return os;
205}
206
207} // namespace nlsr