Split Bridge Net Device into two different classes, with one for the port and one...
authorRichard Whitehouse <github@richardwhiuk.com>
Mon, 24 Jan 2011 00:54:33 +0000 (00:54 +0000)
committerRichard Whitehouse <github@richardwhiuk.com>
Mon, 24 Jan 2011 00:54:33 +0000 (00:54 +0000)
code/.gitignore [new file with mode: 0644]
code/src/devices/bridge/model/bridge-net-device.cc
code/src/devices/bridge/model/bridge-net-device.h
code/src/devices/bridge/model/bridge-port-net-device.cc [new file with mode: 0644]
code/src/devices/bridge/model/bridge-port-net-device.h [new file with mode: 0644]
code/src/devices/bridge/wscript

diff --git a/code/.gitignore b/code/.gitignore
new file mode 100644 (file)
index 0000000..aea275a
--- /dev/null
@@ -0,0 +1,3 @@
+.lock-wscript
+build/
+.waf-*/
index 410645ad3846d0db16a834e91f1ebdd1c56a987c..853997f9564f1fe6e312e91c6e9f5473280d75ba 100644 (file)
@@ -74,7 +74,7 @@ BridgeNetDevice::~BridgeNetDevice()
 BridgeNetDevice::DoDispose ()
 {
   NS_LOG_FUNCTION_NOARGS ();
-  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
+  for (std::vector< Ptr<BridgePortNetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
     {
       *iter = 0;
     }
@@ -84,12 +84,7 @@ BridgeNetDevice::DoDispose ()
   NetDevice::DoDispose ();
 }
 
-void
-BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
-                                    Address const &src, Address const &dst, PacketType packetType)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_DEBUG ("UID is " << packet->GetUid ());
+void BridgeNetDevice::Forward (Ptr<BridgePortNetDevice> port, Ptr<const Packet> packet, uint16_t protocol, Address const &src, Address const &dst, NetDevice::PacketType packetType){
 
   Mac48Address src48 = Mac48Address::ConvertFrom (src);
   Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
@@ -111,7 +106,7 @@ BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packe
     case PACKET_BROADCAST:
     case PACKET_MULTICAST:
       m_rxCallback (this, packet, protocol, src);
-      ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
+      ForwardBroadcast (port, packet, protocol, src48, dst48);
       break;
 
     case PACKET_OTHERHOST:
@@ -121,84 +116,73 @@ BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packe
         }
       else
         {
-          ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
+          ForwardUnicast (port, packet, protocol, src48, dst48);
         }
       break;
     }
 }
 
 void
-BridgeNetDevice::ForwardUnicast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
-                                 uint16_t protocol, Mac48Address src, Mac48Address dst)
+BridgeNetDevice::ForwardUnicast (Ptr<BridgePortNetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
-                << ", packet=" << packet << ", protocol="<<protocol
-                << ", src=" << src << ", dst=" << dst << ")");
 
-  Learn (src, incomingPort);
-  Ptr<NetDevice> outPort = GetLearnedState (dst);
+  Ptr<BridgePortNetDevice> outPort = GetLearnedState (dst);
   if (outPort != NULL && outPort != incomingPort)
     {
       NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetInstanceTypeId ().GetName () << "'");
-      outPort->SendFrom (packet->Copy (), src, dst, protocol);
+      outPort->Send (packet->Copy (), src, dst, protocol);
     }
   else
     {
       NS_LOG_LOGIC ("No learned state: send through all ports");
-      for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
+      for (std::vector< Ptr<BridgePortNetDevice> >::iterator iter = m_ports.begin ();
            iter != m_ports.end (); iter++)
         {
-          Ptr<NetDevice> port = *iter;
+          Ptr<BridgePortNetDevice> port = *iter;
           if (port != incomingPort)
             {
               NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " 
                             << incomingPort->GetInstanceTypeId ().GetName ()
                             << " --> " << port->GetInstanceTypeId ().GetName ()
                             << " (UID " << packet->GetUid () << ").");
-              port->SendFrom (packet->Copy (), src, dst, protocol);
+              port->Send (packet->Copy (), src, dst, protocol);
             }
         }
     }
 }
 
 void
