fix bug 114 and bug 66
authorCraig Dowell <craigdo@ee.washington.edu>
Thu, 20 Nov 2008 16:48:21 -0800
changeset 3942 eef10dbce686
parent 3941 476c3bed16c0
child 3943 e2ada9e99280
fix bug 114 and bug 66
examples/csma-bridge-one-hop.cc
src/routing/global-routing/global-router-interface.cc
src/routing/global-routing/global-router-interface.h
--- a/examples/csma-bridge-one-hop.cc	Wed Nov 19 23:38:01 2008 -0800
+++ b/examples/csma-bridge-one-hop.cc	Thu Nov 20 16:48:21 2008 -0800
@@ -41,19 +41,19 @@
 // Or, more abstractly, recognizing that bridge 1 and bridge 2 are nodes 
 // with three net devices:
 //
-//        n0     n1  
-//        |      | 
-//       -----------
-//       | bridge1 | <- n5
+//        n0     n1                (n0 = 10.1.1.2)
+//        |      |                 (n1 = 10.1.1.3)  Note odd addressing
+//       -----------               (n2 = 10.1.1.1)
+//       | bridge1 | <- n5  
 //       -----------
 //           |    
 //         router    <- n2
 //           |
 //       -----------
 //       | bridge2 | <- n6
-//       -----------
-//        |      | 
-//        n3     n4  
+//       -----------               (n2 = 10.1.2.1)
+//        |      |                 (n3 = 10.1.2.2)
+//        n3     n4                (n4 = 10.1.2.3)
 //
 // So, this example shows two broadcast domains, each interconnected by a bridge
 // with a router node (n2) interconnecting the layer-2 broadcast domains
@@ -61,7 +61,7 @@
 // It is meant to mirror somewhat the csma-bridge example but adds another
 // bridged link separated by a router.
 // 
-// - CBR/UDP flows from n0 to n1 and from n3 to n0
+// - CBR/UDP flows from n0 (10.1.1.2) to n1 (10.1.1.3) and from n3 (10.1.2.2) to n0 (10.1.1.3)
 // - DropTail queues 
 // - Global static routing
 // - Tracing of queues and packet receptions to file "csma-bridge-one-hop.tr"
