Convert the bridge module to the new layout
authorGustavo J. A. M. Carneiro <gjc@inescporto.pt>
Mon, 25 Oct 2010 15:00:28 +0100
changeset 6635 d52752c85699
parent 6634 ef874c63c6b1
child 6636 913bcb88a6a8
Convert the bridge module to the new layout
examples/csma/csma-bridge-one-hop.cc
examples/csma/csma-bridge.cc
examples/csma/csma-bridge.py
examples/csma/wscript
src/devices/bridge/bridge-channel.cc
src/devices/bridge/bridge-channel.h
src/devices/bridge/bridge-net-device.cc
src/devices/bridge/bridge-net-device.h
src/devices/bridge/examples/csma-bridge-one-hop.cc
src/devices/bridge/examples/csma-bridge.cc
src/devices/bridge/examples/csma-bridge.py
src/devices/bridge/examples/wscript
src/devices/bridge/helper/bridge-helper.cc
src/devices/bridge/helper/bridge-helper.h
src/devices/bridge/model/bridge-channel.cc
src/devices/bridge/model/bridge-channel.h
src/devices/bridge/model/bridge-net-device.cc
src/devices/bridge/model/bridge-net-device.h
src/devices/bridge/wscript
src/helper/bridge-helper.cc
src/helper/bridge-helper.h
src/helper/wscript
test.py
--- a/examples/csma/csma-bridge-one-hop.cc	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/* -*- 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
- */
-
-// Network topology
-//
-//         bridge1         The node named bridge1 (node 5 in the nodelist)
-//   ------------------        has three CMSA net devices that are bridged
-//   CSMA   CSMA   CSMA        together using a BridgeNetDevice.
-//     |      |      |
-//     |      |      |     The bridge node talks over three CSMA channels
-//     |      |      |
-//   CSMA   CSMA   CSMA    to three other CSMA net devices
-//   ----   ----   ----    
-//    n0     n1     n2     Node two acts as a router and talks to another
-//                 ----        bridge that connects the remaining nodes.
-//                 CSMA
-//                   |
-//    n3     n4      |
-//   ----   ----     |
-//   CSMA   CSMA     |
-//     |      |      |
-//     |      |      |
-//     |      |      |
-//   CSMA   CSMA   CSMA    The node named bridge2 (node 6 in the nodelist)
-//   ------------------        has three CMSA net devices that are bridged
-//        bridge2              together using a BridgeNetDevice.
-//
-// Or, more abstractly, recognizing that bridge 1 and bridge 2 are nodes 
-// with three net devices:
-//
-//        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
-//       -----------               (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
-// 
-// It is meant to mirror somewhat the csma-bridge example but adds another
-// bridged link separated by a router.
-// 
-// - 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"
-
-#include <iostream>
-#include <fstream>
-
-#include "ns3/simulator-module.h"
-#include "ns3/node-module.h"
-#include "ns3/core-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/bridge-module.h"
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("CsmaBridgeOneHopExample");
-
-int 
-main (int argc, char *argv[])
-{
-  //
-  // Users may find it convenient to turn on explicit debugging
-  // for selected modules; the below lines suggest how to do this
-  //
-#if 0 
-  LogComponentEnable ("CsmaBridgeOneHopExample", LOG_LEVEL_INFO);
-#endif
-
-  //
-  // Allow the user to override any of the defaults and the above Bind() at
-  // run-time, via command-line arguments
-  //
-  CommandLine cmd;
-  cmd.Parse (argc, argv);
-
-  //
-  // Explicitly create the nodes required by the topology (shown above).
-  //
-  NS_LOG_INFO ("Create nodes.");
-
-  Ptr<Node> n0 = CreateObject<Node> ();
-  Ptr<Node> n1 = CreateObject<Node> ();
-  Ptr<Node> n2 = CreateObject<Node> ();
-  Ptr<Node> n3 = CreateObject<Node> ();
-  Ptr<Node> n4 = CreateObject<Node> ();
-
-  Ptr<Node> bridge1 = CreateObject<Node> ();
-  Ptr<Node> bridge2 = CreateObject<Node> ();
-
-  NS_LOG_INFO ("Build Topology");
-  CsmaHelper csma;
-  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
-  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
-
-  // Create the csma links, from each terminal to the bridge
-  // This will create six network devices; we'll keep track separately
-  // of the devices on and off the bridge respectively, for later configuration 
-  NetDeviceContainer topLanDevices;
-  NetDeviceContainer topBridgeDevices;
-
-  // It is easier to iterate the nodes in C++ if we put them into a container
-  NodeContainer topLan (n2, n0, n1);
-
-  for (int i = 0; i < 3; i++)
-    {
-      // install a csma channel between the ith toplan node and the bridge node
-      NetDeviceContainer link = csma.Install (NodeContainer (topLan.Get (i), bridge1));
-      topLanDevices.Add (link.Get (0));
-      topBridgeDevices.Add (link.Get (1));
-    }
-
-  //
-  // Now, Create the bridge netdevice, which will do the packet switching.  The
-  // bridge lives on the node bridge1 and bridges together the topBridgeDevices
-  // which are the three CSMA net devices on the node in the diagram above.
-  //
-  BridgeHelper bridge;
-  bridge.Install (bridge1, topBridgeDevices);
-
-  // Add internet stack to the router nodes
-  NodeContainer routerNodes (n0, n1, n2, n3, n4);
-  InternetStackHelper internet;
-  internet.Install (routerNodes);
-
-  // Repeat for bottom bridged LAN
-  NetDeviceContainer bottomLanDevices;
-  NetDeviceContainer bottomBridgeDevices;
-  NodeContainer bottomLan (n2, n3, n4);
-  for (int i = 0; i < 3; i++)
-    {
-      NetDeviceContainer link = csma.Install (NodeContainer (bottomLan.Get (i), bridge2));
-      bottomLanDevices.Add (link.Get (0));
-      bottomBridgeDevices.Add (link.Get (1));
-    }
-  bridge.Install (bridge2, bottomBridgeDevices);
-
-  // We've got the "hardware" in place.  Now we need to add IP addresses.
-  NS_LOG_INFO ("Assign IP Addresses.");
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  ipv4.Assign (topLanDevices);
-  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
-  ipv4.Assign (bottomLanDevices);
-
-  // 
-  // Create router nodes, initialize routing database and set up the routing
-  // tables in the nodes.  We excuse the bridge nodes from having to serve as
-  // routers, since they don't even have internet stacks on them.
-  //
-  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
-
-  //
-  // Create an OnOff application to send UDP datagrams from node zero to node 1.
-  //
-  NS_LOG_INFO ("Create Applications.");
-  uint16_t port = 9;   // Discard port (RFC 863)
-
-  OnOffHelper onoff ("ns3::UdpSocketFactory", 
-                     Address (InetSocketAddress (Ipv4Address ("10.1.1.3"), port)));
-  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
-  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
-
-  ApplicationContainer app = onoff.Install (n0);
-  // Start the application
-  app.Start (Seconds (1.0));
-  app.Stop (Seconds (10.0));
-
-  // Create an optional packet sink to receive these packets
-  PacketSinkHelper sink ("ns3::UdpSocketFactory",
-                         Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  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
-  //
-  onoff.SetAttribute ("Remote", 
-                      AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
-  ApplicationContainer app2 = onoff.Install (n3);
-  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));
-
-  NS_LOG_INFO ("Configure Tracing.");
-
-  //
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
-  // Trace output will be sent to the file "csma-bridge-one-hop.tr"
-  //
-  AsciiTraceHelper ascii;
-  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-bridge-one-hop.tr"));
-
-  //
-  // Also configure some tcpdump traces; each interface will be traced.
-  // The output files will be named:
-  //     csma-bridge-one-hop-<nodeId>-<interfaceId>.pcap
-  // and can be read by the "tcpdump -r" command (use "-tt" option to
-  // display timestamps correctly)
-  //
-  csma.EnablePcapAll ("csma-bridge-one-hop", false);
-
-  //
-  // Now, do the actual simulation.
-  //
-  NS_LOG_INFO ("Run Simulation.");
-  Simulator::Run ();
-  Simulator::Destroy ();
-  NS_LOG_INFO ("Done.");
-}
--- a/examples/csma/csma-bridge.cc	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/* -*- 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
- */
-
-// Network topology
-//
-//        n0     n1  
-//        |      | 
-//       ----------
-//       | Switch |
-//       ----------
-//        |      | 
-//        n2     n3  
-//
-//
-// - CBR/UDP flows from n0 to n1 and from n3 to n0
-// - DropTail queues 
-// - Tracing of queues and packet receptions to file "csma-bridge.tr"
-
-#include <iostream>
-#include <fstream>
-
-#include "ns3/simulator-module.h"
-#include "ns3/node-module.h"
-#include "ns3/core-module.h"
-#include "ns3/helper-module.h"
-#include "ns3/bridge-module.h"
-
-using namespace ns3;
-
-NS_LOG_COMPONENT_DEFINE ("CsmaBridgeExample");
-
-int 
-main (int argc, char *argv[])
-{
-  //
-  // Users may find it convenient to turn on explicit debugging
-  // for selected modules; the below lines suggest how to do this
-  //
-#if 0 
-  LogComponentEnable ("CsmaBridgeExample", LOG_LEVEL_INFO);
-#endif
-
-  //
-  // Allow the user to override any of the defaults and the above Bind() at
-  // run-time, via command-line arguments
-  //
-  CommandLine cmd;
-  cmd.Parse (argc, argv);
-
-  //
-  // Explicitly create the nodes required by the topology (shown above).
-  //
-  NS_LOG_INFO ("Create nodes.");
-  NodeContainer terminals;
-  terminals.Create (4);
-
-  NodeContainer csmaSwitch;
-  csmaSwitch.Create (1);
-
-  NS_LOG_INFO ("Build Topology");
-  CsmaHelper csma;
-  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
-  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
-
-  // Create the csma links, from each terminal to the switch
-
-  NetDeviceContainer terminalDevices;
-  NetDeviceContainer switchDevices;
-
-  for (int i = 0; i < 4; i++)
-    {
-      NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i), csmaSwitch));
-      terminalDevices.Add (link.Get (0));
-      switchDevices.Add (link.Get (1));
-    }
-
-  // Create the bridge netdevice, which will do the packet switching
-  Ptr<Node> switchNode = csmaSwitch.Get (0);
-  BridgeHelper bridge;
-  bridge.Install (switchNode, switchDevices);
-
-  // Add internet stack to the terminals
-  InternetStackHelper internet;
-  internet.Install (terminals);
-
-  // We've got the "hardware" in place.  Now we need to add IP addresses.
-  //
-  NS_LOG_INFO ("Assign IP Addresses.");
-  Ipv4AddressHelper ipv4;
-  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
-  ipv4.Assign (terminalDevices);
-
-  //
-  // Create an OnOff application to send UDP datagrams from node zero to node 1.
-  //
-  NS_LOG_INFO ("Create Applications.");
-  uint16_t port = 9;   // Discard port (RFC 863)
-
-  OnOffHelper onoff ("ns3::UdpSocketFactory", 
-                     Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
-  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
-  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
-
-  ApplicationContainer app = onoff.Install (terminals.Get (0));
-  // Start the application
-  app.Start (Seconds (1.0));
-  app.Stop (Seconds (10.0));
-
-  // Create an optional packet sink to receive these packets
-  PacketSinkHelper sink ("ns3::UdpSocketFactory",
-                         Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  app = sink.Install (terminals.Get (1));
-  app.Start (Seconds (0.0));
-
-  // 
-  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
-  //
-  onoff.SetAttribute ("Remote", 
-                      AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"), port)));
-  app = onoff.Install (terminals.Get (3));
-  app.Start (Seconds (1.1));
-  app.Stop (Seconds (10.0));
-
-  app = sink.Install (terminals.Get (0));
-  app.Start (Seconds (0.0));
-
-  NS_LOG_INFO ("Configure Tracing.");
-
-  //
-  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
-  // Trace output will be sent to the file "csma-bridge.tr"
-  //
-  AsciiTraceHelper ascii;
-  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-bridge.tr"));
-
-  //
-  // Also configure some tcpdump traces; each interface will be traced.
-  // The output files will be named:
-  //     csma-bridge-<nodeId>-<interfaceId>.pcap
-  // and can be read by the "tcpdump -r" command (use "-tt" option to
-  // display timestamps correctly)
-  //
-  csma.EnablePcapAll ("csma-bridge", false);
-
-  //
-  // Now, do the actual simulation.
-  //
-  NS_LOG_INFO ("Run Simulation.");
-  Simulator::Run ();
-  Simulator::Destroy ();
-  NS_LOG_INFO ("Done.");
-}
--- a/examples/csma/csma-bridge.py	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-# /*
-#  * 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
-#  */
-
-# Network topology
-#
-#        n0     n1  
-#        |      | 
-#       ----------
-#       | Switch |
-#       ----------
-#        |      | 
-#        n2     n3  
-#
-#
-# - CBR/UDP flows from n0 to n1 and from n3 to n0
-# - DropTail queues 
-# - Tracing of queues and packet receptions to file "csma-bridge.tr"
-
-import ns3
-
-
-def main(argv):
-
-    #
-    # Allow the user to override any of the defaults and the above Bind() at
-    # run-time, via command-line arguments
-    #
-    cmd = ns3.CommandLine()
-    cmd.Parse(argv)
-
-    #
-    # Explicitly create the nodes required by the topology(shown above).
-    #
-    #print "Create nodes."
-    terminals = ns3.NodeContainer()
-    terminals.Create(4)
-
-    csmaSwitch = ns3.NodeContainer()
-    csmaSwitch.Create(1)
-
-    #print "Build Topology"
-    csma = ns3.CsmaHelper()
-    csma.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(5000000)))
-    csma.SetChannelAttribute("Delay", ns3.TimeValue(ns3.MilliSeconds(2)))
-
-    # Create the csma links, from each terminal to the switch
-
-    terminalDevices = ns3.NetDeviceContainer()
-    switchDevices = ns3.NetDeviceContainer()
-
-    for i in range(4):
-        link = csma.Install(ns3.NodeContainer(ns3.NodeContainer(terminals.Get(i)), csmaSwitch))
-        terminalDevices.Add(link.Get(0))
-        switchDevices.Add(link.Get(1))
-
-    # Create the bridge netdevice, which will do the packet switching
-    switchNode = csmaSwitch.Get(0)
-    bridgeDevice = ns3.BridgeNetDevice()
-    switchNode.AddDevice(bridgeDevice)
-
-    for portIter in range(switchDevices.GetN()):
-        bridgeDevice.AddBridgePort(switchDevices.Get(portIter))
-
-    # Add internet stack to the terminals
-    internet = ns3.InternetStackHelper()
-    internet.Install(terminals)
-
-    # We've got the "hardware" in place.  Now we need to add IP addresses.
-    #
-    #print "Assign IP Addresses."
-    ipv4 = ns3.Ipv4AddressHelper()
-    ipv4.SetBase(ns3.Ipv4Address("10.1.1.0"), ns3.Ipv4Mask("255.255.255.0"))
-    ipv4.Assign(terminalDevices)
-
-    #
-    # Create an OnOff application to send UDP datagrams from node zero to node 1.
-    #
-    #print "Create Applications."
-    port = 9   # Discard port(RFC 863)
-
-    onoff = ns3.OnOffHelper("ns3::UdpSocketFactory", 
-                            ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.2"), port)))
-    onoff.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1)))
-    onoff.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0)))
-
-    app = onoff.Install(ns3.NodeContainer(terminals.Get(0)))
-    # Start the application
-    app.Start(ns3.Seconds(1.0))
-    app.Stop(ns3.Seconds(10.0))
-
-    # Create an optional packet sink to receive these packets
-    sink = ns3.PacketSinkHelper("ns3::UdpSocketFactory",
-                                ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port)))
-    app = sink.Install(ns3.NodeContainer(terminals.Get(1)))
-    app.Start(ns3.Seconds(0.0))
-
-    # 
-    # Create a similar flow from n3 to n0, starting at time 1.1 seconds
-    #
-    onoff.SetAttribute("Remote", 
-                       ns3.AddressValue(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.1"), port)))
-    app = onoff.Install(ns3.NodeContainer(terminals.Get(3)))
-    app.Start(ns3.Seconds(1.1))
-    app.Stop(ns3.Seconds(10.0))
-
-    app = sink.Install(ns3.NodeContainer(terminals.Get(0)))
-    app.Start(ns3.Seconds(0.0))
-
-    #
-    # Configure tracing of all enqueue, dequeue, and NetDevice receive events.
-    # Trace output will be sent to the file "csma-bridge.tr"
-    #
-    #print "Configure Tracing."
-    #ascii = ns3.AsciiTraceHelper();
-    #csma.EnableAsciiAll(ascii.CreateFileStream ("csma-bridge.tr"));
-
-    #
-    # Also configure some tcpdump traces; each interface will be traced.
-    # The output files will be named:
-    #     csma-bridge.pcap-<nodeId>-<interfaceId>
-    # and can be read by the "tcpdump -r" command(use "-tt" option to
-    # display timestamps correctly)
-    #
-    csma.EnablePcapAll("csma-bridge", False)
-
-    #
-    # Now, do the actual simulation.
-    #
-    #print "Run Simulation."
-    ns3.Simulator.Run()
-    ns3.Simulator.Destroy()
-    #print "Done."
-
-
-
-if __name__ == '__main__':
-    import sys
-    main(sys.argv)
-
--- a/examples/csma/wscript	Mon Oct 25 14:43:02 2010 +0100
+++ b/examples/csma/wscript	Mon Oct 25 15:00:28 2010 +0100
@@ -4,12 +4,6 @@
     obj = bld.create_ns3_program('csma-one-subnet', ['csma', 'internet-stack'])
     obj.source = 'csma-one-subnet.cc'
 
-    obj = bld.create_ns3_program('csma-bridge', ['bridge', 'csma', 'internet-stack'])
-    obj.source = 'csma-bridge.cc'
-
-    obj = bld.create_ns3_program('csma-bridge-one-hop', ['bridge', 'csma', 'internet-stack'])
-    obj.source = 'csma-bridge-one-hop.cc'
-
     obj = bld.create_ns3_program('csma-broadcast', ['csma', 'internet-stack'])
     obj.source = 'csma-broadcast.cc'
 
--- a/src/devices/bridge/bridge-channel.cc	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/* -*- 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>
- */
-
-#include "ns3/log.h"
-#include "bridge-channel.h"
-
-NS_LOG_COMPONENT_DEFINE ("BridgeChannel");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (BridgeChannel);
-
-TypeId 
-BridgeChannel::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::BridgeChannel")
-    .SetParent<Channel> ()
-    .AddConstructor<BridgeChannel> ()
-    ;
-  return tid;
-}
-
-BridgeChannel::BridgeChannel ()
-  : Channel ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-BridgeChannel::~BridgeChannel ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-
-  for (std::vector< Ptr<Channel> >::iterator iter = m_bridgedChannels.begin ();
-       iter != m_bridgedChannels.end (); iter++)
-    {
-      *iter = 0;
-    }
-  m_bridgedChannels.clear ();
-}
-
-
-void
-BridgeChannel::AddChannel (Ptr<Channel> bridgedChannel)
-{
-  m_bridgedChannels.push_back (bridgedChannel);
-}
-
-uint32_t
-BridgeChannel::GetNDevices (void) const
-{
-  uint32_t ndevices = 0;
-  for (std::vector< Ptr<Channel> >::const_iterator iter = m_bridgedChannels.begin ();
-       iter != m_bridgedChannels.end (); iter++)
-    {
-      ndevices += (*iter)->GetNDevices ();
-    }
-  return ndevices;
-}
-
-
-Ptr<NetDevice>
-BridgeChannel::GetDevice (uint32_t i) const
-{
-  uint32_t ndevices = 0;
-  for (std::vector< Ptr<Channel> >::const_iterator iter = m_bridgedChannels.begin ();
-       iter != m_bridgedChannels.end (); iter++)
-    {
-      if ((i - ndevices) < (*iter)->GetNDevices ())
-        {
-          return (*iter)->GetDevice (i - ndevices);
-        }
-      ndevices += (*iter)->GetNDevices ();
-    }
-  return NULL;
-}
-
-
-} // namespace ns3
--- a/src/devices/bridge/bridge-channel.h	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/* -*- 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>
- */
-#ifndef BRIDGE_CHANNEL_H
-#define BRIDGE_CHANNEL_H
-
-#include "ns3/net-device.h"
-#include "ns3/channel.h"
-#include <vector>
-
-namespace ns3 {
-
-/**
- * \ingroup bridge
- * 
- * \brief Virtual channel implementation for bridges (BridgeNetDevice).
- *
- * Just like BridgeNetDevice aggregates multiple NetDevices,
- * BridgeChannel aggregates multiple channels and make them appear as
- * a single channel to upper layers.
- */
-class BridgeChannel : public Channel
-{
-public:
-  static TypeId GetTypeId (void);
-  BridgeChannel ();
-  virtual ~BridgeChannel ();
-
-  void AddChannel (Ptr<Channel> bridgedChannel);
-
-  // virtual methods implementation, from Channel
-  virtual uint32_t GetNDevices (void) const;
-  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
-
-private:
-  std::vector< Ptr<Channel> > m_bridgedChannels;
-
-};
-
-} // namespace ns3
-
-#endif /* BRIDGE_CHANNEL_H */
--- a/src/devices/bridge/bridge-net-device.cc	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,463 +0,0 @@
-/* -*- 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>
- */
-#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 ("BridgeNetDevice");
-
-namespace ns3 {
-
-NS_OBJECT_ENSURE_REGISTERED (BridgeNetDevice);
-
-
-TypeId
-BridgeNetDevice::GetTypeId (void)
-{
-  static TypeId tid = TypeId ("ns3::BridgeNetDevice")
-    .SetParent<NetDevice> ()
-    .AddConstructor<BridgeNetDevice> ()
-    .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
-                   UintegerValue (1500),
-                   MakeUintegerAccessor (&BridgeNetDevice::SetMtu,
-                                         &BridgeNetDevice::GetMtu),
-                   MakeUintegerChecker<uint16_t> ())                   
-    .AddAttribute ("EnableLearning",
-                   "Enable the learning mode of the Learning Bridge",
-                   BooleanValue (true),
-                   MakeBooleanAccessor (&BridgeNetDevice::m_enableLearning),
-                   MakeBooleanChecker ())
-    .AddAttribute ("ExpirationTime",
-                   "Time it takes for learned MAC state entry to expire.",
-                   TimeValue (Seconds (30)),
-                   MakeTimeAccessor (&BridgeNetDevice::m_expirationTime),
-                   MakeTimeChecker ())
-    ;
-  return tid;
-}
-
-
-BridgeNetDevice::BridgeNetDevice ()
-  : m_node (0),
-    m_ifIndex (0)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_channel = CreateObject<BridgeChannel> ();
-}
-
-BridgeNetDevice::~BridgeNetDevice()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-}
-
-  void 
-BridgeNetDevice::DoDispose ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
-    {
-      *iter = 0;
-    }
-  m_ports.clear ();
-  m_channel = 0;
-  m_node = 0;
-  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 ());
-
-  Mac48Address src48 = Mac48Address::ConvertFrom (src);
-  Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
-
-  if (!m_promiscRxCallback.IsNull ())
-    {
-      m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
-    }
-
-  switch (packetType)
-    {
-    case PACKET_HOST:
-      if (dst48 == m_address)
-        {
-          m_rxCallback (this, packet, protocol, src);
-        }
-      break;
-
-    case PACKET_BROADCAST:
-    case PACKET_MULTICAST:
-      m_rxCallback (this, packet, protocol, src);
-      ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
-      break;
-
-    case PACKET_OTHERHOST:
-      if (dst48 == m_address)
-        {
-          m_rxCallback (this, packet, protocol, src);
-        }
-      else
-        {
-          ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
-        }
-      break;
-    }
-}
-
-void
-BridgeNetDevice::ForwardUnicast (Ptr<NetDevice> 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);
-  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);
-    }
-  else
-    {
-      NS_LOG_LOGIC ("No learned state: send through all ports");
-      for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
-           iter != m_ports.end (); iter++)
-        {
-          Ptr<NetDevice> 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);
-            }
-        }
-    }
-}
-
-void
-BridgeNetDevice::ForwardBroadcast (Ptr<NetDevice> 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 ();
-         iter != m_ports.end (); iter++)
-    {
-      Ptr<NetDevice> 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);
-        }
-    }
-}
-
-void BridgeNetDevice::Learn (Mac48Address source, Ptr<NetDevice> port)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_enableLearning)
-    {
-      LearnedState &state = m_learnState[source];
-      state.associatedPort = port;
-      state.expirationTime = Simulator::Now () + m_expirationTime;
-    }
-}
-
-Ptr<NetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  if (m_enableLearning)
-    {
-      Time now = Simulator::Now ();
-      std::map<Mac48Address, LearnedState>::iterator iter =
-        m_learnState.find (source);
-      if (iter != m_learnState.end ())
-        {
-          LearnedState &state = iter->second;
-          if (state.expirationTime > now)
-            {
-              return state.associatedPort;
-            }
-          else
-            {
-              m_learnState.erase (iter);
-            }
-        }
-    }
-  return NULL;
-}
-
-uint32_t
-BridgeNetDevice::GetNBridgePorts (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_ports.size ();
-}
-
-
-Ptr<NetDevice>
-BridgeNetDevice::GetBridgePort (uint32_t n) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_ports[n];
-}
-
-void 
-BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
-{
-  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.");
-    }
-  if (m_address == Mac48Address ())
-    {
-      m_address = Mac48Address::ConvertFrom (bridgePort->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 ());
-}
-
-void 
-BridgeNetDevice::SetIfIndex(const uint32_t index)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_ifIndex = index;
-}
-
-uint32_t 
-BridgeNetDevice::GetIfIndex(void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_ifIndex;
-}
-
-Ptr<Channel> 
-BridgeNetDevice::GetChannel (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_channel;
-}
-
-void
-BridgeNetDevice::SetAddress (Address address)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_address = Mac48Address::ConvertFrom (address);
-}
-
-Address 
-BridgeNetDevice::GetAddress (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_address;
-}
-
-bool 
-BridgeNetDevice::SetMtu (const uint16_t mtu)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_mtu = mtu;
-  return true;
-}
-
-uint16_t 
-BridgeNetDevice::GetMtu (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_mtu;
-}
-
-
-bool 
-BridgeNetDevice::IsLinkUp (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return true;
-}
-
-
-void 
-BridgeNetDevice::AddLinkChangeCallback (Callback<void> callback)
-{}
-
-
-bool 
-BridgeNetDevice::IsBroadcast (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return true;
-}
-
-
-Address
-BridgeNetDevice::GetBroadcast (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return Mac48Address ("ff:ff:ff:ff:ff:ff");
-}
-
-bool
-BridgeNetDevice::IsMulticast (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return true;
-}
-
-Address
-BridgeNetDevice::GetMulticast (Ipv4Address multicastGroup) const
-{
- NS_LOG_FUNCTION (this << multicastGroup);
- Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
- return multicast;
-}
-
-
-bool 
-BridgeNetDevice::IsPointToPoint (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return false;
-}
-
-bool 
-BridgeNetDevice::IsBridge (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return true;
-}
-
-
-bool 
-BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return SendFrom (packet, m_address, dest, protocolNumber);
-}
-
-bool 
-BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Mac48Address dst = Mac48Address::ConvertFrom (dest); 
-
-  // try to use the learned state if data is unicast
-  if (!dst.IsGroup ())
-    {
-      Ptr<NetDevice> outPort = GetLearnedState (dst);
-      if (outPort != NULL) 
-        {
-          outPort->SendFrom (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 ();
-       iter != m_ports.end (); iter++)
-    {
-      Ptr<NetDevice> port = *iter;
-      port->SendFrom (packet, src, dest, protocolNumber);
-    }
-
-  return true;
-}
-
-
-Ptr<Node> 
-BridgeNetDevice::GetNode (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return m_node;
-}
-
-
-void 
-BridgeNetDevice::SetNode (Ptr<Node> node)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_node = node;
-}
-
-
-bool 
-BridgeNetDevice::NeedsArp (void) const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return true;
-}
-
-
-void 
-BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_rxCallback = cb;
-}
-
-void 
-BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_promiscRxCallback = cb;
-}
-
-bool
-BridgeNetDevice::SupportsSendFrom () const
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  return true;
-}
-
-Address BridgeNetDevice::GetMulticast (Ipv6Address addr) const
-{
-  NS_LOG_FUNCTION (this << addr);
-  return Mac48Address::GetMulticast (addr);
-}
-
-} // namespace ns3
--- a/src/devices/bridge/bridge-net-device.h	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/* -*- 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>
- */
-#ifndef BRIDGE_NET_DEVICE_H
-#define BRIDGE_NET_DEVICE_H
-
-#include "ns3/net-device.h"
-#include "ns3/mac48-address.h"
-#include "ns3/nstime.h"
-#include "ns3/bridge-channel.h"
-#include <stdint.h>
-#include <string>
-#include <map>
-
-namespace ns3 {
-
-class Node;
-
-/**
- * \ingroup devices
- * \defgroup bridge Bridge
- * 
- * \brief a virtual net device that bridges multiple LAN segments
- *
- * The BridgeNetDevice object is a "virtual" netdevice that aggregates
- * multiple "real" netdevices and implements the data plane forwarding
- * part of IEEE 802.1D.  By adding a BridgeNetDevice to a Node, it
- * will act as a "bridge", or "switch", to multiple LAN segments.
- * 
- * By default the bridge netdevice implements a "learning bridge"
- * algorithm (see 802.1D), where incoming unicast frames from one port
- * may occasionally be forwarded throughout all other ports, but
- * usually they are forwarded only to a single correct output port.
- *
- * \attention The Spanning Tree Protocol part of 802.1D is not
- * implemented.  Therefore, you have to be careful not to create
- * bridging loops, or else the network will collapse.
- *
- * \attention Bridging is designed to work only with NetDevices
- * modelling IEEE 802-style technologies, such as CsmaNetDevice and
- * WifiNetDevice.
- *
- * \attention If including a WifiNetDevice in a bridge, the wifi
- * device must be in Access Point mode.  Adhoc mode is not supported
- * with bridging.
- */
-
-/**
- * \ingroup bridge
- * \brief a virtual net device that bridges multiple LAN segments
- */
-class BridgeNetDevice : public NetDevice
-{
-public:
-  static TypeId GetTypeId (void);
-  BridgeNetDevice ();
-  virtual ~BridgeNetDevice ();
-
-  /** 
-   * \brief Add a 'port' to a bridge device
-   *
-   * This method adds a new bridge port to a BridgeNetDevice, so that
-   * the new bridge port NetDevice becomes part of the bridge and L2
-   * frames start being forwarded to/from this NetDevice.
-   *
-   * \param bridgePort NetDevice
-   * \attention The netdevice that is being added as bridge port must
-   * _not_ have an IP address.  In order to add IP connectivity to a
-   * bridging node you must enable IP on the BridgeNetDevice itself,
-   * never on its port netdevices.
-   */
-  void AddBridgePort (Ptr<NetDevice> bridgePort);
-
-  uint32_t GetNBridgePorts (void) const;
-
-  Ptr<NetDevice> GetBridgePort (uint32_t n) const;
-
-  // 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;
-  virtual bool IsLinkUp (void) const;
-  virtual void AddLinkChangeCallback (Callback<void> callback);
-  virtual bool IsBroadcast (void) const;
-  virtual Address GetBroadcast (void) const;
-  virtual bool IsMulticast (void) const;
-  virtual Address GetMulticast (Ipv4Address multicastGroup) const;
-  virtual bool IsPointToPoint (void) const;
-  virtual bool IsBridge (void) const;
-  virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
-  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
-  virtual Ptr<Node> GetNode (void) const;
-  virtual void SetNode (Ptr<Node> node);
-  virtual bool NeedsArp (void) const;
-  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
-  virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
-  virtual bool SupportsSendFrom () const;
-  virtual Address GetMulticast (Ipv6Address addr) const;
-
-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);
-
-private:
-  NetDevice::ReceiveCallback m_rxCallback;
-  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
-
-  Mac48Address m_address;
-  Time m_expirationTime; // time it takes for learned MAC state to expire
-  struct LearnedState
-  {
-    Ptr<NetDevice> associatedPort;
-    Time expirationTime;
-  };
-  std::map<Mac48Address, LearnedState> m_learnState;
-  Ptr<Node> m_node;
-  Ptr<BridgeChannel> m_channel;
-  std::vector< Ptr<NetDevice> > m_ports;
-  uint32_t m_ifIndex;
-  uint16_t m_mtu;
-  bool m_enableLearning;
-};
-
-} // namespace ns3
-
-#endif /* BRIDGE_NET_DEVICE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/examples/csma-bridge-one-hop.cc	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,237 @@
+/* -*- 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
+ */
+
+// Network topology
+//
+//         bridge1         The node named bridge1 (node 5 in the nodelist)
+//   ------------------        has three CMSA net devices that are bridged
+//   CSMA   CSMA   CSMA        together using a BridgeNetDevice.
+//     |      |      |
+//     |      |      |     The bridge node talks over three CSMA channels
+//     |      |      |
+//   CSMA   CSMA   CSMA    to three other CSMA net devices
+//   ----   ----   ----    
+//    n0     n1     n2     Node two acts as a router and talks to another
+//                 ----        bridge that connects the remaining nodes.
+//                 CSMA
+//                   |
+//    n3     n4      |
+//   ----   ----     |
+//   CSMA   CSMA     |
+//     |      |      |
+//     |      |      |
+//     |      |      |
+//   CSMA   CSMA   CSMA    The node named bridge2 (node 6 in the nodelist)
+//   ------------------        has three CMSA net devices that are bridged
+//        bridge2              together using a BridgeNetDevice.
+//
+// Or, more abstractly, recognizing that bridge 1 and bridge 2 are nodes 
+// with three net devices:
+//
+//        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
+//       -----------               (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
+// 
+// It is meant to mirror somewhat the csma-bridge example but adds another
+// bridged link separated by a router.
+// 
+// - 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"
+
+#include <iostream>
+#include <fstream>
+
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/core-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/bridge-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("CsmaBridgeOneHopExample");
+
+int 
+main (int argc, char *argv[])
+{
+  //
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+  //
+#if 0 
+  LogComponentEnable ("CsmaBridgeOneHopExample", LOG_LEVEL_INFO);
+#endif
+
+  //
+  // Allow the user to override any of the defaults and the above Bind() at
+  // run-time, via command-line arguments
+  //
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  //
+  // Explicitly create the nodes required by the topology (shown above).
+  //
+  NS_LOG_INFO ("Create nodes.");
+
+  Ptr<Node> n0 = CreateObject<Node> ();
+  Ptr<Node> n1 = CreateObject<Node> ();
+  Ptr<Node> n2 = CreateObject<Node> ();
+  Ptr<Node> n3 = CreateObject<Node> ();
+  Ptr<Node> n4 = CreateObject<Node> ();
+
+  Ptr<Node> bridge1 = CreateObject<Node> ();
+  Ptr<Node> bridge2 = CreateObject<Node> ();
+
+  NS_LOG_INFO ("Build Topology");
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+
+  // Create the csma links, from each terminal to the bridge
+  // This will create six network devices; we'll keep track separately
+  // of the devices on and off the bridge respectively, for later configuration 
+  NetDeviceContainer topLanDevices;
+  NetDeviceContainer topBridgeDevices;
+
+  // It is easier to iterate the nodes in C++ if we put them into a container
+  NodeContainer topLan (n2, n0, n1);
+
+  for (int i = 0; i < 3; i++)
+    {
+      // install a csma channel between the ith toplan node and the bridge node
+      NetDeviceContainer link = csma.Install (NodeContainer (topLan.Get (i), bridge1));
+      topLanDevices.Add (link.Get (0));
+      topBridgeDevices.Add (link.Get (1));
+    }
+
+  //
+  // Now, Create the bridge netdevice, which will do the packet switching.  The
+  // bridge lives on the node bridge1 and bridges together the topBridgeDevices
+  // which are the three CSMA net devices on the node in the diagram above.
+  //
+  BridgeHelper bridge;
+  bridge.Install (bridge1, topBridgeDevices);
+
+  // Add internet stack to the router nodes
+  NodeContainer routerNodes (n0, n1, n2, n3, n4);
+  InternetStackHelper internet;
+  internet.Install (routerNodes);
+
+  // Repeat for bottom bridged LAN
+  NetDeviceContainer bottomLanDevices;
+  NetDeviceContainer bottomBridgeDevices;
+  NodeContainer bottomLan (n2, n3, n4);
+  for (int i = 0; i < 3; i++)
+    {
+      NetDeviceContainer link = csma.Install (NodeContainer (bottomLan.Get (i), bridge2));
+      bottomLanDevices.Add (link.Get (0));
+      bottomBridgeDevices.Add (link.Get (1));
+    }
+  bridge.Install (bridge2, bottomBridgeDevices);
+
+  // We've got the "hardware" in place.  Now we need to add IP addresses.
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  ipv4.Assign (topLanDevices);
+  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
+  ipv4.Assign (bottomLanDevices);
+
+  // 
+  // Create router nodes, initialize routing database and set up the routing
+  // tables in the nodes.  We excuse the bridge nodes from having to serve as
+  // routers, since they don't even have internet stacks on them.
+  //
+  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+  //
+  // Create an OnOff application to send UDP datagrams from node zero to node 1.
+  //
+  NS_LOG_INFO ("Create Applications.");
+  uint16_t port = 9;   // Discard port (RFC 863)
+
+  OnOffHelper onoff ("ns3::UdpSocketFactory", 
+                     Address (InetSocketAddress (Ipv4Address ("10.1.1.3"), port)));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+
+  ApplicationContainer app = onoff.Install (n0);
+  // Start the application
+  app.Start (Seconds (1.0));
+  app.Stop (Seconds (10.0));
+
+  // Create an optional packet sink to receive these packets
+  PacketSinkHelper sink ("ns3::UdpSocketFactory",
+                         Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  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
+  //
+  onoff.SetAttribute ("Remote", 
+                      AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
+  ApplicationContainer app2 = onoff.Install (n3);
+  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));
+
+  NS_LOG_INFO ("Configure Tracing.");
+
+  //
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
+  // Trace output will be sent to the file "csma-bridge-one-hop.tr"
+  //
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-bridge-one-hop.tr"));
+
+  //
+  // Also configure some tcpdump traces; each interface will be traced.
+  // The output files will be named:
+  //     csma-bridge-one-hop-<nodeId>-<interfaceId>.pcap
+  // and can be read by the "tcpdump -r" command (use "-tt" option to
+  // display timestamps correctly)
+  //
+  csma.EnablePcapAll ("csma-bridge-one-hop", false);
+
+  //
+  // Now, do the actual simulation.
+  //
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/examples/csma-bridge.cc	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,165 @@
+/* -*- 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
+ */
+
+// Network topology
+//
+//        n0     n1  
+//        |      | 
+//       ----------
+//       | Switch |
+//       ----------
+//        |      | 
+//        n2     n3  
+//
+//
+// - CBR/UDP flows from n0 to n1 and from n3 to n0
+// - DropTail queues 
+// - Tracing of queues and packet receptions to file "csma-bridge.tr"
+
+#include <iostream>
+#include <fstream>
+
+#include "ns3/simulator-module.h"
+#include "ns3/node-module.h"
+#include "ns3/core-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/bridge-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("CsmaBridgeExample");
+
+int 
+main (int argc, char *argv[])
+{
+  //
+  // Users may find it convenient to turn on explicit debugging
+  // for selected modules; the below lines suggest how to do this
+  //
+#if 0 
+  LogComponentEnable ("CsmaBridgeExample", LOG_LEVEL_INFO);
+#endif
+
+  //
+  // Allow the user to override any of the defaults and the above Bind() at
+  // run-time, via command-line arguments
+  //
+  CommandLine cmd;
+  cmd.Parse (argc, argv);
+
+  //
+  // Explicitly create the nodes required by the topology (shown above).
+  //
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer terminals;
+  terminals.Create (4);
+
+  NodeContainer csmaSwitch;
+  csmaSwitch.Create (1);
+
+  NS_LOG_INFO ("Build Topology");
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+
+  // Create the csma links, from each terminal to the switch
+
+  NetDeviceContainer terminalDevices;
+  NetDeviceContainer switchDevices;
+
+  for (int i = 0; i < 4; i++)
+    {
+      NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i), csmaSwitch));
+      terminalDevices.Add (link.Get (0));
+      switchDevices.Add (link.Get (1));
+    }
+
+  // Create the bridge netdevice, which will do the packet switching
+  Ptr<Node> switchNode = csmaSwitch.Get (0);
+  BridgeHelper bridge;
+  bridge.Install (switchNode, switchDevices);
+
+  // Add internet stack to the terminals
+  InternetStackHelper internet;
+  internet.Install (terminals);
+
+  // We've got the "hardware" in place.  Now we need to add IP addresses.
+  //
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  ipv4.Assign (terminalDevices);
+
+  //
+  // Create an OnOff application to send UDP datagrams from node zero to node 1.
+  //
+  NS_LOG_INFO ("Create Applications.");
+  uint16_t port = 9;   // Discard port (RFC 863)
+
+  OnOffHelper onoff ("ns3::UdpSocketFactory", 
+                     Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)));
+  onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
+  onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
+
+  ApplicationContainer app = onoff.Install (terminals.Get (0));
+  // Start the application
+  app.Start (Seconds (1.0));
+  app.Stop (Seconds (10.0));
+
+  // Create an optional packet sink to receive these packets
+  PacketSinkHelper sink ("ns3::UdpSocketFactory",
+                         Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
+  app = sink.Install (terminals.Get (1));
+  app.Start (Seconds (0.0));
+
+  // 
+  // Create a similar flow from n3 to n0, starting at time 1.1 seconds
+  //
+  onoff.SetAttribute ("Remote", 
+                      AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"), port)));
+  app = onoff.Install (terminals.Get (3));
+  app.Start (Seconds (1.1));
+  app.Stop (Seconds (10.0));
+
+  app = sink.Install (terminals.Get (0));
+  app.Start (Seconds (0.0));
+
+  NS_LOG_INFO ("Configure Tracing.");
+
+  //
+  // Configure tracing of all enqueue, dequeue, and NetDevice receive events.
+  // Trace output will be sent to the file "csma-bridge.tr"
+  //
+  AsciiTraceHelper ascii;
+  csma.EnableAsciiAll (ascii.CreateFileStream ("csma-bridge.tr"));
+
+  //
+  // Also configure some tcpdump traces; each interface will be traced.
+  // The output files will be named:
+  //     csma-bridge-<nodeId>-<interfaceId>.pcap
+  // and can be read by the "tcpdump -r" command (use "-tt" option to
+  // display timestamps correctly)
+  //
+  csma.EnablePcapAll ("csma-bridge", false);
+
+  //
+  // Now, do the actual simulation.
+  //
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/examples/csma-bridge.py	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,151 @@
+# /*
+#  * 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
+#  */
+
+# Network topology
+#
+#        n0     n1  
+#        |      | 
+#       ----------
+#       | Switch |
+#       ----------
+#        |      | 
+#        n2     n3  
+#
+#
+# - CBR/UDP flows from n0 to n1 and from n3 to n0
+# - DropTail queues 
+# - Tracing of queues and packet receptions to file "csma-bridge.tr"
+
+import ns3
+
+
+def main(argv):
+
+    #
+    # Allow the user to override any of the defaults and the above Bind() at
+    # run-time, via command-line arguments
+    #
+    cmd = ns3.CommandLine()
+    cmd.Parse(argv)
+
+    #
+    # Explicitly create the nodes required by the topology(shown above).
+    #
+    #print "Create nodes."
+    terminals = ns3.NodeContainer()
+    terminals.Create(4)
+
+    csmaSwitch = ns3.NodeContainer()
+    csmaSwitch.Create(1)
+
+    #print "Build Topology"
+    csma = ns3.CsmaHelper()
+    csma.SetChannelAttribute("DataRate", ns3.DataRateValue(ns3.DataRate(5000000)))
+    csma.SetChannelAttribute("Delay", ns3.TimeValue(ns3.MilliSeconds(2)))
+
+    # Create the csma links, from each terminal to the switch
+
+    terminalDevices = ns3.NetDeviceContainer()
+    switchDevices = ns3.NetDeviceContainer()
+
+    for i in range(4):
+        link = csma.Install(ns3.NodeContainer(ns3.NodeContainer(terminals.Get(i)), csmaSwitch))
+        terminalDevices.Add(link.Get(0))
+        switchDevices.Add(link.Get(1))
+
+    # Create the bridge netdevice, which will do the packet switching
+    switchNode = csmaSwitch.Get(0)
+    bridgeDevice = ns3.BridgeNetDevice()
+    switchNode.AddDevice(bridgeDevice)
+
+    for portIter in range(switchDevices.GetN()):
+        bridgeDevice.AddBridgePort(switchDevices.Get(portIter))
+
+    # Add internet stack to the terminals
+    internet = ns3.InternetStackHelper()
+    internet.Install(terminals)
+
+    # We've got the "hardware" in place.  Now we need to add IP addresses.
+    #
+    #print "Assign IP Addresses."
+    ipv4 = ns3.Ipv4AddressHelper()
+    ipv4.SetBase(ns3.Ipv4Address("10.1.1.0"), ns3.Ipv4Mask("255.255.255.0"))
+    ipv4.Assign(terminalDevices)
+
+    #
+    # Create an OnOff application to send UDP datagrams from node zero to node 1.
+    #
+    #print "Create Applications."
+    port = 9   # Discard port(RFC 863)
+
+    onoff = ns3.OnOffHelper("ns3::UdpSocketFactory", 
+                            ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.2"), port)))
+    onoff.SetAttribute("OnTime", ns3.RandomVariableValue(ns3.ConstantVariable(1)))
+    onoff.SetAttribute("OffTime", ns3.RandomVariableValue(ns3.ConstantVariable(0)))
+
+    app = onoff.Install(ns3.NodeContainer(terminals.Get(0)))
+    # Start the application
+    app.Start(ns3.Seconds(1.0))
+    app.Stop(ns3.Seconds(10.0))
+
+    # Create an optional packet sink to receive these packets
+    sink = ns3.PacketSinkHelper("ns3::UdpSocketFactory",
+                                ns3.Address(ns3.InetSocketAddress(ns3.Ipv4Address.GetAny(), port)))
+    app = sink.Install(ns3.NodeContainer(terminals.Get(1)))
+    app.Start(ns3.Seconds(0.0))
+
+    # 
+    # Create a similar flow from n3 to n0, starting at time 1.1 seconds
+    #
+    onoff.SetAttribute("Remote", 
+                       ns3.AddressValue(ns3.InetSocketAddress(ns3.Ipv4Address("10.1.1.1"), port)))
+    app = onoff.Install(ns3.NodeContainer(terminals.Get(3)))
+    app.Start(ns3.Seconds(1.1))
+    app.Stop(ns3.Seconds(10.0))
+
+    app = sink.Install(ns3.NodeContainer(terminals.Get(0)))
+    app.Start(ns3.Seconds(0.0))
+
+    #
+    # Configure tracing of all enqueue, dequeue, and NetDevice receive events.
+    # Trace output will be sent to the file "csma-bridge.tr"
+    #
+    #print "Configure Tracing."
+    #ascii = ns3.AsciiTraceHelper();
+    #csma.EnableAsciiAll(ascii.CreateFileStream ("csma-bridge.tr"));
+
+    #
+    # Also configure some tcpdump traces; each interface will be traced.
+    # The output files will be named:
+    #     csma-bridge.pcap-<nodeId>-<interfaceId>
+    # and can be read by the "tcpdump -r" command(use "-tt" option to
+    # display timestamps correctly)
+    #
+    csma.EnablePcapAll("csma-bridge", False)
+
+    #
+    # Now, do the actual simulation.
+    #
+    #print "Run Simulation."
+    ns3.Simulator.Run()
+    ns3.Simulator.Destroy()
+    #print "Done."
+
+
+
+if __name__ == '__main__':
+    import sys
+    main(sys.argv)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/examples/wscript	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,10 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+
+    obj = bld.create_ns3_program('csma-bridge', ['bridge', 'csma', 'internet-stack'])
+    obj.source = 'csma-bridge.cc'
+
+    obj = bld.create_ns3_program('csma-bridge-one-hop', ['bridge', 'csma', 'internet-stack'])
+    obj.source = 'csma-bridge-one-hop.cc'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/helper/bridge-helper.cc	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,69 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c)
+ *
+ * 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
+ */
+
+#include "bridge-helper.h"
+#include "ns3/log.h"
+#include "ns3/bridge-net-device.h"
+#include "ns3/node.h"
+#include "ns3/names.h"
+
+NS_LOG_COMPONENT_DEFINE ("BridgeHelper");
+
+namespace ns3 {
+
+BridgeHelper::BridgeHelper ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_deviceFactory.SetTypeId ("ns3::BridgeNetDevice");
+}
+
+void 
+BridgeHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_deviceFactory.Set (n1, v1);
+}
+
+NetDeviceContainer
+BridgeHelper::Install (Ptr<Node> node, NetDeviceContainer c)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("**** Install bridge device on node " << node->GetId ());
+
+  NetDeviceContainer devs;
+  Ptr<BridgeNetDevice> dev = m_deviceFactory.Create<BridgeNetDevice> ();
+  devs.Add (dev);
+  node->AddDevice (dev);
+
+  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      NS_LOG_LOGIC ("**** Add BridgePort "<< *i);
+      dev->AddBridgePort (*i);
+    }
+  return devs;
+}
+
+NetDeviceContainer
+BridgeHelper::Install (std::string nodeName, NetDeviceContainer c)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  return Install (node, c);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/helper/bridge-helper.h	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,80 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ * Author: Gustavo Carneiro <gjc@inescporto.pt>
+ */
+#ifndef BRIDGE_HELPER_H
+#define BRIDGE_HELPER_H
+
+#include "ns3/net-device-container.h"
+#include "ns3/object-factory.h"
+#include <string>
+
+namespace ns3 {
+
+class Node;
+class AttributeValue;
+
+/**
+ * \brief Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
+ */
+class BridgeHelper
+{
+public:
+  /*
+   * Construct a BridgeHelper
+   */
+  BridgeHelper ();
+  /**
+   * Set an attribute on each ns3::BridgeNetDevice created by
+   * BridgeHelper::Install
+   *
+   * \param n1 the name of the attribute to set
+   * \param v1 the value of the attribute to set
+   */
+  void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
+  /**
+   * This method creates an ns3::BridgeNetDevice with the attributes
+   * configured by BridgeHelper::SetDeviceAttribute, adds the device
+   * to the node, and attaches the given NetDevices as ports of the
+   * bridge.
+   *
+   * \param node The node to install the device in
+   * \param c Container of NetDevices to add as bridge ports
+   * \returns A container holding the added net device.
+   */
+  NetDeviceContainer Install (Ptr<Node> node, NetDeviceContainer c);
+  /**
+   * This method creates an ns3::BridgeNetDevice with the attributes
+   * configured by BridgeHelper::SetDeviceAttribute, adds the device
+   * to the node, and attaches the given NetDevices as ports of the
+   * bridge.
+   *
+   * \param nodeName The name of the node to install the device in
+   * \param c Container of NetDevices to add as bridge ports
+   * \returns A container holding the added net device.
+   */
+  NetDeviceContainer Install (std::string nodeName, NetDeviceContainer c);
+private:
+  ObjectFactory m_deviceFactory;
+};
+
+} // namespace ns3
+
+
+#endif /* BRIDGE_HELPER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/model/bridge-channel.cc	Mon Oct 25 15:00:28 2010 +0100
@@ -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: Gustavo Carneiro  <gjc@inescporto.pt>
+ */
+
+#include "ns3/log.h"
+#include "bridge-channel.h"
+
+NS_LOG_COMPONENT_DEFINE ("BridgeChannel");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (BridgeChannel);
+
+TypeId 
+BridgeChannel::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::BridgeChannel")
+    .SetParent<Channel> ()
+    .AddConstructor<BridgeChannel> ()
+    ;
+  return tid;
+}
+
+BridgeChannel::BridgeChannel ()
+  : Channel ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+BridgeChannel::~BridgeChannel ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  for (std::vector< Ptr<Channel> >::iterator iter = m_bridgedChannels.begin ();
+       iter != m_bridgedChannels.end (); iter++)
+    {
+      *iter = 0;
+    }
+  m_bridgedChannels.clear ();
+}
+
+
+void
+BridgeChannel::AddChannel (Ptr<Channel> bridgedChannel)
+{
+  m_bridgedChannels.push_back (bridgedChannel);
+}
+
+uint32_t
+BridgeChannel::GetNDevices (void) const
+{
+  uint32_t ndevices = 0;
+  for (std::vector< Ptr<Channel> >::const_iterator iter = m_bridgedChannels.begin ();
+       iter != m_bridgedChannels.end (); iter++)
+    {
+      ndevices += (*iter)->GetNDevices ();
+    }
+  return ndevices;
+}
+
+
+Ptr<NetDevice>
+BridgeChannel::GetDevice (uint32_t i) const
+{
+  uint32_t ndevices = 0;
+  for (std::vector< Ptr<Channel> >::const_iterator iter = m_bridgedChannels.begin ();
+       iter != m_bridgedChannels.end (); iter++)
+    {
+      if ((i - ndevices) < (*iter)->GetNDevices ())
+        {
+          return (*iter)->GetDevice (i - ndevices);
+        }
+      ndevices += (*iter)->GetNDevices ();
+    }
+  return NULL;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/model/bridge-channel.h	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,56 @@
+/* -*- 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>
+ */
+#ifndef BRIDGE_CHANNEL_H
+#define BRIDGE_CHANNEL_H
+
+#include "ns3/net-device.h"
+#include "ns3/channel.h"
+#include <vector>
+
+namespace ns3 {
+
+/**
+ * \ingroup bridge
+ * 
+ * \brief Virtual channel implementation for bridges (BridgeNetDevice).
+ *
+ * Just like BridgeNetDevice aggregates multiple NetDevices,
+ * BridgeChannel aggregates multiple channels and make them appear as
+ * a single channel to upper layers.
+ */
+class BridgeChannel : public Channel
+{
+public:
+  static TypeId GetTypeId (void);
+  BridgeChannel ();
+  virtual ~BridgeChannel ();
+
+  void AddChannel (Ptr<Channel> bridgedChannel);
+
+  // virtual methods implementation, from Channel
+  virtual uint32_t GetNDevices (void) const;
+  virtual Ptr<NetDevice> GetDevice (uint32_t i) const;
+
+private:
+  std::vector< Ptr<Channel> > m_bridgedChannels;
+
+};
+
+} // namespace ns3
+
+#endif /* BRIDGE_CHANNEL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/model/bridge-net-device.cc	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,463 @@
+/* -*- 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>
+ */
+#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 ("BridgeNetDevice");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (BridgeNetDevice);
+
+
+TypeId
+BridgeNetDevice::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::BridgeNetDevice")
+    .SetParent<NetDevice> ()
+    .AddConstructor<BridgeNetDevice> ()
+    .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
+                   UintegerValue (1500),
+                   MakeUintegerAccessor (&BridgeNetDevice::SetMtu,
+                                         &BridgeNetDevice::GetMtu),
+                   MakeUintegerChecker<uint16_t> ())                   
+    .AddAttribute ("EnableLearning",
+                   "Enable the learning mode of the Learning Bridge",
+                   BooleanValue (true),
+                   MakeBooleanAccessor (&BridgeNetDevice::m_enableLearning),
+                   MakeBooleanChecker ())
+    .AddAttribute ("ExpirationTime",
+                   "Time it takes for learned MAC state entry to expire.",
+                   TimeValue (Seconds (30)),
+                   MakeTimeAccessor (&BridgeNetDevice::m_expirationTime),
+                   MakeTimeChecker ())
+    ;
+  return tid;
+}
+
+
+BridgeNetDevice::BridgeNetDevice ()
+  : m_node (0),
+    m_ifIndex (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_channel = CreateObject<BridgeChannel> ();
+}
+
+BridgeNetDevice::~BridgeNetDevice()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+  void 
+BridgeNetDevice::DoDispose ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
+    {
+      *iter = 0;
+    }
+  m_ports.clear ();
+  m_channel = 0;
+  m_node = 0;
+  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 ());
+
+  Mac48Address src48 = Mac48Address::ConvertFrom (src);
+  Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
+
+  if (!m_promiscRxCallback.IsNull ())
+    {
+      m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
+    }
+
+  switch (packetType)
+    {
+    case PACKET_HOST:
+      if (dst48 == m_address)
+        {
+          m_rxCallback (this, packet, protocol, src);
+        }
+      break;
+
+    case PACKET_BROADCAST:
+    case PACKET_MULTICAST:
+      m_rxCallback (this, packet, protocol, src);
+      ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
+      break;
+
+    case PACKET_OTHERHOST:
+      if (dst48 == m_address)
+        {
+          m_rxCallback (this, packet, protocol, src);
+        }
+      else
+        {
+          ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
+        }
+      break;
+    }
+}
+
+void
+BridgeNetDevice::ForwardUnicast (Ptr<NetDevice> 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);
+  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);
+    }
+  else
+    {
+      NS_LOG_LOGIC ("No learned state: send through all ports");
+      for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
+           iter != m_ports.end (); iter++)
+        {
+          Ptr<NetDevice> 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);
+            }
+        }
+    }
+}
+
+void
+BridgeNetDevice::ForwardBroadcast (Ptr<NetDevice> 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 ();
+         iter != m_ports.end (); iter++)
+    {
+      Ptr<NetDevice> 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);
+        }
+    }
+}
+
+void BridgeNetDevice::Learn (Mac48Address source, Ptr<NetDevice> port)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_enableLearning)
+    {
+      LearnedState &state = m_learnState[source];
+      state.associatedPort = port;
+      state.expirationTime = Simulator::Now () + m_expirationTime;
+    }
+}
+
+Ptr<NetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  if (m_enableLearning)
+    {
+      Time now = Simulator::Now ();
+      std::map<Mac48Address, LearnedState>::iterator iter =
+        m_learnState.find (source);
+      if (iter != m_learnState.end ())
+        {
+          LearnedState &state = iter->second;
+          if (state.expirationTime > now)
+            {
+              return state.associatedPort;
+            }
+          else
+            {
+              m_learnState.erase (iter);
+            }
+        }
+    }
+  return NULL;
+}
+
+uint32_t
+BridgeNetDevice::GetNBridgePorts (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_ports.size ();
+}
+
+
+Ptr<NetDevice>
+BridgeNetDevice::GetBridgePort (uint32_t n) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_ports[n];
+}
+
+void 
+BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
+{
+  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.");
+    }
+  if (m_address == Mac48Address ())
+    {
+      m_address = Mac48Address::ConvertFrom (bridgePort->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 ());
+}
+
+void 
+BridgeNetDevice::SetIfIndex(const uint32_t index)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_ifIndex = index;
+}
+
+uint32_t 
+BridgeNetDevice::GetIfIndex(void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_ifIndex;
+}
+
+Ptr<Channel> 
+BridgeNetDevice::GetChannel (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_channel;
+}
+
+void
+BridgeNetDevice::SetAddress (Address address)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_address = Mac48Address::ConvertFrom (address);
+}
+
+Address 
+BridgeNetDevice::GetAddress (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_address;
+}
+
+bool 
+BridgeNetDevice::SetMtu (const uint16_t mtu)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_mtu = mtu;
+  return true;
+}
+
+uint16_t 
+BridgeNetDevice::GetMtu (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_mtu;
+}
+
+
+bool 
+BridgeNetDevice::IsLinkUp (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return true;
+}
+
+
+void 
+BridgeNetDevice::AddLinkChangeCallback (Callback<void> callback)
+{}
+
+
+bool 
+BridgeNetDevice::IsBroadcast (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return true;
+}
+
+
+Address
+BridgeNetDevice::GetBroadcast (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return Mac48Address ("ff:ff:ff:ff:ff:ff");
+}
+
+bool
+BridgeNetDevice::IsMulticast (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return true;
+}
+
+Address
+BridgeNetDevice::GetMulticast (Ipv4Address multicastGroup) const
+{
+ NS_LOG_FUNCTION (this << multicastGroup);
+ Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
+ return multicast;
+}
+
+
+bool 
+BridgeNetDevice::IsPointToPoint (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return false;
+}
+
+bool 
+BridgeNetDevice::IsBridge (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return true;
+}
+
+
+bool 
+BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return SendFrom (packet, m_address, dest, protocolNumber);
+}
+
+bool 
+BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Mac48Address dst = Mac48Address::ConvertFrom (dest); 
+
+  // try to use the learned state if data is unicast
+  if (!dst.IsGroup ())
+    {
+      Ptr<NetDevice> outPort = GetLearnedState (dst);
+      if (outPort != NULL) 
+        {
+          outPort->SendFrom (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 ();
+       iter != m_ports.end (); iter++)
+    {
+      Ptr<NetDevice> port = *iter;
+      port->SendFrom (packet, src, dest, protocolNumber);
+    }
+
+  return true;
+}
+
+
+Ptr<Node> 
+BridgeNetDevice::GetNode (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_node;
+}
+
+
+void 
+BridgeNetDevice::SetNode (Ptr<Node> node)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_node = node;
+}
+
+
+bool 
+BridgeNetDevice::NeedsArp (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return true;
+}
+
+
+void 
+BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_rxCallback = cb;
+}
+
+void 
+BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_promiscRxCallback = cb;
+}
+
+bool
+BridgeNetDevice::SupportsSendFrom () const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return true;
+}
+
+Address BridgeNetDevice::GetMulticast (Ipv6Address addr) const
+{
+  NS_LOG_FUNCTION (this << addr);
+  return Mac48Address::GetMulticast (addr);
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/devices/bridge/model/bridge-net-device.h	Mon Oct 25 15:00:28 2010 +0100
@@ -0,0 +1,152 @@
+/* -*- 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>
+ */
+#ifndef BRIDGE_NET_DEVICE_H
+#define BRIDGE_NET_DEVICE_H
+
+#include "ns3/net-device.h"
+#include "ns3/mac48-address.h"
+#include "ns3/nstime.h"
+#include "ns3/bridge-channel.h"
+#include <stdint.h>
+#include <string>
+#include <map>
+
+namespace ns3 {
+
+class Node;
+
+/**
+ * \ingroup devices
+ * \defgroup bridge Bridge
+ * 
+ * \brief a virtual net device that bridges multiple LAN segments
+ *
+ * The BridgeNetDevice object is a "virtual" netdevice that aggregates
+ * multiple "real" netdevices and implements the data plane forwarding
+ * part of IEEE 802.1D.  By adding a BridgeNetDevice to a Node, it
+ * will act as a "bridge", or "switch", to multiple LAN segments.
+ * 
+ * By default the bridge netdevice implements a "learning bridge"
+ * algorithm (see 802.1D), where incoming unicast frames from one port
+ * may occasionally be forwarded throughout all other ports, but
+ * usually they are forwarded only to a single correct output port.
+ *
+ * \attention The Spanning Tree Protocol part of 802.1D is not
+ * implemented.  Therefore, you have to be careful not to create
+ * bridging loops, or else the network will collapse.
+ *
+ * \attention Bridging is designed to work only with NetDevices
+ * modelling IEEE 802-style technologies, such as CsmaNetDevice and
+ * WifiNetDevice.
+ *
+ * \attention If including a WifiNetDevice in a bridge, the wifi
+ * device must be in Access Point mode.  Adhoc mode is not supported
+ * with bridging.
+ */
+
+/**
+ * \ingroup bridge
+ * \brief a virtual net device that bridges multiple LAN segments
+ */
+class BridgeNetDevice : public NetDevice
+{
+public:
+  static TypeId GetTypeId (void);
+  BridgeNetDevice ();
+  virtual ~BridgeNetDevice ();
+
+  /** 
+   * \brief Add a 'port' to a bridge device
+   *
+   * This method adds a new bridge port to a BridgeNetDevice, so that
+   * the new bridge port NetDevice becomes part of the bridge and L2
+   * frames start being forwarded to/from this NetDevice.
+   *
+   * \param bridgePort NetDevice
+   * \attention The netdevice that is being added as bridge port must
+   * _not_ have an IP address.  In order to add IP connectivity to a
+   * bridging node you must enable IP on the BridgeNetDevice itself,
+   * never on its port netdevices.
+   */
+  void AddBridgePort (Ptr<NetDevice> bridgePort);
+
+  uint32_t GetNBridgePorts (void) const;
+
+  Ptr<NetDevice> GetBridgePort (uint32_t n) const;
+
+  // 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;
+  virtual bool IsLinkUp (void) const;
+  virtual void AddLinkChangeCallback (Callback<void> callback);
+  virtual bool IsBroadcast (void) const;
+  virtual Address GetBroadcast (void) const;
+  virtual bool IsMulticast (void) const;
+  virtual Address GetMulticast (Ipv4Address multicastGroup) const;
+  virtual bool IsPointToPoint (void) const;
+  virtual bool IsBridge (void) const;
+  virtual bool Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber);
+  virtual bool SendFrom (Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
+  virtual Ptr<Node> GetNode (void) const;
+  virtual void SetNode (Ptr<Node> node);
+  virtual bool NeedsArp (void) const;
+  virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
+  virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
+  virtual bool SupportsSendFrom () const;
+  virtual Address GetMulticast (Ipv6Address addr) const;
+
+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);
+
+private:
+  NetDevice::ReceiveCallback m_rxCallback;
+  NetDevice::PromiscReceiveCallback m_promiscRxCallback;
+
+  Mac48Address m_address;
+  Time m_expirationTime; // time it takes for learned MAC state to expire
+  struct LearnedState
+  {
+    Ptr<NetDevice> associatedPort;
+    Time expirationTime;
+  };
+  std::map<Mac48Address, LearnedState> m_learnState;
+  Ptr<Node> m_node;
+  Ptr<BridgeChannel> m_channel;
+  std::vector< Ptr<NetDevice> > m_ports;
+  uint32_t m_ifIndex;
+  uint16_t m_mtu;
+  bool m_enableLearning;
+};
+
+} // namespace ns3
+
+#endif /* BRIDGE_NET_DEVICE_H */
--- a/src/devices/bridge/wscript	Mon Oct 25 14:43:02 2010 +0100
+++ b/src/devices/bridge/wscript	Mon Oct 25 15:00:28 2010 +0100
@@ -3,12 +3,17 @@
 def build(bld):
     obj = bld.create_ns3_module('bridge', ['node'])
     obj.source = [
-        'bridge-net-device.cc',
-        'bridge-channel.cc',
+        'model/bridge-net-device.cc',
+        'model/bridge-channel.cc',
+        'helper/bridge-helper.cc',
         ]
     headers = bld.new_task_gen('ns3header')
     headers.module = 'bridge'
     headers.source = [
-        'bridge-net-device.h',
-        'bridge-channel.h',
+        'model/bridge-net-device.h',
+        'model/bridge-channel.h',
+        'helper/bridge-helper.h',
         ]