-BridgeNetDevice::ForwardBroadcast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
-                                        uint16_t protocol, Mac48Address src, Mac48Address dst)
+BridgeNetDevice::ForwardBroadcast (Ptr<BridgePortNetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
-                << ", packet=" << packet << ", protocol="<<protocol
-                << ", src=" << src << ", dst=" << dst << ")");
-  Learn (src, incomingPort);
 
-  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
+  for (std::vector< Ptr<BridgePortNetDevice> >::iterator iter = m_ports.begin ();
          iter != m_ports.end (); iter++)
     {
-      Ptr<NetDevice> port = *iter;
+      Ptr<BridgePortNetDevice> port = *iter;
       if (port != incomingPort)
         {
-          NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " 
-                        << incomingPort->GetInstanceTypeId ().GetName ()
-                        << " --> " << port->GetInstanceTypeId ().GetName ()
-                        << " (UID " << packet->GetUid () << ").");
-          port->SendFrom (packet->Copy (), src, dst, protocol);
+          port->Send(packet->Copy (), src, dst, protocol);
         }
     }
 }
 
-void BridgeNetDevice::Learn (Mac48Address source, Ptr<NetDevice> port)
+void BridgeNetDevice::Learn (Address const &src, Ptr<BridgePortNetDevice> port)
 {
   NS_LOG_FUNCTION_NOARGS ();
+
+  Mac48Address src48 = Mac48Address::ConvertFrom (src);
+
   if (m_enableLearning)
     {
-      LearnedState &state = m_learnState[source];
+      LearnedState &state = m_learnState[src48];
       state.associatedPort = port;
       state.expirationTime = Simulator::Now () + m_expirationTime;
     }
 }
 
-Ptr<NetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
+Ptr<BridgePortNetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
 {
   NS_LOG_FUNCTION_NOARGS ();
   if (m_enableLearning)
@@ -229,37 +213,32 @@ BridgeNetDevice::GetNBridgePorts (void) const
   return m_ports.size ();
 }
 
+/** Dislike this. */
 
 Ptr<NetDevice>
 BridgeNetDevice::GetBridgePort (uint32_t n) const
 {
   NS_LOG_FUNCTION_NOARGS ();
-  return m_ports[n];
+  return m_ports[n]->m_device;
 }
 
 void 
-BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
+BridgeNetDevice::AddBridgePort (Ptr<NetDevice> device)
 {
   NS_LOG_FUNCTION_NOARGS ();
-  NS_ASSERT (bridgePort != this);
-  if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ()))
-    {
-      NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
-    }
-  if (!bridgePort->SupportsSendFrom ())
-    {
-      NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
-    }
+  NS_ASSERT (device != this);
+
+// This is probably wrong and needs fixing.
   if (m_address == Mac48Address ())
     {
-      m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
+      m_address = Mac48Address::ConvertFrom (device->GetAddress ());
     }
 
-  NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetInstanceTypeId ().GetName ());
-  m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this),
-                                   0, bridgePort, true);
-  m_ports.push_back (bridgePort);
-  m_channel->AddChannel (bridgePort->GetChannel ());
+  Ptr<BridgePortNetDevice> port = CreateObject<BridgePortNetDevice>(this, device, m_node);
+
+  m_ports.push_back(port);
+  m_channel->AddChannel (device->GetChannel ());
+
 }
 
 void 
@@ -388,21 +367,21 @@ BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address
   // try to use the learned state if data is unicast
   if (!dst.IsGroup ())
     {
-      Ptr<NetDevice> outPort = GetLearnedState (dst);
+      Ptr<BridgePortNetDevice> outPort = GetLearnedState (dst);
       if (outPort != NULL) 
         {
-          outPort->SendFrom (packet, src, dest, protocolNumber);
+          outPort->Send(packet, src, dest, protocolNumber);
           return true;
         }
     }
 
   // data was not unicast or no state has been learned for that mac
   // address => flood through all ports.