@@ -201,7 +201,9 @@
   // Create an optional packet sink to receive these packets
   PacketSinkHelper sink ("ns3::UdpSocketFactory",
                          Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  sink.Install (n1);
+  ApplicationContainer sink1 = sink.Install (n1);
+  sink1.Start (Seconds (1.0));
+  sink1.Stop (Seconds (10.0));
 
   // 
   // Create a similar flow from n3 to n0, starting at time 1.1 seconds
@@ -209,12 +211,13 @@
   onoff.SetAttribute ("Remote", 
                       AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
   ApplicationContainer app2 = onoff.Install (n3);
-
-  sink.Install (n0);
-
   app2.Start (Seconds (1.1));
   app2.Stop (Seconds (10.0));
 
+  ApplicationContainer sink2 = sink.Install (n0);
+  sink2.Start (Seconds (1.1));
+  sink2.Stop (Seconds (10.0));
+
   //
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
   // Trace output will be sent to the file "csma-bridge-one-hop.tr"
--- a/src/routing/global-routing/global-router-interface.cc	Wed Nov 19 23:38:01 2008 -0800
+++ b/src/routing/global-routing/global-router-interface.cc	Thu Nov 20 16:48:21 2008 -0800
@@ -383,9 +383,25 @@
   void 
 GlobalRoutingLSA::Print (std::ostream &os) const
 {
-  os << "m_lsType = " << m_lsType << std::endl <<
-        "m_linkStateId = " << m_linkStateId << std::endl <<
-        "m_advertisingRtr = " << m_advertisingRtr << std::endl;
+  os << std::endl;
+  os << "========== Global Routing LSA ==========" << std::endl;
+  os << "m_lsType = " << m_lsType;
+  if (m_lsType == GlobalRoutingLSA::RouterLSA) 
+    {
+      os << " (GlobalRoutingLSA::RouterLSA)";
+    }
+  else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
+    {
+      os << " (GlobalRoutingLSA::NetworkLSA)";
+    }
+  else
+    {
+      os << "(Unknown LSType)";
+    }
+  os << std::endl;
+
+  os << "m_linkStateId = " << m_linkStateId << " (Router ID)" << std::endl;
+  os << "m_advertisingRtr = " << m_advertisingRtr << " (Router ID)" << std::endl;
 
   if (m_lsType == GlobalRoutingLSA::RouterLSA) 
     {
@@ -394,30 +410,49 @@
             i++)
         {
           GlobalRoutingLinkRecord *p = *i;
-          os << "----------" << std::endl;
-          os << "m_linkId = " << p->GetLinkId () << std::endl;
-          os << "m_linkData = " << p->GetLinkData () << std::endl;
-          os << "m_metric = " << p->GetMetric () << std::endl;
+
+          os << "---------- RouterLSA Link Record ----------" << std::endl;
+          os << "m_linkType = " << p->m_linkType;
+          if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
+            {
+              os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
+              os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          else if (p->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
+            {
+              os << "(GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
+              os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          else
+            {
+              os << "(Unknown LinkType)" << std::endl;
+              os << "m_linkId = " << p->m_linkId << std::endl;
+              os << "m_linkData = " << p->m_linkData << std::endl;
+              os << "m_metric = " << p->m_metric << std::endl;
+            }
+          os << "---------- End RouterLSA Link Record ----------" << std::endl;
         }
     }
   else if (m_lsType == GlobalRoutingLSA::NetworkLSA) 
     {
-      os << "----------" << std::endl;
-      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask 
-         << std::endl;
-      for ( ListOfAttachedRouters_t::const_iterator i = 
-            m_attachedRouters.begin ();
-            i != m_attachedRouters.end (); 
-            i++)
+      os << "---------- NetworkLSA Link Record ----------" << std::endl;
+      os << "m_networkLSANetworkMask = " << m_networkLSANetworkMask << std::endl;
+      for ( ListOfAttachedRouters_t::const_iterator i = m_attachedRouters.begin (); i != m_attachedRouters.end (); i++)
         {
           Ipv4Address p = *i;
           os << "attachedRouter = " << p << std::endl;
         }
+      os << "---------- End NetworkLSA Link Record ----------" << std::endl;
     }
   else 
     {
       NS_ASSERT_MSG(0, "Illegal LSA LSType: " << m_lsType);
     }
+  os << "========== End Global Routing LSA ==========" << std::endl;
 }
 
 std::ostream& operator<< (std::ostream& os, GlobalRoutingLSA& lsa)
@@ -699,7 +734,7 @@
       // gets the IP interface address of the designated router in this 
       // case.
       //
-      Ipv4Address desigRtr = FindDesignatedRouterForLink (nd);
+      Ipv4Address desigRtr = FindDesignatedRouterForLink (nd, true);
       if (desigRtr == addrLocal) 
         {
           c.Add (nd);
@@ -758,7 +793,7 @@
           // for the lowest address on each segment and pick the lowest of them
           // all.
           //
-          Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp);
+          Ipv4Address desigRtrTemp = FindDesignatedRouterForLink (ndTemp, true);
           if (desigRtrTemp < desigRtr)
             {
               desigRtr = desigRtrTemp;
@@ -1041,66 +1076,114 @@
 // connecting to the channel becomes the designated router for the link.
 //
   Ipv4Address
-GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal) const
+GlobalRouter::FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const
 {
-  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_FUNCTION (ndLocal << allowRecursion);
 
   Ptr<Channel> ch = ndLocal->GetChannel();
   uint32_t nDevices = ch->GetNDevices();
   NS_ASSERT (nDevices);
 
-  Ipv4Address addr ("255.255.255.255");
+  NS_LOG_LOGIC ("**** Looking for designated router off of net device " << ndLocal << " on node " << 
+                ndLocal->GetNode ()->GetId ());
+
+  Ipv4Address desigRtr ("255.255.255.255");
 
+  //
+  // Look through all of the devices on the channel to which the net device
+  // in question is attached.
+  //
   for (uint32_t i = 0; i < nDevices; i++)
     {
-      Ptr<NetDevice> currentNd = ch->GetDevice (i);
-      NS_ASSERT (currentNd);
+      Ptr<NetDevice> ndOther = ch->GetDevice (i);
+      NS_ASSERT (ndOther);
 
-      Ptr<Node> currentNode = currentNd->GetNode ();
-      NS_ASSERT (currentNode);
-      //
-      // We require a designated router to have a GlobalRouter interface and
-      // an internet stack that includes the Ipv4 interface.
-      //
-      Ptr<GlobalRouter> rtr = currentNode->GetObject<GlobalRouter> ();
-      Ptr<Ipv4> ipv4 = currentNode->GetObject<Ipv4> ();
-      if (rtr == 0 || ipv4 == 0 )
-        {
-          continue;
-        }
+      Ptr<Node> nodeOther = ndOther->GetNode ();
+
+      NS_LOG_LOGIC ("**** Examine channel device " << i << " on node " << nodeOther->GetId ());
 
       //
-      // This node could be a designated router, so we can check and see if
-      // it has a lower IP address than the one we have.  In order to have
-      // an IP address, it needs to have an interface index.  If it doesen't
-      // have an interface index directly, it's probably part of a bridge
-      // net device XXX which is not yet handled.
+      // For all other net devices, we need to check and see if a router
+      // is present.  If the net device on the other side is a bridged
+      // device, we need to consider all of the other devices on the 
+      // bridge as well (all of the bridge ports.
       //
-      uint32_t currentIfIndex;
-      bool rc = FindIfIndexForDevice(currentNode, currentNd, currentIfIndex);
-      if (rc == false)
+      NS_LOG_LOGIC ("**** checking to see if the device is bridged");
+      Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
+      if (bnd)
         {
-          continue;
-        }
+          NS_LOG_LOGIC ("**** Device is bridged by BridgeNetDevice " << bnd);
+
+          //
+          // It is possible that the bridge net device is sitting under a
+          // router, so we have to check for the presence of that router
+          // before we run off and follow all the links
+          //
+          // We require a designated router to have a GlobalRouter interface and
+          // an internet stack that includes the Ipv4 interface.  If it doesn't
+          // it can't play router.
+          //
+          NS_LOG_LOGIC ("**** Checking for router on bridge net device " << bnd);
+          Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
+          Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
+          if (rtr && ipv4)
+            {
+              uint32_t ifIndexOther;
+              if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther))
+                {
+                  NS_LOG_LOGIC ("**** Found router on bridge net device " << bnd);
+                  Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
+                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+                  NS_LOG_LOGIC ("**** designated router now " << desigRtr);
+                }
+            }
 
-      //
-      // Okay, get the IP address corresponding to the interface we're 
-      // examining and if it's the lowest so far, remember it.
-      //
-      Ipv4Address currentAddr = ipv4->GetAddress(currentIfIndex);
+          NS_LOG_LOGIC ("**** Looking through bridge ports of bridge net device " << bnd);
+          for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
+            {
+              Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
+              NS_LOG_LOGIC ("**** Examining bridge port " << j << " device " << ndBridged);
+              if (ndBridged == ndOther)
+                {
+                  NS_LOG_LOGIC ("**** That bridge port is me, don't walk backward");
+                  continue;
+                }
 
-      if (currentAddr < addr)
+              if (allowRecursion)
+                {
+                  NS_LOG_LOGIC ("**** Recursively looking for routers down bridge port " << ndBridged);
+                  Ipv4Address addrOther = FindDesignatedRouterForLink (ndBridged, false);
+                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+                  NS_LOG_LOGIC ("**** designated router now " << desigRtr);
+                }
+            }
+        }
+      else
         {
-          addr = currentAddr;
+          NS_LOG_LOGIC ("**** This device is not bridged");
+          Ptr<Node> nodeOther = ndOther->GetNode ();
+          NS_ASSERT (nodeOther);
+
+          //
+          // We require a designated router to have a GlobalRouter interface and
+          // an internet stack that includes the Ipv4 interface.  If it doesn't
+          //
+          Ptr<GlobalRouter> rtr = nodeOther->GetObject<GlobalRouter> ();
+          Ptr<Ipv4> ipv4 = nodeOther->GetObject<Ipv4> ();
+          if (rtr && ipv4)
+            {
+              uint32_t ifIndexOther;
+              if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther))
+                {
+                  NS_LOG_LOGIC ("**** Found router on net device " << ndOther);
+                  Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
+                  desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
+                  NS_LOG_LOGIC ("**** designated router now " << desigRtr);
+                }
+            }
         }
     }
