1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation;
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * Author: Gustavo Carneiro <gjc@inescporto.pt>
18 #include "bridge-net-device.h"
20 #include "ns3/channel.h"
21 #include "ns3/packet.h"
23 #include "ns3/boolean.h"
24 #include "ns3/simulator.h"
26 NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice");
30 NS_OBJECT_ENSURE_REGISTERED (BridgeNetDevice);
34 BridgeNetDevice::GetTypeId (void)
36 static TypeId tid = TypeId ("ns3::BridgeNetDevice")
37 .SetParent<NetDevice> ()
38 .AddConstructor<BridgeNetDevice> ()
39 .AddAttribute ("EnableLearning",
40 "Enable the learning mode of the Learning Bridge",
42 MakeBooleanAccessor (&BridgeNetDevice::m_enableLearning),
43 MakeBooleanChecker ())
44 .AddAttribute ("ExpirationTime",
45 "Time it takes for learned MAC state entry to expire.",
46 TimeValue (Seconds (30)),
47 MakeTimeAccessor (&BridgeNetDevice::m_expirationTime),
54 BridgeNetDevice::BridgeNetDevice ()
60 m_channel = CreateObject<BridgeChannel> ();
64 BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
65 Address const &src, Address const &dst, PacketType packetType)
67 NS_LOG_FUNCTION_NOARGS ();
68 NS_LOG_DEBUG ("UID is " << packet->GetUid ());
70 Mac48Address src48 = Mac48Address::ConvertFrom (src);
71 Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
73 if (!m_promiscRxCallback.IsNull ())
75 m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
81 if (dst48 == m_address)
83 m_rxCallback (this, packet, protocol, src);
87 case PACKET_BROADCAST:
88 case PACKET_MULTICAST:
89 m_rxCallback (this, packet, protocol, src);
90 ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
93 case PACKET_OTHERHOST:
94 ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
100 BridgeNetDevice::ForwardUnicast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
101 uint16_t protocol, Mac48Address src, Mac48Address dst)
103 NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName ()
104 << ", packet=" << packet << ", protocol="<<protocol
105 << ", src=" << src << ", dst=" << dst << ")");
107 Learn (src, incomingPort);
108 Ptr<NetDevice> outPort = GetLearnedState (dst);
109 if (outPort != NULL && outPort != incomingPort)
111 NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetName () << "'");
112 outPort->SendFrom (packet->Copy (), src, dst, protocol);
116 NS_LOG_LOGIC ("No learned state: send through all ports");
117 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
118 iter != m_ports.end (); iter++)
120 Ptr<NetDevice> port = *iter;
121 if (port != incomingPort)
123 NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " << incomingPort->GetName ()
124 << " --> " << port->GetName ()
125 << " (UID " << packet->GetUid () << ").");
126 port->SendFrom (packet->Copy (), src, dst, protocol);
133 BridgeNetDevice::ForwardBroadcast (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet,
134 uint16_t protocol, Mac48Address src, Mac48Address dst)
136 NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName ()
137 << ", packet=" << packet << ", protocol="<<protocol
138 << ", src=" << src << ", dst=" << dst << ")");
139 Learn (src, incomingPort);
141 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
142 iter != m_ports.end (); iter++)
144 Ptr<NetDevice> port = *iter;
145 if (port != incomingPort)
147 NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): " << incomingPort->GetName ()
148 << " --> " << port->GetName ()
149 << " (UID " << packet->GetUid () << ").");
150 port->SendFrom (packet->Copy (), src, dst, protocol);
155 void BridgeNetDevice::Learn (Mac48Address source, Ptr<NetDevice> port)
157 if (m_enableLearning)
159 LearnedState &state = m_learnState[source];
160 state.associatedPort = port;
161 state.expirationTime = Simulator::Now () + m_expirationTime;
165 Ptr<NetDevice> BridgeNetDevice::GetLearnedState (Mac48Address source)
167 if (m_enableLearning)
169 Time now = Simulator::Now ();
170 std::map<Mac48Address, LearnedState>::iterator iter =
171 m_learnState.find (source);
172 if (iter != m_learnState.end ())
174 LearnedState &state = iter->second;
175 if (state.expirationTime > now)
177 return state.associatedPort;
181 m_learnState.erase (iter);
189 BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
191 NS_ASSERT (bridgePort != this);
192 if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ()))
194 NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
196 if (!bridgePort->SupportsSendFrom ())
198 NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
200 if (m_address == Mac48Address ())
202 m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
205 NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetName ());
206 m_node->RegisterProtocolHandler (MakeCallback (&BridgeNetDevice::ReceiveFromDevice, this),
207 0, bridgePort, true);
208 m_ports.push_back (bridgePort);
209 m_channel->AddChannel (bridgePort->GetChannel ());
213 BridgeNetDevice::SetName(const std::string name)
219 BridgeNetDevice::GetName(void) const
225 BridgeNetDevice::SetIfIndex(const uint32_t index)
231 BridgeNetDevice::GetIfIndex(void) const
237 BridgeNetDevice::GetChannel (void) const
243 BridgeNetDevice::GetAddress (void) const
249 BridgeNetDevice::SetMtu (const uint16_t mtu)
256 BridgeNetDevice::GetMtu (void) const
263 BridgeNetDevice::IsLinkUp (void) const
270 BridgeNetDevice::SetLinkChangeCallback (Callback<void> callback)
275 BridgeNetDevice::IsBroadcast (void) const
282 BridgeNetDevice::GetBroadcast (void) const
284 return Mac48Address ("ff:ff:ff:ff:ff:ff");
288 BridgeNetDevice::IsMulticast (void) const
294 BridgeNetDevice::GetMulticast (Ipv4Address multicastGroup) const
296 NS_LOG_FUNCTION (this << multicastGroup);
297 Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
303 BridgeNetDevice::IsPointToPoint (void) const
310 BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
312 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
313 iter != m_ports.end (); iter++)
315 Ptr<NetDevice> port = *iter;
316 port->SendFrom (packet, m_address, dest, protocolNumber);
323 BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
325 for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
326 iter != m_ports.end (); iter++)
328 Ptr<NetDevice> port = *iter;
329 port->SendFrom (packet, src, dest, protocolNumber);
337 BridgeNetDevice::GetNode (void) const
344 BridgeNetDevice::SetNode (Ptr<Node> node)
351 BridgeNetDevice::NeedsArp (void) const
358 BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
364 BridgeNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
366 m_promiscRxCallback = cb;
370 BridgeNetDevice::SupportsSendFrom () const
377 BridgeNetDevice::DoDispose (void)
380 NetDevice::DoDispose ();
383 Address BridgeNetDevice::GetMulticast (Ipv6Address addr) const
385 NS_LOG_FUNCTION (this << addr);
386 return Mac48Address::GetMulticast (addr);