1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright 2007 University of Washington
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  * Authors:  Craig Dowell (craigdo@ee.washington.edu)
19  *           Tom Henderson (tomhend@u.washington.edu)
20  */
21 
22 #ifndef GLOBAL_ROUTER_INTERFACE_H
23 #define GLOBAL_ROUTER_INTERFACE_H
24 
25 #include <stdint.h>
26 #include <list>
27 #include "ns3/object.h"
28 #include "ns3/ptr.h"
29 #include "ns3/node.h"
30 #include "ns3/channel.h"
31 #include "ns3/ipv4-address.h"
32 #include "ns3/net-device-container.h"
33 #include "ns3/bridge-net-device.h"
34 #include "ns3/global-route-manager.h"
35 #include "ns3/ipv4-routing-table-entry.h"
36 
37 namespace ns3 {
38 
39 class GlobalRouter;
40 class Ipv4GlobalRouting;
41 
42 /**
43  * \ingroup globalrouting
44  *
45  * @brief A single link record for a link state advertisement.
46  *
47  * The GlobalRoutingLinkRecord is modeled after the OSPF link record field of
48  * a Link State Advertisement.  Right now we will only see two types of link
49  * records corresponding to a stub network and a point-to-point link (channel).
50  */
51 class GlobalRoutingLinkRecord
52 {
53 public:
54   friend class GlobalRoutingLSA; //!< Friend class.
55 /**
56  * @enum LinkType
57  * @brief Enumeration of the possible types of Global Routing Link Records.
58  *
59  * These values are defined in the OSPF spec.  We currently only use
60  * PointToPoint and StubNetwork types.
61  */
62   enum LinkType {
63     Unknown = 0,        /**< Uninitialized Link Record */
64     PointToPoint,       /**< Record representing a point to point channel */
65     TransitNetwork,     /**< Unused -- for future OSPF compatibility  */
66     StubNetwork,        /**< Record represents a leaf node network */
67     VirtualLink         /**< Unused -- for future OSPF compatibility  */
68   };
69 
70 /**
71  * @brief Construct an empty ("uninitialized") Global Routing Link Record.
72  *
73  * The Link ID and Link Data Ipv4 addresses are set to "0.0.0.0";
74  * The Link Type is set to Unknown;
75  * The metric is set to 0.
76  */
77   GlobalRoutingLinkRecord ();
78 
79 /**
80  * Construct an initialized Global Routing Link Record.
81  *
82  * @param linkType The type of link record to construct.
83  * @param linkId The link ID for the record.
84  * @param linkData The link data field for the record.
85  * @param metric The metric field for the record.
86  * @see LinkType
87  * @see SetLinkId
88  * @see SetLinkData
89  */
90   GlobalRoutingLinkRecord (
91     LinkType    linkType,
92     Ipv4Address linkId,
93     Ipv4Address linkData,
94     uint16_t    metric);
95 
96 /**
97  * @brief Destroy a Global Routing Link Record.
98  *
99  * Currently does nothing.  Here as a placeholder only.
100  */
101   ~GlobalRoutingLinkRecord ();
102 
103 /**
104  * Get the Link ID field of the Global Routing Link Record.
105  *
106  * For an OSPF type 1 link (PointToPoint) the Link ID will be the Router ID
107  * of the neighboring router.
108  *
109  * For an OSPF type 3 link (StubNetwork), the Link ID will be the adjacent
110  * neighbor's IP address
111  *
112  * @returns The Ipv4Address corresponding to the Link ID field of the record.
113  */
114   Ipv4Address GetLinkId (void) const;
115 
116 /**
117  * @brief Set the Link ID field of the Global Routing Link Record.
118  *
119  * For an OSPF type 1 link (PointToPoint) the Link ID must be the Router ID
120  * of the neighboring router.
121  *
122  * For an OSPF type 3 link (StubNetwork), the Link ID must be the adjacent
123  * neighbor's IP address
124  *
125  * @param addr An Ipv4Address to store in the Link ID field of the record.
126  */
127   void SetLinkId (Ipv4Address addr);
128 
129 /**
130  * @brief Get the Link Data field of the Global Routing Link Record.
131  *
132  * For an OSPF type 1 link (PointToPoint) the Link Data will be the IP
133  * address of the node of the local side of the link.
134  *
135  * For an OSPF type 3 link (StubNetwork), the Link Data will be the
136  * network mask
137  *
138  * @returns The Ipv4Address corresponding to the Link Data field of the record.
139  */
140   Ipv4Address GetLinkData (void) const;
141 
142 /**
143  * @brief Set the Link Data field of the Global Routing Link Record.
144  *
145  * For an OSPF type 1 link (PointToPoint) the Link Data must be the IP
146  * address of the node of the local side of the link.
147  *
148  * For an OSPF type 3 link (StubNetwork), the Link Data must be set to the
149  * network mask
150  *
151  * @param addr An Ipv4Address to store in the Link Data field of the record.
152  */
153   void SetLinkData (Ipv4Address addr);
154 
155 /**
156  * @brief Get the Link Type field of the Global Routing Link Record.
157  *
158  * The Link Type describes the kind of link a given record represents.  The
159  * values are defined by OSPF.
160  *
161  * @see LinkType
162  * @returns The LinkType of the current Global Routing Link Record.
163  */
164   LinkType GetLinkType (void) const;
165 
166 /**
167  * @brief Set the Link Type field of the Global Routing Link Record.
168  *
169  * The Link Type describes the kind of link a given record represents.  The
170  * values are defined by OSPF.
171  *
172  * @see LinkType
173  * @param linkType The new LinkType for the current Global Routing Link Record.
174  */
175   void SetLinkType (LinkType linkType);
176 
177 /**
178  * @brief Get the Metric Data field of the Global Routing Link Record.
179  *
180  * The metric is an abstract cost associated with forwarding a packet across
181  * a link.  A sum of metrics must have a well-defined meaning.  That is, you
182  * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
183  * two hops relate to the cost of sending a packet); rather you should use
184  * something like delay.
185  *
186  * @returns The metric field of the Global Routing Link Record.
187  */
188   uint16_t GetMetric (void) const;
189 
190 /**
191  * @brief Set the Metric Data field of the Global Routing Link Record.
192  *
193  * The metric is an abstract cost associated with forwarding a packet across
194  * a link.  A sum of metrics must have a well-defined meaning.  That is, you
195  * shouldn't use bandwidth as a metric (how does the sum of the bandwidth of
196  * two hops relate to the cost of sending a packet); rather you should use
197  * something like delay.
198  *
199  * @param metric The new metric for the current Global Routing Link Record.
200  */
201   void SetMetric (uint16_t metric);
202 
203 private:
204 /**
205  * m_linkId and m_linkData are defined by OSPF to have different meanings
206  * depending on the type of link a given link records represents.  They work
207  * together.
208  *
209  * For Type 1 link (PointToPoint), set m_linkId to Router ID of
210  * neighboring router.
211  *
212  * For Type 3 link (Stub), set m_linkId to neighbor's IP address
213  */
214   Ipv4Address m_linkId;
215 
216 /**
217  * m_linkId and m_linkData are defined by OSPF to have different meanings
218  * depending on the type of link a given link records represents.  They work
219  * together.
220  *
221  * For Type 1 link (PointToPoint), set m_linkData to local IP address
222  *
223  * For Type 3 link (Stub), set m_linkData to mask
224  */
225   Ipv4Address m_linkData;    // for links to RouterLSA,
226 
227 /**
228  * The type of the Global Routing Link Record.  Defined in the OSPF spec.
229  * We currently only use PointToPoint and StubNetwork types.
230  */
231   LinkType m_linkType;
232 
233 /**
234  * The metric for a given link.
235  *
236  * A metric is abstract cost associated with forwarding a packet across a
237  * link.  A sum of metrics must have a well-defined meaning.  That is, you
238  * shouldn't use bandwidth as a metric (how does the sum of the bandwidth
239  * of two hops relate to the cost of sending a packet); rather you should
240  * use something like delay.
241  */
242   uint16_t m_metric;
243 };
244 
245 /**
246  * @brief a Link State Advertisement (LSA) for a router, used in global
247  * routing.
248  *
249  * Roughly equivalent to a global incarnation of the OSPF link state header
250  * combined with a list of Link Records.  Since it's global, there's
251  * no need for age or sequence number.  See \RFC{2328}, Appendix A.
252  */
253 class GlobalRoutingLSA
254 {
255 public:
256 /**
257  * @enum LSType
258  * @brief corresponds to LS type field of \RFC{2328} OSPF LSA header
259  */
260   enum LSType {
261     Unknown = 0,        /**< Uninitialized Type */
262     RouterLSA,
263     NetworkLSA,
264     SummaryLSA,
265     SummaryLSA_ASBR,
266     ASExternalLSAs
267   };
268 /**
269  * @enum SPFStatus
270  * @brief Enumeration of the possible values of the status flag in the Routing
271  * Link State Advertisements.
272  */
273   enum SPFStatus {
274     LSA_SPF_NOT_EXPLORED = 0,   /**< New vertex not yet considered */
275     LSA_SPF_CANDIDATE,          /**< Vertex is in the SPF candidate queue */
276     LSA_SPF_IN_SPFTREE          /**< Vertex is in the SPF tree */
277   };
278 /**
279  * @brief Create a blank Global Routing Link State Advertisement.
280  *
281  * On completion Ipv4Address variables initialized to 0.0.0.0 and the
282  * list of Link State Records is empty.
283  */
284   GlobalRoutingLSA();
285 
286 /**
287  * @brief Create an initialized Global Routing Link State Advertisement.
288  *
289  * On completion the list of Link State Records is empty.
290  *
291  * @param status The status to of the new LSA.
292  * @param linkStateId The Ipv4Address for the link state ID field.
293  * @param advertisingRtr The Ipv4Address for the advertising router field.
294  */
295   GlobalRoutingLSA(SPFStatus status, Ipv4Address linkStateId,
296                    Ipv4Address advertisingRtr);
297 
298 /**
299  * @brief Copy constructor for a Global Routing Link State Advertisement.
300  *
301  * Takes a piece of memory and constructs a semantically identical copy of
302  * the given LSA.
303  *
304  * @param lsa The existing LSA to be used as the source.
305  */
306   GlobalRoutingLSA (GlobalRoutingLSA& lsa);
307 
308 /**
309  * @brief Destroy an existing Global Routing Link State Advertisement.
310  *
311  * Any Global Routing Link Records present in the list are freed.
312  */
313   ~GlobalRoutingLSA();
314 
315 /**
316  * @brief Assignment operator for a Global Routing Link State Advertisement.
317  *
318  * Takes an existing Global Routing Link State Advertisement and overwrites
319  * it to make a semantically identical copy of a given prototype LSA.
320  *
321  * If there are any Global Routing Link Records present in the existing
322  * LSA, they are freed before the assignment happens.
323  *
324  * @param lsa The existing LSA to be used as the source.
325  * @returns Reference to the overwritten LSA.
326  */
327   GlobalRoutingLSA& operator= (const GlobalRoutingLSA& lsa);
328 
329 /**
330  * @brief Copy any Global Routing Link Records in a given Global Routing Link
331  * State Advertisement to the current LSA.
332  *
333  * Existing Link Records are not deleted -- this is a concatenation of Link
334  * Records.
335  *
336  * @see ClearLinkRecords ()
337  * @param lsa The LSA to copy the Link Records from.
338  */
339   void CopyLinkRecords (const GlobalRoutingLSA& lsa);
340 
341 /**
342  * @brief Add a given Global Routing Link Record to the LSA.
343  *
344  * @param lr The Global Routing Link Record to be added.
345  * @returns The number of link records in the list.
346  */
347   uint32_t AddLinkRecord (GlobalRoutingLinkRecord* lr);
348 
349 /**
350  * @brief Return the number of Global Routing Link Records in the LSA.
351  *
352  * @returns The number of link records in the list.
353  */
354   uint32_t GetNLinkRecords (void) const;
355 
356 /**
357  * @brief Return a pointer to the specified Global Routing Link Record.
358  *
359  * @param n The LSA number desired.
360  * @returns The number of link records in the list.
361  */
362   GlobalRoutingLinkRecord* GetLinkRecord (uint32_t n) const;
363 
364 /**
365  * @brief Release all of the Global Routing Link Records present in the Global
366  * Routing Link State Advertisement and make the list of link records empty.
367  */
368   void ClearLinkRecords (void);
369 
370 /**
371  * @brief Check to see if the list of Global Routing Link Records present in the
372  * Global Routing Link State Advertisement is empty.
373  *
374  * @returns True if the list is empty, false otherwise.
375  */
376   bool IsEmpty (void) const;
377 
378 /**
379  * @brief Print the contents of the Global Routing Link State Advertisement and
380  * any Global Routing Link Records present in the list.  Quite verbose.
381  * @param os the output stream
382  */
383   void Print (std::ostream &os) const;
384 
385 /**
386  * @brief Return the LSType field of the LSA
387  * @returns The LS Type.
388  */
389   LSType GetLSType (void) const;
390 /**
391  * @brief Set the LS type field of the LSA
392  * @param typ the LS Type.
393  */
394   void SetLSType (LSType typ);
395 
396 /**
397  * @brief Get the Link State ID as defined by the OSPF spec.  We always set it
398  * to the router ID of the router making the advertisement.
399  *
400  * @see RoutingEnvironment::AllocateRouterId ()
401  * @see GlobalRouting::GetRouterId ()
402  * @returns The Ipv4Address stored as the link state ID.
403  */
404   Ipv4Address GetLinkStateId (void) const;
405 
406 /**
407  * @brief Set the Link State ID is defined by the OSPF spec.  We always set it
408  * to the router ID of the router making the advertisement.
409  * @param addr IPv4 address which will act as ID
410  * @see RoutingEnvironment::AllocateRouterId ()
411  * @see GlobalRouting::GetRouterId ()
412  */
413   void SetLinkStateId (Ipv4Address addr);
414 
415 /**
416  * @brief Get the Advertising Router as defined by the OSPF spec.  We always
417  * set it to the router ID of the router making the advertisement.
418  *
419  * @see RoutingEnvironment::AllocateRouterId ()
420  * @see GlobalRouting::GetRouterId ()
421  * @returns The Ipv4Address stored as the advertising router.
422  */
423   Ipv4Address GetAdvertisingRouter (void) const;
424 
425 /**
426  * @brief Set the Advertising Router as defined by the OSPF spec.  We always
427  * set it to the router ID of the router making the advertisement.
428  *
429  * @param rtr ID of the router making advertisement
430  * @see RoutingEnvironment::AllocateRouterId ()
431  * @see GlobalRouting::GetRouterId ()
432  */
433   void SetAdvertisingRouter (Ipv4Address  rtr);
434 
435 /**
436  * @brief For a Network LSA, set the Network Mask field that precedes
437  * the list of attached routers.
438  * @param mask the Network Mask field.
439  */
440   void SetNetworkLSANetworkMask (Ipv4Mask mask);
441 
442 /**
443  * @brief For a Network LSA, get the Network Mask field that precedes
444  * the list of attached routers.
445  *
446  * @returns the NetworkLSANetworkMask
447  */
448   Ipv4Mask GetNetworkLSANetworkMask (void) const;
449 
450 /**
451  * @brief Add an attached router to the list in the NetworkLSA
452  *
453  * @param addr The Ipv4Address of the interface on the network link
454  * @returns The number of addresses in the list.
455  */
456   uint32_t AddAttachedRouter (Ipv4Address addr);
457 
458 /**
459  * @brief Return the number of attached routers listed in the NetworkLSA
460  *
461  * @returns The number of attached routers.
462  */
463   uint32_t GetNAttachedRouters (void) const;
464 
465 /**
466  * @brief Return an Ipv4Address corresponding to the specified attached router
467  *
468  * @param n The attached router number desired (number in the list).
469  * @returns The Ipv4Address of the requested router
470  */
471   Ipv4Address GetAttachedRouter (uint32_t n) const;
472 
473 /**
474  * @brief Get the SPF status of the advertisement.
475  *
476  * @see SPFStatus
477  * @returns The SPFStatus of the LSA.
478  */
479   SPFStatus GetStatus (void) const;
480 
481 /**
482  * @brief Set the SPF status of the advertisement
483  * @param status SPF status to set
484  * @see SPFStatus
485  */
486   void SetStatus (SPFStatus status);
487 
488 /**
489  * @brief Get the Node pointer of the node that originated this LSA
490  * @returns Node pointer
491  */
492   Ptr<Node> GetNode (void) const;
493 
494 /**
495  * @brief Set the Node pointer of the node that originated this LSA
496  * @param node Node pointer
497  */
498   void SetNode (Ptr<Node> node);
499 
500 private:
501 /**
502  * The type of the LSA.  Each LSA type has a separate advertisement
503  * format.
504  */
505   LSType m_lsType;
506 /**
507  * The Link State ID is defined by the OSPF spec.  We always set it to the
508  * router ID of the router making the advertisement.
509  *
510  * @see RoutingEnvironment::AllocateRouterId ()
511  * @see GlobalRouting::GetRouterId ()
512  */
513   Ipv4Address  m_linkStateId;
514 
515 /**
516  * The Advertising Router is defined by the OSPF spec.  We always set it to
517  * the router ID of the router making the advertisement.
518  *
519  * @see RoutingEnvironment::AllocateRouterId ()
520  * @see GlobalRouting::GetRouterId ()
521  */
522   Ipv4Address  m_advertisingRtr;
523 
524 /**
525  * A convenience typedef to avoid too much writers cramp.
526  */
527   typedef std::list<GlobalRoutingLinkRecord*> ListOfLinkRecords_t;
528 
529 /**
530  * Each Link State Advertisement contains a number of Link Records that
531  * describe the kinds of links that are attached to a given node.  We
532  * consider PointToPoint and StubNetwork links.
533  *
534  * m_linkRecords is an STL list container to hold the Link Records that have
535  * been discovered and prepared for the advertisement.
536  *
537  * @see GlobalRouting::DiscoverLSAs ()
538  */
539   ListOfLinkRecords_t m_linkRecords;
540 
541 /**
542  * Each Network LSA contains the network mask of the attached network
543  */
544   Ipv4Mask m_networkLSANetworkMask;
545 
546 /**
547  * A convenience typedef to avoid too much writers cramp.
548  */
549   typedef std::list<Ipv4Address> ListOfAttachedRouters_t;
550 
551 /**
552  * Each Network LSA contains a list of attached routers
553  *
554  * m_attachedRouters is an STL list container to hold the addresses that have
555  * been discovered and prepared for the advertisement.
556  *
557  * @see GlobalRouting::DiscoverLSAs ()
558  */
559   ListOfAttachedRouters_t m_attachedRouters;
560 
561 /**
562  * This is a tristate flag used internally in the SPF computation to mark
563  * if an SPFVertex (a data structure representing a vertex in the SPF tree
564  * -- a router) is new, is a candidate for a shortest path, or is in its
565  * proper position in the tree.
566  */
567   SPFStatus m_status;
568   uint32_t m_node_id; //!< node ID
569 };
570 
571 /**
572  * \brief Stream insertion operator.
573  *
574  * \param os the reference to the output stream
575  * \param lsa the LSA
576  * \returns the reference to the output stream
577  */
578 std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa);
579 
580 /**
581  * @brief An interface aggregated to a node to provide global routing info
582  *
583  * An interface aggregated to a node that provides global routing information
584  * to a global route manager.  The presence of the interface indicates that
585  * the node is a router.  The interface is the mechanism by which the router
586  * advertises its connections to neighboring routers.  We're basically
587  * allowing the route manager to query for link state advertisements.
588  */
589 class GlobalRouter : public Object
590 {
591 public:
592   /**
593    * \brief Get the type ID.
594    * \return the object TypeId
595    */
596   static TypeId GetTypeId (void);
597 
598 /**
599  * @brief Create a Global Router class
600  */
601   GlobalRouter ();
602 
603   /**
604    * \brief Set the specific Global Routing Protocol to be used
605    * \param routing the routing protocol
606    */
607   void SetRoutingProtocol (Ptr<Ipv4GlobalRouting> routing);
608 
609   /**
610    * \brief Get the specific Global Routing Protocol used
611    * \returns the routing protocol
612    */
613   Ptr<Ipv4GlobalRouting> GetRoutingProtocol (void);
614 
615 /**
616  * @brief Get the Router ID associated with this Global Router.
617  *
618  * The Router IDs are allocated in the RoutingEnvironment -- one per Router,
619  * starting at 0.0.0.1 and incrementing with each instantiation of a router.
620  *
621  * @see RoutingEnvironment::AllocateRouterId ()
622  * @returns The Router ID associated with the Global Router.
623  */
624   Ipv4Address GetRouterId (void) const;
625 
626 /**
627  * @brief Walk the connected channels, discover the adjacent routers and build
628  * the associated number of Global Routing Link State Advertisements that
629  * this router can export.
630  *
631  * This is a fairly expensive operation in that every time it is called
632  * the current list of LSAs is built by walking connected point-to-point
633  * channels and peeking into adjacent IPV4 stacks to get address information.
634  * This is done to allow for limited dynamics of the Global Routing
635  * environment.  By that we mean that you can discover new link state
636  * advertisements after a network topology change by calling DiscoverLSAs
637  * and then by reading those advertisements.
638  *
639  * @see GlobalRoutingLSA
640  * @see GlobalRouter::GetLSA ()
641  * @returns The number of Global Routing Link State Advertisements.
642  */
643   uint32_t DiscoverLSAs (void);
644 
645 /**
646  * @brief Get the Number of Global Routing Link State Advertisements that this
647  * router can export.
648  *
649  * To get meaningful information you must have previously called DiscoverLSAs.
650  * After you know how many LSAs are present in the router, you may call
651  * GetLSA () to retrieve the actual advertisement.
652  *
653  * @see GlobalRouterLSA
654  * @see GlobalRouting::DiscoverLSAs ()
655  * @see GlobalRouting::GetLSA ()
656  * @returns The number of Global Routing Link State Advertisements.
657  */
658   uint32_t GetNumLSAs (void) const;
659 
660 /**
661  * @brief Get a Global Routing Link State Advertisements that this router has
662  * said that it can export.
663  *
664  * This is a fairly inexpensive expensive operation in that the hard work
665  * was done in GetNumLSAs.  We just copy the indicated Global Routing Link
666  * State Advertisement into the requested GlobalRoutingLSA object.
667  *
668  * You must call GlobalRouter::GetNumLSAs before calling this method in
669  * order to discover the adjacent routers and build the advertisements.
670  * GetNumLSAs will return the number of LSAs this router advertises.
671  * The parameter n (requested LSA number) must be in the range 0 to
672  * GetNumLSAs() - 1.
673  *
674  * @see GlobalRoutingLSA
675  * @see GlobalRouting::GetNumLSAs ()
676  * @param n The index number of the LSA you want to read.
677  * @param lsa The GlobalRoutingLSA class to receive the LSA information.
678  * @returns The number of Global Router Link State Advertisements.
679  */
680   bool GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const;
681 
682 /**
683  * @brief Inject a route to be circulated to other routers as an external
684  * route
685  *
686  * @param network The Network to inject
687  * @param networkMask The Network Mask to inject
688  */
689   void InjectRoute (Ipv4Address network, Ipv4Mask networkMask);
690 
691 /**
692  * @brief Get the number of injected routes that have been added
693  * to the routing table.
694  * @return number of injected routes
695  */
696   uint32_t GetNInjectedRoutes (void);
697 
698 /**
699  * @brief Return the injected route indexed by i
700  * @param i the index of the route
701  * @return a pointer to that Ipv4RoutingTableEntry is returned
702  *
703  */
704   Ipv4RoutingTableEntry *GetInjectedRoute (uint32_t i);
705 
706 /**
707  * @brief Withdraw a route from the global unicast routing table.
708  *
709  * Calling this function will cause all indexed routes numbered above
710  * index i to have their index decremented.  For instance, it is possible to
711  * remove N injected routes by calling RemoveInjectedRoute (0) N times.
712  *
713  * @param i The index (into the injected routing list) of the route to remove.
714  *
715  * @see GlobalRouter::WithdrawRoute ()
716  */
717   void RemoveInjectedRoute (uint32_t i);
718 
719 /**
720  * @brief Withdraw a route from the global unicast routing table.
721  *
722  * @param network The Network to withdraw
723  * @param networkMask The Network Mask to withdraw
724  * @return whether the operation succeeded (will return false if no such route)
725  *
726  * @see GlobalRouter::RemoveInjectedRoute ()
727  */
728   bool WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask);
729 
730 private:
731   virtual ~GlobalRouter ();
732 
733   /**
734    * \brief Clear list of LSAs
735    */
736   void ClearLSAs (void);
737 
738   /**
739    * \brief Link through the given channel and find the net device that's on the other end.
740    *
741    * This only makes sense with a point-to-point channel.
742    *
743    * \param nd outgoing NetDevice
744    * \param ch channel
745    * \returns the NetDevice on the other end
746    */
747   Ptr<NetDevice> GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const;
748 
749   /**
750    * \brief Given a node and a net device, find an IPV4 interface index that corresponds
751    *        to that net device.
752    *
753    * This function may fail for various reasons.  If a node
754    * does not have an internet stack (for example if it is a bridge) we won't have
755    * an IPv4 at all.  If the node does have a stack, but the net device in question
756    * is bridged, there will not be an interface associated directly with the device.
757    *
758    * \param node the node
759    * \param nd outgoing NetDevice
760    * \param index the IPV4 interface index
761    * \returns true on success
762    */
763   bool FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
764 
765   /**
766    * \brief Finds a designated router
767    *
768    * Given a local net device, we need to walk the channel to which the net device is
769    * attached and look for nodes with GlobalRouter interfaces on them (one of them
770    * will be us).  Of these, the router with the lowest IP address on the net device
771    * connecting to the channel becomes the designated router for the link.
772    *
773    * \param ndLocal local NetDevice to scan
774    * \returns the IP address of the designated router
775    */
776   Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal) const;
777 
778   /**
779    * \brief Checks for the presence of another router on the NetDevice
780    *
781    * Given a node and an attached net device, take a look off in the channel to
782    * which the net device is attached and look for a node on the other side
783    * that has a GlobalRouter interface aggregated.
784    *
785    * \param nd NetDevice to scan
786    * \returns true if a router is found
787    */
788   bool AnotherRouterOnLink (Ptr<NetDevice> nd) const;
789 
790   /**
791    * \brief Process a generic broadcast link
792    *
793    * \param nd the NetDevice
794    * \param pLSA the Global LSA
795    * \param c the returned NetDevice container
796    */
797   void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
798 
799   /**
800    * \brief Process a single broadcast link
801    *
802    * \param nd the NetDevice
803    * \param pLSA the Global LSA
804    * \param c the returned NetDevice container
805    */
806   void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
807 
808   /**
809    * \brief Process a bridged broadcast link
810    *
811    * \param nd the NetDevice
812    * \param pLSA the Global LSA
813    * \param c the returned NetDevice container
814    */
815   void ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
816 
817   /**
818    * \brief Process a point to point link
819    *
820    * \param ndLocal the NetDevice
821    * \param pLSA the Global LSA
822    */
823   void ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA);
824 
825   /**
826    * \brief Build one NetworkLSA for each net device talking to a network that we are the
827    * designated router for.
828    *
829    * \param c the devices.
830    */
831   void BuildNetworkLSAs (NetDeviceContainer c);
832 
833   /**
834    * \brief Return a container of all non-bridged NetDevices on a link
835    *
836    * This method will recursively find all of the 'edge' devices in an
837    * L2 broadcast domain.  If there are no bridged devices, then the
838    * container returned is simply the set of devices on the channel
839    * passed in as an argument.  If the link has bridges on it
840    * (and therefore multiple ns3::Channel objects interconnected by
841    * bridges), the method will find all of the non-bridged devices
842    * in the L2 broadcast domain.
843    *
844    * \param ch a channel from the link
845    * \returns the NetDeviceContainer.
846    */
847   NetDeviceContainer FindAllNonBridgedDevicesOnLink (Ptr<Channel> ch) const;
848 
849   /**
850    * \brief Decide whether or not a given net device is being bridged by a BridgeNetDevice.
851    *
852    * \param nd the NetDevice
853    * \returns the BridgeNetDevice smart pointer or null if not found
854    */
855   Ptr<BridgeNetDevice> NetDeviceIsBridged (Ptr<NetDevice> nd) const;
856 
857 
858   typedef std::list<GlobalRoutingLSA*> ListOfLSAs_t; //!< container for the GlobalRoutingLSAs
859   ListOfLSAs_t m_LSAs; //!< database of GlobalRoutingLSAs
860 
861   Ipv4Address m_routerId; //!< router ID (its IPv4 address)
862   Ptr<Ipv4GlobalRouting> m_routingProtocol; //!< the Ipv4GlobalRouting in use
863 
864   typedef std::list<Ipv4RoutingTableEntry *> InjectedRoutes; //!< container of Ipv4RoutingTableEntry
865   typedef std::list<Ipv4RoutingTableEntry *>::const_iterator InjectedRoutesCI; //!< Const Iterator to container of Ipv4RoutingTableEntry
866   typedef std::list<Ipv4RoutingTableEntry *>::iterator InjectedRoutesI; //!< Iterator to container of Ipv4RoutingTableEntry
867   InjectedRoutes m_injectedRoutes; //!< Routes we are exporting
868 
869   // Declared mutable so that const member functions can clear it
870   // (supporting the logical constness of the search methods of this class)
871   /**
872    * Container of bridges visited.
873    */
874   mutable std::vector<Ptr<BridgeNetDevice> > m_bridgesVisited;
875   /**
876    * Clear the list of bridges visited on the link
877    */
878   void ClearBridgesVisited (void) const;
879   /**
880    * When recursively checking for devices on the link, check whether a
881    * given device has already been visited.
882    *
883    * \param device the bridge device to check
884    * \return true if bridge has already been visited
885    */
886   bool BridgeHasAlreadyBeenVisited (Ptr<BridgeNetDevice> device) const;
887   /**
888    * When recursively checking for devices on the link, mark a given device
889    * as having been visited.
890    *
891    * \param device the bridge device to mark
892    */
893   void MarkBridgeAsVisited (Ptr<BridgeNetDevice> device) const;
894 
895   // inherited from Object
896   virtual void DoDispose (void);
897 
898 /**
899  * @brief Global Router copy construction is disallowed.
900  * @param sr object to copy from.
901  */
902   GlobalRouter (GlobalRouter& sr);
903 
904 /**
905  * @brief Global Router assignment operator is disallowed.
906  * @param sr object to copy from.
907  * @returns The object copied.
908  */
909   GlobalRouter& operator= (GlobalRouter& sr);
910 };
911 
912 } // namespace ns3
913 
914 #endif /* GLOBAL_ROUTER_INTERFACE_H */
915