Finally make tap bridge work with VMs (bug 569)
authorCraig Dowell <craigdo@ee.washington.edu>
Tue, 23 Jun 2009 22:12:35 -0700
changeset 4578 88434ff8f0a5
parent 4577 84c133267507
child 4579 c86681050541
Finally make tap bridge work with VMs (bug 569)
examples/tap-wifi-dumbbell.cc
src/devices/bridge/bridge-net-device.cc
src/devices/bridge/bridge-net-device.h
src/devices/csma/csma-net-device.cc
src/devices/csma/csma-net-device.h
src/devices/emu/emu-net-device.cc
src/devices/emu/emu-net-device.h
src/devices/point-to-point/point-to-point-net-device.cc
src/devices/point-to-point/point-to-point-net-device.h
src/devices/tap-bridge/tap-bridge.cc
src/devices/tap-bridge/tap-bridge.h
src/devices/virtual-net-device/virtual-net-device.h
src/devices/wifi/wifi-net-device.cc
src/devices/wifi/wifi-net-device.h
src/internet-stack/loopback-net-device.cc
src/internet-stack/loopback-net-device.h
src/internet-stack/tcp-test.cc
src/internet-stack/udp-test.cc
src/node/net-device.h
src/node/node.cc
src/node/simple-net-device.cc
src/node/simple-net-device.h
--- a/examples/tap-wifi-dumbbell.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/examples/tap-wifi-dumbbell.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -227,7 +227,7 @@
   apps = sink.Install (nodesRight.Get (0));
   apps.Start (Seconds (1.0));
 
-  CsmaHelper::EnablePcapAll ("tap-dumbbell", false);
+  CsmaHelper::EnablePcapAll ("tap-wifi-dumbbell", false);
   GlobalRouteManager::PopulateRoutingTables ();
 
   Simulator::Stop (Seconds (60.));
--- a/src/devices/bridge/bridge-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/bridge/bridge-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -278,6 +278,13 @@
   return m_channel;
 }
 
+void
+BridgeNetDevice::SetAddress (Address address)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_address = Mac48Address::ConvertFrom (address);
+}
+
 Address 
 BridgeNetDevice::GetAddress (void) const
 {
--- a/src/devices/bridge/bridge-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/bridge/bridge-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -91,6 +91,7 @@
   virtual void SetIfIndex(const uint32_t index);
   virtual uint32_t GetIfIndex(void) const;
   virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual bool SetMtu (const uint16_t mtu);
   virtual uint16_t GetMtu (void) const;
--- a/src/devices/csma/csma-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/csma/csma-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -321,13 +321,6 @@
   return m_frameSize;
 }
 
-  void 
-CsmaNetDevice::SetAddress (Mac48Address self)
-{
-  NS_LOG_FUNCTION (self);
-  m_address = self;
-}
-
   void
 CsmaNetDevice::SetSendEnable (bool sendEnable)
 {
@@ -875,6 +868,13 @@
   return m_channel;
 }
 