-  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
+  for (std::vector< Ptr<BridgePortNetDevice> >::iterator iter = m_ports.begin ();
        iter != m_ports.end (); iter++)
     {
-      Ptr<NetDevice> port = *iter;
-      port->SendFrom (packet, src, dest, protocolNumber);
+      Ptr<BridgePortNetDevice> port = *iter;
+      port->Send (packet, src, dest, protocolNumber);
     }
 
   return true;
index d982b09ad8dbff58bfe0c39d7488879070c72ec9..947e05cff1331023e73695ba739ef4099dac3e4a 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * Author: Gustavo Carneiro  <gjc@inescporto.pt>
+ * Author: Richard Whitehouse <ns3@richardwhiuk.com>
  */
 #ifndef BRIDGE_NET_DEVICE_H
 #define BRIDGE_NET_DEVICE_H
 
+#include "bridge-port-net-device.h"
 #include "ns3/net-device.h"
 #include "ns3/mac48-address.h"
 #include "ns3/nstime.h"
@@ -118,14 +120,11 @@ public:
 protected:
   virtual void DoDispose (void);
 
-  void ReceiveFromDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
-                          Address const &source, Address const &destination, PacketType packetType);
-  void ForwardUnicast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
-                       uint16_t protocol, Mac48Address src, Mac48Address dst);
-  void ForwardBroadcast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
-                         uint16_t protocol, Mac48Address src, Mac48Address dst);
-  void Learn (Mac48Address source, Ptr<NetDevice> port);
-  Ptr<NetDevice> GetLearnedState (Mac48Address source);
+  void Forward (Ptr<BridgePortNetDevice> port, Ptr<const Packet> packet, uint16_t protocol, Address const &src, Address const &dst, PacketType packetType);
+  void ForwardUnicast (Ptr<BridgePortNetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol, Mac48Address src, Mac48Address dst);
+  void ForwardBroadcast (Ptr<BridgePortNetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol, Mac48Address src, Mac48Address dst);
+  void Learn (Address const &src, Ptr<BridgePortNetDevice> port);
+  Ptr<BridgePortNetDevice> GetLearnedState (Mac48Address source);
 
 private:
   NetDevice::ReceiveCallback m_rxCallback;
@@ -135,16 +134,22 @@ private:
   Time m_expirationTime; // time it takes for learned MAC state to expire
   struct LearnedState
   {
-    Ptr<NetDevice> associatedPort;
+    Ptr<BridgePortNetDevice> associatedPort;
     Time expirationTime;
   };
   std::map<Mac48Address, LearnedState> m_learnState;
   Ptr<Node> m_node;
   Ptr<BridgeChannel> m_channel;
-  std::vector< Ptr<NetDevice> > m_ports;
+
+  std::vector<Ptr<BridgePortNetDevice> > m_ports;
+
+  uint16_t mPortNumber;
   uint32_t m_ifIndex;
   uint16_t m_mtu;
   bool m_enableLearning;
+
+  friend class BridgePortNetDevice;
+
 };
 
 } // namespace ns3