+
+    if bld.env['ENABLE_EXAMPLES']:
+        bld.add_subdirs('examples')
--- a/src/helper/bridge-helper.cc	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c)
- *
- * 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
- */
-
-#include "bridge-helper.h"
-#include "ns3/log.h"
-#include "ns3/bridge-net-device.h"
-#include "ns3/node.h"
-#include "ns3/names.h"
-
-NS_LOG_COMPONENT_DEFINE ("BridgeHelper");
-
-namespace ns3 {
-
-BridgeHelper::BridgeHelper ()
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_deviceFactory.SetTypeId ("ns3::BridgeNetDevice");
-}
-
-void 
-BridgeHelper::SetDeviceAttribute (std::string n1, const AttributeValue &v1)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  m_deviceFactory.Set (n1, v1);
-}
-
-NetDeviceContainer
-BridgeHelper::Install (Ptr<Node> node, NetDeviceContainer c)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  NS_LOG_LOGIC ("**** Install bridge device on node " << node->GetId ());
-
-  NetDeviceContainer devs;
-  Ptr<BridgeNetDevice> dev = m_deviceFactory.Create<BridgeNetDevice> ();
-  devs.Add (dev);
-  node->AddDevice (dev);
-
-  for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
-    {
-      NS_LOG_LOGIC ("**** Add BridgePort "<< *i);
-      dev->AddBridgePort (*i);
-    }
-  return devs;
-}
-
-NetDeviceContainer
-BridgeHelper::Install (std::string nodeName, NetDeviceContainer c)
-{
-  NS_LOG_FUNCTION_NOARGS ();
-  Ptr<Node> node = Names::Find<Node> (nodeName);
-  return Install (node, c);
-}
-
-} // namespace ns3
--- a/src/helper/bridge-helper.h	Mon Oct 25 14:43:02 2010 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2008 INRIA
- *
- * 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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
- * Author: Gustavo Carneiro <gjc@inescporto.pt>
- */
-#ifndef BRIDGE_HELPER_H
-#define BRIDGE_HELPER_H
-
-#include "net-device-container.h"
-#include "ns3/object-factory.h"
-#include <string>
-
-namespace ns3 {
-
-class Node;
-class AttributeValue;
-
-/**
- * \brief Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
- */
-class BridgeHelper
-{
-public:
-  /*
-   * Construct a BridgeHelper
-   */
-  BridgeHelper ();
-  /**
-   * Set an attribute on each ns3::BridgeNetDevice created by
-   * BridgeHelper::Install
-   *
-   * \param n1 the name of the attribute to set
-   * \param v1 the value of the attribute to set
-   */
-  void SetDeviceAttribute (std::string n1, const AttributeValue &v1);
-  /**
-   * This method creates an ns3::BridgeNetDevice with the attributes
-   * configured by BridgeHelper::SetDeviceAttribute, adds the device
-   * to the node, and attaches the given NetDevices as ports of the
-   * bridge.
-   *
-   * \param node The node to install the device in
-   * \param c Container of NetDevices to add as bridge ports
-   * \returns A container holding the added net device.
-   */
-  NetDeviceContainer Install (Ptr<Node> node, NetDeviceContainer c);
-  /**
-   * This method creates an ns3::BridgeNetDevice with the attributes
-   * configured by BridgeHelper::SetDeviceAttribute, adds the device
-   * to the node, and attaches the given NetDevices as ports of the
-   * bridge.
-   *
-   * \param nodeName The name of the node to install the device in
-   * \param c Container of NetDevices to add as bridge ports
-   * \returns A container holding the added net device.
-   */
-  NetDeviceContainer Install (std::string nodeName, NetDeviceContainer c);
-private:
-  ObjectFactory m_deviceFactory;
-};
-
-} // namespace ns3
-
-
-#endif /* BRIDGE_HELPER_H */
--- a/src/helper/wscript	Mon Oct 25 14:43:02 2010 +0100
+++ b/src/helper/wscript	Mon Oct 25 15:00:28 2010 +0100
@@ -19,7 +19,6 @@
         'packet-socket-helper.cc',
         'ipv4-interface-container.cc',
         'udp-echo-helper.cc',
-        'bridge-helper.cc',
         'yans-wifi-helper.cc',
         'spectrum-helper.cc',
         'adhoc-aloha-noack-ideal-phy-helper.cc',
@@ -74,7 +73,6 @@
         'packet-socket-helper.h',
         'ipv4-interface-container.h',
         'udp-echo-helper.h',
-        'bridge-helper.h',
         'yans-wifi-helper.h',
         'spectrum-helper.h',
         'adhoc-aloha-noack-ideal-phy-helper.h',
--- a/test.py	Mon Oct 25 14:43:02 2010 +0100
+++ b/test.py	Mon Oct 25 15:00:28 2010 +0100
@@ -189,7 +189,7 @@
 # hardcoded.
 #
 python_tests = [
-    ("examples/csma/csma-bridge.py", "True"),
+    ("src/devices/bridge/examples/csma-bridge.py", "True"),
 
     ("src/contrib/flowmon/examples/wifi-olsr-flowmon.py", "True"),