A Discrete-Event Network Simulator
API
bridge-net-device.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
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;
6  *
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.
11  *
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
15  *
16  * Author: Gustavo Carneiro <gjc@inescporto.pt>
17  */
18 #include "bridge-net-device.h"
19 #include "ns3/node.h"
20 #include "ns3/channel.h"
21 #include "ns3/packet.h"
22 #include "ns3/log.h"
23 #include "ns3/boolean.h"
24 #include "ns3/simulator.h"
25 #include "ns3/uinteger.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice");
30 
31 NS_OBJECT_ENSURE_REGISTERED (BridgeNetDevice);
32 
33 
34 TypeId
36 {
37  static TypeId tid = TypeId ("ns3::BridgeNetDevice")
38  .SetParent<NetDevice> ()
39  .SetGroupName("Bridge")
40  .AddConstructor<BridgeNetDevice> ()
41  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
42  UintegerValue (1500),
45  MakeUintegerChecker<uint16_t> ())
46  .AddAttribute ("EnableLearning",
47  "Enable the learning mode of the Learning Bridge",
48  BooleanValue (true),
51  .AddAttribute ("ExpirationTime",
52  "Time it takes for learned MAC state entry to expire.",
53  TimeValue (Seconds (300)),
55  MakeTimeChecker ())
56  ;
57  return tid;
58 }
59 
60 
62  : m_node (0),
63  m_ifIndex (0)
64 {
66  m_channel = CreateObject<BridgeChannel> ();
67 }
68 
70 {
72 }
73 
74 void
76 {
78  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
79  {
80  *iter = 0;
81  }
82  m_ports.clear ();
83  m_channel = 0;
84  m_node = 0;
86 }
87 
88 void
89 BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
90  Address const &src, Address const &dst, PacketType packetType)
91 {
93  NS_LOG_DEBUG ("UID is " << packet->GetUid ());
94 
97 
99  {
100  m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
101  }
102 
103  switch (packetType)
104  {
105  case PACKET_HOST:
106  if (dst48 == m_address)
107  {
108  m_rxCallback (this, packet, protocol, src);
109  }
110  break;
111 
112  case PACKET_BROADCAST:
113  case PACKET_MULTICAST:
114  m_rxCallback (this, packet, protocol, src);
115  ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
116  break;
117 
118  case PACKET_OTHERHOST:
119  if (dst48 == m_address)
120  {
121  m_rxCallback (this, packet, protocol, src);
122  }
123  else
124  {
125  ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
126  }
127  break;
128  }
129 }
130 
131 void
133  uint16_t protocol, Mac48Address src, Mac48Address dst)
134 {
136  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
137  << ", packet=" << packet << ", protocol="<<protocol
138  << ", src=" << src << ", dst=" << dst << ")");
139 
140  Learn (src, incomingPort);
141  Ptr<NetDevice> outPort = GetLearnedState (dst);
142  if (outPort != NULL && outPort != incomingPort)
143  {
144  NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetInstanceTypeId ().GetName () << "'");
145  outPort->SendFrom (packet->Copy (), src, dst, protocol);
146  }
147  else
148  {
149  NS_LOG_LOGIC ("No learned state: send through all ports");
150  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
151  iter != m_ports.end (); iter++)
152  {
153  Ptr<NetDevice> port = *iter;
154  if (port != incomingPort)
155  {
156  NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): "
157  << incomingPort->GetInstanceTypeId ().GetName ()
158  << " --> " << port->GetInstanceTypeId ().GetName ()
159  << " (UID " << packet->GetUid () << ").");
160  port->SendFrom (packet->Copy (), src, dst, protocol);
161  }
162  }
163  }
164 }
165 
166 void
168  uint16_t protocol, Mac48Address src, Mac48Address dst)
169 {
171  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
172  << ", packet=" << packet << ", protocol="<<protocol
173  << ", src=" << src << ", dst=" << dst << ")");
174  Learn (src, incomingPort);
175 
176  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
177  iter != m_ports.end (); iter++)
178  {
179  Ptr<NetDevice> port = *iter;
180  if (port != incomingPort)
181  {
182  NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): "
183  << incomingPort->GetInstanceTypeId ().GetName ()
184  << " --> " << port->GetInstanceTypeId ().GetName ()
185  << " (UID " << packet->GetUid () << ").");
186  port->SendFrom (packet->Copy (), src, dst, protocol);
187  }
188  }
189 }
190 
192 {
194  if (m_enableLearning)
195  {
196  LearnedState &state = m_learnState[source];
197  state.associatedPort = port;
199  }
200 }
201 
203 {
205  if (m_enableLearning)
206  {
207  Time now = Simulator::Now ();
208  std::map<Mac48Address, LearnedState>::iterator iter =
209  m_learnState.find (source);
210  if (iter != m_learnState.end ())
211  {
212  LearnedState &state = iter->second;
213  if (state.expirationTime > now)
214  {
215  return state.associatedPort;
216  }
217  else
218  {
219  m_learnState.erase (iter);
220  }
221  }
222  }
223  return NULL;
224 }
225 
226 uint32_t
228 {
230  return m_ports.size ();
231 }
232 
233 
236 {
238  return m_ports[n];
239 }
240 
241 void
243 {
245  NS_ASSERT (bridgePort != this);
246  if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ()))
247  {
248  NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
249  }
250  if (!bridgePort->SupportsSendFrom ())
251  {
252  NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
253  }
254  if (m_address == Mac48Address ())
255  {
256  m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
257  }
258 
259  NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetInstanceTypeId ().GetName ());
261  0, bridgePort, true);
262  m_ports.push_back (bridgePort);
263  m_channel->AddChannel (bridgePort->GetChannel ());
264 }
265 
266 void
267 BridgeNetDevice::SetIfIndex (const uint32_t index)
268 {
270  m_ifIndex = index;
271 }
272 
273 uint32_t
275 {
277  return m_ifIndex;
278 }
279 
282 {
284  return m_channel;
285 }
286 
287 void
289 {
292 }
293 
294 Address
296 {
298  return m_address;
299 }
300 
301 bool
302 BridgeNetDevice::SetMtu (const uint16_t mtu)
303 {
305  m_mtu = mtu;
306  return true;
307 }
308 
309 uint16_t
311 {
313  return m_mtu;
314 }
315 
316 
317 bool
319 {
321  return true;
322 }
323 
324 
325 void
327 {}
328 
329 
330 bool
332 {
334  return true;
335 }
336 
337 
338 Address
340 {
342  return Mac48Address ("ff:ff:ff:ff:ff:ff");
343 }
344 
345 bool
347 {
349  return true;
350 }
351 
352 Address
354 {
355  NS_LOG_FUNCTION (this << multicastGroup);
356  Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
357  return multicast;
358 }
359 
360 
361 bool
363 {
365  return false;
366 }
367 
368 bool
370 {
372  return true;
373 }
374 
375 
376 bool
377 BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
378 {
380  return SendFrom (packet, m_address, dest, protocolNumber);
381 }
382 
383 bool
384 BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
385 {
388 
389  // try to use the learned state if data is unicast
390  if (!dst.IsGroup ())
391  {
392  Ptr<NetDevice> outPort = GetLearnedState (dst);
393  if (outPort != NULL)
394  {
395  outPort->SendFrom (packet, src, dest, protocolNumber);
396  return true;
397  }
398  }
399 
400  // data was not unicast or no state has been learned for that mac
401  // address => flood through all ports.
402  Ptr<Packet> pktCopy;
403  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
404  iter != m_ports.end (); iter++)
405  {
406  pktCopy = packet->Copy ();
407  Ptr<NetDevice> port = *iter;
408  port->SendFrom (pktCopy, src, dest, protocolNumber);
409  }
410 
411  return true;
412 }
413 
414 
415 Ptr<Node>
417 {
419  return m_node;
420 }
421 
422 
423 void
425 {
427  m_node = node;
428 }
429 
430 
431 bool
433 {
435  return true;
436 }
437 
438 
439 void
441 {
443  m_rxCallback = cb;
444 }
445 
446 void
448 {
450  m_promiscRxCallback = cb;
451 }
452 
453 bool
455 {
457  return true;
458 }
459 
461 {
462  NS_LOG_FUNCTION (this << addr);
463  return Mac48Address::GetMulticast (addr);
464 }
465 
466 } // namespace ns3
void AddBridgePort(Ptr< NetDevice > bridgePort)
Add a 'port' to a bridge device.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
static bool IsMatchingType(const Address &address)
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void Learn(Mac48Address source, Ptr< NetDevice > port)
Learns the port a MAC address is sending from.
AttributeValue implementation for Boolean.
Definition: boolean.h:36
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
Ptr< NetDevice > GetLearnedState(Mac48Address source)
Gets the port associated to a source address.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void ForwardBroadcast(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
Forwards a broadcast or a multicast packet.
virtual bool IsPointToPoint(void) const
Return true if the net device is on a point-to-point link.
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
virtual void SetIfIndex(const uint32_t index)
virtual uint32_t GetIfIndex(void) const
Time expirationTime
time it takes for learned MAC state to expire
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: boolean.h:84
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:367
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:296
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual bool IsMulticast(void) const
virtual Ptr< Channel > GetChannel(void) const
static TypeId GetTypeId(void)
Get the type ID.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
Packet addressed to multicast group.
Definition: net-device.h:302
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual void SetAddress(Address address)
Set the address of this interface.
a virtual net device that bridges multiple LAN segments
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Packet addressed oo us.
Definition: net-device.h:298
NetDevice::PromiscReceiveCallback m_promiscRxCallback
promiscuous receive callback
virtual void AddLinkChangeCallback(Callback< void > callback)
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:90
Ptr< NetDevice > associatedPort
port associated with the address
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:446
static Mac48Address GetMulticast(Ipv4Address address)
Ptr< NetDevice > GetBridgePort(uint32_t n) const
Gets the n-th bridged port.
AttributeValue implementation for Time.
Definition: nstime.h:1055
std::vector< Ptr< NetDevice > > m_ports
bridged ports
virtual uint16_t GetMtu(void) const
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual bool SetMtu(const uint16_t mtu)
virtual bool SupportsSendFrom() const
virtual bool IsBroadcast(void) const
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
uint32_t m_ifIndex
Interface index.
virtual Address GetBroadcast(void) const
static Mac48Address ConvertFrom(const Address &address)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
virtual bool NeedsArp(void) const
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
NetDevice::ReceiveCallback m_rxCallback
receive callback
virtual Address GetAddress(void) const
bool IsGroup(void) const
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Packet addressed to someone else.
Definition: net-device.h:304
Mac48Address m_address
MAC address of the NetDevice.
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
an EUI-48 address
Definition: mac48-address.h:43
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: nstime.h:1056
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:249
virtual Ptr< Node > GetNode(void) const
virtual void DoDispose(void)
Destructor implementation.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:227
Ptr< Node > m_node
node owning this NetDevice
std::map< Mac48Address, LearnedState > m_learnState
Container for known address statuses.
Structure holding the status of an address.
Describes an IPv6 address.
Definition: ipv6-address.h:48
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
uint16_t m_mtu
MTU of the bridged NetDevice.
void ForwardUnicast(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
Forwards a unicast packet.
Network layer to device interface.
Definition: net-device.h:95
bool m_enableLearning
true if the bridge will learn the node status
Packet addressed to all.
Definition: net-device.h:300
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
Ptr< BridgeChannel > m_channel
virtual bridged channel
Time m_expirationTime
time it takes for learned MAC state to expire
uint32_t GetNBridgePorts(void) const
Gets the number of bridged 'ports', i.e., the NetDevices currently bridged.
tuple address
Definition: first.py:37
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
virtual void SetNode(Ptr< Node > node)
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
virtual bool IsLinkUp(void) const
void ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &source, Address const &destination, PacketType packetType)
Receives a packet from one bridged port.