+  void
+CsmaNetDevice::SetAddress (Address address)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_address = Mac48Address::ConvertFrom (address);
+}
+
   Address 
 CsmaNetDevice::GetAddress (void) const
 {
--- a/src/devices/csma/csma-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/csma/csma-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -183,13 +183,6 @@
   void SetReceiveEnable (bool enable);
 
   /**
-   * Set the MAC address of the the network device.
-   *
-   * \param addr The Mac48Address to use as the address of the device.
-   */
-  void SetAddress (Mac48Address addr);
-
-  /**
    * Set The max frame size of packets sent over this device.
    *
    * Okay, that was easy to say, but the details are a bit thorny.  We have a MAC-level MTU that is the payload that higher 
@@ -310,6 +303,7 @@
   virtual Ptr<Channel> GetChannel (void) const;
   virtual bool SetMtu (const uint16_t mtu);
   virtual uint16_t GetMtu (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual bool IsLinkUp (void) const;
   virtual void SetLinkChangeCallback (Callback<void> callback);
--- a/src/devices/emu/emu-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/emu/emu-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -876,10 +876,10 @@
 }
 
 void 
-EmuNetDevice::SetAddress (Mac48Address addr)
+EmuNetDevice::SetAddress (Address address)
 {
-  NS_LOG_FUNCTION (addr);
-  m_address = addr;
+  NS_LOG_FUNCTION (address);
+  m_address = Mac48Address::ConvertFrom (address);
 }
 
 Address 
--- a/src/devices/emu/emu-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/emu/emu-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -94,14 +94,6 @@
    */
   void SetQueue (Ptr<Queue> queue);
 
-  /**
-   * Assign a MAC address to this device.
-   *
-   * @see Mac48Address
-   * @param addr The new address.
-   */
-  void SetAddress (Mac48Address addr);
-
 //
 // Pure virtual methods inherited from NetDevice we must implement.
 //
@@ -109,6 +101,8 @@
   virtual uint32_t GetIfIndex(void) const;
 
   virtual Ptr<Channel> GetChannel (void) const;
+
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
 
   virtual bool SetMtu (const uint16_t mtu);
--- a/src/devices/point-to-point/point-to-point-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -395,10 +395,11 @@
 // information.  However, the base class NetDevice wants us to define the
 // methods to get and set the address.  Rather than be rude and assert, we let
 // clients get and set the address, but simply ignore them.
+
   void 
-PointToPointNetDevice::SetAddress (Mac48Address addr)
+PointToPointNetDevice::SetAddress (Address address)
 {
-  m_address = addr;
+  m_address = Mac48Address::ConvertFrom (address);
 }
 
   Address 
--- a/src/devices/point-to-point/point-to-point-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/point-to-point/point-to-point-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -132,14 +132,6 @@
   void Receive (Ptr<Packet> p);
 
   /**
-   * Assign a MAC address to this device.
-   *
-   * @see Mac48Address
-   * @param addr The new address.
-   */
-  void SetAddress (Mac48Address addr);
-
-  /**
    * Set The max frame size of packets sent over this device.
    *
    * Okay, that was easy to say, but the details are a bit thorny.  We have a MAC-level MTU that is the payload that higher 
@@ -230,6 +222,8 @@
   virtual uint32_t GetIfIndex(void) const;
 
   virtual Ptr<Channel> GetChannel (void) const;
+
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
 
   virtual bool SetMtu (const uint16_t mtu);
--- a/src/devices/tap-bridge/tap-bridge.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/tap-bridge/tap-bridge.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -131,7 +131,7 @@
   m_startEvent (),
   m_stopEvent (),
   m_readThread (0),
-  m_learnedMac (Mac48Address ("ff:ff:ff:ff:ff:ff"))
+  m_ns3AddressRewritten (false)
 {
   NS_LOG_FUNCTION_NOARGS ();
   Start (m_tStart);
@@ -641,7 +641,7 @@
           return;
         }
 
-      NS_LOG_INFO ("TapBridge::ReadThread(): Received packet");
+      NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_node->GetId ());
       NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler");
       DynamicCast<RealtimeSimulatorImpl> (Simulator::GetImplementation ())->ScheduleRealtimeNow (
         MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len));
@@ -713,21 +713,21 @@
       //
       NS_ASSERT_MSG (Mac48Address::ConvertFrom (src) != Mac48Address ("ff:ff:ff:ff:ff:ff"), 
                      "TapBridge::ForwardToBridgedDevice:  Source addr is broadcast");
-      //
-      // Remember the Mac address since we are going to spoof it when we go
-      // the other way.
-      //
-      m_learnedMac = Mac48Address::ConvertFrom (src);
-      NS_LOG_LOGIC ("Learned MacAddr is " << m_learnedMac);
-
+      if (m_ns3AddressRewritten == false)
+        {
+          //
+          // Set the ns-3 device's mac address to the overlying container's
+          // mac address
+          //
+          Mac48Address learnedMac = Mac48Address::ConvertFrom (src);
+          NS_LOG_LOGIC ("Learned MacAddr is " << learnedMac << ": setting ns-3 device to use this address");
+          m_bridgedDevice->SetAddress (Mac48Address::ConvertFrom (learnedMac));
+          m_ns3AddressRewritten = true;
+        }
       // 
       // If we are operating in USE_LOCAL mode, we may be attached to an ns-3
       // device that does not support bridging (SupportsSendFrom returns false).
-      // The whole point of this mode is really to support this case.  We allow
-      // only packets from one source MAC to flow across the TapBridge in this 
-      // mode and will spoof that address when packets flow the other way.  
-      // Since we will be doing this spoofing, we can relax the normal bridged
-      // device requirement to support SendFrom and use Send.
+      // But, since the mac addresses are now aligned, we can call Send()
       //
       NS_LOG_LOGIC ("Forwarding packet to ns-3 device via Send()");
       m_bridgedDevice->Send (packet, dst, type);
@@ -864,20 +864,34 @@
     }
 
   //
-  // Tell the bridged device to forward its received packets here.  We use the 
-  // promiscuous mode hook to get both the source and destination addresses.
+  // We need to disconnect the bridged device from the internet stack on our
+  // node to ensure that only one stack responds to packets inbound over the
+  // bridged device.  That one stack lives outside ns-3 so we just blatantly
+  // steal the device callbacks.
   //
-  m_node->RegisterProtocolHandler (MakeCallback (&TapBridge::ReceiveFromBridgedDevice, this), 0, bridgedDevice, true);
+  // N.B This can be undone if someone does a RegisterProtocolHandler later 
+  // on this node.
+  //
+  bridgedDevice->SetReceiveCallback (MakeCallback (&TapBridge::DiscardFromBridgedDevice, this));
+  bridgedDevice->SetPromiscReceiveCallback (MakeCallback (&TapBridge::ReceiveFromBridgedDevice, this));
   m_bridgedDevice = bridgedDevice;
 }
 
-void
+bool
+TapBridge::DiscardFromBridgedDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &src)
+{
+  NS_LOG_FUNCTION (device << packet << protocol << src);
+  NS_LOG_LOGIC ("Discarding packet stolen from bridged device " << device);
+  return true;
+}
+
+bool
 TapBridge::ReceiveFromBridgedDevice (
   Ptr<NetDevice> device, 
   Ptr<const Packet> packet, 
   uint16_t protocol,
-  Address const &src, 
-  Address const &dst, 
+  const Address &src, 
+  const Address &dst, 
   PacketType packetType)
 {
   NS_LOG_FUNCTION (device << packet << protocol << src << dst << packetType);
@@ -913,35 +927,11 @@
       // we want to act like a bridge and forward these PACKET_OTHERHOST 
       // packets.
       //
-      return;
+      return true;
     }
 
-  //
-  // We have received a packet from the ns-3 net device that has been associated
-  // with this bridge.  We want to take these bits and send them off to the tap
-  // device on the Linux host.  The only question we have to answer is, what 
-  // should the destination address be?
-  //
-  // If we are in CONFIGURE_LOCAL mode, then the destination address is just
-  // left alone since it can only be the shared single MAC address, broadcast
-  // or multicast.
-  //
-  // If we are in USE_LOCAL mode, then we need to spoof the destination 
-  // address with the one we saved.
-  //
-  // If we are in USE_BRIDGE mode, then we need to do the equvalent of a 
-  // SendFrom and leave the source and destination alone.
-  //
   Mac48Address from = Mac48Address::ConvertFrom (src);
-  Mac48Address to;
-  if (m_mode == USE_LOCAL)
-    {
-      to = Mac48Address::ConvertFrom (m_learnedMac);
-    }
-  else 
-    {
-      to = Mac48Address::ConvertFrom (dst);
-    }
+  Mac48Address to = Mac48Address::ConvertFrom (dst);
 
   Ptr<Packet> p = packet->Copy ();
   EthernetHeader header = EthernetHeader (false);
@@ -956,9 +946,11 @@
   NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
   NS_LOG_LOGIC ("Pkt LengthType is " << header.GetLengthType ());
   NS_LOG_LOGIC ("Pkt size is " << p->GetSize ());
+  NS_LOG_LOGIC ("End of receive packet handling on node " << m_node->GetId ());
 
   uint32_t bytesWritten = write (m_sock, p->PeekData (), p->GetSize ());
   NS_ABORT_MSG_IF (bytesWritten != p->GetSize (), "TapBridge::ReceiveFromBridgedDevice(): Write error.");
+  return true;
 }
 
 void 
@@ -982,6 +974,13 @@
   return 0;
 }
 
+void
+TapBridge::SetAddress (Address address)
+{
+  NS_LOG_FUNCTION (address);
+  m_address = Mac48Address::ConvertFrom (address);
+}
+
 Address 
 TapBridge::GetAddress (void) const
 {
--- a/src/devices/tap-bridge/tap-bridge.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/tap-bridge/tap-bridge.h	Tue Jun 23 22:12:35 2009 -0700
@@ -176,6 +176,7 @@
   virtual void SetIfIndex(const uint32_t index);
   virtual uint32_t GetIfIndex(void) const;
   virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual bool SetMtu (const uint16_t mtu);
   virtual uint16_t GetMtu (void) const;
@@ -208,8 +209,11 @@
    */
   virtual void DoDispose (void);
 
-  void ReceiveFromBridgedDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
+  bool ReceiveFromBridgedDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol,
                                  Address const &src, Address const &dst, PacketType packetType);