diff --git a/code/src/devices/bridge/model/bridge-port-net-device.cc b/code/src/devices/bridge/model/bridge-port-net-device.cc
new file mode 100644 (file)
index 0000000..29093e6
--- /dev/null
@@ -0,0 +1,93 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Richard Whitehouse <ns3@richardwhiuk.com>
+ */
+#include "bridge-net-device.h"
+#include "ns3/node.h"
+#include "ns3/channel.h"
+#include "ns3/packet.h"
+#include "ns3/log.h"
+#include "ns3/boolean.h"
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+
+NS_LOG_COMPONENT_DEFINE ("BridgePortNetDevice");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (BridgePortNetDevice);
+
+TypeId
+BridgePortNetDevice::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::BridgePortNetDevice")
+    .SetParent<Object> ()
+    ;
+  return tid;
+}
+
+
+BridgePortNetDevice::BridgePortNetDevice(Ptr<BridgeNetDevice> bridge, Ptr<NetDevice> device, Ptr<Node> node) : m_bridge(bridge), m_device(device){
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (!Mac48Address::IsMatchingType (device->GetAddress()))
+    {
+      NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
+    }
+  if (!device->SupportsSendFrom ())
+    {
+      NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
+    }
+
+  NS_LOG_DEBUG ("RegisterProtocolHandler for " << device->GetInstanceTypeId ().GetName ());
+
+  node->RegisterProtocolHandler (MakeCallback (&BridgePortNetDevice::Receive, this), 0, device, true);
+
+}
+
+BridgePortNetDevice::~BridgePortNetDevice(){
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void BridgePortNetDevice::Send(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber){
+       NS_LOG_FUNCTION_NOARGS ();
+       NS_LOG_LOGIC("SendingPacket(src=" << source << ", dest=" << dest << ")");
+       m_device->SendFrom(packet->Copy(), source, dest, protocolNumber);
+}
+
+/**
+ * By moving learning to the port, we can have some ports which learn, and some which don't.
+ **/
+
+void
+BridgePortNetDevice::Receive (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
+                                    Address const &src, Address const &dst, NetDevice::PacketType packetType)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("UID is " << packet->GetUid ());
+
+  NS_LOG_LOGIC ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
+                << ", packet=" << packet << ", protocol="<<protocol
+                << ", src=" << src << ", dst=" << dst << ")");
+
+  m_bridge->Learn(src, this);
+
+  m_bridge->Forward(this, packet, protocol, src, dst, packetType);
+
+}
+
+}
+
diff --git a/code/src/devices/bridge/model/bridge-port-net-device.h b/code/src/devices/bridge/model/bridge-port-net-device.h
new file mode 100644 (file)
index 0000000..b9d62bf
--- /dev/null
@@ -0,0 +1,62 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Gustavo Carneiro  <gjc@inescporto.pt>
+ * Author: Richard Whitehouse <ns3@richardwhiuk.com>
+ */
+#ifndef BRIDGE_PORT_NET_DEVICE_H
+#define BRIDGE_PORT_NET_DEVICE_H
+
+#include "ns3/net-device.h"
+#include "ns3/mac48-address.h"
+#include "ns3/nstime.h"
+#include <stdint.h>
+#include <string>
+#include <map>
+
+namespace ns3 {
+
+class Node;
+class BridgeNetDevice;
+
+/**
+ * \ingroup bridge
+ * \brief a port on a virtual net device that bridges multiple LAN segments
+ */
+
+class BridgePortNetDevice : public Object {
+
+public:
+  BridgePortNetDevice(Ptr<BridgeNetDevice> bridge, Ptr<NetDevice> device, Ptr<Node> node);
+  virtual ~BridgePortNetDevice();
+
+  static TypeId GetTypeId (void);
+
+protected:
+  void Send (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber);
+  void Receive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, Address const &source, Address const &destination, NetDevice::PacketType packetType);
+     
+private:
+  Ptr<BridgeNetDevice> m_bridge;
+  Ptr<NetDevice> m_device;
+
+
+  friend class BridgeNetDevice;
+
+};
+
+} // namespace ns3
+
+#endif /* BRIDGE_PORT_NET_DEVICE_H */
index 3dde0ec7515e8dcb8581d2e726f334ec45fea492..a14d756ad4a49df0c1183ec774a691df0897722b 100644 (file)
@@ -4,6 +4,7 @@ def build(bld):
     obj = bld.create_ns3_module('bridge', ['node'])
     obj.source = [
         'model/bridge-net-device.cc',
+        'model/bridge-port-net-device.cc',
         'model/bridge-channel.cc',
         'helper/bridge-helper.cc',
         ]
@@ -11,6 +12,7 @@ def build(bld):
     headers.module = 'bridge'
     headers.source = [
         'model/bridge-net-device.h',
+       'model/bridge-port-net-device.h',
         'model/bridge-channel.h',
         'helper/bridge-helper.h',
         ]