| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /* |
| * Copyright (c) 2014-2022, Regents of the University of California, |
| * Arizona Board of Regents, |
| * Colorado State University, |
| * University Pierre & Marie Curie, Sorbonne University, |
| * Washington University in St. Louis, |
| * Beijing Institute of Technology, |
| * The University of Memphis. |
| * |
| * This file is part of NFD (Named Data Networking Forwarding Daemon). |
| * See AUTHORS.md for complete list of NFD authors and contributors. |
| * |
| * NFD is free software: you can redistribute it and/or modify it under the terms |
| * of the GNU General Public License as published by the Free Software Foundation, |
| * either version 3 of the License, or (at your option) any later version. |
| * |
| * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
| * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| * PURPOSE. See the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along with |
| * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| |
| #ifndef NFD_DAEMON_RIB_RIB_ENTRY_HPP |
| #define NFD_DAEMON_RIB_RIB_ENTRY_HPP |
| |
| #include "route.hpp" |
| |
| #include <list> |
| |
| namespace nfd::rib { |
| |
| /** |
| * \brief Represents a RIB entry, which contains one or more Routes with the same prefix. |
| */ |
| class RibEntry : public std::enable_shared_from_this<RibEntry> |
| { |
| public: |
| using RouteList = std::list<Route>; |
| using iterator = RouteList::iterator; |
| using const_iterator = RouteList::const_iterator; |
| |
| void |
| setName(const Name& prefix); |
| |
| const Name& |
| getName() const; |
| |
| shared_ptr<RibEntry> |
| getParent() const; |
| |
| bool |
| hasParent() const; |
| |
| void |
| addChild(shared_ptr<RibEntry> child); |
| |
| void |
| removeChild(shared_ptr<RibEntry> child); |
| |
| const std::list<shared_ptr<RibEntry>>& |
| getChildren() const; |
| |
| bool |
| hasChildren() const; |
| |
| /** \brief inserts a new route into the entry's route list |
| * If another route already exists with the same faceId and origin, |
| * the new route is not inserted. |
| * \return a pair, whose first element is the iterator to the newly |
| * inserted element if the insert succeeds and to the |
| * previously-existing element otherwise, and whose second element |
| * is true if the insert succeeds and false otherwise. |
| */ |
| std::pair<RibEntry::iterator, bool> |
| insertRoute(const Route& route); |
| |
| /** \brief erases a Route with the same faceId and origin |
| */ |
| void |
| eraseRoute(const Route& route); |
| |
| /** \brief erases a Route with the passed iterator |
| * \return{ an iterator to the element that followed the erased iterator } |
| */ |
| iterator |
| eraseRoute(RouteList::iterator route); |
| |
| bool |
| hasFaceId(uint64_t faceId) const; |
| |
| const RouteList& |
| getRoutes() const; |
| |
| size_t |
| getNRoutes() const; |
| |
| iterator |
| findRoute(const Route& route); |
| |
| const_iterator |
| findRoute(const Route& route) const; |
| |
| bool |
| hasRoute(const Route& route); |
| |
| void |
| addInheritedRoute(const Route& route); |
| |
| void |
| removeInheritedRoute(const Route& route); |
| |
| /** \brief Returns the routes this namespace has inherited. |
| * The inherited routes returned represent inherited routes this namespace has in the FIB. |
| * \return{ routes inherited by this namespace } |
| */ |
| const RouteList& |
| getInheritedRoutes() const; |
| |
| /** \brief Finds an inherited route with a matching face ID. |
| * \return{ An iterator to the matching route if one is found; |
| * otherwise, an iterator to the end of the entry's |
| * inherited route list } |
| */ |
| RouteList::const_iterator |
| findInheritedRoute(const Route& route) const; |
| |
| /** \brief Determines if the entry has an inherited route with a matching face ID. |
| * \return{ True, if a matching inherited route is found; otherwise, false. } |
| */ |
| bool |
| hasInheritedRoute(const Route& route) const; |
| |
| bool |
| hasCapture() const; |
| |
| /** \brief Determines if the entry has an inherited route with the passed |
| * face ID and its child inherit flag set. |
| * \return{ True, if a matching inherited route is found; otherwise, false. } |
| */ |
| bool |
| hasChildInheritOnFaceId(uint64_t faceId) const; |
| |
| /** \brief Returns the route with the lowest cost that has the passed face ID. |
| * \return{ The route with the lowest cost that has the passed face ID} |
| */ |
| const Route* |
| getRouteWithLowestCostByFaceId(uint64_t faceId) const; |
| |
| const Route* |
| getRouteWithSecondLowestCostByFaceId(uint64_t faceId) const; |
| |
| /** \brief Returns the route with the lowest cost that has the passed face ID |
| * and its child inherit flag set. |
| * \return{ The route with the lowest cost that has the passed face ID |
| * and its child inherit flag set } |
| */ |
| const Route* |
| getRouteWithLowestCostAndChildInheritByFaceId(uint64_t faceId) const; |
| |
| /** \brief Retrieve a prefix announcement suitable for readvertising this route. |
| * |
| * If one or more routes in this RIB entry contains a prefix announcement, this method returns |
| * the announcement from the route that expires last. |
| * |
| * If this RIB entry does not have a route containing a prefix announcement, this method creates |
| * a new announcement. Its expiration period reflects the remaining lifetime of this RIB entry, |
| * confined within [\p minExpiration, \p maxExpiration] range. The caller is expected to sign |
| * this announcement. |
| * |
| * \warning (minExpiration > maxExpiration) triggers undefined behavior. |
| */ |
| ndn::PrefixAnnouncement |
| getPrefixAnnouncement(time::milliseconds minExpiration = 15_s, |
| time::milliseconds maxExpiration = 1_h) const; |
| |
| const_iterator |
| begin() const; |
| |
| const_iterator |
| end() const; |
| |
| iterator |
| begin(); |
| |
| iterator |
| end(); |
| |
| private: |
| void |
| setParent(shared_ptr<RibEntry> parent); |
| |
| private: |
| Name m_name; |
| std::list<shared_ptr<RibEntry>> m_children; |
| shared_ptr<RibEntry> m_parent; |
| RouteList m_routes; |
| RouteList m_inheritedRoutes; |
| |
| /** \brief The number of routes on this namespace with the capture flag set. |
| * |
| * This count is used to check if the namespace will block inherited routes. |
| * If the number is greater than zero, a route on the namespace has its capture |
| * flag set which means the namespace should not inherit any routes. |
| */ |
| uint64_t m_nRoutesWithCaptureSet = 0; |
| }; |
| |
| inline void |
| RibEntry::setName(const Name& prefix) |
| { |
| m_name = prefix; |
| } |
| |
| inline const Name& |
| RibEntry::getName() const |
| { |
| return m_name; |
| } |
| |
| inline void |
| RibEntry::setParent(shared_ptr<RibEntry> parent) |
| { |
| m_parent = std::move(parent); |
| } |
| |
| inline shared_ptr<RibEntry> |
| RibEntry::getParent() const |
| { |
| return m_parent; |
| } |
| |
| inline const std::list<shared_ptr<RibEntry>>& |
| RibEntry::getChildren() const |
| { |
| return m_children; |
| } |
| |
| inline const RibEntry::RouteList& |
| RibEntry::getRoutes() const |
| { |
| return m_routes; |
| } |
| |
| inline const RibEntry::RouteList& |
| RibEntry::getInheritedRoutes() const |
| { |
| return m_inheritedRoutes; |
| } |
| |
| inline RibEntry::const_iterator |
| RibEntry::begin() const |
| { |
| return m_routes.begin(); |
| } |
| |
| inline RibEntry::const_iterator |
| RibEntry::end() const |
| { |
| return m_routes.end(); |
| } |
| |
| inline RibEntry::iterator |
| RibEntry::begin() |
| { |
| return m_routes.begin(); |
| } |
| |
| inline RibEntry::iterator |
| RibEntry::end() |
| { |
| return m_routes.end(); |
| } |
| |
| std::ostream& |
| operator<<(std::ostream& os, const RibEntry& entry); |
| |
| } // namespace nfd::rib |
| |
| #endif // NFD_DAEMON_RIB_RIB_ENTRY_HPP |