+
+  bool DiscardFromBridgedDevice (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, Address const &src);
+
 private:
 
   /**
@@ -443,13 +447,10 @@
   /**
    * \internal
    *
-   * The MAC address of the local tap device is stored in this variable.
-   * When in UseLocal mode, this address is added back to the destination 
-   * Mac address for frames destined to the tap device.  It is learned from
-   * the first frame sent from the host to the TapBridge device.  In the
-   * other modes of this device, this value is unused.  
+   * Whether the MAC address of the underlying ns-3 device has already been
+   * rewritten is stored in this variable (for UseLocal mode only).
    */
-  Mac48Address m_learnedMac;
+  bool m_ns3AddressRewritten;
 
 };
 
--- a/src/devices/virtual-net-device/virtual-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/virtual-net-device/virtual-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -114,17 +114,11 @@
                 PacketType packetType);
 
 
-  /**
-   * Set the MAC address of the the network device.
-   *
-   * \param addr The Address to use as the address of the device.
-   */
-  void SetAddress (Address addr);
-
   // inherited from NetDevice base class.
   virtual void SetIfIndex(const uint32_t index);
   virtual uint32_t GetIfIndex(void) const;
   virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual uint16_t GetMtu (void) const;
   virtual bool IsLinkUp (void) const;