-
-  //
-  // Return the lowest IP address found, which will become the designated router
-  // for the link.
-  //
-  NS_ASSERT_MSG (addr.IsBroadcast() == false, "GlobalRouter::FindDesignatedRouterForLink(): Bogus address");
-  return addr;
+  return desigRtr;
 }
 
 //
@@ -1118,23 +1201,25 @@
   uint32_t nDevices = ch->GetNDevices();
   NS_ASSERT (nDevices);
 
+  NS_LOG_LOGIC ("**** Looking for routers off of net device " << nd << " on node " << nd->GetNode ()->GetId ());
+
   //
   // Look through all of the devices on the channel to which the net device
-  // in questin is attached.
+  // in question is attached.
   //
   for (uint32_t i = 0; i < nDevices; i++)
     {
-      NS_LOG_LOGIC ("**** Examine device " << i << "on node " << nd->GetNode ()->GetId ());
-
       Ptr<NetDevice> ndOther = ch->GetDevice (i);
       NS_ASSERT (ndOther);
 
+      NS_LOG_LOGIC ("**** Examine channel device " << i << " on node " << ndOther->GetNode ()->GetId ());
+
       // 
       // Ignore the net device itself.
       //
       if (ndOther == nd)
         {
-          NS_LOG_LOGIC ("**** Self");
+          NS_LOG_LOGIC ("**** Myself, skip");
           continue;
         }
 
@@ -1144,45 +1229,52 @@
       // device, we need to consider all of the other devices on the 
       // bridge.
       //
+      NS_LOG_LOGIC ("**** checking to see if device is bridged");
       Ptr<BridgeNetDevice> bnd = NetDeviceIsBridged (ndOther);
       if (bnd)
         {
-          NS_LOG_LOGIC ("**** Device is bridged");
+          NS_LOG_LOGIC ("**** Device is bridged by net device " << bnd);
+          NS_LOG_LOGIC ("**** Looking through bridge ports of bridge net device " << bnd);
           for (uint32_t j = 0; j < bnd->GetNBridgePorts (); ++j)
             {
-              NS_LOG_LOGIC ("**** Examining bridge port " << j);
               Ptr<NetDevice> ndBridged = bnd->GetBridgePort (j);
+              NS_LOG_LOGIC ("**** Examining bridge port " << j << " device " << ndBridged);
               if (ndBridged == ndOther)
                 {
-                  NS_LOG_LOGIC ("**** Self");
+                  NS_LOG_LOGIC ("**** That bridge port is me, skip");
                   continue;
                 }
+
               if (allowRecursion)
                 {
-                  NS_LOG_LOGIC ("**** Recursing");
+                  NS_LOG_LOGIC ("**** Recursively looking for routers on bridge port " << ndBridged);
                   if (AnotherRouterOnLink (ndBridged, false))
                     {
-                      NS_LOG_LOGIC ("**** Return true");
+                      NS_LOG_LOGIC ("**** Found routers on bridge port, return true");
                       return true;
                     }
                 }
             }
-          NS_LOG_LOGIC ("**** Return false");
+          NS_LOG_LOGIC ("**** No routers on bridged net device, return false");
           return false;
         }
 
-      NS_LOG_LOGIC ("**** Device is not bridged");
+      NS_LOG_LOGIC ("**** This device is not bridged");
       Ptr<Node> nodeTemp = ndOther->GetNode ();
       NS_ASSERT (nodeTemp);
 
       Ptr<GlobalRouter> rtr = nodeTemp->GetObject<GlobalRouter> ();
       if (rtr)
         {
-          NS_LOG_LOGIC ("**** Return true");
+          NS_LOG_LOGIC ("**** Found GlobalRouter interface, return true");
           return true;
         }
+      else 
+        {
+          NS_LOG_LOGIC ("**** No GlobalRouter interface on device, continue search");
+        }
     }
