blob: 56bea2da9c6a12a53ca53bd90247142d1ffaa6f3 [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Vince Lehmanc2e51f62015-01-20 15:03:11 -06003 * Copyright (c) 2014-2015, The University of Memphis,
4 * 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{
Vince Lehmancae33b62015-06-05 09:21:30 -050045 NptEntryList::iterator it = std::find_if(m_table.begin(),
46 m_table.end(),
47 bind(&npteCompare, _1, name));
akmhoque157b0a42014-05-13 00:26:37 -050048 if (it == m_table.end()) {
Vince Lehmancae33b62015-06-05 09:21:30 -050049 _LOG_TRACE("Adding origin: " << rte.getDestination() << " to new name prefix: " << name);
50
51 NamePrefixTableEntry entry(name);
52
53 entry.addRoutingTableEntry(rte);
54
55 entry.generateNhlfromRteList();
56 entry.getNexthopList().sort();
57
58 m_table.push_back(entry);
59
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);
67
68 it->addRoutingTableEntry(rte);
69
70 it->generateNhlfromRteList();
71 it->getNexthopList().sort();
72
73 if (it->getNexthopList().getSize() > 0) {
74 _LOG_TRACE("Updating FIB with next hops for " << *it);
75 m_nlsr.getFib().update(name, it->getNexthopList());
akmhoque53353462014-04-22 08:43:45 -050076 }
akmhoque157b0a42014-05-13 00:26:37 -050077 else {
Vince Lehmancae33b62015-06-05 09:21:30 -050078 // The routing table may recalculate and add a routing table entry with no next hops to
79 // replace an existing routing table entry. In this case, the name prefix is no longer
80 // reachable through a next hop and should be removed from the FIB. But, the prefix
81 // should remain in the Name Prefix Table as a future routing table calculation may
82 // add next hops.
83 _LOG_TRACE(*it << " has no next hops; removing from FIB");
akmhoque31d1d4b2014-05-05 22:08:14 -050084 m_nlsr.getFib().remove(name);
akmhoque53353462014-04-22 08:43:45 -050085 }
86 }
87}
88
89void
akmhoque31d1d4b2014-05-05 22:08:14 -050090NamePrefixTable::removeEntry(const ndn::Name& name, RoutingTableEntry& rte)
akmhoque53353462014-04-22 08:43:45 -050091{
Vince Lehmancae33b62015-06-05 09:21:30 -050092 NptEntryList::iterator it = std::find_if(m_table.begin(),
93 m_table.end(),
94 bind(&npteCompare, _1, name));
akmhoque157b0a42014-05-13 00:26:37 -050095 if (it != m_table.end()) {
Vince Lehmancae33b62015-06-05 09:21:30 -050096 _LOG_TRACE("Removing origin: " << rte.getDestination() << " from prefix: " << *it);
97
Vince Lehman9630fbf2015-05-05 12:33:44 -050098 it->removeRoutingTableEntry(rte);
99
Vince Lehmancae33b62015-06-05 09:21:30 -0500100 // If the prefix is a router prefix and it does not have any other routing table entries,
101 // the Adjacency/Coordinate LSA associated with that origin router has been removed from
102 // the LSDB and so the router prefix should be removed from the Name Prefix Table.
103 //
104 // If the prefix is an advertised name prefix:
105 // If another router advertises this name prefix, the RteList should have another entry
106 // for that router; the next hops should be recalculated and installed in the FIB.
107 //
108 // If no other router advertises this name prefix, the RteList should be empty and the
109 // prefix can be removed from the Name Prefix Table. Once a new Name LSA advertises this
110 // prefix, a new entry for the prefix will be created.
111 //
112 if (it->getRteListSize() == 0) {
113 _LOG_TRACE(*it << " has no routing table entries; removing from table and FIB");
akmhoquefdbddb12014-05-02 18:35:19 -0500114 m_table.erase(it);
akmhoque31d1d4b2014-05-05 22:08:14 -0500115 m_nlsr.getFib().remove(name);
akmhoque53353462014-04-22 08:43:45 -0500116 }
akmhoque157b0a42014-05-13 00:26:37 -0500117 else {
Vince Lehmancae33b62015-06-05 09:21:30 -0500118 _LOG_TRACE(*it << " has other routing table entries; updating FIB with next hops");
119 it->generateNhlfromRteList();
120 it->getNexthopList().sort();
121
122 m_nlsr.getFib().update(name, it->getNexthopList());
akmhoque53353462014-04-22 08:43:45 -0500123 }
124 }
125}
126
akmhoque53353462014-04-22 08:43:45 -0500127void
akmhoque31d1d4b2014-05-05 22:08:14 -0500128NamePrefixTable::addEntry(const ndn::Name& name, const ndn::Name& destRouter)
akmhoque53353462014-04-22 08:43:45 -0500129{
Vince Lehmancae33b62015-06-05 09:21:30 -0500130 _LOG_DEBUG("Adding origin: " << destRouter << " to " << name);
131
132 RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
133
134 if (rteCheck != nullptr) {
135 addEntry(name, *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500136 }
akmhoque157b0a42014-05-13 00:26:37 -0500137 else {
akmhoque53353462014-04-22 08:43:45 -0500138 RoutingTableEntry rte(destRouter);
akmhoque31d1d4b2014-05-05 22:08:14 -0500139 addEntry(name, rte);
akmhoque53353462014-04-22 08:43:45 -0500140 }
141}
142
143void
akmhoque31d1d4b2014-05-05 22:08:14 -0500144NamePrefixTable::removeEntry(const ndn::Name& name, const ndn::Name& destRouter)
akmhoque53353462014-04-22 08:43:45 -0500145{
Vince Lehmancae33b62015-06-05 09:21:30 -0500146 _LOG_DEBUG("Removing origin: " << destRouter << " from " << name);
147
148 RoutingTableEntry* rteCheck = m_nlsr.getRoutingTable().findRoutingTableEntry(destRouter);
149
150 if (rteCheck != nullptr) {
151 removeEntry(name, *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500152 }
akmhoque157b0a42014-05-13 00:26:37 -0500153 else {
akmhoque53353462014-04-22 08:43:45 -0500154 RoutingTableEntry rte(destRouter);
akmhoque31d1d4b2014-05-05 22:08:14 -0500155 removeEntry(name, rte);
akmhoque53353462014-04-22 08:43:45 -0500156 }
157}
158
159void
akmhoque31d1d4b2014-05-05 22:08:14 -0500160NamePrefixTable::updateWithNewRoute()
akmhoque53353462014-04-22 08:43:45 -0500161{
Vince Lehmancae33b62015-06-05 09:21:30 -0500162 _LOG_DEBUG("Updating table with newly calculated routes");
163
164 // Update each name prefix entry in the Name Prefix Table with newly calculated next hops
165 for (const NamePrefixTableEntry& prefixEntry : m_table) {
166 for (const RoutingTableEntry& routingEntry : prefixEntry.getRteList()) {
167 _LOG_TRACE("Updating next hops to origin: " << routingEntry.getDestination()
168 << " for prefix: " << prefixEntry);
169
akmhoqueb6450b12014-04-24 00:01:03 -0500170 RoutingTableEntry* rteCheck =
Vince Lehmancae33b62015-06-05 09:21:30 -0500171 m_nlsr.getRoutingTable().findRoutingTableEntry(routingEntry.getDestination());
172
173 if (rteCheck != nullptr) {
174 addEntry(prefixEntry.getNamePrefix(), *rteCheck);
akmhoque53353462014-04-22 08:43:45 -0500175 }
akmhoque157b0a42014-05-13 00:26:37 -0500176 else {
Vince Lehmancae33b62015-06-05 09:21:30 -0500177 RoutingTableEntry rte(routingEntry.getDestination());
178 addEntry(prefixEntry.getNamePrefix(), rte);
akmhoque53353462014-04-22 08:43:45 -0500179 }
180 }
181 }
182}
183
184void
akmhoque674b0b12014-05-20 14:33:28 -0500185NamePrefixTable::writeLog()
186{
Vince Lehmancae33b62015-06-05 09:21:30 -0500187 _LOG_DEBUG(*this);
akmhoque674b0b12014-05-20 14:33:28 -0500188}
189
Vince Lehmancae33b62015-06-05 09:21:30 -0500190std::ostream&
191operator<<(std::ostream& os, const NamePrefixTable& table)
192{
193 os << "----------------NPT----------------------\n";
194
195 for (const NamePrefixTableEntry& entry : table) {
196 os << entry << std::endl;
197 }
198
199 return os;
200}
201
202} // namespace nlsr