00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "bridge-net-device.h"
00019 #include "ns3/node.h"
00020 #include "ns3/channel.h"
00021 #include "ns3/packet.h"
00022 #include "ns3/log.h"
00023 #include "ns3/boolean.h"
00024 #include "ns3/simulator.h"
00025
00026 NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice");
00027
00028 namespace ns3 {
00029
00030 NS_OBJECT_ENSURE_REGISTERED (BridgeNetDevice);
00031
00032
00033 TypeId
00034 BridgeNetDevice::GetTypeId (void)
00035 {
00036 static TypeId tid = TypeId ("ns3::BridgeNetDevice")
00037 .SetParent<NetDevice> ()
00038 .AddConstructor<BridgeNetDevice> ()
00039 .AddAttribute ("EnableLearning",
00040 "Enable the learning mode of the Learning Bridge",
00041 BooleanValue (true),
00042 MakeBooleanAccessor (&BridgeNetDevice::m_enableLearning),
00043 MakeBooleanChecker ())
00044 .AddAttribute ("ExpirationTime",
00045 "Time it takes for learned MAC state entry to expire.",
00046 TimeValue (Seconds (30)),
00047 MakeTimeAccessor (&BridgeNetDevice::m_expirationTime),
00048 MakeTimeChecker ())
00049 ;
00050 return tid;
00051 }
00052
00053
00054 BridgeNetDevice::BridgeNetDevice ()
00055 : m_node (0),
00056 m_name (""),
00057 m_ifIndex (0),
00058 m_mtu (0xffff)
00059 {
00060 NS_LOG_FUNCTION_NOARGS ();
00061 m_channel = CreateObject<BridgeChannel> ();
00062 }
00063
00064 BridgeNetDevice::~BridgeNetDevice()
00065 {
00066 NS_LOG_FUNCTION_NOARGS ();
00067 }
00068
00069 void
00070 BridgeNetDevice::DoDispose ()
00071 {
00072 NS_LOG_FUNCTION_NOARGS ();
00073 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
00074 {
00075 *iter = 0;
00076 }
00077 m_ports.clear ();
00078 m_channel = 0;
00079 m_node = 0;
00080 NetDevice::DoDispose ();
00081 }
00082
00083 void
00084 BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
00085 Address const &src, Address const &dst, PacketType packetType)
00086 {
00087 NS_LOG_FUNCTION_NOARGS ();
00088 NS_LOG_DEBUG ("UID is " << packet->GetUid ());
00089
00090 Mac48Address src48 = Mac48Address::ConvertFrom (src);
00091 Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
00092
00093 if (!m_promiscRxCallback.IsNull ())
00094 {
00095 m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
00096 }
00097
00098 switch (packetType)
00099 {
00100 case PACKET_HOST:
00101 if (dst48 == m_address)
00102 {
00103 m_rxCallback (this, packet, protocol, src);
00104 }
00105 break;
00106
00107 case PACKET_BROADCAST:
00108 case PACKET_MULTICAST:
00109 m_rxCallback (this, packet, protocol, src);
00110 ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
00111 break;
00112
00113 case PACKET_OTHERHOST:
00114 ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
00115 break;
00116 }
00117 }
00118
00119 void
00120 BridgeNetDevice::ForwardUnicast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
00121 uint16_t protocol, Mac48Address src, Mac48Address dst)
00122 {
00123 NS_LOG_FUNCTION_NOARGS ();
00124 NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName ()
00125 << ", packet=" << packet << ", protocol="<<protocol
00126 << ", src=" << src << ", dst=" << dst << ")");
00127
00128 Learn (src, incomingPort);
00129 Ptr<NetDevice> outPort = GetLearnedState (dst);
00130 if (outPort != NULL && outPort != incomingPort)
00131 {
00132 NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetName () << "'");
00133 outPort->SendFrom (packet->Copy (), src, dst, protocol);
00134 }
00135 else
00136 {
00137 NS_LOG_LOGIC ("No learned state: send through all ports");
00138 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
00139 iter != m_ports.end (); iter++)
00140 {
00141 Ptr<NetDevice> port = *iter;
00142 if (port != incomingPort)
00143 {
00144 NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " << incomingPort->GetName ()
00145 << " --> " << port->GetName ()
00146 << " (UID " << packet->GetUid () << ").");
00147 port->SendFrom (packet->Copy (), src, dst, protocol);
00148 }
00149 }
00150 }
00151 }
00152
00153 void
00154 BridgeNetDevice::ForwardBroadcast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
00155 uint16_t protocol, Mac48Address src, Mac48Address dst)
00156 {
00157 NS_LOG_FUNCTION_NOARGS ();
00158 NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName ()
00159 << ", packet=" << packet << ", protocol="<<protocol
00160 << ", src=" << src << ", dst=" << dst << ")");
00161 Learn (src, incomingPort);
00162
00163 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
00164 iter != m_ports.end (); iter++)
00165 {
00166 Ptr<NetDevice> port = *iter;
00167 if (port != incomingPort)
00168 {
00169 NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " << incomingPort->GetName ()
00170 << " --> " << port->GetName ()
00171 << " (UID " << packet->GetUid () << ").");
00172 port->SendFrom (packet->Copy (), src, dst, protocol);
00173 }
00174 }
00175 }
00176
00177 void BridgeNetDevice::Learn (Mac48Address source, Ptr<NetDevice> port)
00178 {
00179 NS_LOG_FUNCTION_NOARGS ();
00180 if (m_enableLearning)
00181 {
00182 LearnedState &state = m_learnState[source];
00183 state.associatedPort = port;
00184 state.expirationTime = Simulator::Now () + m_expirationTime;
00185 }
00186 }
00187
00188 Ptr<NetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
00189 {
00190 NS_LOG_FUNCTION_NOARGS ();
00191 if (m_enableLearning)
00192 {
00193 Time now = Simulator::Now ();
00194 std::map<Mac48Address, LearnedState>::iterator iter =
00195 m_learnState.find (source);
00196 if (iter != m_learnState.end ())
00197 {
00198 LearnedState &state = iter->second;
00199 if (state.expirationTime > now)
00200 {
00201 return state.associatedPort;
00202 }
00203 else
00204 {
00205 m_learnState.erase (iter);
00206 }
00207 }
00208 }
00209 return NULL;
00210 }
00211
00212 uint32_t
00213 BridgeNetDevice::GetNBridgePorts (void) const
00214 {
00215 NS_LOG_FUNCTION_NOARGS ();
00216 return m_ports.size ();
00217 }
00218
00219
00220 Ptr<NetDevice>
00221 BridgeNetDevice::GetBridgePort (uint32_t n) const
00222 {
00223 NS_LOG_FUNCTION_NOARGS ();
00224 return m_ports[n];
00225 }
00226
00227 void
00228 BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
00229 {
00230 NS_LOG_FUNCTION_NOARGS ();
00231 NS_ASSERT (bridgePort != this);
00232 if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ()))
00233 {
00234 NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
00235 }
00236 if (!bridgePort->SupportsSendFrom ())
00237 {
00238 NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
00239 }
00240 if (m_address == Mac48Address ())
00241 {
00242 m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
00243 }
00244
00245 NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetName ());
00246 m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this),
00247 0, bridgePort, true);
00248 m_ports.push_back (bridgePort);
00249 m_channel->AddChannel (bridgePort->GetChannel ());
00250 }
00251
00252 void
00253 BridgeNetDevice::SetName(const std::string name)
00254 {
00255 NS_LOG_FUNCTION_NOARGS ();
00256 m_name = name;
00257 }
00258
00259 std::string
00260 BridgeNetDevice::GetName(void) const
00261 {
00262 NS_LOG_FUNCTION_NOARGS ();
00263 return m_name;
00264 }
00265
00266 void
00267 BridgeNetDevice::SetIfIndex(const uint32_t index)
00268 {
00269 NS_LOG_FUNCTION_NOARGS ();
00270 m_ifIndex = index;
00271 }
00272
00273 uint32_t
00274 BridgeNetDevice::GetIfIndex(void) const
00275 {
00276 NS_LOG_FUNCTION_NOARGS ();
00277 return m_ifIndex;
00278 }
00279
00280 Ptr<Channel>
00281 BridgeNetDevice::GetChannel (void) const
00282 {
00283 NS_LOG_FUNCTION_NOARGS ();
00284 return m_channel;
00285 }
00286
00287 Address
00288 BridgeNetDevice::GetAddress (void) const
00289 {
00290 NS_LOG_FUNCTION_NOARGS ();
00291 return m_address;
00292 }
00293
00294 bool
00295 BridgeNetDevice::SetMtu (const uint16_t mtu)
00296 {
00297 NS_LOG_FUNCTION_NOARGS ();
00298 m_mtu = mtu;
00299 return true;
00300 }
00301
00302 uint16_t
00303 BridgeNetDevice::GetMtu (void) const
00304 {
00305 NS_LOG_FUNCTION_NOARGS ();
00306 return m_mtu;
00307 }
00308
00309
00310 bool
00311 BridgeNetDevice::IsLinkUp (void) const
00312 {
00313 NS_LOG_FUNCTION_NOARGS ();
00314 return true;
00315 }
00316
00317
00318 void
00319 BridgeNetDevice::SetLinkChangeCallback (Callback<void> callback)
00320 {}
00321
00322
00323 bool
00324 BridgeNetDevice::IsBroadcast (void) const
00325 {
00326 NS_LOG_FUNCTION_NOARGS ();
00327 return true;
00328 }
00329
00330
00331 Address
00332 BridgeNetDevice::GetBroadcast (void) const
00333 {
00334 NS_LOG_FUNCTION_NOARGS ();
00335 return Mac48Address ("ff:ff:ff:ff:ff:ff");
00336 }
00337
00338 bool
00339 BridgeNetDevice::IsMulticast (void) const
00340 {
00341 NS_LOG_FUNCTION_NOARGS ();
00342 return true;
00343 }
00344
00345 Address
00346 BridgeNetDevice::GetMulticast (Ipv4Address multicastGroup) const
00347 {
00348 NS_LOG_FUNCTION (this << multicastGroup);
00349 Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
00350 return multicast;
00351 }
00352
00353
00354 bool
00355 BridgeNetDevice::IsPointToPoint (void) const
00356 {
00357 NS_LOG_FUNCTION_NOARGS ();
00358 return false;
00359 }
00360
00361 bool
00362 BridgeNetDevice::IsBridge (void) const
00363 {
00364 NS_LOG_FUNCTION_NOARGS ();
00365 return true;
00366 }
00367
00368
00369 bool
00370 BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
00371 {
00372 NS_LOG_FUNCTION_NOARGS ();
00373 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
00374 iter != m_ports.end (); iter++)
00375 {
00376 Ptr<NetDevice> port = *iter;
00377 port->SendFrom (packet, m_address, dest, protocolNumber);
00378 }
00379
00380 return true;
00381 }
00382
00383 bool
00384 BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
00385 {
00386 NS_LOG_FUNCTION_NOARGS ();
00387 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
00388 iter != m_ports.end (); iter++)
00389 {
00390 Ptr<NetDevice> port = *iter;
00391 port->SendFrom (packet, src, dest, protocolNumber);
00392 }
00393
00394 return true;
00395 }
00396
00397
00398 Ptr<Node>
00399 BridgeNetDevice::GetNode (void) const
00400 {
00401 NS_LOG_FUNCTION_NOARGS ();
00402 return m_node;
00403 }
00404
00405
00406 void
00407 BridgeNetDevice::SetNode (Ptr<Node> node)
00408 {
00409 NS_LOG_FUNCTION_NOARGS ();
00410 m_node = node;
00411 }
00412
00413
00414 bool
00415 BridgeNetDevice::NeedsArp (void) const
00416 {
00417 NS_LOG_FUNCTION_NOARGS ();
00418 return true;
00419 }
00420
00421
00422 void
00423 BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
00424 {
00425 NS_LOG_FUNCTION_NOARGS ();
00426 m_rxCallback = cb;
00427 }
00428
00429 void
00430 BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
00431 {
00432 NS_LOG_FUNCTION_NOARGS ();
00433 m_promiscRxCallback = cb;
00434 }
00435
00436 bool
00437 BridgeNetDevice::SupportsSendFrom () const
00438 {
00439 NS_LOG_FUNCTION_NOARGS ();
00440 return true;
00441 }
00442
00443 Address BridgeNetDevice::GetMulticast (Ipv6Address addr) const
00444 {
00445 NS_LOG_FUNCTION (this << addr);
00446 return Mac48Address::GetMulticast (addr);
00447 }
00448
00449 }