Add the 'learning' part of the Learning Bridge, with option to disable it and revert to dummy mode (hub-like).
--- a/src/devices/bridge/bridge-net-device.cc Fri Jul 04 18:04:13 2008 +0100
+++ b/src/devices/bridge/bridge-net-device.cc Fri Jul 04 18:48:10 2008 +0100
@@ -20,6 +20,8 @@
#include "ns3/channel.h"
#include "ns3/packet.h"
#include "ns3/log.h"
+#include "ns3/boolean.h"
+#include "ns3/simulator.h"
NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice");
@@ -32,6 +34,16 @@
static TypeId tid = TypeId ("ns3::BridgeNetDevice")
.SetParent<NetDevice> ()
.AddConstructor<BridgeNetDevice> ()
+ .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;
}
@@ -39,9 +51,9 @@
BridgeNetDevice::BridgeNetDevice ()
: m_node (0),
- m_mtu (0xffff),
m_name (""),
- m_ifIndex (0)
+ m_ifIndex (0),
+ m_mtu (0xffff)
{}
void
@@ -102,21 +114,57 @@
// decide whether the packet should be forwarded
if ((dst48 == broadcast) ||
- (mcDest == multicast) ||
- (dst48 != m_address))
+ (mcDest == multicast))
{
- LearningBridgeForward (incomingPort, packet, protocol, src48, dst48);
+ ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
+ }
+ else if (dst48 != m_address)
+ {
+ ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
}
}
void
-BridgeNetDevice::LearningBridgeForward (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
+BridgeNetDevice::ForwardUnicast (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
+ uint16_t protocol, Mac48Address src, Mac48Address dst)
+{
+ NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->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->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->GetName ()
+ << " --> " << port->GetName ()
+ << " (UID " << packet->GetUid () << ").");
+ port->SendFrom (packet->Copy (), src, dst, protocol);
+ }
+ }
+ }
+}
+
+void
+BridgeNetDevice::ForwardBroadcast (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
uint16_t protocol, Mac48Address src, Mac48Address dst)
{
NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName ()
<< ", packet=" << packet << ", protocol="<<protocol
<< ", src=" << src << ", dst=" << dst << ")");
- // TODO: add the "learning" part
+ Learn (src, incomingPort);
for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
iter != m_ports.end (); iter++)
@@ -132,6 +180,37 @@
}
}
+void BridgeNetDevice::Learn (Mac48Address source, Ptr<NetDevice> port)
+{
+ if (m_enableLearning)
+ {
+ LearnedState &state = m_learnState[source];
+ state.associatedPort = port;
+ state.expirationTime = Simulator::Now () + m_expirationTime;
+ }
+}
+
+Ptr<NetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
+{
+ if (m_enableLearning)
+ {
+ std::map<Mac48Address, LearnedState>::iterator iter =
+ m_learnState.find (source);
+ if (iter != m_learnState.end ())
+ {
+ LearnedState &state = iter->second;
+ if (state.expirationTime > Simulator::Now ())
+ {
+ return state.associatedPort;
+ }
+ else
+ {
+ m_learnState.erase (iter);
+ }
+ }
+ }
+ return NULL;
+}
void
BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
--- a/src/devices/bridge/bridge-net-device.h Fri Jul 04 18:04:13 2008 +0100
+++ b/src/devices/bridge/bridge-net-device.h Fri Jul 04 18:48:10 2008 +0100
@@ -20,8 +20,10 @@
#include "ns3/net-device.h"
#include "ns3/mac48-address.h"
+#include "ns3/nstime.h"
#include <stdint.h>
#include <string>
+#include <map>
namespace ns3 {
@@ -70,20 +72,31 @@
void PromiscReceive (Ptr<NetDevice> device, Ptr<Packet> packet, uint16_t protocol,
Address const &source, Address const &destination, bool forMe);
- void LearningBridgeForward (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
- uint16_t protocol, Mac48Address src, Mac48Address dst);
-
+ void ForwardUnicast (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
+ uint16_t protocol, Mac48Address src, Mac48Address dst);
+ void ForwardBroadcast (Ptr<NetDevice> incomingPort, Ptr<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::PromiscuousReceiveCallback 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;
- uint16_t m_mtu;
std::string m_name;
+ std::vector< Ptr<NetDevice> > m_ports;
uint32_t m_ifIndex;
- Mac48Address m_address;
-
- std::vector< Ptr<NetDevice> > m_ports;
+ uint16_t m_mtu;
+ bool m_enableLearning;
};
} // namespace ns3