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  Learn (src48, incomingPort);
109  m_rxCallback (this, packet, protocol, src);
110  }
111  break;
112 
113  case PACKET_BROADCAST:
114  case PACKET_MULTICAST:
115  m_rxCallback (this, packet, protocol, src);
116  ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
117  break;
118 
119  case PACKET_OTHERHOST:
120  if (dst48 == m_address)
121  {
122  Learn (src48, incomingPort);
123  m_rxCallback (this, packet, protocol, src);
124  }
125  else
126  {
127  ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
128  }
129  break;
130  }
131 }
132 
133 void
135  uint16_t protocol, Mac48Address src, Mac48Address dst)
136 {
138  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
139  << ", packet=" << packet << ", protocol="<<protocol
140  << ", src=" << src << ", dst=" << dst << ")");
141 
142  Learn (src, incomingPort);
143  Ptr<NetDevice> outPort = GetLearnedState (dst);
144  if (outPort != NULL && outPort != incomingPort)
145  {
146  NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetInstanceTypeId ().GetName () << "'");
147  outPort->SendFrom (packet->Copy (), src, dst, protocol);
148  }
149  else
150  {
151  NS_LOG_LOGIC ("No learned state: send through all ports");
152  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
153  iter != m_ports.end (); iter++)
154  {
155  Ptr<NetDevice> port = *iter;
156  if (port != incomingPort)
157  {
158  NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): "
159  << incomingPort->GetInstanceTypeId ().GetName ()
160  << " --> " << port->GetInstanceTypeId ().GetName ()
161  << " (UID " << packet->GetUid () << ").");
162  port->SendFrom (packet->Copy (), src, dst, protocol);
163  }
164  }
165  }
166 }
167 
168 void
170  uint16_t protocol, Mac48Address src, Mac48Address dst)
171 {
173  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
174  << ", packet=" << packet << ", protocol="<<protocol
175  << ", src=" << src << ", dst=" << dst << ")");
176  Learn (src, incomingPort);
177 
178  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
179  iter != m_ports.end (); iter++)
180  {
181  Ptr<NetDevice> port = *iter;
182  if (port != incomingPort)
183  {
184  NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): "
185  << incomingPort->GetInstanceTypeId ().GetName ()
186  << " --> " << port->GetInstanceTypeId ().GetName ()
187  << " (UID " << packet->GetUid () << ").");
188  port->SendFrom (packet->Copy (), src, dst, protocol);
189  }
190  }
191 }
192 
194 {
196  if (m_enableLearning)
197  {
198  LearnedState &state = m_learnState[source];
199  state.associatedPort = port;
201  }
202 }
203 
205 {
207  if (m_enableLearning)
208  {
209  Time now = Simulator::Now ();
210  std::map<Mac48Address, LearnedState>::iterator iter =
211  m_learnState.find (source);
212  if (iter != m_learnState.end ())
213  {
214  LearnedState &state = iter->second;
215  if (state.expirationTime > now)
216  {
217  return state.associatedPort;
218  }
219  else
220  {
221  m_learnState.erase (iter);
222  }
223  }
224  }
225  return NULL;
226 }
227 
228 uint32_t
230 {
232  return m_ports.size ();
233 }
234 
235 
238 {
240  return m_ports[n];
241 }
242 
243 void
245 {
247  NS_ASSERT (bridgePort != this);
248  if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ()))
249  {
250  NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
251  }
252  if (!bridgePort->SupportsSendFrom ())
253  {
254  NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
255  }
256  if (m_address == Mac48Address ())
257  {
258  m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
259  }
260 
261  NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetInstanceTypeId ().GetName ());
263  0, bridgePort, true);
264  m_ports.push_back (bridgePort);
265  m_channel->AddChannel (bridgePort->GetChannel ());
266 }
267 
268 void
269 BridgeNetDevice::SetIfIndex (const uint32_t index)
270 {
272  m_ifIndex = index;
273 }
274 
275 uint32_t
277 {
279  return m_ifIndex;
280 }
281 
284 {
286  return m_channel;
287 }
288 
289 void
291 {
294 }
295 
296 Address
298 {
300  return m_address;
301 }
302 
303 bool
304 BridgeNetDevice::SetMtu (const uint16_t mtu)
305 {
307  m_mtu = mtu;
308  return true;
309 }
310 
311 uint16_t
313 {
315  return m_mtu;
316 }
317 
318 
319 bool
321 {
323  return true;
324 }
325 
326 
327 void
329 {}
330 
331 
332 bool
334 {
336  return true;
337 }
338 
339 
340 Address
342 {
344  return Mac48Address ("ff:ff:ff:ff:ff:ff");
345 }
346 
347 bool
349 {
351  return true;
352 }
353 
354 Address
356 {
357  NS_LOG_FUNCTION (this << multicastGroup);
358  Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
359  return multicast;
360 }
361 
362 
363 bool
365 {
367  return false;
368 }
369 
370 bool
372 {
374  return true;
375 }
376 
377 
378 bool
379 BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
380 {
382  return SendFrom (packet, m_address, dest, protocolNumber);
383 }
384 
385 bool
386 BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
387 {
390 
391  // try to use the learned state if data is unicast
392  if (!dst.IsGroup ())
393  {
394  Ptr<NetDevice> outPort = GetLearnedState (dst);
395  if (outPort != NULL)
396  {
397  outPort->SendFrom (packet, src, dest, protocolNumber);
398  return true;
399  }
400  }
401 
402  // data was not unicast or no state has been learned for that mac
403  // address => flood through all ports.
404  Ptr<Packet> pktCopy;
405  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
406  iter != m_ports.end (); iter++)
407  {
408  pktCopy = packet->Copy ();
409  Ptr<NetDevice> port = *iter;
410  port->SendFrom (pktCopy, src, dest, protocolNumber);
411  }
412 
413  return true;
414 }
415 
416 
417 Ptr<Node>
419 {
421  return m_node;
422 }
423 
424 
425 void
427 {
429  m_node = node;
430 }
431 
432 
433 bool
435 {
437  return true;
438 }
439 
440 
441 void
443 {
445  m_rxCallback = cb;
446 }
447 
448 void
450 {
452  m_promiscRxCallback = cb;
453 }
454 
455 bool
457 {
459  return true;
460 }
461 
463 {
464  NS_LOG_FUNCTION (this << addr);
465  return Mac48Address::GetMulticast (addr);
466 }
467 
468 } // namespace ns3
void AddBridgePort(Ptr< NetDevice > bridgePort)
Add a &#39;port&#39; to a bridge device.
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
static bool IsMatchingType(const Address &address)
uint64_t GetUid(void) const
Returns the packet&#39;s Uid.
Definition: packet.cc:390
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
Packet addressed to someone else.
Definition: net-device.h:304
virtual bool IsPointToPoint(void) const
Return true if the net device is on a point-to-point link.
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 IsMulticast(void) const
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
virtual void SetIfIndex(const uint32_t index)
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
virtual bool IsLinkUp(void) const
#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
virtual Ptr< Node > GetNode(void) const
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
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
virtual bool NeedsArp(void) const
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)
virtual Address GetAddress(void) const
uint32_t GetNBridgePorts(void) const
Gets the number of bridged &#39;ports&#39;, i.e., the NetDevices currently bridged.
NetDevice::PromiscReceiveCallback m_promiscRxCallback
promiscuous receive callback
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
virtual void AddLinkChangeCallback(Callback< void > callback)
uint16_t port
Definition: dsdv-manet.cc:45
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)
AttributeValue implementation for Time.
Definition: nstime.h:1124
std::vector< Ptr< NetDevice > > m_ports
bridged ports
Hold an unsigned integer type.
Definition: uinteger.h:44
virtual bool SetMtu(const uint16_t mtu)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
uint32_t m_ifIndex
Interface index.
static Mac48Address ConvertFrom(const Address &address)
Ptr< NetDevice > GetBridgePort(uint32_t n) const
Gets the n-th bridged port.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
virtual void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
address
Definition: first.py:37
NetDevice::ReceiveCallback m_rxCallback
receive callback
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
Mac48Address m_address
MAC address of the NetDevice.
virtual bool IsBroadcast(void) const
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:1125
bool IsGroup(void) const
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:193
virtual uint32_t GetIfIndex(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
virtual Address GetBroadcast(void) const
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:49
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
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.
Packet addressed oo us.
Definition: net-device.h:298
Network layer to device interface.
Definition: net-device.h:95
bool m_enableLearning
true if the bridge will learn the node status
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:272
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1062
Ptr< BridgeChannel > m_channel
virtual bridged channel
Time m_expirationTime
time it takes for learned MAC state to expire
virtual uint16_t GetMtu(void) const
virtual bool SupportsSendFrom() const
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:296
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1270
Packet addressed to multicast group.
Definition: net-device.h:302
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
virtual Ptr< Channel > GetChannel(void) const
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
Packet addressed to all.
Definition: net-device.h:300
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.