blob: f383961fc393ec794cee9e6e5696a2abe8ec59f2 [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
24#include "hash-helper.h"
25#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 Afanasyev78cf0c92011-09-01 19:57:14 -070053 enum Status { NDN_FIB_GREEN = 1,
54 NDN_FIB_YELLOW = 2,
55 NDN_FIB_RED = 3 };
56public:
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070057 /**
58 * \brief Metric constructor
59 *
60 * \param face Face for which metric
61 * \param cost Initial value for routing cost
62 */
63 CcnxFibFaceMetric (Ptr<CcnxFace> face, int cost)
64 : m_face (face)
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070065 , m_status (NDN_FIB_YELLOW)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070066 , m_routingCost (cost)
67 , m_sRtt (Seconds (0))
68 , m_rttVar (Seconds (0))
69 { }
70
71 /**
72 * \brief Comparison operator used by boost::multi_index::identity<>
73 */
74 bool
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070075 operator< (const CcnxFibFaceMetric &fm) const { return *m_face < *fm.m_face; } // return identity of the face
76
77 bool
78 operator< (const Ptr<CcnxFace> &face) const { return *m_face < *face; }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070079
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070080 Ptr<CcnxFace>
81 GetFace () const { return m_face; }
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070082
83 /**
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080084 * \brief Recalculate smoothed RTT and RTT variation
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070085 * \param rttSample RTT sample
86 */
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080087 void
88 UpdateRtt (const Time &rttSample);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070089
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070090private:
91 friend std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric);
92public:
93 Ptr<CcnxFace> m_face; ///< Face
94
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070095 Status m_status; ///< \brief Status of the next hop:
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080096 ///< - NDN_FIB_GREEN
97 ///< - NDN_FIB_YELLOW
98 ///< - NDN_FIB_RED
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -070099
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700100 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 -0700101
102 Time m_sRtt; ///< \brief smoothed round-trip time
103 Time m_rttVar; ///< \brief round-trip time variation
104};
105
106/**
107 * \ingroup ccnx
108 * \brief Typedef for indexed face container of CcnxFibEntry
109 *
110 * Currently, there are 2 indexes:
111 * - by face (used to find record and update metric)
112 * - by metric (face ranking)
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700113 * - random access index (for fast lookup on nth face). Order is
114 * maintained manually to be equal to the 'by metric' order
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700115 */
116struct CcnxFibFaceMetricContainer
117{
118 typedef boost::multi_index::multi_index_container<
119 CcnxFibFaceMetric,
120 boost::multi_index::indexed_by<
121 // For fast access to elements using CcnxFace
122 boost::multi_index::ordered_unique<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700123 boost::multi_index::tag<__ccnx_private::i_face>,
124 boost::multi_index::member<CcnxFibFaceMetric,Ptr<CcnxFace>,&CcnxFibFaceMetric::m_face>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700125 >,
126
127 // List of available faces ordered by (status, m_routingCost)
128 boost::multi_index::ordered_non_unique<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700129 boost::multi_index::tag<__ccnx_private::i_metric>,
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700130 boost::multi_index::composite_key<
131 CcnxFibFaceMetric,
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700132 boost::multi_index::member<CcnxFibFaceMetric,CcnxFibFaceMetric::Status,&CcnxFibFaceMetric::m_status>,
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700133 boost::multi_index::member<CcnxFibFaceMetric,int32_t,&CcnxFibFaceMetric::m_routingCost>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700134 >
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700135 >,
136
137 // To optimize nth candidate selection (sacrifice a little bit space to gain speed)
138 boost::multi_index::random_access<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700139 boost::multi_index::tag<__ccnx_private::i_nth>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700140 >
141 >
142 > type;
143};
144
145/**
146 * \ingroup ccnx
147 * \brief Structure for FIB table entry, holding indexed list of
148 * available faces and their respective metrics
149 */
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700150class CcnxFibEntry : public SimpleRefCount<CcnxFibEntry>
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700151{
152public:
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800153 class NoFaces {};
154
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700155 /**
156 * \brief Constructor
157 * \param prefix Prefix for the FIB entry
158 */
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700159 CcnxFibEntry (const CcnxNameComponents &prefix)
160 : m_prefix (Create<CcnxNameComponents> (prefix))
161 , m_needsProbing (false)
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700162 { }
163
164 /**
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800165 * \brief Update status of FIB next hop
166 * \param status Status to set on the FIB entry
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700167 */
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800168 void UpdateStatus (Ptr<CcnxFace> face, CcnxFibFaceMetric::Status status);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700169
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800170 /**
171 * \brief Add or update routing metric of FIB next hop
172 *
173 * Initial status of the next hop is set to YELLOW
174 */
175 void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700176
177 /**
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800178 * @brief Update RTT averages for the face
179 */
180 void
181 UpdateFaceRtt (Ptr<CcnxFace> face, const Time &sample);
182
183 /**
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700184 * \brief Get prefix for the FIB entry
185 */
186 const CcnxNameComponents&
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700187 GetPrefix () const { return *m_prefix; }
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700188
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700189 /**
190 * \brief Find "best route" candidate, skipping `skip' first candidates (modulo # of faces)
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800191 *
192 * throws CcnxFibEntry::NoFaces if m_faces.size()==0
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700193 */
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800194 const CcnxFibFaceMetric &
195 FindBestCandidate (uint32_t skip = 0) const;
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800196
197 /**
198 * @brief Remove record associated with `face`
199 */
200 void
201 RemoveFace (const Ptr<CcnxFace> &face)
202 {
203 m_faces.erase (face);
204 }
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700205
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700206private:
207 friend std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
208
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700209public:
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700210 Ptr<CcnxNameComponents> m_prefix; ///< \brief Prefix of the FIB entry
211 CcnxFibFaceMetricContainer::type m_faces; ///< \brief Indexed list of faces
212
213 bool m_needsProbing; ///< \brief flag indicating that probing should be performed
214};
215
216///////////////////////////////////////////////////////////////////////////////
217///////////////////////////////////////////////////////////////////////////////
218
219/**
220 * \ingroup ccnx
221 * \brief Typedef for indexed container for FIB entries
222 *
223 * Currently, there is only one index
224 * - by prefix hash, which is used to perform prefix match
225 */
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700226struct CcnxFibEntryContainer
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700227{
228 typedef boost::multi_index::multi_index_container<
229 CcnxFibEntry,
230 boost::multi_index::indexed_by<
231 // For fast access to elements using CcnxFace
232 boost::multi_index::hashed_unique<
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -0700233 boost::multi_index::tag<__ccnx_private::i_prefix>,
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700234 boost::multi_index::const_mem_fun<CcnxFibEntry,
235 const CcnxNameComponents&,
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700236 &CcnxFibEntry::GetPrefix>,
Alexander Afanasyev07827182011-12-13 01:07:32 -0800237 CcnxPrefixHash>,
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700238
Alexander Afanasyev07827182011-12-13 01:07:32 -0800239 boost::multi_index::random_access<
240 boost::multi_index::tag<__ccnx_private::i_nth>
241 >
242 >
243 > type;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700244};
245
246/**
247 * \ingroup ccnx
248 * \brief Class implementing FIB functionality
249 */
Alexander Afanasyev07827182011-12-13 01:07:32 -0800250class CcnxFib : public Object
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700251{
252public:
253 /**
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700254 * \brief Interface ID
255 *
256 * \return interface ID
257 */
258 static TypeId GetTypeId ();
259
260 /**
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700261 * \brief Constructor
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700262 */
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700263 CcnxFib ();
264 // * \param node smart pointer to Ccnx stack associated with particular node
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700265
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700266 /**
267 * \brief Perform longest prefix match
268 *
269 * \todo Implement exclude filters
270 *
271 * \param interest Interest packet header
Alexander Afanasyev8accdf62011-09-20 11:33:59 -0700272 * \returns If entry found a valid iterator will be returned, otherwise end ()
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700273 */
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700274 CcnxFibEntryContainer::type::iterator
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700275 LongestPrefixMatch (const CcnxInterestHeader &interest) const;
276
277 /**
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700278 * \brief Add or update FIB entry
279 *
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700280 * If the entry exists, metric will be updated. Otherwise, new entry will be created
281 *
282 * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
283 *
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700284 * @param name Prefix
285 * @param face Forwarding face
286 * @param metric Routing metric
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700287 */
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700288 CcnxFibEntryContainer::type::iterator
289 Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700290
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800291 /**
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800292 * @brief Remove reference to a face from the entry. If entry had only this face, the whole
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800293 * entry will be removed
294 */
295 void
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800296 Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face);
Alexander Afanasyev09c7deb2011-11-23 14:50:10 -0800297
298 /**
299 * @brief Remove all references to a face from FIB. If for some enty that face was the only element,
300 * this FIB entry will be removed.
301 */
302 void
Alexander Afanasyev19426ef2011-11-23 20:55:28 -0800303 RemoveFromAll (Ptr<CcnxFace> face);
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700304
Alexander Afanasyev07827182011-12-13 01:07:32 -0800305 /**
306 * \brief Get number of FIB entry (for python bindings)
307 */
308 uint32_t
309 GetCcnxFibEntryCount () const;
310
311 /**
312 * \brief Get FIB entry by index (for python bindings)
313 */
314 const CcnxFibEntry &
315 GetCcnxFibEntry (uint32_t index);
316
317public:
318 CcnxFibEntryContainer::type m_fib;
319
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700320protected:
321 // inherited from Object class
322 virtual void NotifyNewAggregate ();
323 virtual void DoDispose ();
324
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700325private:
326 friend std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
Alexander Afanasyeva67e28c2011-08-31 21:16:25 -0700327 CcnxFib(const CcnxFib&) {} ; ///< \brief copy constructor is disabled
328
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700329private:
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700330 Ptr<Node> m_node;
Alexander Afanasyev7fd74f92011-08-25 19:40:17 -0700331};
332
333///////////////////////////////////////////////////////////////////////////////
334///////////////////////////////////////////////////////////////////////////////
335
336std::ostream& operator<< (std::ostream& os, const CcnxFib &fib);
337std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
338std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric);
339
340} // namespace ns3
341
342#endif /* NDN_FIB_H */