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