--- a/src/devices/wifi/wifi-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/wifi/wifi-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -157,6 +157,11 @@
 {
   return m_phy->GetChannel ();
 }
+void 
+WifiNetDevice::SetAddress (Address address)
+{
+  m_mac->SetAddress (Mac48Address::ConvertFrom (address));
+}
 Address 
 WifiNetDevice::GetAddress (void) const
 {
--- a/src/devices/wifi/wifi-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/devices/wifi/wifi-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -78,6 +78,7 @@
   virtual void SetIfIndex(const uint32_t index);
   virtual uint32_t GetIfIndex(void) const;
   virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual bool SetMtu (const uint16_t mtu);
   virtual uint16_t GetMtu (void) const;
--- a/src/internet-stack/loopback-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/internet-stack/loopback-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -93,6 +93,12 @@
   return 0;
 }
 
+void 
+LoopbackNetDevice::SetAddress (Address address)
+{
+  m_address = Mac48Address::ConvertFrom (address);
+}
+
 Address 
 LoopbackNetDevice::GetAddress (void) const
 {
--- a/src/internet-stack/loopback-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/internet-stack/loopback-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -45,6 +45,7 @@
   virtual void SetIfIndex(const uint32_t index);
   virtual uint32_t GetIfIndex(void) const;
   virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual bool SetMtu (const uint16_t mtu);
   virtual uint16_t GetMtu (void) const;
--- a/src/internet-stack/tcp-test.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/internet-stack/tcp-test.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -300,7 +300,7 @@
 TcpSocketImplTest::AddSimpleNetDevice (Ptr<Node> node, const char* ipaddr, const char* netmask)
 {
   Ptr<SimpleNetDevice> dev = CreateObject<SimpleNetDevice> ();
-  dev->SetAddress (Mac48Address::Allocate ());
+  dev->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
   node->AddDevice (dev);
   Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   uint32_t ndid = ipv4->AddInterface (dev);
--- a/src/internet-stack/udp-test.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/internet-stack/udp-test.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -134,7 +134,7 @@
   Ptr<SimpleNetDevice> rxDev1, rxDev2;
   { // first interface
     rxDev1 = CreateObject<SimpleNetDevice> ();
-    rxDev1->SetAddress (Mac48Address::Allocate ());
+    rxDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
     rxNode->AddDevice (rxDev1);
     Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (rxDev1);
@@ -145,7 +145,7 @@
 
   { // second interface
     rxDev2 = CreateObject<SimpleNetDevice> ();
-    rxDev2->SetAddress (Mac48Address::Allocate ());
+    rxDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
     rxNode->AddDevice (rxDev2);
     Ptr<Ipv4> ipv4 = rxNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (rxDev2);
@@ -160,7 +160,7 @@
   Ptr<SimpleNetDevice> txDev1;
   {
     txDev1 = CreateObject<SimpleNetDevice> ();
-    txDev1->SetAddress (Mac48Address::Allocate ());
+    txDev1->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
     txNode->AddDevice (txDev1);
     Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (txDev1);
@@ -171,7 +171,7 @@
   Ptr<SimpleNetDevice> txDev2;
   {
     txDev2 = CreateObject<SimpleNetDevice> ();
-    txDev2->SetAddress (Mac48Address::Allocate ());
+    txDev2->SetAddress (Mac48Address::ConvertFrom (Mac48Address::Allocate ()));
     txNode->AddDevice (txDev2);
     Ptr<Ipv4> ipv4 = txNode->GetObject<Ipv4> ();
     uint32_t netdev_idx = ipv4->AddInterface (txDev2);
--- a/src/node/net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/node/net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -98,9 +98,15 @@
   virtual Ptr<Channel> GetChannel (void) const = 0;
 
   /**
+   * Set the address of this interface
+   */
+  virtual void SetAddress (Address address) = 0;
+
+  /**
    * \return the current Address of this interface.
    */
   virtual Address GetAddress (void) const = 0;
+
   /**
    * \param mtu MTU value, in bytes, to set for the device
    * \return whether the MTU value was within legal bounds
--- a/src/node/node.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/node/node.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -192,23 +192,12 @@
                i != m_devices.end (); i++)
             {
               Ptr<NetDevice> dev = *i;
-              if (dev->SupportsSendFrom ())
-                {
-                  dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
-                }
+              dev->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
             }
         }
       else
         {
-          if (device->SupportsSendFrom ())
-            {
-              device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
-            }
-          else
-            {
-              NS_LOG_WARN ("Protocol handler request promiscuous mode for a specific netdevice,"
-                           " but netdevice does not support promiscuous mode.");
-            }
+          device->SetPromiscReceiveCallback (MakeCallback (&Node::PromiscReceiveFromDevice, this));
         }
     }
 
--- a/src/node/simple-net-device.cc	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/node/simple-net-device.cc	Tue Jun 23 22:12:35 2009 -0700
@@ -77,12 +77,6 @@
 }
 
 void 
-SimpleNetDevice::SetAddress (Mac48Address address)
-{
-  m_address = address;
-}
-
-void 
 SimpleNetDevice::SetIfIndex(const uint32_t index)
 {
   m_ifIndex = index;
@@ -97,9 +91,17 @@
 {
   return m_channel;
 }
+void
+SimpleNetDevice::SetAddress (Address address)
+{
+  m_address = Mac48Address::ConvertFrom(address);
+}
 Address 
 SimpleNetDevice::GetAddress (void) const
 {
+  //
+  // Implicit conversion from Mac48Address to Address
+  //
   return m_address;
 }
 bool 
--- a/src/node/simple-net-device.h	Tue Jun 23 19:44:57 2009 -0700
+++ b/src/node/simple-net-device.h	Tue Jun 23 22:12:35 2009 -0700
@@ -43,12 +43,12 @@
 
   void Receive (Ptr<Packet> packet, uint16_t protocol, Mac48Address to, Mac48Address from);
   void SetChannel (Ptr<SimpleChannel> channel);
-  void SetAddress (Mac48Address address);
 
   // inherited from NetDevice base class.
   virtual void SetIfIndex(const uint32_t index);
   virtual uint32_t GetIfIndex(void) const;
   virtual Ptr<Channel> GetChannel (void) const;
+  virtual void SetAddress (Address address);
   virtual Address GetAddress (void) const;
   virtual bool SetMtu (const uint16_t mtu);
   virtual uint16_t GetMtu (void) const;