blob: e5199b06b29303b151982cfceb4556395219be5e [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.
56 entry.getNexthopList().sort(); // Sort it.
Vince Lehmancae33b62015-06-05 09:21:30 -050057
Nick G97e34942016-07-11 14:46:27 -050058 m_table.push_back(entry); // Add the new, completed entry into the main table.
Vince Lehmancae33b62015-06-05 09:21:30 -050059
Nick G97e34942016-07-11 14:46:27 -050060 // If the RTE we added has any next hops, we inform the FIB of this.
akmhoque157b0a42014-05-13 00:26:37 -050061 if (rte.getNexthopList().getSize() > 0) {
Vince Lehmancae33b62015-06-05 09:21:30 -050062 _LOG_TRACE("Updating FIB with next hops for " << entry);
63 m_nlsr.getFib().update(name, entry.getNexthopList());
akmhoque53353462014-04-22 08:43:45 -050064 }
65 }
akmhoque157b0a42014-05-13 00:26:37 -050066 else {
Vince Lehmancae33b62015-06-05 09:21:30 -050067 _LOG_TRACE("Adding origin: " << rte.getDestination() << " to existing prefix: " << *it);
Nick G97e34942016-07-11 14:46:27 -050068 // Update the existing entry with the new RTE.
Vince Lehmancae33b62015-06-05 09:21:30 -050069 it->addRoutingTableEntry(rte);
70
Nick G97e34942016-07-11 14:46:27 -050071 it->generateNhlfromRteList(); // Rebuild the list of next-hops
72 it->getNexthopList().sort(); // Sort it.
Vince Lehmancae33b62015-06-05 09:21:30 -050073
Nick G97e34942016-07-11 14:46:27 -050074 // As above, inform the FIB of this fact.
75 // We may possibly have a new best next-hop for this name prefix
76 // So this is a necessary step.
Vince Lehmancae33b62015-06-05 09:21:30 -050077 if (it->getNexthopList().getSize() > 0) {
78 _LOG_TRACE("Updating FIB with next hops for " << *it);
79 m_nlsr.getFib().update(name, it->getNexthopList());
akmhoque53353462014-04-22 08:43:45 -050080 }
akmhoque157b0a42014-05-13 00:26:37 -050081 else {
Nick G97e34942016-07-11 14:46:27 -050082 // The routing table may recalculate and add a routing table
83 // entry with no next hops to replace an existing routing table
84 // entry. In this case, the name prefix is no longer reachable
85 // through a next hop and should be removed from the FIB. But,
86 // the prefix should remain in the Name Prefix Table as a future
87 // routing table calculation may add next hops.
Vince Lehmancae33b62015-06-05 09:21:30 -050088 _LOG_TRACE(*it << " has no next hops; removing from FIB");
akmhoque31d1d4b2014-05-05 22:08:14 -050089 m_nlsr.getFib().remove(name);
akmhoque53353462014-04-22 08:43:45 -050090 }
91 }
92}
93
94void
akmhoque31d1d4b2014-05-05 22:08:14 -050095NamePrefixTable::removeEntry(const ndn::Name& name, RoutingTableEntry& rte)
akmhoque53353462014-04-22 08:43:45 -050096{
Vince Lehmancae33b62015-06-05 09:21:30 -050097 NptEntryList::iterator it = std::find_if(m_table.begin(),
98 m_table.end(),
99 bind(&npteCompare, _1, name));
akmhoque157b0a42014-05-13 00:26:37 -0500100 if (it != m_table.end()) {
Vince Lehmancae33b62015-06-05 09:21:30 -0500101 _LOG_TRACE("Removing origin: " << rte.getDestination() << " from prefix: " << *it);
102
Vince Lehman9630fbf2015-05-05 12:33:44 -0500103 it->removeRoutingTableEntry(rte);
104
Vince Lehmancae33b62015-06-05 09:21:30 -0500105 // If the prefix is a router prefix and it does not have any other routing table entries,
106 // the Adjacency/Coordinate LSA associated with that origin router has been removed from
107 // the LSDB and so the router prefix should be removed from the Name Prefix Table.
108 //
109 // If the prefix is an advertised name prefix:
110 // If another router advertises this name prefix, the RteList should have another entry
111 // for that router; the next hops should be recalculated and installed in the FIB.
112 //
113 // If no other router advertises this name prefix, the RteList should be empty and the
114 // prefix can be removed from the Name Prefix Table. Once a new Name LSA advertises this
115 // prefix, a new entry for the prefix will be created.
116 //
117 if (it->getRteListSize() == 0) {
118 _LOG_TRACE(*it << " has no routing table entries; removing from table and FIB");
akmhoquefdbddb12014-05-02 18:35:19 -0500119 m_table.erase(it);
akmhoque31d1d4b2014-05-05 22:08:14 -0500120 m_nlsr.getFib().remove(name);
akmhoque53353462014-04-22 08:43:45 -0500121 }
akmhoque157b0a42014-05-13 00:26:37 -0500122 else {
Vince Lehmancae33b62015-06-05 09:21:30 -0500123 _LOG_TRACE(*it << " has other routing table entries; updating FIB with next hops");
124 it->generateNhlfromRteList();
125 it->getNexthopList().sort();
126
127 m_nlsr.getFib().update(name, it->getNexthopList());
akmhoque53353462014-04-22 08:43:45 -0500128 }
129 }
130}
131
akmhoque53353462014-04-22 08:43:45 -0500132void
akmhoque31d1d4b2014-05-05 22:08:14 -0500133NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
akmhoque53353462014-04-22 08:43:45 -0500134{
Vince Lehmancae33b62015-06-05 09:21:30 -0500135 _LOG_DEBUG("Adding origin: " << destRouter << " to " << name);
136
137 RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
138
139 if (rteCheck != nullptr) {
140 addEntry(name, *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500141 }
akmhoque157b0a42014-05-13 00:26:37 -0500142 else {
akmhoque53353462014-04-22 08:43:45 -0500143 RoutingTableEntry rte(destRouter);
akmhoque31d1d4b2014-05-05 22:08:14 -0500144 addEntry(name, rte);
akmhoque53353462014-04-22 08:43:45 -0500145 }
146}
147
148void
akmhoque31d1d4b2014-05-05 22:08:14 -0500149NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
akmhoque53353462014-04-22 08:43:45 -0500150{
Vince Lehmancae33b62015-06-05 09:21:30 -0500151 _LOG_DEBUG("Removing origin: " << destRouter << " from " << name);
152
153 RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
154
155 if (rteCheck != nullptr) {
156 removeEntry(name, *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500157 }
akmhoque157b0a42014-05-13 00:26:37 -0500158 else {
akmhoque53353462014-04-22 08:43:45 -0500159 RoutingTableEntry rte(destRouter);
akmhoque31d1d4b2014-05-05 22:08:14 -0500160 removeEntry(name, rte);
akmhoque53353462014-04-22 08:43:45 -0500161 }
162}
163
164void
akmhoque31d1d4b2014-05-05 22:08:14 -0500165NamePrefixTable::updateWithNewRoute()
akmhoque53353462014-04-22 08:43:45 -0500166{
Vince Lehmancae33b62015-06-05 09:21:30 -0500167 _LOG_DEBUG("Updating table with newly calculated routes");
168
169 // Update each name prefix entry in the Name Prefix Table with newly calculated next hops
Nick G97e34942016-07-11 14:46:27 -0500170 // For each entry in the NPT
Vince Lehmancae33b62015-06-05 09:21:30 -0500171 for (const NamePrefixTableEntry& prefixEntry : m_table) {
Nick G97e34942016-07-11 14:46:27 -0500172 // For each routing table entry
Vince Lehmancae33b62015-06-05 09:21:30 -0500173 for (const RoutingTableEntry& routingEntry : prefixEntry.getRteList()) {
174 _LOG_TRACE("Updating next hops to origin: " << routingEntry.getDestination()
175 << " for prefix: " << prefixEntry);
176
akmhoqueb6450b12014-04-24 00:01:03 -0500177 RoutingTableEntry* rteCheck =
Vince Lehmancae33b62015-06-05 09:21:30 -0500178 m_nlsr.getRoutingTable().findRoutingTableEntry(routingEntry.getDestination());
179
Nick G97e34942016-07-11 14:46:27 -0500180 // If there is a routing table entry for this prefix, update the NPT with it.
Vince Lehmancae33b62015-06-05 09:21:30 -0500181 if (rteCheck != nullptr) {
182 addEntry(prefixEntry.getNamePrefix(), *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500183 }
akmhoque157b0a42014-05-13 00:26:37 -0500184 else {
Vince Lehmancae33b62015-06-05 09:21:30 -0500185 RoutingTableEntry rte(routingEntry.getDestination());
186 addEntry(prefixEntry.getNamePrefix(), rte);
akmhoque53353462014-04-22 08:43:45 -0500187 }
188 }
189 }
190}
191
192void
akmhoque674b0b12014-05-20 14:33:28 -0500193NamePrefixTable::writeLog()
194{
Vince Lehmancae33b62015-06-05 09:21:30 -0500195 _LOG_DEBUG(*this);
akmhoque674b0b12014-05-20 14:33:28 -0500196}
197
Vince Lehmancae33b62015-06-05 09:21:30 -0500198std::ostream&
199operator<<(std::ostream& os, const NamePrefixTable& table)
200{
201 os << "----------------NPT----------------------\n";
202
203 for (const NamePrefixTableEntry& entry : table) {
204 os << entry << std::endl;
205 }
206
207 return os;
208}
209
210} // namespace nlsr