deal with bridged stub/transit networks on routers
authorCraig Dowell <craigdo@ee.washington.edu>
Wed, 19 Nov 2008 22:16:43 -0800
changeset 3940 49b432aefbd0
parent 3939 206f627bd5af
child 3941 476c3bed16c0
deal with bridged stub/transit networks on routers
src/routing/global-routing/global-router-interface.cc
src/routing/global-routing/global-router-interface.h
--- a/src/routing/global-routing/global-router-interface.cc	Wed Nov 19 21:21:14 2008 -0800
+++ b/src/routing/global-routing/global-router-interface.cc	Wed Nov 19 22:16:43 2008 -0800
@@ -614,8 +614,23 @@
 {
   NS_LOG_FUNCTION (nd << pLSA << &c);
 
+  if (nd->IsBridge ())
+    {
+      ProcessBridgedBroadcastLink (nd, pLSA, c);
+    }
+  else
+    {
+      ProcessSingleBroadcastLink (nd, pLSA, c);
+    }
+}
+
+  void
+GlobalRouter::ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+  NS_LOG_FUNCTION (nd << pLSA << &c);
+
   GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
-  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBroadcastLink(): Can't alloc link record");
+  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessSingleBroadcastLink(): Can't alloc link record");
 
   //
   // We have some preliminaries to do to get enough information to proceed.
@@ -628,10 +643,10 @@
 
   uint32_t ifIndexLocal;
   bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal);
-  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBroadcastLink(): No interface index associated with device");
+  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessSingleBroadcastLink(): No interface index associated with device");
 
   Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
-  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBroadcastLink (): GetObject for <Ipv4> interface failed");
+  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessSingleBroadcastLink (): GetObject for <Ipv4> interface failed");
 
   Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
   Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
@@ -702,6 +717,147 @@
 }
 
   void
