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