-  NS_LOG_LOGIC ("**** Return false");
+  NS_LOG_LOGIC ("**** No routers found, return false");
   return false;
 }
 
--- a/src/routing/global-routing/global-router-interface.h	Wed Nov 19 23:38:01 2008 -0800
+++ b/src/routing/global-routing/global-router-interface.h	Thu Nov 20 16:48:21 2008 -0800
@@ -35,6 +35,8 @@
 
 namespace ns3 {
 
+class GlobalRouter;
+
 /**
  * @brief A single link record for a link state advertisement.
  *
@@ -45,6 +47,7 @@
 class GlobalRoutingLinkRecord
 {
 public:
+  friend class GlobalRoutingLSA;
 /**
  * @enum LinkType
  * @brief Enumeration of the possible types of Global Routing Link Records.
@@ -642,7 +645,7 @@
 
   Ptr<NetDevice> GetAdjacent(Ptr<NetDevice> nd, Ptr<Channel> ch) const;
   bool FindIfIndexForDevice(Ptr<Node> node, Ptr<NetDevice> nd, uint32_t &index) const;
-  Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal) const;
+  Ipv4Address FindDesignatedRouterForLink (Ptr<NetDevice> ndLocal, bool allowRecursion) const;
   bool AnotherRouterOnLink (Ptr<NetDevice> nd, bool allowRecursion) const;
   void ProcessBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);
   void ProcessSingleBroadcastLink (Ptr<NetDevice> nd, GlobalRoutingLSA *pLSA, NetDeviceContainer &c);