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;
411  {
412  os << " (GlobalRoutingLSA::RouterLSA)";
413  }
415  {
416  os << " (GlobalRoutingLSA::NetworkLSA)";
417  }
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 
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  }
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  }
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 supports
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  //
841  Ipv4Address desigRtr;
842  desigRtr = FindDesignatedRouterForLink (nd);
843 
844  //
845  // Let's double-check that any designated router we find out on our
846  // network is really on our network.
847  //
848  if (desigRtr != "255.255.255.255")
849  {
850  Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
851  Ipv4Address networkThere = desigRtr.CombineMask (maskLocal);
852  NS_ABORT_MSG_UNLESS (networkHere == networkThere,
853  "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
854  }
855  if (desigRtr == addrLocal)
856  {
857  c.Add (nd);
858  NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
859  }
860  plr->SetLinkId (desigRtr);
861 
862  //
863  // OSPF says that the Link Data is this router's own IP address.
864  //
865  plr->SetLinkData (addrLocal);
866  plr->SetMetric (metricLocal);
867  pLSA->AddLinkRecord (plr);
868  plr = 0;
869  }
870 }
871 
872 void
874 {
875  NS_LOG_FUNCTION (this << nd << pLSA << &c);
876  NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
877 
878 #if 0
879  //
880  // It is possible to admit the possibility that a bridge device on a node
881  // can also participate in routing. This would surprise people who don't
882  // come from Microsoft-land where they do use such a construct. Based on
883  // the principle of least-surprise, we will leave the relatively simple
884  // code in place to do this, but not enable it until someone really wants
885  // the capability. Even then, we will not enable this code as a default
886  // but rather something you will have to go and turn on.
887  //
888 
889  Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
890  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
891 
892  //
893  // We have some preliminaries to do to get enough information to proceed.
894  // This information we need comes from the internet stack, so notice that
895  // there is an implied assumption that global routing is only going to
896  // work with devices attached to the internet stack (have an ipv4 interface
897  // associated to them.
898  //
899  Ptr<Node> node = nd->GetNode ();
900  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
901  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
902 
903  // Initialize to value out of bounds to silence compiler
904  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
905  bool rc = FindInterfaceForDevice (node, nd, interfaceLocal);
906  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
907 
908  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
909  {
910  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
911  }
912  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
913  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
914  NS_LOG_LOGIC ("Working with local address " << addrLocal);
915  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
916 
917  //
918  // We need to handle a bridge on the router. This means that we have been
919  // given a net device that is a BridgeNetDevice. It has an associated Ipv4
920  // interface index and address. Some number of other net devices live "under"
921  // the bridge device as so-called bridge ports. In a nutshell, what we have
922  // to do is to repeat what is done for a single broadcast link on all of
923  // those net devices living under the bridge (trolls?)
924  //
925 
926  bool areTransitNetwork = false;
927  Ipv4Address desigRtr ("255.255.255.255");
928 
929  for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
930  {
931  Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
932 
933  //
934  // We have to decide if we are a transit network. This is characterized
935  // by the presence of another router on the network segment. If we find
936  // another router on any of our bridged links, we are a transit network.
937  //
939  if (AnotherRouterOnLink (ndTemp))
940  {
941  areTransitNetwork = true;
942 
943  //
944  // If we're going to be a transit network, then we have got to elect
945  // a designated router for the whole bridge. This means finding the
946  // router with the lowest IP address on the whole bridge. We ask
947  // for the lowest address on each segment and pick the lowest of them
948  // all.
949  //
951  Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp);
952 
953  //
954  // Let's double-check that any designated router we find out on our
955  // network is really on our network.
956  //
957  if (desigRtrTemp != "255.255.255.255")
958  {
959  Ipv4Address networkHere = addrLocal.CombineMask (maskLocal);
960  Ipv4Address networkThere = desigRtrTemp.CombineMask (maskLocal);
961  NS_ABORT_MSG_UNLESS (networkHere == networkThere,
962  "GlobalRouter::ProcessSingleBroadcastLink(): Network number confusion");
963  }
964  if (desigRtrTemp < desigRtr)
965  {
966  desigRtr = desigRtrTemp;
967  }
968  }
969  }
970  //
971  // That's all the information we need to put it all together, just like we did
972  // in the case of a single broadcast link.
973  //
974 
976  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
977 
978  if (areTransitNetwork == false)
979  {
980  //
981  // This is a net device connected to a bridge of stub networks
982  //
983  NS_LOG_LOGIC ("Router-LSA Stub Network");
985 
986  //
987  // According to OSPF, the Link ID is the IP network number of
988  // the attached network.
989  //
990  plr->SetLinkId (addrLocal.CombineMask (maskLocal));
991 
992  //
993  // and the Link Data is the network mask; converted to Ipv4Address
994  //
995  Ipv4Address maskLocalAddr;
996  maskLocalAddr.Set (maskLocal.Get ());
997  plr->SetLinkData (maskLocalAddr);
998  plr->SetMetric (metricLocal);
999  pLSA->AddLinkRecord (plr);
1000  plr = 0;
1001  }
1002  else
1003  {
1004  //
1005  // We have multiple routers on a bridged broadcast interface, so this is
1006  // a transit network.
1007  //
1008  NS_LOG_LOGIC ("Router-LSA Transit Network");
1010 
1011  //
1012  // By definition, the router with the lowest IP address is the
1013  // designated router for the network. OSPF says that the Link ID
1014  // gets the IP interface address of the designated router in this
1015  // case.
1016  //
1017  if (desigRtr == addrLocal)
1018  {
1019  c.Add (nd);
1020  NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
1021  }
1022  plr->SetLinkId (desigRtr);
1023 
1024  //
1025  // OSPF says that the Link Data is this router's own IP address.
1026  //
1027  plr->SetLinkData (addrLocal);
1028  plr->SetMetric (metricLocal);
1029  pLSA->AddLinkRecord (plr);
1030  plr = 0;
1031  }
1032 #endif
1033 }
1034 
1035 void
1037 {
1038  NS_LOG_FUNCTION (this << ndLocal << pLSA);
1039 
1040  //
1041  // We have some preliminaries to do to get enough information to proceed.
1042  // This information we need comes from the internet stack, so notice that
1043  // there is an implied assumption that global routing is only going to
1044  // work with devices attached to the internet stack (have an ipv4 interface
1045  // associated to them.
1046  //
1047  Ptr<Node> nodeLocal = ndLocal->GetNode ();
1048 
1049  Ptr<Ipv4> ipv4Local = nodeLocal->GetObject<Ipv4> ();
1050  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
1051 
1052  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
1053  bool rc = FindInterfaceForDevice (nodeLocal, ndLocal, interfaceLocal);
1054  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLink (): No interface index associated with device");
1055 
1056  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
1057  {
1058  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1059  }
1060  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
1061  NS_LOG_LOGIC ("Working with local address " << addrLocal);
1062  uint16_t metricLocal = ipv4Local->GetMetric (interfaceLocal);
1063 
1064  //
1065  // Now, we're going to walk over to the remote net device on the other end of
1066  // the point-to-point channel we know we have. This is where our adjacent
1067  // router (to use OSPF lingo) is running.
1068  //
1069  Ptr<Channel> ch = ndLocal->GetChannel ();
1070 
1071  //
1072  // Get the net device on the other side of the point-to-point channel.
1073  //
1074  Ptr<NetDevice> ndRemote = GetAdjacent (ndLocal, ch);
1075 
1076  //
1077  // The adjacent net device is aggregated to a node. We need to ask that net
1078  // device for its node, then ask that node for its Ipv4 interface. Note a
1079  // requirement that nodes on either side of a point-to-point link must have
1080  // internet stacks; and an assumption that point-to-point links are incompatible
1081  // with bridging.
1082  //
1083  Ptr<Node> nodeRemote = ndRemote->GetNode ();
1084  Ptr<Ipv4> ipv4Remote = nodeRemote->GetObject<Ipv4> ();
1085  NS_ABORT_MSG_UNLESS (ipv4Remote,
1086  "GlobalRouter::ProcessPointToPointLink(): GetObject for remote <Ipv4> failed");
1087 
1088  //
1089  // Further note the requirement that nodes on either side of a point-to-point
1090  // link must participate in global routing and therefore have a GlobalRouter
1091  // interface aggregated.
1092  //
1093  Ptr<GlobalRouter> rtrRemote = nodeRemote->GetObject<GlobalRouter> ();
1094  if (rtrRemote == 0)
1095  {
1096  // This case is possible if the remote does not participate in global routing
1097  return;
1098  }
1099  //
1100  // We're going to need the remote router ID, so we might as well get it now.
1101  //
1102  Ipv4Address rtrIdRemote = rtrRemote->GetRouterId ();
1103  NS_LOG_LOGIC ("Working with remote router " << rtrIdRemote);
1104 
1105  //
1106  // Now, just like we did above, we need to get the IP interface index for the
1107  // net device on the other end of the point-to-point channel.
1108  //
1109  uint32_t interfaceRemote = ipv4Remote->GetNInterfaces () + 1;
1110  rc = FindInterfaceForDevice (nodeRemote, ndRemote, interfaceRemote);
1111  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
1112 
1113  //
1114  // Now that we have the Ipv4 interface, we can get the (remote) address and
1115  // mask we need.
1116  //
1117  if (ipv4Remote->GetNAddresses (interfaceRemote) > 1)
1118  {
1119  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1120  }
1121  Ipv4Address addrRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetLocal ();
1122  Ipv4Mask maskRemote = ipv4Remote->GetAddress (interfaceRemote, 0).GetMask ();
1123  NS_LOG_LOGIC ("Working with remote address " << addrRemote);
1124 
1125  //
1126  // Now we can fill out the link records for this link. There are always two
1127  // link records; the first is a point-to-point record describing the link and
1128  // the second is a stub network record with the network number.
1129  //
1131  if (ipv4Remote->IsUp (interfaceRemote))
1132  {
1133  NS_LOG_LOGIC ("Remote side interface " << interfaceRemote << " is up-- add a type 1 link");
1134 
1136  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
1138  plr->SetLinkId (rtrIdRemote);
1139  plr->SetLinkData (addrLocal);
1140  plr->SetMetric (metricLocal);
1141  pLSA->AddLinkRecord (plr);
1142  plr = 0;
1143  }
1144 
1145  // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
1147  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
1149  plr->SetLinkId (addrRemote);
1150  plr->SetLinkData (Ipv4Address (maskRemote.Get ())); // Frown
1151  plr->SetMetric (metricLocal);
1152  pLSA->AddLinkRecord (plr);
1153  plr = 0;
1154 }
1155 
1156 void
1158 {
1159  NS_LOG_FUNCTION (this << &c);
1160 
1161  uint32_t nDesignatedRouters = c.GetN ();
1162  NS_LOG_DEBUG ("Number of designated routers: " << nDesignatedRouters);
1163 
1164  for (uint32_t i = 0; i < nDesignatedRouters; ++i)
1165  {
1166  //
1167  // Build one NetworkLSA for each net device talking to a network that we are the
1168  // designated router for. These devices are in the provided container.
1169  //
1170  Ptr<NetDevice> ndLocal = c.Get (i);
1171  Ptr<Node> node = ndLocal->GetNode ();
1172 
1173  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
1174  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessPointToPointLink (): GetObject for <Ipv4> interface failed");
1175 
1176  uint32_t interfaceLocal = ipv4Local->GetNInterfaces () + 1;
1177  bool rc = FindInterfaceForDevice (node, ndLocal, interfaceLocal);
1178  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::BuildNetworkLSAs (): No interface index associated with device");
1179 
1180  if (ipv4Local->GetNAddresses (interfaceLocal) > 1)
1181  {
1182  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1183  }
1184  Ipv4Address addrLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetLocal ();
1185  Ipv4Mask maskLocal = ipv4Local->GetAddress (interfaceLocal, 0).GetMask ();
1186 
1187  GlobalRoutingLSA *pLSA = new GlobalRoutingLSA;
1188  NS_ABORT_MSG_IF (pLSA == 0, "GlobalRouter::BuildNetworkLSAs(): Can't alloc link record");
1189 
1191  pLSA->SetLinkStateId (addrLocal);
1193  pLSA->SetNetworkLSANetworkMask (maskLocal);
1195  pLSA->SetNode (node);
1196 
1197  //
1198  // Build a list of AttachedRouters by walking the devices in the channel
1199  // and, if we find a node with a GlobalRouter interface and an IPv4
1200  // interface associated with that device, we call it an attached router.
1201  //
1203  Ptr<Channel> ch = ndLocal->GetChannel ();
1204  std::size_t nDevices = ch->GetNDevices ();
1205  NS_ASSERT (nDevices);
1207  NS_LOG_LOGIC ("Found " << deviceList.GetN () << " non-bridged devices on channel");
1208 
1209  for (uint32_t i = 0; i < deviceList.GetN (); i++)
1210  {
1211  Ptr<NetDevice> tempNd = deviceList.Get (i);
1212  NS_ASSERT (tempNd);
1213  if (tempNd == ndLocal)
1214  {
1215  NS_LOG_LOGIC ("Adding " << addrLocal << " to Network LSA");
1216  pLSA->AddAttachedRouter (addrLocal);
1217  continue;
1218  }
1219  Ptr<Node> tempNode = tempNd->GetNode ();
1220 
1221  // Does the node in question have a GlobalRouter interface? If not it can
1222  // hardly be considered an attached router.
1223  //
1224  Ptr<GlobalRouter> rtr = tempNode->GetObject<GlobalRouter> ();
1225  if (rtr == 0)
1226  {
1227  NS_LOG_LOGIC ("Node " << tempNode->GetId () << " does not have GlobalRouter interface--skipping");
1228  continue;
1229  }
1230 
1231  //
1232  // Does the attached node have an ipv4 interface for the device we're probing?
1233  // If not, it can't play router.
1234  //
1235  uint32_t tempInterface = 0;
1236  if (FindInterfaceForDevice (tempNode, tempNd, tempInterface))
1237  {
1238  Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
1239  NS_ASSERT (tempIpv4);
1240  if (!tempIpv4->IsUp (tempInterface))
1241  {
1242  NS_LOG_LOGIC ("Remote side interface " << tempInterface << " not up");
1243  }
1244  else
1245  {
1246  if (tempIpv4->GetNAddresses (tempInterface) > 1)
1247  {
1248  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1249  }
1250  Ipv4Address tempAddr = tempIpv4->GetAddress (tempInterface, 0).GetLocal ();
1251  NS_LOG_LOGIC ("Adding " << tempAddr << " to Network LSA");
1252  pLSA->AddAttachedRouter (tempAddr);
1253  }
1254  }
1255  else
1256  {
1257  NS_LOG_LOGIC ("Node " << tempNode->GetId () << " device " << tempNd << " does not have IPv4 interface; skipping");
1258  }
1259  }
1260  m_LSAs.push_back (pLSA);
1261  NS_LOG_LOGIC ("========== LSA for node " << node->GetId () << " ==========");
1262  NS_LOG_LOGIC (*pLSA);
1263  pLSA = 0;
1264  }
1265 }
1266 
1269 {
1270  NS_LOG_FUNCTION (this << ch);
1272 
1273  for (std::size_t i = 0; i < ch->GetNDevices (); i++)
1274  {
1275  Ptr<NetDevice> nd = ch->GetDevice (i);
1276  NS_LOG_LOGIC ("checking to see if the device " << nd << " is bridged");
1278  if (bnd && BridgeHasAlreadyBeenVisited (bnd) == false)
1279  {
1280  NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd << " with " << bnd->GetNBridgePorts () << " ports");
1281  MarkBridgeAsVisited (bnd);
1282  // Find all channels bridged together, and recursively call
1283  // on all other channels
1284  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); j++)
1285  {
1286  Ptr<NetDevice> bridgedDevice = bnd->GetBridgePort (j);
1287  if (bridgedDevice->GetChannel () == ch)
1288  {
1289  NS_LOG_LOGIC ("Skipping my own device/channel");
1290  continue;
1291  }
1292  NS_LOG_LOGIC ("Calling on channel " << bridgedDevice->GetChannel ());
1293  c.Add (FindAllNonBridgedDevicesOnLink (bridgedDevice->GetChannel ()));
1294  }
1295  }
1296  else
1297  {
1298  NS_LOG_LOGIC ("Device is not bridged; adding");
1299  c.Add (nd);
1300  }
1301  }
1302  NS_LOG_LOGIC ("Found " << c.GetN () << " devices");
1303  return c;
1304 }
1305 
1306 //
1307 // Given a local net device, we need to walk the channel to which the net device is
1308 // attached and look for nodes with GlobalRouter interfaces on them (one of them
1309 // will be us). Of these, the router with the lowest IP address on the net device
1310 // connecting to the channel becomes the designated router for the link.
1311 //
1312 Ipv4Address
1313 GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal) const
1314 {
1315  NS_LOG_FUNCTION (this << ndLocal);
1316 
1317  Ptr<Channel> ch = ndLocal->GetChannel ();
1318  uint32_t nDevices = ch->GetNDevices ();
1319  NS_ASSERT (nDevices);
1320 
1321  NS_LOG_LOGIC ("Looking for designated router off of net device " << ndLocal << " on node " <<
1322  ndLocal->GetNode ()->GetId ());
1323 
1324  Ipv4Address desigRtr ("255.255.255.255");
1325 
1326  //
1327  // Look through all of the devices on the channel to which the net device
1328  // in question is attached.
1329  //
1330  for (uint32_t i = 0; i < nDevices; i++)
1331  {
1332  Ptr<NetDevice> ndOther = ch->GetDevice (i);
1333  NS_ASSERT (ndOther);
1334 
1335  Ptr<Node> nodeOther = ndOther->GetNode ();
1336 
1337  NS_LOG_LOGIC ("Examine channel device " << i << " on node " << nodeOther->GetId ());
1338 
1339  //
1340  // For all other net devices, we need to check and see if a router
1341  // is present. If the net device on the other side is a bridged
1342  // device, we need to consider all of the other devices on the
1343  // bridge as well (all of the bridge ports.
1344  //
1345  NS_LOG_LOGIC ("checking to see if the device is bridged");
1346  Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
1347  if (bnd)
1348  {
1349  NS_LOG_LOGIC ("Device is bridged by BridgeNetDevice " << bnd);
1350 
1351  //
1352  // When enumerating a bridge, don't count the netdevice we came in on
1353  //
1354  if (ndLocal == ndOther)
1355  {
1356  NS_LOG_LOGIC ("Skip -- it is where we came from.");
1357  continue;
1358  }
1359 
1360  //
1361  // It is possible that the bridge net device is sitting under a
1362  // router, so we have to check for the presence of that router
1363  // before we run off and follow all the links
1364  //
1365  // We require a designated router to have a GlobalRouter interface and
1366  // an internet stack that includes the Ipv4 interface. If it doesn't
1367  // it can't play router.
1368  //
1369  NS_LOG_LOGIC ("Checking for router on bridge net device " << bnd);
1370  Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
1371  Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
1372  if (rtr && ipv4)
1373  {
1374  // Initialize to value out of bounds to silence compiler
1375  uint32_t interfaceOther = ipv4->GetNInterfaces () + 1;
1376  if (FindInterfaceForDevice (nodeOther, bnd, interfaceOther))
1377  {
1378  NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
1379  if (!ipv4->IsUp (interfaceOther))
1380  {
1381  NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
1382  continue;
1383  }
1384  if (ipv4->GetNAddresses (interfaceOther) > 1)
1385  {
1386  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1387  }
1388  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
1389  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
1390  NS_LOG_LOGIC ("designated router now " << desigRtr);
1391  }
1392  }
1393 
1394  //
1395  // Check if we have seen this bridge net device already while
1396  // recursively enumerating an L2 broadcast domain. If it is new
1397  // to us, go ahead and process it. If we have already processed it,
1398  // move to the next
1399  //
1401  {
1402  NS_ABORT_MSG ("ERROR: L2 forwarding loop detected!");
1403  }
1404 
1405  MarkBridgeAsVisited(bnd);
1406 
1407  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
1408  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
1409  {
1410  Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
1411  NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
1412  if (ndBridged == ndOther)
1413  {
1414  NS_LOG_LOGIC ("That bridge port is me, don't walk backward");
1415  continue;
1416  }
1417 
1418  NS_LOG_LOGIC ("Recursively looking for routers down bridge port " << ndBridged);
1419  Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged);
1420  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
1421  NS_LOG_LOGIC ("designated router now " << desigRtr);
1422  }
1423  }
1424  else
1425  {
1426  NS_LOG_LOGIC ("This device is not bridged");
1427  Ptr<Node> nodeOther = ndOther->GetNode ();
1428  NS_ASSERT (nodeOther);
1429 
1430  //
1431  // We require a designated router to have a GlobalRouter interface and
1432  // an internet stack that includes the Ipv4 interface. If it doesn't
1433  //
1434  Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
1435  Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
1436  if (rtr && ipv4)
1437  {
1438  // Initialize to value out of bounds to silence compiler
1439  uint32_t interfaceOther = ipv4->GetNInterfaces () + 1;
1440  if (FindInterfaceForDevice (nodeOther, ndOther, interfaceOther))
1441  {
1442  if (!ipv4->IsUp (interfaceOther))
1443  {
1444  NS_LOG_LOGIC ("Remote side interface " << interfaceOther << " not up");
1445  continue;
1446  }
1447  NS_LOG_LOGIC ("Found router on net device " << ndOther);
1448  if (ipv4->GetNAddresses (interfaceOther) > 1)
1449  {
1450  NS_LOG_WARN ("Warning, interface has multiple IP addresses; using only the primary one");
1451  }
1452  Ipv4Address addrOther = ipv4->GetAddress (interfaceOther, 0).GetLocal ();
1453  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
1454  NS_LOG_LOGIC ("designated router now " << desigRtr);
1455  }
1456  }
1457  }
1458  }
1459  return desigRtr;
1460 }
1461 
1462 //
1463 // Given a node and an attached net device, take a look off in the channel to
1464 // which the net device is attached and look for a node on the other side
1465 // that has a GlobalRouter interface aggregated. Life gets more complicated
1466 // when there is a bridged net device on the other side.
1467 //
1468 bool
1469 GlobalRouter::AnotherRouterOnLink (Ptr<NetDevice> nd) const
1470 {
1471  NS_LOG_FUNCTION (this << nd);
1472 
1473  Ptr<Channel> ch = nd->GetChannel ();
1474  if (!ch)
1475  {
1476  // It may be that this net device is a stub device, without a channel
1477  return false;
1478  }
1479  uint32_t nDevices = ch->GetNDevices ();
1480  NS_ASSERT (nDevices);
1481 
1482  NS_LOG_LOGIC ("Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
1483 
1484  //
1485  // Look through all of the devices on the channel to which the net device
1486  // in question is attached.
1487  //
1488  for (uint32_t i = 0; i < nDevices; i++)
1489  {
1490  Ptr<NetDevice> ndOther = ch->GetDevice (i);
1491  NS_ASSERT (ndOther);
1492 
1493  NS_LOG_LOGIC ("Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
1494 
1495  //
1496  // Ignore the net device itself.
1497  //
1498  if (ndOther == nd)
1499  {
1500  NS_LOG_LOGIC ("Myself, skip");
1501  continue;
1502  }
1503 
1504  //
1505  // For all other net devices, we need to check and see if a router
1506  // is present. If the net device on the other side is a bridged
1507  // device, we need to consider all of the other devices on the
1508  // bridge.
1509  //
1510  NS_LOG_LOGIC ("checking to see if device is bridged");
1511  Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
1512  if (bnd)
1513  {
1514  NS_LOG_LOGIC ("Device is bridged by net device " << bnd);
1515 
1516  //
1517  // Check if we have seen this bridge net device already while
1518  // recursively enumerating an L2 broadcast domain. If it is new
1519  // to us, go ahead and process it. If we have already processed it,
1520  // move to the next
1521  //
1523  {
1524  NS_ABORT_MSG ("ERROR: L2 forwarding loop detected!");
1525  }
1526 
1527  MarkBridgeAsVisited(bnd);
1528 
1529  NS_LOG_LOGIC ("Looking through bridge ports of bridge net device " << bnd);
1530  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
1531  {
1532  Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
1533  NS_LOG_LOGIC ("Examining bridge port " << j << " device " << ndBridged);
1534  if (ndBridged == ndOther)
1535  {
1536  NS_LOG_LOGIC ("That bridge port is me, skip");
1537  continue;
1538  }
1539 
1540  NS_LOG_LOGIC ("Recursively looking for routers on bridge port " << ndBridged);
1541  if (AnotherRouterOnLink (ndBridged))
1542  {
1543  NS_LOG_LOGIC ("Found routers on bridge port, return true");
1544  return true;
1545  }
1546  }
1547  NS_LOG_LOGIC ("No routers on bridged net device, return false");
1548  return false;
1549  }
1550 
1551  NS_LOG_LOGIC ("This device is not bridged");
1552  Ptr<Node> nodeTemp = ndOther->GetNode ();
1553  NS_ASSERT (nodeTemp);
1554 
1555  Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
1556  if (rtr)
1557  {
1558  NS_LOG_LOGIC ("Found GlobalRouter interface, return true");
1559  return true;
1560  }
1561  else
1562  {
1563  NS_LOG_LOGIC ("No GlobalRouter interface on device, continue search");
1564  }
1565  }
1566  NS_LOG_LOGIC ("No routers found, return false");
1567  return false;
1568 }
1569 
1570 uint32_t
1571 GlobalRouter::GetNumLSAs (void) const
1572 {
1573  NS_LOG_FUNCTION (this);
1574  return m_LSAs.size ();
1575 }
1576 
1577 //
1578 // Get the nth link state advertisement from this router.
1579 //
1580 bool
1581 GlobalRouter::GetLSA (uint32_t n, GlobalRoutingLSA &lsa) const
1582 {
1583  NS_LOG_FUNCTION (this << n << &lsa);
1584  NS_ASSERT_MSG (lsa.IsEmpty (), "GlobalRouter::GetLSA (): Must pass empty LSA");
1585 //
1586 // All of the work was done in GetNumLSAs. All we have to do here is to
1587 // walk the list of link state advertisements created there and return the
1588 // one the client is interested in.
1589 //
1590  ListOfLSAs_t::const_iterator i = m_LSAs.begin ();
1591  uint32_t j = 0;
1592 
1593  for (; i != m_LSAs.end (); i++, j++)
1594  {
1595  if (j == n)
1596  {
1597  GlobalRoutingLSA *p = *i;
1598  lsa = *p;
1599  return true;
1600  }
1601  }
1602 
1603  return false;
1604 }
1605 
1606 void
1607 GlobalRouter::InjectRoute (Ipv4Address network, Ipv4Mask networkMask)
1608 {
1609  NS_LOG_FUNCTION (this << network << networkMask);
1610  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
1611 //
1612 // Interface number does not matter here, using 1.
1613 //
1615  networkMask,
1616  1);
1617  m_injectedRoutes.push_back (route);
1618 }
1619 
1620 Ipv4RoutingTableEntry *
1621 GlobalRouter::GetInjectedRoute (uint32_t index)
1622 {
1623  NS_LOG_FUNCTION (this << index);
1624  if (index < m_injectedRoutes.size ())
1625  {
1626  uint32_t tmp = 0;
1627  for (InjectedRoutesCI i = m_injectedRoutes.begin ();
1628  i != m_injectedRoutes.end ();
1629  i++)
1630  {
1631  if (tmp == index)
1632  {
1633  return *i;
1634  }
1635  tmp++;
1636  }
1637  }
1638  NS_ASSERT (false);
1639  // quiet compiler.
1640  return 0;
1641 }
1642 
1643 uint32_t
1645 {
1646  NS_LOG_FUNCTION (this);
1647  return m_injectedRoutes.size ();
1648 }
1649 
1650 void
1651 GlobalRouter::RemoveInjectedRoute (uint32_t index)
1652 {
1653  NS_LOG_FUNCTION (this << index);
1654  NS_ASSERT (index < m_injectedRoutes.size ());
1655  uint32_t tmp = 0;
1656  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
1657  {
1658  if (tmp == index)
1659  {
1660  NS_LOG_LOGIC ("Removing route " << index << "; size = " << m_injectedRoutes.size ());
1661  delete *i;
1662  m_injectedRoutes.erase (i);
1663  return;
1664  }
1665  tmp++;
1666  }
1667 }
1668 
1669 bool
1670 GlobalRouter::WithdrawRoute (Ipv4Address network, Ipv4Mask networkMask)
1671 {
1672  NS_LOG_FUNCTION (this << network << networkMask);
1673  for (InjectedRoutesI i = m_injectedRoutes.begin (); i != m_injectedRoutes.end (); i++)
1674  {
1675  if ((*i)->GetDestNetwork () == network && (*i)->GetDestNetworkMask () == networkMask)
1676  {
1677  NS_LOG_LOGIC ("Withdrawing route to network/mask " << network << "/" << networkMask);
1678  delete *i;
1679  m_injectedRoutes.erase (i);
1680  return true;
1681  }
1682  }
1683  return false;
1684 }
1685 
1686 
1687 //
1688 // Link through the given channel and find the net device that's on the
1689 // other end. This only makes sense with a point-to-point channel.
1690 //
1691 Ptr<NetDevice>
1692 GlobalRouter::GetAdjacent (Ptr<NetDevice> nd, Ptr<Channel> ch) const
1693 {
1694  NS_LOG_FUNCTION (this << nd << ch);
1695  NS_ASSERT_MSG (ch->GetNDevices () == 2, "GlobalRouter::GetAdjacent (): Channel with other than two devices");
1696 //
1697 // This is a point to point channel with two endpoints. Get both of them.
1698 //
1699  Ptr<NetDevice> nd1 = ch->GetDevice (0);
1700  Ptr<NetDevice> nd2 = ch->GetDevice (1);
1701 //
1702 // One of the endpoints is going to be "us" -- that is the net device attached
1703 // to the node on which we're running -- i.e., "nd". The other endpoint (the
1704 // one to which we are connected via the channel) is the adjacent router.
1705 //
1706  if (nd1 == nd)
1707  {
1708  return nd2;
1709  }
1710  else if (nd2 == nd)
1711  {
1712  return nd1;
1713  }
1714  else
1715  {
1716  NS_ASSERT_MSG (false,
1717  "GlobalRouter::GetAdjacent (): Wrong or confused channel?");
1718  return 0;
1719  }
1720 }
1721 
1722 //
1723 // Given a node and a net device, find an IPV4 interface index that corresponds
1724 // to that net device. This function may fail for various reasons. If a node
1725 // does not have an internet stack (for example if it is a bridge) we won't have
1726 // an IPv4 at all. If the node does have a stack, but the net device in question
1727 // is bridged, there will not be an interface associated directly with the device.
1728 //
1729 bool
1730 GlobalRouter::FindInterfaceForDevice (Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const
1731 {
1732  NS_LOG_FUNCTION (this << node << nd << &index);
1733  NS_LOG_LOGIC ("For node " << node->GetId () << " for net device " << nd );
1734 
1735  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
1736  if (ipv4 == 0)
1737  {
1738  NS_LOG_LOGIC ("No Ipv4 interface on node " << node->GetId ());
1739  return false;
1740  }
1741 
1742  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); ++i )
1743  {
1744  if (ipv4->GetNetDevice (i) == nd)
1745  {
1746  NS_LOG_LOGIC ("Device " << nd << " has associated ipv4 index " << i);
1747  index = i;
1748  return true;
1749  }
1750  }
1751 
1752  NS_LOG_LOGIC ("Device " << nd << " has no associated ipv4 index");
1753  return false;
1754 }
1755 
1756 //
1757 // Decide whether or not a given net device is being bridged by a BridgeNetDevice.
1758 //
1759 Ptr<BridgeNetDevice>
1760 GlobalRouter::NetDeviceIsBridged (Ptr<NetDevice> nd) const
1761 {
1762  NS_LOG_FUNCTION (this << nd);
1763 
1764  Ptr<Node> node = nd->GetNode ();
1765  uint32_t nDevices = node->GetNDevices ();
1766 
1767  //
1768  // There is no bit on a net device that says it is being bridged, so we have
1769  // to look for bridges on the node to which the device is attached. If we
1770  // find a bridge, we need to look through its bridge ports (the devices it
1771  // bridges) to see if we find the device in question.
1772  //
1773  for (uint32_t i = 0; i < nDevices; ++i)
1774  {
1775  Ptr<NetDevice> ndTest = node->GetDevice (i);
1776  NS_LOG_LOGIC ("Examine device " << i << " " << ndTest);
1777 
1778  if (ndTest->IsBridge ())
1779  {
1780  NS_LOG_LOGIC ("device " << i << " is a bridge net device");
1781  Ptr<BridgeNetDevice> bnd = ndTest->GetObject<BridgeNetDevice> ();
1782  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
1783 
1784  for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
1785  {
1786  NS_LOG_LOGIC ("Examine bridge port " << j << " " << bnd->GetBridgePort (j));
1787  if (bnd->GetBridgePort (j) == nd)
1788  {
1789  NS_LOG_LOGIC ("Net device " << nd << " is bridged by " << bnd);
1790  return bnd;
1791  }
1792  }
1793  }
1794  }
1795  NS_LOG_LOGIC ("Net device " << nd << " is not bridged");
1796  return 0;
1797 }
1798 
1799 //
1800 // Start a new enumeration of an L2 broadcast domain by clearing m_bridgesVisited
1801 //
1802 void
1804 {
1805  m_bridgesVisited.clear();
1806 }
1807 
1808 //
1809 // Check if we have already visited a given bridge net device by searching m_bridgesVisited
1810 //
1811 bool
1813 {
1814  std::vector<Ptr<BridgeNetDevice> >::iterator iter;
1815  for (iter = m_bridgesVisited.begin (); iter != m_bridgesVisited.end (); ++iter)
1816  {
1817  if (bridgeNetDevice == *iter)
1818  {
1819  NS_LOG_LOGIC ("Bridge " << bridgeNetDevice << " has been visited.");
1820  return true;
1821  }
1822  }
1823  return false;
1824 }
1825 
1826 //
1827 // Remember that we visited a bridge net device by adding it to m_bridgesVisited
1828 //
1829 void
1831 {
1832  NS_LOG_FUNCTION (this << bridgeNetDevice);
1833  m_bridgesVisited.push_back (bridgeNetDevice);
1834 }
1835 
1836 
1837 } // namespace ns3
void SetRoutingProtocol(Ptr< Ipv4GlobalRouting > routing)
Set the specific Global Routing Protocol to be used.
void MarkBridgeAsVisited(Ptr< BridgeNetDevice > device) const
When recursively checking for devices on the link, mark a given device as having been visited...
Ptr< Ipv4GlobalRouting > GetRoutingProtocol(void)
Get the specific Global Routing Protocol used.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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 "...
~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
uint32_t GetId(void) const
Definition: node.cc:107
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
Ipv4Address m_advertisingRtr
The Advertising Router is defined by the OSPF spec.
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.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:142
static TypeId GetTypeId(void)
Get the type ID.
bool WithdrawRoute(Ipv4Address network, Ipv4Mask networkMask)
Withdraw a route from the global unicast routing table.
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 GetLSType(void) const
Return the LSType field of the LSA.
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:204
uint32_t AddLinkRecord(GlobalRoutingLinkRecord *lr)
Add a given Global Routing Link Record to the LSA.
Ipv4Mask m_networkLSANetworkMask
Each Network LSA contains the network mask of the attached network.
SPFStatus GetStatus(void) const
Get the SPF status of the advertisement.
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.
uint32_t AddAttachedRouter(Ipv4Address addr)
Add an attached router to the list in the NetworkLSA.
InjectedRoutes m_injectedRoutes
Routes we are exporting.
void SetNode(Ptr< Node > node)
Set the Node pointer of the node that originated this LSA.
Ipv4Address FindDesignatedRouterForLink(Ptr< NetDevice > ndLocal) const
Finds a designated router.
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.
LSType
corresponds to LS type field of RFC 2328 OSPF LSA header
Ipv4Mask GetNetworkLSANetworkMask(void) const
For a Network LSA, get the Network Mask field that precedes the list of attached routers.
Ptr< Ipv4GlobalRouting > m_routingProtocol
the Ipv4GlobalRouting in use
void Print(std::ostream &os) const
Print the contents of the Global Routing Link State Advertisement and any Global Routing Link Records...
a Link State Advertisement (LSA) for a router, used in global routing.
Ipv4Address CombineMask(Ipv4Mask const &mask) const
Combine this address with a network mask.
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.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
void ClearBridgesVisited(void) const
Clear the list of bridges visited on the link.
static Ipv4RoutingTableEntry CreateNetworkRouteTo(Ipv4Address network, Ipv4Mask networkMask, Ipv4Address nextHop, uint32_t interface)
holds a vector of ns3::NetDevice pointers
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...
GlobalRoutingLinkRecord * GetLinkRecord(uint32_t n) const
Return a pointer to the specified Global Routing Link Record.
Ptr< NetDevice > GetAdjacent(Ptr< NetDevice > nd, Ptr< Channel > ch) const
Link through the given channel and find the net device that&#39;s on the other end.
Ipv4Address GetRouterId(void) const
Get the Router ID associated with this Global Router.
void SetLSType(LSType typ)
Set the LS type field of the LSA.
void RemoveInjectedRoute(uint32_t i)
Withdraw a route from the global unicast routing table.
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
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:459
void SetStatus(SPFStatus status)
Set the SPF status of the advertisement.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
NetDeviceContainer FindAllNonBridgedDevicesOnLink(Ptr< Channel > ch) const
Return a container of all non-bridged NetDevices on a link.
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")
bool AnotherRouterOnLink(Ptr< NetDevice > nd) const
Checks for the presence of another router on the NetDevice.
Ptr< BridgeNetDevice > NetDeviceIsBridged(Ptr< NetDevice > nd) const
Decide whether or not a given net device is being bridged by a BridgeNetDevice.
An interface aggregated to a node to provide global routing info.
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.
bool GetLSA(uint32_t n, GlobalRoutingLSA &lsa) const
Get a Global Routing Link State Advertisements that this router has said that it can export...
#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 Get(void) const
Get the host-order 32-bit IP mask.
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:264
uint32_t GetNAttachedRouters(void) const
Return the number of attached routers listed in the NetworkLSA.
static uint32_t AllocateRouterId()
Allocate a 32-bit router ID from monotonically increasing counter.
uint32_t GetNLinkRecords(void) const
Return the number of Global Routing Link Records in the LSA.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
uint32_t GetN(void) const
Get the number of Ptr<NetDevice> stored in this container.
SPFStatus
Enumeration of the possible values of the status flag in the Routing Link State Advertisements.
GlobalRouter()
Create a Global Router class.
ListOfAttachedRouters_t m_attachedRouters
Each Network LSA contains a list of attached routers.
void ProcessPointToPointLink(Ptr< NetDevice > ndLocal, GlobalRoutingLSA *pLSA)
Process a point to point link.
Ipv4Address GetLinkStateId(void) const
Get the Link State ID as defined by the OSPF spec.
uint32_t GetNumLSAs(void) const
Get the Number of Global Routing Link State Advertisements that this router can export.
A base class which provides memory management and object aggregation.
Definition: object.h:87
Ptr< Node > GetNode(void) const
Get the Node pointer of the node that originated this LSA.
Ipv4Address GetAttachedRouter(uint32_t n) const
Return an Ipv4Address corresponding to the specified attached router.
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
Ipv4Address GetAdvertisingRouter(void) const
Get the Advertising Router as defined by the OSPF spec.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
void SetLinkStateId(Ipv4Address addr)
Set the Link State ID is defined by the OSPF spec.
bool IsEmpty(void) const
Check to see if the list of Global Routing Link Records present in the Global Routing Link State Adve...
uint32_t GetNDevices(void) const
Definition: node.cc:150
std::list< Ipv4RoutingTableEntry * >::iterator InjectedRoutesI
Iterator to container of Ipv4RoutingTableEntry.
void ProcessBroadcastLink(Ptr< NetDevice > nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
Process a generic broadcast link.