blob: 1baaf6fe859ed5371efbf77f695d1d770cc3a6e5 [file] [log] [blame]
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -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
21#ifndef _CCNX_FIB_H_
22#define _CCNX_FIB_H_
23
Alexander Afanasyev161a5c42012-04-17 15:14:04 -070024#include "ccnx-name-components-hash-helper.h"
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070025#include "ccnx-face.h"
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070026#include "ccnx.h"
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070027#include "ns3/nstime.h"
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070028#include "ns3/simple-ref-count.h"
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -070029#include "ns3/node.h"
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070030
31#include <boost/multi_index_container.hpp>
32#include <boost/multi_index/tag.hpp>
33#include <boost/multi_index/ordered_index.hpp>
34#include <boost/multi_index/composite_key.hpp>
35#include <boost/multi_index/hashed_index.hpp>
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070036#include <boost/multi_index/random_access_index.hpp>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070037#include <boost/multi_index/member.hpp>
38#include <boost/multi_index/mem_fun.hpp>
39
40#include <iostream>
41
42namespace ns3 {
43
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070044class CcnxInterestHeader;
45
46/**
47 * \ingroup ccnx
48 * \brief Structure holding various parameters associated with a (FibEntry, Face) tuple
49 */
50class CcnxFibFaceMetric
51{
52public:
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -070053 /**
54 * @brief Color codes for FIB face status
55 */
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070056 enum Status { NDN_FIB_GREEN = 1,
57 NDN_FIB_YELLOW = 2,
58 NDN_FIB_RED = 3 };
59public:
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070060 /**
61 * \brief Metric constructor
62 *
63 * \param face Face for which metric
64 * \param cost Initial value for routing cost
65 */
Alexander Afanasyevef056552012-01-20 16:19:12 -080066 CcnxFibFaceMetric (Ptr<CcnxFace> face, int32_t cost)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070067 : m_face (face)
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070068 , m_status (NDN_FIB_YELLOW)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070069 , m_routingCost (cost)
70 , m_sRtt (Seconds (0))
71 , m_rttVar (Seconds (0))
72 { }
73
74 /**
75 * \brief Comparison operator used by boost::multi_index::identity<>
76 */
77 bool
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070078 operator< (const CcnxFibFaceMetric &fm) const { return *m_face < *fm.m_face; } // return identity of the face
79
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -070080 /**
81 * @brief Comparison between CcnxFibFaceMetric and CcnxFace
82 */
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070083 bool
84 operator< (const Ptr<CcnxFace> &face) const { return *m_face < *face; }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070085
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -070086 /**
87 * @brief Return CcnxFace associated with CcnxFibFaceMetric
88 */
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070089 Ptr<CcnxFace>
90 GetFace () const { return m_face; }
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070091
92 /**
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080093 * \brief Recalculate smoothed RTT and RTT variation
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070094 * \param rttSample RTT sample
95 */
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080096 void
97 UpdateRtt (const Time &rttSample);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070098
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070099private:
100 friend std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric);
101public:
102 Ptr<CcnxFace> m_face; ///< Face
103
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700104 Status m_status; ///< \brief Status of the next hop:
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800105 ///< - NDN_FIB_GREEN
106 ///< - NDN_FIB_YELLOW
107 ///< - NDN_FIB_RED
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700108
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700109 int32_t m_routingCost; ///< \brief routing protocol cost (interpretation of the value depends on the underlying routing protocol)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700110
111 Time m_sRtt; ///< \brief smoothed round-trip time
112 Time m_rttVar; ///< \brief round-trip time variation
113};
114
115/**
116 * \ingroup ccnx
117 * \brief Typedef for indexed face container of CcnxFibEntry
118 *
119 * Currently, there are 2 indexes:
120 * - by face (used to find record and update metric)
121 * - by metric (face ranking)
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700122 * - random access index (for fast lookup on nth face). Order is
123 * maintained manually to be equal to the 'by metric' order
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700124 */
125struct CcnxFibFaceMetricContainer
126{
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700127 /// @cond include_hidden
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700128 typedef boost::multi_index::multi_index_container<
129 CcnxFibFaceMetric,
130 boost::multi_index::indexed_by<
131 // For fast access to elements using CcnxFace
132 boost::multi_index::ordered_unique<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700133 boost::multi_index::tag<__ccnx_private::i_face>,
134 boost::multi_index::member<CcnxFibFaceMetric,Ptr<CcnxFace>,&CcnxFibFaceMetric::m_face>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700135 >,
136
137 // List of available faces ordered by (status, m_routingCost)
138 boost::multi_index::ordered_non_unique<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700139 boost::multi_index::tag<__ccnx_private::i_metric>,
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700140 boost::multi_index::composite_key<
141 CcnxFibFaceMetric,
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700142 boost::multi_index::member<CcnxFibFaceMetric,CcnxFibFaceMetric::Status,&CcnxFibFaceMetric::m_status>,
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700143 boost::multi_index::member<CcnxFibFaceMetric,int32_t,&CcnxFibFaceMetric::m_routingCost>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700144 >
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700145 >,
146
147 // To optimize nth candidate selection (sacrifice a little bit space to gain speed)
148 boost::multi_index::random_access<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700149 boost::multi_index::tag<__ccnx_private::i_nth>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700150 >
151 >
152 > type;
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700153 /// @endcond
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700154};
155
156/**
157 * \ingroup ccnx
158 * \brief Structure for FIB table entry, holding indexed list of
159 * available faces and their respective metrics
160 */
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700161class CcnxFibEntry // : public SimpleRefCount<CcnxFibEntry>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700162{
163public:
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700164 class NoFaces {}; ///< @brief Exception class for the case when FIB entry is not found
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800165
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700166 /**
167 * \brief Constructor
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700168 * \param prefix smart pointer to the prefix for the FIB entry
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700169 */
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700170 CcnxFibEntry (const Ptr<const CcnxNameComponents> &prefix)
171 : m_prefix (prefix)
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700172 , m_needsProbing (false)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700173 { }
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700174
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700175 /**
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800176 * \brief Update status of FIB next hop
177 * \param status Status to set on the FIB entry
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700178 */
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800179 void UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700180
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800181 /**
182 * \brief Add or update routing metric of FIB next hop
183 *
184 * Initial status of the next hop is set to YELLOW
185 */
186 void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700187
188 /**
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700189 * @brief Invalidate face
190 *
191 * Set routing metric on all faces to max and status to RED
192 */
193 void
194 Invalidate ();
195
196 /**
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800197 * @brief Update RTT averages for the face
198 */
199 void
200 UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample);
201
202 /**
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700203 * \brief Get prefix for the FIB entry
204 */
205 const CcnxNameComponents&
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700206 GetPrefix () const { return *m_prefix; }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700207
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700208 /**
209 * \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800210 *
211 * throws CcnxFibEntry::NoFaces if m_faces.size()==0
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700212 */
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800213 const CcnxFibFaceMetric &
214 FindBestCandidate (uint32_t skip = 0) const;
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800215
216 /**
217 * @brief Remove record associated with `face`
218 */
219 void
220 RemoveFace (const Ptr<CcnxFace> &face)
221 {
222 m_faces.erase (face);
223 }
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700224
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700225private:
226 friend std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
227
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700228public:
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700229 Ptr<const CcnxNameComponents> m_prefix; ///< \brief Prefix of the FIB entry
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700230 CcnxFibFaceMetricContainer::type m_faces; ///< \brief Indexed list of faces
231
232 bool m_needsProbing; ///< \brief flag indicating that probing should be performed
233};
234
235///////////////////////////////////////////////////////////////////////////////
236///////////////////////////////////////////////////////////////////////////////
237
238/**
239 * \ingroup ccnx
240 * \brief Typedef for indexed container for FIB entries
241 *
242 * Currently, there is only one index
243 * - by prefix hash, which is used to perform prefix match
244 */
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700245struct CcnxFibEntryContainer
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700246{
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700247 /// @cond include_hidden
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700248 typedef boost::multi_index::multi_index_container<
249 CcnxFibEntry,
250 boost::multi_index::indexed_by<
251 // For fast access to elements using CcnxFace
252 boost::multi_index::hashed_unique<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700253 boost::multi_index::tag<__ccnx_private::i_prefix>,
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700254 boost::multi_index::const_mem_fun<CcnxFibEntry,
255 const CcnxNameComponents&,
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700256 &CcnxFibEntry::GetPrefix>,
Alexander Afanasyev71ed2382012-07-06 11:37:41 -0700257 CcnxPrefixHash>
Alexander Afanasyev07827182011-12-13 01:07:32 -0800258 >
259 > type;
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700260 /// @endcond
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700261};
262
263/**
264 * \ingroup ccnx
265 * \brief Class implementing FIB functionality
266 */
Alexander Afanasyev07827182011-12-13 01:07:32 -0800267class CcnxFib : public Object
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700268{
269public:
Alexander Afanasyevf034cbd2012-06-29 14:28:31 -0700270 typedef CcnxFibEntryContainer::type::iterator iterator;
271
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700272 /**
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700273 * \brief Interface ID
274 *
275 * \return interface ID
276 */
277 static TypeId GetTypeId ();
278
279 /**
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700280 * \brief Constructor
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700281 */
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700282 CcnxFib ();
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700283
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700284 /**
285 * \brief Perform longest prefix match
286 *
287 * \todo Implement exclude filters
288 *
289 * \param interest Interest packet header
Alexander Afanasyev8accdf62011-09-20 11:33:59 -0700290 * \returns If entry found a valid iterator will be returned, otherwise end ()
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700291 */
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700292 CcnxFibEntryContainer::type::iterator
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700293 LongestPrefixMatch (const CcnxInterestHeader &interest) const;
294
295 /**
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700296 * \brief Add or update FIB entry
297 *
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700298 * If the entry exists, metric will be updated. Otherwise, new entry will be created
299 *
300 * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
301 *
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700302 * @param name Prefix
303 * @param face Forwarding face
304 * @param metric Routing metric
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700305 */
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700306 CcnxFibEntryContainer::type::iterator
307 Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700308
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800309 /**
Alexander Afanasyev8e2f1122012-04-17 15:01:11 -0700310 * \brief Add or update FIB entry using smart pointer to prefix
311 *
312 * If the entry exists, metric will be updated. Otherwise, new entry will be created
313 *
314 * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
315 *
316 * @param name Smart pointer to prefix
317 * @param face Forwarding face
318 * @param metric Routing metric
319 */
320 CcnxFibEntryContainer::type::iterator
321 Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric);
322
323 /**
324 * @brief Remove FIB entry
325 *
326 * ! ATTENTION ! Use with caution. All PIT entries referencing the corresponding FIB entry will become invalid.
327 * So, simulation may crash.
328 *
329 * @param name Smart pointer to prefix
330 */
331 void
332 Remove (const Ptr<const CcnxNameComponents> &prefix);
333
334 /**
335 * @brief Invalidate FIB entry ("Safe" version of Remove)
336 *
337 * All faces for the entry will be assigned maximum routing metric and NDN_FIB_RED status
338 * @param name Smart pointer to prefix
339 */
340 void
341 Invalidate (const Ptr<const CcnxNameComponents> &prefix);
342
343 /**
344 * @brief Invalidate all FIB entries
345 */
346 void
347 InvalidateAll ();
348
349 /**
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800350 * @brief Remove reference to a face from the entry. If entry had only this face, the whole
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800351 * entry will be removed
352 */
353 void
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800354 Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face);
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800355
356 /**
357 * @brief Remove all references to a face from FIB. If for some enty that face was the only element,
358 * this FIB entry will be removed.
359 */
360 void
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800361 RemoveFromAll (Ptr<CcnxFace> face);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700362
Alexander Afanasyev07827182011-12-13 01:07:32 -0800363public:
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700364 CcnxFibEntryContainer::type m_fib; ///< @brief Internal container
Alexander Afanasyev07827182011-12-13 01:07:32 -0800365
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700366protected:
367 // inherited from Object class
Alexander Afanasyevb4fee8b2012-06-06 12:54:26 -0700368 virtual void NotifyNewAggregate (); ///< @brief Notify when object is aggregated
369 virtual void DoDispose (); ///< @brief Perform cleanup
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700370
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700371private:
372 friend std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700373 CcnxFib(const CcnxFib&) {} ; ///< \brief copy constructor is disabled
374
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700375private:
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700376 Ptr<Node> m_node;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700377};
378
379///////////////////////////////////////////////////////////////////////////////
380///////////////////////////////////////////////////////////////////////////////
381
382std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
383std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
384std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric);
385
386} // namespace ns3
387
388#endif /* NDN_FIB_H */