+GlobalRouter::ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c)
+{
+  NS_LOG_FUNCTION (nd << pLSA << &c);
+
+  NS_ASSERT_MSG (nd->IsBridge (), "GlobalRouter::ProcessBridgedBroadcastLink(): Called with non-bridge net device");
+
+  Ptr<BridgeNetDevice> bnd = nd->GetObject<BridgeNetDevice> ();
+  NS_ABORT_MSG_UNLESS (bnd, "GlobalRouter::DiscoverLSAs (): GetObject for <BridgeNetDevice> failed");
+
+  //
+  // We need to handle a bridge on the router.  This means that we have been 
+  // given a net device that is a BridgeNetDevice.  It has an associated Ipv4
+  // interface index and address.  Some number of other net devices live "under"
+  // the bridge device as so-called bridge ports.  In a nutshell, what we have
+  // to do is to repeat what is done for a single broadcast link on all of 
+  // those net devices living under the bridge (trolls?)
+  //
+  bool areTransitNetwork = false;
+  Ipv4Address desigRtr ("255.255.255.255");
+
+  for (uint32_t i = 0; i < bnd->GetNBridgePorts (); ++i)
+    {
+      Ptr<NetDevice> ndTemp = bnd->GetBridgePort (i);
+      GlobalRoutingLSA *pLsaTest = new GlobalRoutingLSA;
+      NetDeviceContainer cTest;
+      ProcessSingleBroadcastLink (ndTemp, pLsaTest, cTest);
+
+      //
+      // The GlobalRoutingLSA pLsaTest will now have a link record attached to
+      // it indicating what was found.  If another router is found on any one
+      // of the bridged networks, we need to treat the whole bridge as a transit 
+      // network.
+      //
+      // If the link type is a transit network, then we have got to do some work
+      // to figure out what to do about the other routers on the bridge.
+      //
+      if (pLsaTest->GetLinkRecord (0)->GetLinkType () == GlobalRoutingLinkRecord::TransitNetwork)
+        {
+          areTransitNetwork = true;
+
+          //
+          // If we're going to be a transit network, then we have got to elect
+          // a designated router for the whole bridge.  This means finding the
+          // router with the lowest IP address on the whole bridge.  We ask 
+          // for the lowest address on each segment and pick the lowest of them
+          // all.
+          //
+          Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp);
+          if (desigRtrTemp < desigRtr)
+            {
+              desigRtr = desigRtrTemp;
+            }
+        }
+    }
+
+  //
+  // That's all the information we need to put it all together, just like we did
+  // in the case of a single broadcast link.
+  //
+
+  GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
+  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessBridgedBroadcastLink(): Can't alloc link record");
+
+  //
+  // We have some preliminaries to do to get enough information to proceed.
+  // This information we need comes from the internet stack, so notice that
+  // there is an implied assumption that global routing is only going to 
+  // work with devices attached to the internet stack (have an ipv4 interface
+  // associated to them.
+  //
+  Ptr<Node> node = nd->GetNode ();
+
+  uint32_t ifIndexLocal;
+  bool rc = FindIfIndexForDevice(node, nd, ifIndexLocal);
+  NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessBridgedBroadcastLink(): No interface index associated with device");
+
+  Ptr<Ipv4> ipv4Local = node->GetObject<Ipv4> ();
+  NS_ABORT_MSG_UNLESS (ipv4Local, "GlobalRouter::ProcessBridgedBroadcastLink (): GetObject for <Ipv4> interface failed");
+
+  Ipv4Address addrLocal = ipv4Local->GetAddress(ifIndexLocal);
+  Ipv4Mask maskLocal = ipv4Local->GetNetworkMask(ifIndexLocal);
+  NS_LOG_LOGIC ("Working with local address " << addrLocal);
+  uint16_t metricLocal = ipv4Local->GetMetric (ifIndexLocal);
+
+  if (areTransitNetwork == false)
+    {
+      //
+      // This is a net device connected to a bridge of stub networks
+      //
+      NS_LOG_LOGIC("**** Router-LSA Stub Network");
+      plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
+
+      // 
+      // According to OSPF, the Link ID is the IP network number of 
+      // the attached network.
+      //
+      plr->SetLinkId (addrLocal.CombineMask(maskLocal));
+
+      //
+      // and the Link Data is the network mask; converted to Ipv4Address
+      //
+      Ipv4Address maskLocalAddr;
+      maskLocalAddr.Set(maskLocal.Get ());
+      plr->SetLinkData (maskLocalAddr);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord(plr);
+      plr = 0;
+    }
+  else
+    {
+      //
+      // We have multiple routers on a bridged broadcast interface, so this is
+      // a transit network.
+      //
+      NS_LOG_LOGIC ("**** Router-LSA Transit Network");
+      plr->SetLinkType (GlobalRoutingLinkRecord::TransitNetwork);
+
+      // 
+      // By definition, the router with the lowest IP address is the
+      // designated router for the network.  OSPF says that the Link ID
+      // gets the IP interface address of the designated router in this 
+      // case.
+      //
+      if (desigRtr == addrLocal) 
+        {
+          c.Add (nd);
+          NS_LOG_LOGIC ("Node " << node->GetId () << " elected a designated router");
+        }
+      plr->SetLinkId (desigRtr);
+      
+      //
+      // OSPF says that the Link Data is this router's own IP address.
+      //
+      plr->SetLinkData (addrLocal);
+      plr->SetMetric (metricLocal);
+      pLSA->AddLinkRecord (plr);
+      plr = 0;
+    }
+}
+
+  void
 GlobalRouter::ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA)
 {
   NS_LOG_FUNCTION (ndLocal << pLSA);
--- a/src/routing/global-routing/global-router-interface.h	Wed Nov 19 21:21:14 2008 -0800
+++ b/src/routing/global-routing/global-router-interface.h	Wed Nov 19 22:16:43 2008 -0800
@@ -644,6 +644,9 @@
   Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal) const;
   bool AnotherRouterOnLink (Ptr<NetDevice> nd) const;
   void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+  void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+  void ProcessBridgedBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
+
   void ProcessPointToPointLink (Ptr<NetDevice> ndLocal, GlobalRoutingLSA *pLSA);
   void BuildNetworkLSAs (NetDeviceContainer c);
   bool IsNetDeviceBridged (Ptr<NetDevice> nd) const;