A Discrete-Event Network Simulator
API
global-router-interface.cc
Go to the documentation of this file.
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: Tom Henderson (tomhend@u.washington.edu)
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/assert.h"
23 #include "ns3/abort.h"
24 #include "ns3/channel.h"
25 #include "ns3/net-device.h"
26 #include "ns3/node.h"
27 #include "ns3/node-list.h"
28 #include "ns3/ipv4.h"
29 #include "ns3/bridge-net-device.h"
30 #include "ipv4-global-routing.h"
32 #include "loopback-net-device.h"
33 #include <vector>
34 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("GlobalRouter");
38 
39 // ---------------------------------------------------------------------------
40 //
41 // GlobalRoutingLinkRecord Implementation
42 //
43 // ---------------------------------------------------------------------------
44 
46  :
47  m_linkId ("0.0.0.0"),
48  m_linkData ("0.0.0.0"),
49  m_linkType (Unknown),
50  m_metric (0)
51 {
52  NS_LOG_FUNCTION (this);
53 }
54 
56  LinkType linkType,
57  Ipv4Address linkId,
58  Ipv4Address linkData,
59  uint16_t metric)
60  :
61  m_linkId (linkId),
62  m_linkData (linkData),
63  m_linkType (linkType),
64  m_metric (metric)
65 {
66  NS_LOG_FUNCTION (this << linkType << linkId << linkData << metric);
67 }
68 
70 {
71  NS_LOG_FUNCTION (this);
72 }
73 
76 {
77  NS_LOG_FUNCTION (this);
78  return m_linkId;
79 }
80 
81 void
83 {
84  NS_LOG_FUNCTION (this << addr);
85  m_linkId = addr;
86 }
87 
90 {
91  NS_LOG_FUNCTION (this);
92  return m_linkData;
93 }
94 
95 void
97 {
98  NS_LOG_FUNCTION (this << addr);
99  m_linkData = addr;
100 }
101 
104 {
105  NS_LOG_FUNCTION (this);
106  return m_linkType;
107 }
108 
109 void
112 {
113  NS_LOG_FUNCTION (this << linkType);
114  m_linkType = linkType;
115 }
116 
117 uint16_t
119 {
120  NS_LOG_FUNCTION (this);
121  return m_metric;
122 }
123 
124 void
126 {
127  NS_LOG_FUNCTION (this << metric);
128  m_metric = metric;
129 }
130 
131 // ---------------------------------------------------------------------------
132 //
133 // GlobalRoutingLSA Implementation
134 //
135 // ---------------------------------------------------------------------------
136 
138  :
139  m_lsType (GlobalRoutingLSA::Unknown),
140  m_linkStateId ("0.0.0.0"),
141  m_advertisingRtr ("0.0.0.0"),
142  m_linkRecords (),
143  m_networkLSANetworkMask ("0.0.0.0"),
144  m_attachedRouters (),
145  m_status (GlobalRoutingLSA::LSA_SPF_NOT_EXPLORED),
146  m_node_id (0)
147 {
148  NS_LOG_FUNCTION (this);
149 }
150 
153  Ipv4Address linkStateId,
154  Ipv4Address advertisingRtr)
155  :
156  m_lsType (GlobalRoutingLSA::Unknown),
157  m_linkStateId (linkStateId),
158  m_advertisingRtr (advertisingRtr),
159  m_linkRecords (),
160  m_networkLSANetworkMask ("0.0.0.0"),
161  m_attachedRouters (),
162  m_status (status),
163  m_node_id (0)
164 {
165  NS_LOG_FUNCTION (this << status << linkStateId << advertisingRtr);
166 }
167 
169  : m_lsType (lsa.m_lsType), m_linkStateId (lsa.m_linkStateId),
170  m_advertisingRtr (lsa.m_advertisingRtr),
171  m_networkLSANetworkMask (lsa.m_networkLSANetworkMask),
172  m_status (lsa.m_status),
173  m_node_id (lsa.m_node_id)
174 {
175  NS_LOG_FUNCTION (this << &lsa);
177  "GlobalRoutingLSA::GlobalRoutingLSA (): Non-empty LSA in constructor");
178  CopyLinkRecords (lsa);
179 }
180 
183 {
184  NS_LOG_FUNCTION (this << &lsa);
185  m_lsType = lsa.m_lsType;
189  m_status = lsa.m_status;
190  m_node_id = lsa.m_node_id;
191 
192  ClearLinkRecords ();
193  CopyLinkRecords (lsa);
194  return *this;
195 }
196 
197 void
199 {
200  NS_LOG_FUNCTION (this << &lsa);
201  for (ListOfLinkRecords_t::const_iterator i = lsa.m_linkRecords.begin ();
202  i != lsa.m_linkRecords.end ();
203  i++)
204  {
205  GlobalRoutingLinkRecord *pSrc = *i;
207 
208  pDst->SetLinkType (pSrc->GetLinkType ());
209  pDst->SetLinkId (pSrc->GetLinkId ());
210  pDst->SetLinkData (pSrc->GetLinkData ());
211  pDst->SetMetric (pSrc->GetMetric ());
212 
213  m_linkRecords.push_back (pDst);
214  pDst = 0;
215  }
216 
218 }
219 
221 {
222  NS_LOG_FUNCTION (this);
223  ClearLinkRecords ();
224 }
225 
226 void
228 {
229  NS_LOG_FUNCTION (this);
230  for ( ListOfLinkRecords_t::iterator i = m_linkRecords.begin ();
231  i != m_linkRecords.end ();
232  i++)
233  {
234  NS_LOG_LOGIC ("Free link record");
235 
236  GlobalRoutingLinkRecord *p = *i;
237  delete p;
238  p = 0;
239 
240  *i = 0;
241  }
242  NS_LOG_LOGIC ("Clear list");
243  m_linkRecords.clear ();
244 }
245 
246 uint32_t
248 {
249  NS_LOG_FUNCTION (this << lr);
250  m_linkRecords.push_back (lr);
251  return m_linkRecords.size ();
252 }
253 
254 uint32_t
256 {
257  NS_LOG_FUNCTION (this);
258  return m_linkRecords.size ();
259 }
260 
263 {
264  NS_LOG_FUNCTION (this << n);
265  uint32_t j = 0;
266  for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
267  i != m_linkRecords.end ();
268  i++, j++)
269  {
270  if (j == n)
271  {
272  return *i;
273  }
274  }
275  NS_ASSERT_MSG (false, "GlobalRoutingLSA::GetLinkRecord (): invalid index");
276  return 0;
277 }
278 
279 bool
281 {
282  NS_LOG_FUNCTION (this);
283  return m_linkRecords.size () == 0;
284 }
285 
288 {
289  NS_LOG_FUNCTION (this);
290  return m_lsType;
291 }
292 
293 void
295 {
296  NS_LOG_FUNCTION (this << typ);
297  m_lsType = typ;
298 }
299 
302 {
303  NS_LOG_FUNCTION (this);
304  return m_linkStateId;
305 }
306 
307 void
309 {
310  NS_LOG_FUNCTION (this << addr);
311  m_linkStateId = addr;
312 }
313 
316 {
317  NS_LOG_FUNCTION (this);
318  return m_advertisingRtr;
319 }
320 
321 void
323 {
324  NS_LOG_FUNCTION (this << addr);
325  m_advertisingRtr = addr;
326 }
327 
328 void
330 {
331  NS_LOG_FUNCTION (this << mask);
333 }
334 
335 Ipv4Mask
337 {
338  NS_LOG_FUNCTION (this);
340 }
341 
344 {
345  NS_LOG_FUNCTION (this);
346  return m_status;
347 }
348 
349 uint32_t
351 {
352  NS_LOG_FUNCTION (this << addr);
353  m_attachedRouters.push_back (addr);
354  return m_attachedRouters.size ();
355 }
356 
357 uint32_t
359 {
360  NS_LOG_FUNCTION (this);
361  return m_attachedRouters.size ();
362 }
363 
366 {
367  NS_LOG_FUNCTION (this << n);
368  uint32_t j = 0;
369  for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin ();
370  i != m_attachedRouters.end ();
371  i++, j++)
372  {
373  if (j == n)
374  {
375  return *i;
376  }
377  }
378  NS_ASSERT_MSG (false, "GlobalRoutingLSA::GetAttachedRouter (): invalid index");
379  return Ipv4Address ("0.0.0.0");
380 }
381 
382 void
384 {
385  NS_LOG_FUNCTION (this << status);
386  m_status = status;
387 }
388 
389 Ptr<Node>
391 {
392  NS_LOG_FUNCTION (this);
393  return NodeList::GetNode (m_node_id);
394 }
395 
396 void
398 {
399  NS_LOG_FUNCTION (this << node);
400  m_node_id = node->GetId ();
401 }
402 
403 void
404 GlobalRoutingLSA::Print (std::ostream &os) const
405 {
406  NS_LOG_FUNCTION (this << &os);
407  os << std::endl;
408  os << "========== Global Routing LSA ==========" << std::endl;
409  os << "m_lsType = " << m_lsType;
410  if (m_lsType == GlobalRoutingLSA::RouterLSA)
411  {
412  os << " (GlobalRoutingLSA::RouterLSA)";
413  }
414  else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
415  {
416  os << " (GlobalRoutingLSA::NetworkLSA)";
417  }
418  else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
419  {
420  os << " (GlobalRoutingLSA::ASExternalLSA)";
421  }
422  else
423  {
424  os << "(Unknown LSType)";
425  }
426  os << std::endl;
427 
428  os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl;
429  os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl;
430 
431  if (m_lsType == GlobalRoutingLSA::RouterLSA)
432  {
433  for ( ListOfLinkRecords_t::const_iterator i = m_linkRecords.begin ();
434  i != m_linkRecords.end ();
435  i++)
436  {
437  GlobalRoutingLinkRecord *p = *i;
438 
439  os << "---------- RouterLSA Link Record ----------" << std::endl;
440  os << "m_linkType = " << p->m_linkType;
442  {
443  os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl;
444  os << "m_linkId = " << p->m_linkId << std::endl;
445  os << "m_linkData = " << p->m_linkData << std::endl;
446  os << "m_metric = " << p->m_metric << std::endl;
447  }
449  {
450  os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
451  os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
452  os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
453  os << "m_metric = " << p->m_metric << std::endl;
454  }
456  {
457  os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
458  os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
459  os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
460  os << "m_metric = " << p->m_metric << std::endl;
461  }
462  else
463  {
464  os << " (Unknown LinkType)" << std::endl;
465  os << "m_linkId = " << p->m_linkId << std::endl;
466  os << "m_linkData = " << p->m_linkData << std::endl;
467  os << "m_metric = " << p->m_metric << std::endl;
468  }
469  os << "---------- End RouterLSA Link Record ----------" << std::endl;
470  }
471  }
472  else if (m_lsType == GlobalRoutingLSA::NetworkLSA)
473  {
474  os << "---------- NetworkLSA Link Record ----------" << std::endl;
475  os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
476  for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++)
477  {
478  Ipv4Address p = *i;
479  os << "attachedRouter = " << p << std::endl;
480  }
481  os << "---------- End NetworkLSA Link Record ----------" << std::endl;
482  }
483  else if (m_lsType == GlobalRoutingLSA::ASExternalLSAs)
484  {
485  os << "---------- ASExternalLSA Link Record --------" << std::endl;
486  os << "m_linkStateId = " << m_linkStateId << std::endl;
487  os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
488  }
489  else
490  {
491  NS_ASSERT_MSG (0, "Illegal LSA LSType: " << m_lsType);
492  }
493  os << "========== End Global Routing LSA ==========" << std::endl;
494 }
495 
496 std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
497 {
498  lsa.Print (os);
499  return os;
500 }
501 
502 // ---------------------------------------------------------------------------
503 //
504 // GlobalRouter Implementation
505 //
506 // ---------------------------------------------------------------------------
507 
508 NS_OBJECT_ENSURE_REGISTERED (GlobalRouter);
509 
510 TypeId
512 {
513  static TypeId tid = TypeId ("ns3::GlobalRouter")
514  .SetParent<Object> ()
515  .SetGroupName ("Internet");
516  return tid;
517 }
518 
520  : m_LSAs ()
521 {
522  NS_LOG_FUNCTION (this);
524 }
525 
527 {
528  NS_LOG_FUNCTION (this);
529  ClearLSAs ();
530 }
531 
532 void
534 {
535  NS_LOG_FUNCTION (this << routing);
536  m_routingProtocol = routing;
537 }
540 {
541  NS_LOG_FUNCTION (this);
542  return m_routingProtocol;
543 }
544 
545 void
547 {
548  NS_LOG_FUNCTION (this);
549  m_routingProtocol = 0;
550  for (InjectedRoutesI k = m_injectedRoutes.begin ();
551  k != m_injectedRoutes.end ();
552  k = m_injectedRoutes.erase (k))
553  {
554  delete (*k);
555  }
557 }
558 
559 void
561 {
562  NS_LOG_FUNCTION (this);
563  for ( ListOfLSAs_t::iterator i = m_LSAs.begin ();
564  i != m_LSAs.end ();
565  i++)
566  {
567  NS_LOG_LOGIC ("Free LSA");
568 
569  GlobalRoutingLSA *p = *i;
570  delete p;
571  p = 0;
572 
573  *i = 0;
574  }
575  NS_LOG_LOGIC ("Clear list of LSAs");
576  m_LSAs.clear ();
577 }
578 
581 {
582  NS_LOG_FUNCTION (this);
583  return m_routerId;
584 }
585 
586 //
587 // DiscoverLSAs is called on all nodes in the system that have a GlobalRouter
588 // interface aggregated. We need to go out and discover any adjacent routers
589 // and build the Link State Advertisements that reflect them and their associated
590 // networks.
591 //
592 uint32_t
594 {
595  NS_LOG_FUNCTION (this);
596  Ptr<Node> node = GetObject<Node> ();
597  NS_ABORT_MSG_UNLESS (node, "GlobalRouter::DiscoverLSAs (): GetObject for <Node> interface failed");
598  NS_LOG_LOGIC ("For node " << node->GetId () );
599 
600  ClearLSAs ();
601 
602  //
603  // While building the Router-LSA, keep a list of those NetDevices for
604  // which the current node is the designated router and we will later build
605  // a NetworkLSA for.
606  //
608 
609  //
610  // We're aggregated to a node. We need to ask the node for a pointer to its
611  // Ipv4 interface. This is where the information regarding the attached
612  // interfaces lives. If we're a router, we had better have an Ipv4 interface.
613  //
614  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
615  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::DiscoverLSAs (): GetObject for <Ipv4> interface failed");
616 
617  //
618  // Every router node originates a Router-LSA
619  //
622  pLSA->SetLinkStateId (m_routerId);
625  pLSA->SetNode (node);
626 
627  //
628  // Ask the node for the number of net devices attached. This isn't necessarily
629  // equal to the number of links to adjacent nodes (other routers) as the number
630  // of devices may include those for stub networks (e.g., ethernets, etc.) and
631  // bridge devices also take up an "extra" net device.
632  //
633  uint32_t numDevices = node->GetNDevices ();
634 
635  //
636  // Iterate through the devices on the node and walk the channel to see what's
637  // on the other side of the standalone devices..
638  //
639  for (uint32_t i = 0; i < numDevices; ++i)
640  {
641  Ptr<NetDevice> ndLocal = node->GetDevice (i);
642 
643  if (DynamicCast <LoopbackNetDevice> (ndLocal))
644  {
645  continue;
646  }
647 
648  //
649  // There is an assumption that bridge ports must never have an IP address
650  // associated with them. This turns out to be a very convenient place to
651  // check and make sure that this is the case.
652  //
653  if (NetDeviceIsBridged (ndLocal))
654  {
655  // Initialize to value out of bounds to silence compiler
656  uint32_t interfaceBridge = ipv4Local->GetNInterfaces () + 1;
657  bool rc = FindInterfaceForDevice (node, ndLocal, interfaceBridge);
658  NS_ABORT_MSG_IF (rc, "GlobalRouter::DiscoverLSAs(): Bridge ports must not have an IPv4 interface index");
659  }
660 
661  //
662  // Check to see if the net device we just got has a corresponding IP
663  // interface (could be a pure L2 NetDevice) -- for example a net device
664  // associated with a bridge. We are only going to involve devices with
665  // IP addresses in routing.
666  //
667  bool isForwarding = false;
668  for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
669  {
670  if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j) &&
671  ipv4Local->IsForwarding (j))
672  {
673  isForwarding = true;
674  break;
675  }
676  }
677 
678  if (!isForwarding)
679  {
680  NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface or is not enabled for forwarding, skipping");
681  continue;
682  }
683 
684  //
685  // We have a net device that we need to check out. If it suports
686  // broadcast and is not a point-point link, then it will be either a stub
687  // network or a transit network depending on the number of routers on
688  // the segment. We add the appropriate link record to the LSA.
689  //
690  // If the device is a point to point link, we treat it separately. In
691  // that case, there may be zero, one, or two link records added.
692  //
693 
694  if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
695  {
696  NS_LOG_LOGIC ("Broadcast link");
697  ProcessBroadcastLink (ndLocal, pLSA, c);
698  }
699  else if (ndLocal->IsPointToPoint () )
700  {
701  NS_LOG_LOGIC ("Point=to-point link");
702  ProcessPointToPointLink (ndLocal, pLSA);
703  }
704  else
705  {
706  NS_ASSERT_MSG (0, "GlobalRouter::DiscoverLSAs (): unknown link type");
707  }
708  }
709 
710  NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
711  NS_LOG_LOGIC (*pLSA);
712  m_LSAs.push_back (pLSA);
713  pLSA = 0;
714 
715  //
716  // Now, determine whether we need to build a NetworkLSA. This is the case if
717  // we found at least one designated router.
718  //
719  uint32_t nDesignatedRouters = c.GetN ();
720  if (nDesignatedRouters > 0)
721  {
722  NS_LOG_LOGIC ("Build Network LSAs");
723  BuildNetworkLSAs (c);
724  }
725 
726  //
727  // Build injected route LSAs as external routes
728  // RFC 2328, section 12.4.4
729  //
730  for (InjectedRoutesCI i = m_injectedRoutes.begin ();
731  i != m_injectedRoutes.end ();
732  i++)
733  {
736  pLSA->SetLinkStateId ((*i)->GetDestNetwork ());
738  pLSA->SetNetworkLSANetworkMask ((*i)->GetDestNetworkMask ());
740  m_LSAs.push_back (pLSA);
741  }
742  return m_LSAs.size ();
743 }
744 
745 void
747 {
748  NS_LOG_FUNCTION (this << nd << pLSA << &c);
749 
750  if (nd->IsBridge ())
751  {
752  ProcessBridgedBroadcastLink (nd, pLSA, c);
753  }
754  else
755  {
756  ProcessSingleBroadcastLink (nd, pLSA, c);
757  }
758 }
759 
760 void
762 {
763  NS_LOG_FUNCTION (this << nd << pLSA << &c);
764 
766  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record");
767 
768  //
769  // We have some preliminaries to do to get enough information to proceed.
770  // This information we need comes from the internet stack, so notice that
771  // there is an implied assumption that global routing is only going to
772  // work with devices attached to the internet stack (have an ipv4 interface
773  // associated to them.
774  //
775  Ptr<Node> node = nd->GetNode ();
776 
777  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
778  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
779 
780  // Initialize to value out of bounds to silence compiler
781  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
782  bool rc = FindInterfaceForDevice (node, nd, interfaceLocal);
783  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
784 
785  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
786  {
787  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
788  }
789  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
790  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
791  NS_LOG_LOGIC ("Working with local address " << addrLocal);
792  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
793 
794  //
795  // Check to see if the net device is connected to a channel/network that has
796  // another router on it. If there is no other router on the link (but us) then
797  // this is a stub network. If we find another router, then what we have here
798  // is a transit network.
799  //
801  if (AnotherRouterOnLink (nd) == false)
802  {
803  //
804  // This is a net device connected to a stub network
805  //
806  NS_LOG_LOGIC ("Router-LSA Stub Network");
808 
809  //
810  // According to OSPF, the Link ID is the IP network number of
811  // the attached network.
812  //
813  plr->SetLinkId (addrLocal.CombineMask (maskLocal));
814 
815  //
816  // and the Link Data is the network mask; converted to Ipv4Address
817  //
818  Ipv4Address maskLocalAddr;
819  maskLocalAddr.Set (maskLocal.Get ());
820  plr->SetLinkData (maskLocalAddr);
821  plr->SetMetric (metricLocal);
822  pLSA->AddLinkRecord (plr);
823  plr = 0;
824  }
825  else
826  {
827  //
828  // We have multiple routers on a broadcast interface, so this is
829  // a transit network.
830  //
831  NS_LOG_LOGIC ("Router-LSA Transit Network");
833 
834  //
835  // By definition, the router with the lowest IP address is the
836  // designated router for the network. OSPF says that the Link ID
837  // gets the IP interface address of the designated router in this
838  // case.
839  //
842 
843  //
844  // Let's double-check that any designated router we find out on our
845  // network is really on our network.
846  //
847  if (desigRtr != "255.255.255.255")
848  {
849  Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
850  Ipv4Address networkThere = desigRtr.CombineMask (maskLocal);
851  NS_ABORT_MSG_UNLESS (networkHere == networkThere,
852  "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
853  }
854  if (desigRtr == addrLocal)
855  {
856  c.Add (nd);
857  NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
858  }
859  plr->SetLinkId (desigRtr);
860 
861  //
862  // OSPF says that the Link Data is this router's own IP address.
863  //
864  plr->SetLinkData (addrLocal);
865  plr->SetMetric (metricLocal);
866  pLSA->AddLinkRecord (plr);
867  plr = 0;
868  }
869 }
870 
871 void
873 {
874  NS_LOG_FUNCTION (this << nd << pLSA << &c);
875  NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
876 
877 #if 0
878  //
879  // It is possible to admit the possibility that a bridge device on a node
880  // can also participate in routing. This would surprise people who don't
881  // come from Microsoft-land where they do use such a construct. Based on
882  // the principle of least-surprise, we will leave the relatively simple
883  // code in place to do this, but not enable it until someone really wants
884  // the capability. Even then, we will not enable this code as a default
885  // but rather something you will have to go and turn on.
886  //
887 
888  Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
889  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
890 
891  //
892  // We have some preliminaries to do to get enough information to proceed.
893  // This information we need comes from the internet stack, so notice that
894  // there is an implied assumption that global routing is only going to
895  // work with devices attached to the internet stack (have an ipv4 interface
896  // associated to them.
897  //
898  Ptr<Node> node = nd->GetNode ();
899  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
900  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
901 
902  // Initialize to value out of bounds to silence compiler
903  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
904  bool rc = FindInterfaceForDevice (node, nd, interfaceLocal);
905  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
906 
907  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
908  {
909  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
910  }
911  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
912  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();;
913  NS_LOG_LOGIC ("Working with local address " << addrLocal);
914  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
915 
916  //
917  // We need to handle a bridge on the router. This means that we have been
918  // given a net device that is a BridgeNetDevice. It has an associated Ipv4
919  // interface index and address. Some number of other net devices live "under"
920  // the bridge device as so-called bridge ports. In a nutshell, what we have
921  // to do is to repeat what is done for a single broadcast link on all of
922  // those net devices living under the bridge (trolls?)
923  //
924 
925  bool areTransitNetwork = false;
926  Ipv4Address desigRtr ("255.255.255.255");
927 
928  for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
929  {
930  Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
931 
932  //
933  // We have to decide if we are a transit network. This is characterized
934  // by the presence of another router on the network segment. If we find
935  // another router on any of our bridged links, we are a transit network.
936  //
938  if (AnotherRouterOnLink (ndTemp))
939  {
940  areTransitNetwork = true;
941 
942  //
943  // If we're going to be a transit network, then we have got to elect
944  // a designated router for the whole bridge. This means finding the
945  // router with the lowest IP address on the whole bridge. We ask
946  // for the lowest address on each segment and pick the lowest of them
947  // all.
948  //
950  Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp);
951 
952  //
953  // Let's double-check that any designated router we find out on our
954  // network is really on our network.
955  //
956  if (desigRtrTemp != "255.255.255.255")
957  {
958  Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
959  Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal);
960  NS_ABORT_MSG_UNLESS (networkHere == networkThere,
961  "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
962  }
963  if (desigRtrTemp < desigRtr)
964  {
965  desigRtr = desigRtrTemp;
966  }
967  }
968  }
969  //
970  // That's all the information we need to put it all together, just like we did
971  // in the case of a single broadcast link.
972  //
973 
975  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
976 
977  if (areTransitNetwork == false)
978  {
979  //
980  // This is a net device connected to a bridge of stub networks
981  //
982  NS_LOG_LOGIC ("Router-LSA Stub Network");
984 
985  //
986  // According to OSPF, the Link ID is the IP network number of
987  // the attached network.
988  //
989  plr->SetLinkId (addrLocal.CombineMask (maskLocal));
990 
991  //
992  // and the Link Data is the network mask; converted to Ipv4Address
993  //
994  Ipv4Address maskLocalAddr;
995  maskLocalAddr.Set (maskLocal.Get ());
996  plr->SetLinkData (maskLocalAddr);
997  plr->SetMetric (metricLocal);
998  pLSA->AddLinkRecord (plr);
999  plr = 0;
1000  }
1001  else
1002  {
1003  //
1004  // We have multiple routers on a bridged broadcast interface, so this is
1005  // a transit network.
1006  //
1007  NS_LOG_LOGIC ("Router-LSA Transit Network");
1009 
1010  //
1011  // By definition, the router with the lowest IP address is the
1012  // designated router for the network. OSPF says that the Link ID
1013  // gets the IP interface address of the designated router in this
1014  // case.
1015  //
1016  if (desigRtr == addrLocal)
1017  {
1018  c.Add (nd);
1019  NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
1020  }
1021  plr->SetLinkId (desigRtr);
1022 
1023  //
1024  // OSPF says that the Link Data is this router's own IP address.
1025  //
1026  plr->SetLinkData (addrLocal);
1027  plr->SetMetric (metricLocal);
1028  pLSA->AddLinkRecord (plr);
1029  plr = 0;
1030  }
1031 #endif
1032 }
1033 
1034 void
1036 {
1037  NS_LOG_FUNCTION (this << ndLocal << pLSA);
1038 
1039  //
1040  // We have some preliminaries to do to get enough information to proceed.
1041  // This information we need comes from the internet stack, so notice that
1042  // there is an implied assumption that global routing is only going to
1043  // work with devices attached to the internet stack (have an ipv4 interface
1044  // associated to them.
1045  //
1046  Ptr<Node> nodeLocal = ndLocal->GetNode ();
1047 
1048  Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
1049  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
1050 
1051  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
1052  bool rc = FindInterfaceForDevice (nodeLocal, ndLocal, interfaceLocal);
1053  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
1054 
1055  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
1056  {
1057  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1058  }
1059  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
1060  NS_LOG_LOGIC ("Working with local address " << addrLocal);
1061  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
1062 
1063  //
1064  // Now, we're going to walk over to the remote net device on the other end of
1065  // the point-to-point channel we know we have. This is where our adjacent
1066  // router (to use OSPF lingo) is running.
1067  //
1068  Ptr<Channel> ch = ndLocal->GetChannel ();
1069 
1070  //
1071  // Get the net device on the other side of the point-to-point channel.
1072  //
1073  Ptr<NetDevice> ndRemote = GetAdjacent (ndLocal, ch);
1074 
1075  //
1076  // The adjacent net device is aggregated to a node. We need to ask that net
1077  // device for its node, then ask that node for its Ipv4 interface. Note a
1078  // requirement that nodes on either side of a point-to-point link must have
1079  // internet stacks; and an assumption that point-to-point links are incompatible
1080  // with bridging.
1081  //
1082  Ptr<Node> nodeRemote = ndRemote->GetNode ();
1083  Ptr<Ipv4> ipv4Remote = nodeRemote->GetObject<Ipv4> ();
1084  NS_ABORT_MSG_UNLESS (ipv4Remote,
1085  "GlobalRouter::ProcessPointToPointLink(): GetObject for remote <Ipv4> failed");
1086 
1087  //
1088  // Further note the requirement that nodes on either side of a point-to-point
1089  // link must participate in global routing and therefore have a GlobalRouter
1090  // interface aggregated.
1091  //
1092  Ptr<GlobalRouter> rtrRemote = nodeRemote->GetObject<GlobalRouter> ();
1093  if (rtrRemote == 0)
1094  {
1095  // This case is possible if the remote does not participate in global routing
1096  return;
1097  }
1098  //
1099  // We're going to need the remote router ID, so we might as well get it now.
1100  //
1101  Ipv4Address rtrIdRemote = rtrRemote->GetRouterId ();
1102  NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote);
1103 
1104  //
1105  // Now, just like we did above, we need to get the IP interface index for the
1106  // net device on the other end of the point-to-point channel.
1107  //
1108  uint32_t interfaceRemote = ipv4Remote->GetNInterfaces () + 1;
1109  rc = FindInterfaceForDevice (nodeRemote, ndRemote, interfaceRemote);
1110  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
1111 
1112  //
1113  // Now that we have the Ipv4 interface, we can get the (remote) address and
1114  // mask we need.
1115  //
1116  if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
1117  {
1118  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1119  }
1120  Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
1121  Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
1122  NS_LOG_LOGIC ("Working with remote address " << addrRemote);
1123 
1124  //
1125  // Now we can fill out the link records for this link. There are always two
1126  // link records; the first is a point-to-point record describing the link and
1127  // the second is a stub network record with the network number.
1128  //
1130  if (ipv4Remote->IsUp (interfaceRemote))
1131  {
1132  NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
1133 
1134  plr = new GlobalRoutingLinkRecord;
1135  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
1137  plr->SetLinkId (rtrIdRemote);
1138  plr->SetLinkData (addrLocal);
1139  plr->SetMetric (metricLocal);
1140  pLSA->AddLinkRecord (plr);
1141  plr = 0;
1142  }
1143 
1144  // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
1145  plr = new GlobalRoutingLinkRecord;
1146  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
1148  plr->SetLinkId (addrRemote);
1149  plr->SetLinkData (Ipv4Address (maskRemote.Get ())); // Frown
1150  plr->SetMetric (metricLocal);
1151  pLSA->AddLinkRecord (plr);
1152  plr = 0;
1153 }
1154 
1155 void
1157 {
1158  NS_LOG_FUNCTION (this << &c);
1159 
1160  uint32_t nDesignatedRouters = c.GetN ();
1161  NS_LOG_DEBUG ("Number of designated routers: " << nDesignatedRouters);
1162 
1163  for (uint32_t i = 0; i < nDesignatedRouters; ++i)
1164  {
1165  //
1166  // Build one NetworkLSA for each net device talking to a network that we are the
1167  // designated router for. These devices are in the provided container.
1168  //
1169  Ptr<NetDevice> ndLocal = c.Get (i);
1170  Ptr<Node> node = ndLocal->GetNode ();
1171 
1172  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
1173  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
1174 
1175  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
1176  bool rc = FindInterfaceForDevice (node, ndLocal, interfaceLocal);
1177  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
1178 
1179  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
1180  {
1181  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1182  }
1183  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
1184  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
1185 
1186  GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
1187  NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
1188 
1190  pLSA->SetLinkStateId (addrLocal);
1192  pLSA->SetNetworkLSANetworkMask (maskLocal);
1194  pLSA->SetNode (node);
1195 
1196  //
1197  // Build a list of AttachedRouters by walking the devices in the channel
1198  // and, if we find a node with a GlobalRouter interface and an IPv4
1199  // interface associated with that device, we call it an attached router.
1200  //
1202  Ptr<Channel> ch = ndLocal->GetChannel ();
1203  uint32_t nDevices = ch->GetNDevices ();
1204  NS_ASSERT (nDevices);
1206  NS_LOG_LOGIC ("Found " << deviceList.GetN () << " non-bridged devices on channel");
1207 
1208  for (uint32_t i = 0; i < deviceList.GetN (); i++)
1209  {
1210  Ptr<NetDevice> tempNd = deviceList.Get (i);
1211  NS_ASSERT (tempNd);
1212  if (tempNd == ndLocal)
1213  {
1214  NS_LOG_LOGIC ("Adding " << addrLocal << " to Network LSA");
1215  pLSA->AddAttachedRouter (addrLocal);
1216  continue;
1217  }
1218  Ptr<Node> tempNode = tempNd->GetNode ();
1219 
1220  // Does the node in question have a GlobalRouter interface? If not it can
1221  // hardly be considered an attached router.
1222  //
1223  Ptr<GlobalRouter> rtr = tempNode->GetObject<GlobalRouter> ();
1224  if (rtr == 0)
1225  {
1226  NS_LOG_LOGIC ("Node " << tempNode->GetId () << " does not have GlobalRouter interface--skipping");
1227  continue;
1228  }
1229 
1230  //
1231  // Does the attached node have an ipv4 interface for the device we're probing?
1232  // If not, it can't play router.
1233  //
1234  uint32_t tempInterface = 0;
1235  if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
1236  {
1237  Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
1238  NS_ASSERT (tempIpv4);
1239  if (!tempIpv4->IsUp (tempInterface))
1240  {
1241  NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
1242  }
1243  else
1244  {
1245  if (tempIpv4->GetNAddresses (tempInterface) > 1)
1246  {
1247  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1248  }
1249  Ipv4Address tempAddr = tempIpv4->GetAddress (tempInterface, 0).GetLocal ();
1250  NS_LOG_LOGIC ("Adding " << tempAddr << " to Network LSA");
1251  pLSA->AddAttachedRouter (tempAddr);
1252  }
1253  }
1254  else
1255  {
1256  NS_LOG_LOGIC ("Node " << tempNode->GetId () << " device " << tempNd << " does not have IPv4 interface; skipping");
1257  }
1258  }
1259  m_LSAs.push_back (pLSA);
1260  NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
1261  NS_LOG_LOGIC (*pLSA);
1262  pLSA = 0;
1263  }
1264 }
1265 
1268 {
1269  NS_LOG_FUNCTION (this << ch);
1271 
1272  for (uint32_t i = 0; i < ch->GetNDevices (); i++)
1273  {
1274  Ptr<NetDevice> nd = ch->GetDevice (i);
1275  NS_LOG_LOGIC ("checking to see if the device " << nd << " is bridged");
1277  if (bnd && BridgeHasAlreadyBeenVisited (bnd) == false)
1278  {
1279  NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd << " with " << bnd->GetNBridgePorts () << " ports");
1280  MarkBridgeAsVisited (bnd);
1281  // Find all channels bridged together, and recursively call
1282  // on all other channels
1283  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); j++)
1284  {
1285  Ptr<NetDevice> bridgedDevice = bnd->GetBridgePort (j);
1286  if (bridgedDevice->GetChannel () == ch)
1287  {
1288  NS_LOG_LOGIC ("Skipping my own device/channel");
1289  continue;
1290  }
1291  NS_LOG_LOGIC ("Calling on channel " << bridgedDevice->GetChannel ());
1292  c.Add (FindAllNonBridgedDevicesOnLink (bridgedDevice->GetChannel ()));
1293  }
1294  }
1295  else
1296  {
1297  NS_LOG_LOGIC ("Device is not bridged; adding");
1298  c.Add (nd);
1299  }
1300  }
1301  NS_LOG_LOGIC ("Found " << c.GetN () << " devices");
1302  return c;
1303 }
1304 
1305 //
1306 // Given a local net device, we need to walk the channel to which the net device is
1307 // attached and look for nodes with GlobalRouter interfaces on them (one of them
1308 // will be us). Of these, the router with the lowest IP address on the net device
1309 // connecting to the channel becomes the designated router for the link.
1310 //
1311 Ipv4Address
1312 GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal) const
1313 {
1314  NS_LOG_FUNCTION (this << ndLocal);
1315 
1316  Ptr<Channel> ch = ndLocal->GetChannel ();
1317  uint32_t nDevices = ch->GetNDevices ();
1318  NS_ASSERT (nDevices);
1319 
1320  NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " <<
1321  ndLocal->GetNode ()->GetId ());
1322 
1323  Ipv4Address desigRtr ("255.255.255.255");
1324 
1325  //
1326  // Look through all of the devices on the channel to which the net device
1327  // in question is attached.
1328  //
1329  for (uint32_t i = 0; i < nDevices; i++)
1330  {
1331  Ptr<NetDevice> ndOther = ch->GetDevice (i);
1332  NS_ASSERT (ndOther);
1333 
1334  Ptr<Node> nodeOther = ndOther->GetNode ();
1335 
1336  NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ());
1337 
1338  //
1339  // For all other net devices, we need to check and see if a router
1340  // is present. If the net device on the other side is a bridged
1341  // device, we need to consider all of the other devices on the
1342  // bridge as well (all of the bridge ports.
1343  //
1344  NS_LOG_LOGIC ("checking to see if the device is bridged");
1345  Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
1346  if (bnd)
1347  {
1348  NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd);
1349 
1350  //
1351  // When enumerating a bridge, don't count the netdevice we came in on
1352  //
1353  if (ndLocal == ndOther)
1354  {
1355  NS_LOG_LOGIC ("Skip -- it is where we came from.");
1356  continue;
1357  }
1358 
1359  //
1360  // It is possible that the bridge net device is sitting under a
1361  // router, so we have to check for the presence of that router
1362  // before we run off and follow all the links
1363  //
1364  // We require a designated router to have a GlobalRouter interface and
1365  // an internet stack that includes the Ipv4 interface. If it doesn't
1366  // it can't play router.
1367  //
1368  NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd);
1369  Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
1370  Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
1371  if (rtr && ipv4)
1372  {
1373  // Initialize to value out of bounds to silence compiler
1374  uint32_t interfaceOther = ipv4->GetNInterfaces () + 1;
1375  if (FindInterfaceForDevice (nodeOther, bnd, interfaceOther))
1376  {
1377  NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
1378  if (!ipv4->IsUp (interfaceOther))
1379  {
1380  NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
1381  continue;
1382  }
1383  if (ipv4->GetNAddresses (interfaceOther) > 1)
1384  {
1385  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1386  }
1387  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
1388  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
1389  NS_LOG_LOGIC ("designated router now " << desigRtr);
1390  }
1391  }
1392 
1393  //
1394  // Check if we have seen this bridge net device already while
1395  // recursively enumerating an L2 broadcast domain. If it is new
1396  // to us, go ahead and process it. If we have already processed it,
1397  // move to the next
1398  //
1400  {
1401  NS_ABORT_MSG ("ERROR: L2 forwarding loop detected!");
1402  }
1403 
1404  MarkBridgeAsVisited(bnd);
1405 
1406  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
1407  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
1408  {
1409  Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
1410  NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
1411  if (ndBridged == ndOther)
1412  {
1413  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
1414  continue;
1415  }
1416 
1417  NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged);
1418  Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged);
1419  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
1420  NS_LOG_LOGIC ("designated router now " << desigRtr);
1421  }
1422  }
1423  else
1424  {
1425  NS_LOG_LOGIC ("This device is not bridged");
1426  Ptr<Node> nodeOther = ndOther->GetNode ();
1427  NS_ASSERT (nodeOther);
1428 
1429  //
1430  // We require a designated router to have a GlobalRouter interface and
1431  // an internet stack that includes the Ipv4 interface. If it doesn't
1432  //
1433  Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
1434  Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
1435  if (rtr && ipv4)
1436  {
1437  // Initialize to value out of bounds to silence compiler
1438  uint32_t interfaceOther = ipv4->GetNInterfaces () + 1;
1439  if (FindInterfaceForDevice (nodeOther, ndOther, interfaceOther))
1440  {
1441  if (!ipv4->IsUp (interfaceOther))
1442  {
1443  NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
1444  continue;
1445  }
1446  NS_LOG_LOGIC ("Found router on net device " << ndOther);
1447  if (ipv4->GetNAddresses (interfaceOther) > 1)
1448  {
1449  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1450  }
1451  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
1452  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
1453  NS_LOG_LOGIC ("designated router now " << desigRtr);
1454  }
1455  }
1456  }
1457  }
1458  return desigRtr;
1459 }
1460 
1461 //
1462 // Given a node and an attached net device, take a look off in the channel to
1463 // which the net device is attached and look for a node on the other side
1464 // that has a GlobalRouter interface aggregated. Life gets more complicated
1465 // when there is a bridged net device on the other side.
1466 //
1467 bool
1468 GlobalRouter::AnotherRouterOnLink (Ptr<NetDevice> nd) const
1469 {
1470  NS_LOG_FUNCTION (this << nd);
1471 
1472  Ptr<Channel> ch = nd->GetChannel ();
1473  if (!ch)
1474  {
1475  // It may be that this net device is a stub device, without a channel
1476  return false;
1477  }
1478  uint32_t nDevices = ch->GetNDevices ();
1479  NS_ASSERT (nDevices);
1480 
1481  NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
1482 
1483  //
1484  // Look through all of the devices on the channel to which the net device
1485  // in question is attached.
1486  //
1487  for (uint32_t i = 0; i < nDevices; i++)
1488  {
1489  Ptr<NetDevice> ndOther = ch->GetDevice (i);
1490  NS_ASSERT (ndOther);
1491 
1492  NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
1493 
1494  //
1495  // Ignore the net device itself.
1496  //
1497  if (ndOther == nd)
1498  {
1499  NS_LOG_LOGIC ("Myself, skip");
1500  continue;
1501  }
1502 
1503  //
1504  // For all other net devices, we need to check and see if a router
1505  // is present. If the net device on the other side is a bridged
1506  // device, we need to consider all of the other devices on the
1507  // bridge.
1508  //
1509  NS_LOG_LOGIC ("checking to see if device is bridged");
1510  Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
1511  if (bnd)
1512  {
1513  NS_LOG_LOGIC ("Device is bridged by net device " << bnd);
1514 
1515  //
1516  // Check if we have seen this bridge net device already while
1517  // recursively enumerating an L2 broadcast domain. If it is new
1518  // to us, go ahead and process it. If we have already processed it,
1519  // move to the next
1520  //
1522  {
1523  NS_ABORT_MSG ("ERROR: L2 forwarding loop detected!");
1524  }
1525 
1526  MarkBridgeAsVisited(bnd);
1527 
1528  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
1529  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
1530  {
1531  Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
1532  NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
1533  if (ndBridged == ndOther)
1534  {
1535  NS_LOG_LOGIC ("That bridge port is me, skip");
1536  continue;
1537  }
1538 
1539  NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged);
1540  if (AnotherRouterOnLink (ndBridged))
1541  {
1542  NS_LOG_LOGIC ("Found routers on bridge port, return true");
1543  return true;
1544  }
1545  }
1546  NS_LOG_LOGIC ("No routers on bridged net device, return false");
1547  return false;
1548  }
1549 
1550  NS_LOG_LOGIC ("This device is not bridged");
1551  Ptr<Node> nodeTemp = ndOther->GetNode ();
1552  NS_ASSERT (nodeTemp);
1553 
1554  Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
1555  if (rtr)
1556  {
1557  NS_LOG_LOGIC ("Found GlobalRouter interface, return true");
1558  return true;
1559  }
1560  else
1561  {
1562  NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search");
1563  }
1564  }
1565  NS_LOG_LOGIC ("No routers found, return false");
1566  return false;
1567 }
1568 
1569 uint32_t
1570 GlobalRouter::GetNumLSAs (void) const
1571 {
1572  NS_LOG_FUNCTION (this);
1573  return m_LSAs.size ();
1574 }
1575 
1576 //
1577 // Get the nth link state advertisement from this router.
1578 //
1579 bool
1580 GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
1581 {
1582  NS_LOG_FUNCTION (this << n << &lsa);
1583  NS_ASSERT_MSG (lsa.IsEmpty (), "GlobalRouter::GetLSA (): Must pass empty LSA");
1584 //
1585 // All of the work was done in GetNumLSAs. All we have to do here is to
1586 // walk the list of link state advertisements created there and return the
1587 // one the client is interested in.
1588 //
1589  ListOfLSAs_t::const_iterator i = m_LSAs.begin ();
1590  uint32_t j = 0;
1591 
1592  for (; i != m_LSAs.end (); i++, j++)
1593  {
1594  if (j == n)
1595  {
1596  GlobalRoutingLSA *p = *i;
1597  lsa = *p;
1598  return true;
1599  }
1600  }
1601 
1602  return false;
1603 }
1604 
1605 void
1606 GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
1607 {
1608  NS_LOG_FUNCTION (this << network << networkMask);
1609  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
1610 //
1611 // Interface number does not matter here, using 1.
1612 //
1614  networkMask,
1615  1);
1616  m_injectedRoutes.push_back (route);
1617 }
1618 
1619 Ipv4RoutingTableEntry *
1620 GlobalRouter::GetInjectedRoute (uint32_t index)
1621 {
1622  NS_LOG_FUNCTION (this << index);
1623  if (index < m_injectedRoutes.size ())
1624  {
1625  uint32_t tmp = 0;
1626  for (InjectedRoutesCI i = m_injectedRoutes.begin ();
1627  i != m_injectedRoutes.end ();
1628  i++)
1629  {
1630  if (tmp == index)
1631  {
1632  return *i;
1633  }
1634  tmp++;
1635  }
1636  }
1637  NS_ASSERT (false);
1638  // quiet compiler.
1639  return 0;
1640 }
1641 
1642 uint32_t
1644 {
1645  NS_LOG_FUNCTION (this);
1646  return m_injectedRoutes.size ();
1647 }
1648 
1649 void
1650 GlobalRouter::RemoveInjectedRoute (uint32_t index)
1651 {
1652  NS_LOG_FUNCTION (this << index);
1653  NS_ASSERT (index < m_injectedRoutes.size ());
1654  uint32_t tmp = 0;
1655  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
1656  {
1657  if (tmp == index)
1658  {
1659  NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size ());
1660  delete *i;
1661  m_injectedRoutes.erase (i);
1662  return;
1663  }
1664  tmp++;
1665  }
1666 }
1667 
1668 bool
1669 GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
1670 {
1671  NS_LOG_FUNCTION (this << network << networkMask);
1672  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
1673  {
1674  if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
1675  {
1676  NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
1677  delete *i;
1678  m_injectedRoutes.erase (i);
1679  return true;
1680  }
1681  }
1682  return false;
1683 }
1684 
1685 
1686 //
1687 // Link through the given channel and find the net device that's on the
1688 // other end. This only makes sense with a point-to-point channel.
1689 //
1690 Ptr<NetDevice>
1691 GlobalRouter::GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const
1692 {
1693  NS_LOG_FUNCTION (this << nd << ch);
1694  NS_ASSERT_MSG (ch->GetNDevices () == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices");
1695 //
1696 // This is a point to point channel with two endpoints. Get both of them.
1697 //
1698  Ptr<NetDevice> nd1 = ch->GetDevice (0);
1699  Ptr<NetDevice> nd2 = ch->GetDevice (1);
1700 //
1701 // One of the endpoints is going to be "us" -- that is the net device attached
1702 // to the node on which we're running -- i.e., "nd". The other endpoint (the
1703 // one to which we are connected via the channel) is the adjacent router.
1704 //
1705  if (nd1 == nd)
1706  {
1707  return nd2;
1708  }
1709  else if (nd2 == nd)
1710  {
1711  return nd1;
1712  }
1713  else
1714  {
1715  NS_ASSERT_MSG (false,
1716  "GlobalRouter::GetAdjacent (): Wrong or confused channel?");
1717  return 0;
1718  }
1719 }
1720 
1721 //
1722 // Given a node and a net device, find an IPV4 interface index that corresponds
1723 // to that net device. This function may fail for various reasons. If a node
1724 // does not have an internet stack (for example if it is a bridge) we won't have
1725 // an IPv4 at all. If the node does have a stack, but the net device in question
1726 // is bridged, there will not be an interface associated directly with the device.
1727 //
1728 bool
1729 GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
1730 {
1731  NS_LOG_FUNCTION (this << node << nd << &index);
1732  NS_LOG_LOGIC ("For node " << node->GetId () << " for net device " << nd );
1733 
1734  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
1735  if (ipv4 == 0)
1736  {
1737  NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ());
1738  return false;
1739  }
1740 
1741  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); ++i )
1742  {
1743  if (ipv4->GetNetDevice (i) == nd)
1744  {
1745  NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i);
1746  index = i;
1747  return true;
1748  }
1749  }
1750 
1751  NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index");
1752  return false;
1753 }
1754 
1755 //
1756 // Decide whether or not a given net device is being bridged by a BridgeNetDevice.
1757 //
1758 Ptr<BridgeNetDevice>
1759 GlobalRouter::NetDeviceIsBridged (Ptr<NetDevice> nd) const
1760 {
1761  NS_LOG_FUNCTION (this << nd);
1762 
1763  Ptr<Node> node = nd->GetNode ();
1764  uint32_t nDevices = node->GetNDevices ();
1765 
1766  //
1767  // There is no bit on a net device that says it is being bridged, so we have
1768  // to look for bridges on the node to which the device is attached. If we
1769  // find a bridge, we need to look through its bridge ports (the devices it
1770  // bridges) to see if we find the device in question.
1771  //
1772  for (uint32_t i = 0; i < nDevices; ++i)
1773  {
1774  Ptr<NetDevice> ndTest = node->GetDevice (i);
1775  NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
1776 
1777  if (ndTest->IsBridge ())
1778  {
1779  NS_LOG_LOGIC ("device " << i << " is a bridge net device");
1780  Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
1781  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
1782 
1783  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
1784  {
1785  NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
1786  if (bnd->GetBridgePort (j) == nd)
1787  {
1788  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
1789  return bnd;
1790  }
1791  }
1792  }
1793  }
1794  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
1795  return 0;
1796 }
1797 
1798 //
1799 // Start a new enumeration of an L2 broadcast domain by clearing m_bridgesVisited
1800 //
1801 void
1803 {
1804  m_bridgesVisited.clear();
1805 }
1806 
1807 //
1808 // Check if we have already visited a given bridge net device by searching m_bridgesVisited
1809 //
1810 bool
1812 {
1813  std::vector<Ptr<BridgeNetDevice> >::iterator iter;
1814  for (iter = m_bridgesVisited.begin (); iter != m_bridgesVisited.end (); ++iter)
1815  {
1816  if (bridgeNetDevice == *iter)
1817  {
1818  NS_LOG_LOGIC ("Bridge " << bridgeNetDevice << " has been visited.");
1819  return true;
1820  }
1821  }
1822  return false;
1823 }
1824 
1825 //
1826 // Remember that we visited a bridge net device by adding it to m_bridgesVisited
1827 //
1828 void
1830 {
1831  NS_LOG_FUNCTION (this << bridgeNetDevice);
1832  m_bridgesVisited.push_back (bridgeNetDevice);
1833 }
1834 
1835 
1836 } // namespace ns3
void SetRoutingProtocol(Ptr< Ipv4GlobalRouting > routing)
Set the specific Global Routing Protocol to be used.
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
Decide whether or not a given net device is being bridged by a BridgeNetDevice.
LSType GetLSType(void) const
Return the LSType field of the LSA.
Ptr< Ipv4GlobalRouting > GetRoutingProtocol(void)
Get the specific Global Routing Protocol used.
GlobalRoutingLinkRecord * GetLinkRecord(uint32_t n) const
Return a pointer to the specified Global Routing Link Record.
virtual void DoDispose(void)
Destructor implementation.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Record represents a leaf node network.
~GlobalRoutingLSA()
Destroy an existing Global Routing Link State Advertisement.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
Ipv4Address m_advertisingRtr
The Advertising Router is defined by the OSPF spec.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
static Ptr< Node > GetNode(uint32_t n)
Definition: node-list.cc:241
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
std::list< Ipv4RoutingTableEntry * >::const_iterator InjectedRoutesCI
Const Iterator to container of Ipv4RoutingTableEntry.
static TypeId GetTypeId(void)
Get the type ID.
bool WithdrawRoute(Ipv4Address network, Ipv4Mask networkMask)
Withdraw a route from the global unicast routing table.
bool FindInterfaceForDevice(Ptr< Node > node, Ptr< NetDevice > nd, uint32_t &index) const
Given a node and a net device, find an IPV4 interface index that corresponds to that net device...
uint32_t DiscoverLSAs(void)
Walk the connected channels, discover the adjacent routers and build the associated number of Global ...
void SetAdvertisingRouter(Ipv4Address rtr)
Set the Advertising Router as defined by the OSPF spec.
LSType m_lsType
The type of the LSA.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
uint32_t AddLinkRecord(GlobalRoutingLinkRecord *lr)
Add a given Global Routing Link Record to the LSA.
NetDeviceContainer FindAllNonBridgedDevicesOnLink(Ptr< Channel > ch) const
Return a container of all non-bridged NetDevices on a link.
Ipv4Mask m_networkLSANetworkMask
Each Network LSA contains the network mask of the attached network.
Ipv4Address CombineMask(Ipv4Mask const &mask) const
Combine this address with a network mask.
bool GetLSA(uint32_t n, GlobalRoutingLSA &lsa) const
Get a Global Routing Link State Advertisements that this router has said that it can export...
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
a virtual net device that bridges multiple LAN segments
uint32_t GetNInjectedRoutes(void)
Get the number of injected routes that have been added to the routing table.
void ProcessSingleBroadcastLink(Ptr< NetDevice > nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
Process a single broadcast link.
Ipv4Address FindDesignatedRouterForLink(Ptr< NetDevice > ndLocal) const
Finds a designated router.
uint32_t AddAttachedRouter(Ipv4Address addr)
Add an attached router to the list in the NetworkLSA.
InjectedRoutes m_injectedRoutes
Routes we are exporting.
Ipv4Mask GetNetworkLSANetworkMask(void) const
For a Network LSA, get the Network Mask field that precedes the list of attached routers.
void SetNode(Ptr< Node > node)
Set the Node pointer of the node that originated this LSA.
Ipv4Address GetAdvertisingRouter(void) const
Get the Advertising Router as defined by the OSPF spec.
void ClearLinkRecords(void)
Release all of the Global Routing Link Records present in the Global Routing Link State Advertisement...
Ipv4RoutingTableEntry * GetInjectedRoute(uint32_t i)
Return the injected route indexed by i.
uint32_t GetN(void) const
Get the number of Ptr stored in this container.
LSType
corresponds to LS type field of RFC 2328 OSPF LSA header
Ptr< Ipv4GlobalRouting > m_routingProtocol
the Ipv4GlobalRouting in use
a Link State Advertisement (LSA) for a router, used in global routing.
void InjectRoute(Ipv4Address network, Ipv4Mask networkMask)
Inject a route to be circulated to other routers as an external route.
void ClearLSAs(void)
Clear list of LSAs.
Unused – for future OSPF compatibility.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static Ipv4RoutingTableEntry CreateNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
LinkType
Enumeration of the possible types of Global Routing Link Records.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
void SetLSType(LSType typ)
Set the LS type field of the LSA.
void Print(std::ostream &os) const
Print the contents of the Global Routing Link State Advertisement and any Global Routing Link Records...
void RemoveInjectedRoute(uint32_t i)
Withdraw a route from the global unicast routing table.
SPFStatus GetStatus(void) const
Get the SPF status of the advertisement.
Record representing a point to point channel.
SPFStatus m_status
This is a tristate flag used internally in the SPF computation to mark if an SPFVertex (a data struct...
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
uint32_t GetNDevices(void) const
Definition: node.cc:150
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
void SetStatus(SPFStatus status)
Set the SPF status of the advertisement.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t GetNAttachedRouters(void) const
Return the number of attached routers listed in the NetworkLSA.
uint32_t GetNLinkRecords(void) const
Return the number of Global Routing Link Records in the LSA.
Ptr< NetDevice > GetAdjacent(Ptr< NetDevice > nd, Ptr< Channel > ch) const
Link through the given channel and find the net device that's on the other end.
ListOfLSAs_t m_LSAs
database of GlobalRoutingLSAs
void BuildNetworkLSAs(NetDeviceContainer c)
Build one NetworkLSA for each net device talking to a network that we are the designated router for...
std::vector< Ptr< BridgeNetDevice > > m_bridgesVisited
Container of bridges visited.
bool BridgeHasAlreadyBeenVisited(Ptr< BridgeNetDevice > device) const
When recursively checking for devices on the link, check whether a given device has already been visi...
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
An interface aggregated to a node to provide global routing info.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:90
Ipv4Address m_routerId
router ID (its IPv4 address)
Ipv4Address m_linkStateId
The Link State ID is defined by the OSPF spec.
void Set(uint32_t address)
input address is in host order.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void CopyLinkRecords(const GlobalRoutingLSA &lsa)
Copy any Global Routing Link Records in a given Global Routing Link State Advertisement to the curren...
GlobalRoutingLSA & operator=(const GlobalRoutingLSA &lsa)
Assignment operator for a Global Routing Link State Advertisement.
void MarkBridgeAsVisited(Ptr< BridgeNetDevice > device) const
When recursively checking for devices on the link, mark a given device as having been visited...
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
uint32_t GetId(void) const
Definition: node.cc:107
void SetNetworkLSANetworkMask(Ipv4Mask mask)
For a Network LSA, set the Network Mask field that precedes the list of attached routers.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
static uint32_t AllocateRouterId()
Allocate a 32-bit router ID from monotonically increasing counter.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
SPFStatus
Enumeration of the possible values of the status flag in the Routing Link State Advertisements.
uint32_t GetNumLSAs(void) const
Get the Number of Global Routing Link State Advertisements that this router can export.
GlobalRouter()
Create a Global Router class.
Ipv4Address GetRouterId(void) const
Get the Router ID associated with this Global Router.
void ClearBridgesVisited(void) const
Clear the list of bridges visited on the link.
Ipv4Address GetAttachedRouter(uint32_t n) const
Return an Ipv4Address corresponding to the specified attached router.
Ptr< Node > GetNode(void) const
Get the Node pointer of the node that originated this LSA.
ListOfAttachedRouters_t m_attachedRouters
Each Network LSA contains a list of attached routers.
uint32_t Get(void) const
Get the host-order 32-bit IP mask.
void ProcessPointToPointLink(Ptr< NetDevice > ndLocal, GlobalRoutingLSA *pLSA)
Process a point to point link.
bool IsEmpty(void) const
Check to see if the list of Global Routing Link Records present in the Global Routing Link State Adve...
A base class which provides memory management and object aggregation.
Definition: object.h:87
GlobalRoutingLSA()
Create a blank Global Routing Link State Advertisement.
void ProcessBridgedBroadcastLink(Ptr< NetDevice > nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
Process a bridged broadcast link.
ListOfLinkRecords_t m_linkRecords
Each Link State Advertisement contains a number of Link Records that describe the kinds of links that...
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
void SetLinkStateId(Ipv4Address addr)
Set the Link State ID is defined by the OSPF spec.
Ipv4Address GetLinkStateId(void) const
Get the Link State ID as defined by the OSPF spec.
std::list< Ipv4RoutingTableEntry * >::iterator InjectedRoutesI
Iterator to container of Ipv4RoutingTableEntry.
void ProcessBroadcastLink(Ptr< NetDevice > nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
Process a generic broadcast link.
bool AnotherRouterOnLink(Ptr< NetDevice > nd) const
Checks for the presence of another router on the NetDevice.