blob: 532120fc0c1630fdca3ba3d042f027b32f4c0062 [file] [log] [blame]
Alexander Afanasyev78057c32012-07-06 15:18:46 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070021#ifndef _NDN_FIB_ENTRY_H_
22#define _NDN_FIB_ENTRY_H_
Alexander Afanasyev78057c32012-07-06 15:18:46 -070023
24#include "ns3/ptr.h"
25#include "ns3/nstime.h"
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070026#include "ns3/ndn-face.h"
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070027#include "ns3/ndn-name-components.h"
Alexander Afanasyev78057c32012-07-06 15:18:46 -070028
29#include <boost/multi_index_container.hpp>
30#include <boost/multi_index/tag.hpp>
31#include <boost/multi_index/ordered_index.hpp>
32#include <boost/multi_index/composite_key.hpp>
33#include <boost/multi_index/hashed_index.hpp>
34#include <boost/multi_index/random_access_index.hpp>
35#include <boost/multi_index/member.hpp>
36#include <boost/multi_index/mem_fun.hpp>
37
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070038namespace ns3 {
39namespace ndn {
Alexander Afanasyev78057c32012-07-06 15:18:46 -070040
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070041class NameComponents;
42
43namespace fib {
Alexander Afanasyev78057c32012-07-06 15:18:46 -070044
45/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -070046 * \ingroup ndn
Alexander Afanasyev78057c32012-07-06 15:18:46 -070047 * \brief Structure holding various parameters associated with a (FibEntry, Face) tuple
48 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070049class FaceMetric
Alexander Afanasyev78057c32012-07-06 15:18:46 -070050{
51public:
52 /**
53 * @brief Color codes for FIB face status
54 */
55 enum Status { NDN_FIB_GREEN = 1,
56 NDN_FIB_YELLOW = 2,
57 NDN_FIB_RED = 3 };
58public:
59 /**
60 * \brief Metric constructor
61 *
62 * \param face Face for which metric
63 * \param cost Initial value for routing cost
64 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070065 FaceMetric (Ptr<Face> face, int32_t cost)
Alexander Afanasyev78057c32012-07-06 15:18:46 -070066 : m_face (face)
67 , m_status (NDN_FIB_YELLOW)
68 , m_routingCost (cost)
69 , m_sRtt (Seconds (0))
70 , m_rttVar (Seconds (0))
71 { }
72
73 /**
74 * \brief Comparison operator used by boost::multi_index::identity<>
75 */
76 bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070077 operator< (const FaceMetric &fm) const { return *m_face < *fm.m_face; } // return identity of the face
Alexander Afanasyev78057c32012-07-06 15:18:46 -070078
79 /**
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070080 * @brief Comparison between FaceMetric and Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -070081 */
82 bool
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070083 operator< (const Ptr<Face> &face) const { return *m_face < *face; }
Alexander Afanasyev78057c32012-07-06 15:18:46 -070084
85 /**
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070086 * @brief Return Face associated with FaceMetric
Alexander Afanasyev78057c32012-07-06 15:18:46 -070087 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070088 Ptr<Face>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070089 GetFace () const { return m_face; }
90
91 /**
92 * \brief Recalculate smoothed RTT and RTT variation
93 * \param rttSample RTT sample
94 */
95 void
96 UpdateRtt (const Time &rttSample);
97
98private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -070099 friend std::ostream& operator<< (std::ostream& os, const FaceMetric &metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700100public:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700101 Ptr<Face> m_face; ///< Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700102
103 Status m_status; ///< \brief Status of the next hop:
104 ///< - NDN_FIB_GREEN
105 ///< - NDN_FIB_YELLOW
106 ///< - NDN_FIB_RED
107
108 int32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
109
110 Time m_sRtt; ///< \brief smoothed round-trip time
111 Time m_rttVar; ///< \brief round-trip time variation
112};
113
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700114/// @cond include_hidden
115class i_face {};
116class i_metric {};
117class i_nth {};
118/// @endcond
119
120
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700121/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700122 * \ingroup ndn
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700123 * \brief Typedef for indexed face container of Entry
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700124 *
125 * Currently, there are 2 indexes:
126 * - by face (used to find record and update metric)
127 * - by metric (face ranking)
128 * - random access index (for fast lookup on nth face). Order is
129 * maintained manually to be equal to the 'by metric' order
130 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700131struct FaceMetricContainer
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700132{
133 /// @cond include_hidden
134 typedef boost::multi_index::multi_index_container<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700135 FaceMetric,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700136 boost::multi_index::indexed_by<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700137 // For fast access to elements using Face
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700138 boost::multi_index::ordered_unique<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700139 boost::multi_index::tag<i_face>,
140 boost::multi_index::member<FaceMetric,Ptr<Face>,&FaceMetric::m_face>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700141 >,
142
143 // List of available faces ordered by (status, m_routingCost)
144 boost::multi_index::ordered_non_unique<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700145 boost::multi_index::tag<i_metric>,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700146 boost::multi_index::composite_key<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700147 FaceMetric,
148 boost::multi_index::member<FaceMetric,FaceMetric::Status,&FaceMetric::m_status>,
149 boost::multi_index::member<FaceMetric,int32_t,&FaceMetric::m_routingCost>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700150 >
151 >,
152
153 // To optimize nth candidate selection (sacrifice a little bit space to gain speed)
154 boost::multi_index::random_access<
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700155 boost::multi_index::tag<i_nth>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700156 >
157 >
158 > type;
159 /// @endcond
160};
161
162/**
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700163 * \ingroup ndn
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700164 * \brief Structure for FIB table entry, holding indexed list of
165 * available faces and their respective metrics
166 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700167class Entry : public SimpleRefCount<Entry>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700168{
169public:
170 class NoFaces {}; ///< @brief Exception class for the case when FIB entry is not found
171
172 /**
173 * \brief Constructor
174 * \param prefix smart pointer to the prefix for the FIB entry
175 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700176 Entry (const Ptr<const NameComponents> &prefix)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700177 : m_prefix (prefix)
178 , m_needsProbing (false)
179 { }
180
181 /**
182 * \brief Update status of FIB next hop
183 * \param status Status to set on the FIB entry
184 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700185 void UpdateStatus (Ptr<Face> face, FaceMetric::Status status);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700186
187 /**
188 * \brief Add or update routing metric of FIB next hop
189 *
190 * Initial status of the next hop is set to YELLOW
191 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700192 void AddOrUpdateRoutingMetric (Ptr<Face> face, int32_t metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700193
194 /**
195 * @brief Invalidate face
196 *
197 * Set routing metric on all faces to max and status to RED
198 */
199 void
200 Invalidate ();
201
202 /**
203 * @brief Update RTT averages for the face
204 */
205 void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700206 UpdateFaceRtt (Ptr<Face> face, const Time &sample);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700207
208 /**
209 * \brief Get prefix for the FIB entry
210 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700211 const NameComponents&
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700212 GetPrefix () const { return *m_prefix; }
213
214 /**
215 * \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
216 *
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700217 * throws Entry::NoFaces if m_faces.size()==0
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700218 */
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700219 const FaceMetric &
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700220 FindBestCandidate (uint32_t skip = 0) const;
221
222 /**
223 * @brief Remove record associated with `face`
224 */
225 void
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700226 RemoveFace (const Ptr<Face> &face)
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700227 {
228 m_faces.erase (face);
229 }
230
231private:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700232 friend std::ostream& operator<< (std::ostream& os, const Entry &entry);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700233
234public:
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700235 Ptr<const NameComponents> m_prefix; ///< \brief Prefix of the FIB entry
236 FaceMetricContainer::type m_faces; ///< \brief Indexed list of faces
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700237
238 bool m_needsProbing; ///< \brief flag indicating that probing should be performed
239};
240
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700241std::ostream& operator<< (std::ostream& os, const Entry &entry);
242std::ostream& operator<< (std::ostream& os, const FaceMetric &metric);
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700243
Alexander Afanasyev2b4c9472012-08-09 15:00:38 -0700244} // namespace fib
245} // namespace ndn
246} // namespace ns3
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700247
Alexander Afanasyev4aac5572012-08-09 10:49:55 -0700248#endif // _NDN_FIB_ENTRY_H_