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  .AddConstructor<BridgeNetDevice> ()
40  .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
41  UintegerValue (1500),
44  MakeUintegerChecker<uint16_t> ())
45  .AddAttribute ("EnableLearning",
46  "Enable the learning mode of the Learning Bridge",
47  BooleanValue (true),
50  .AddAttribute ("ExpirationTime",
51  "Time it takes for learned MAC state entry to expire.",
52  TimeValue (Seconds (300)),
54  MakeTimeChecker ())
55  ;
56  return tid;
57 }
58 
59 
61  : m_node (0),
62  m_ifIndex (0)
63 {
65  m_channel = CreateObject<BridgeChannel> ();
66 }
67 
69 {
71 }
72 
73 void
75 {
77  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin (); iter != m_ports.end (); iter++)
78  {
79  *iter = 0;
80  }
81  m_ports.clear ();
82  m_channel = 0;
83  m_node = 0;
85 }
86 
87 void
88 BridgeNetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Packet> packet, uint16_t protocol,
89  Address const &src, Address const &dst, PacketType packetType)
90 {
92  NS_LOG_DEBUG ("UID is " << packet->GetUid ());
93 
96 
98  {
99  m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
100  }
101 
102  switch (packetType)
103  {
104  case PACKET_HOST:
105  if (dst48 == m_address)
106  {
107  m_rxCallback (this, packet, protocol, src);
108  }
109  break;
110 
111  case PACKET_BROADCAST:
112  case PACKET_MULTICAST:
113  m_rxCallback (this, packet, protocol, src);
114  ForwardBroadcast (incomingPort, packet, protocol, src48, dst48);
115  break;
116 
117  case PACKET_OTHERHOST:
118  if (dst48 == m_address)
119  {
120  m_rxCallback (this, packet, protocol, src);
121  }
122  else
123  {
124  ForwardUnicast (incomingPort, packet, protocol, src48, dst48);
125  }
126  break;
127  }
128 }
129 
130 void
132  uint16_t protocol, Mac48Address src, Mac48Address dst)
133 {
135  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
136  << ", packet=" << packet << ", protocol="<<protocol
137  << ", src=" << src << ", dst=" << dst << ")");
138 
139  Learn (src, incomingPort);
140  Ptr<NetDevice> outPort = GetLearnedState (dst);
141  if (outPort != NULL && outPort != incomingPort)
142  {
143  NS_LOG_LOGIC ("Learning bridge state says to use port `" << outPort->GetInstanceTypeId ().GetName () << "'");
144  outPort->SendFrom (packet->Copy (), src, dst, protocol);
145  }
146  else
147  {
148  NS_LOG_LOGIC ("No learned state: send through all ports");
149  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
150  iter != m_ports.end (); iter++)
151  {
152  Ptr<NetDevice> port = *iter;
153  if (port != incomingPort)
154  {
155  NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): "
156  << incomingPort->GetInstanceTypeId ().GetName ()
157  << " --> " << port->GetInstanceTypeId ().GetName ()
158  << " (UID " << packet->GetUid () << ").");
159  port->SendFrom (packet->Copy (), src, dst, protocol);
160  }
161  }
162  }
163 }
164 
165 void
167  uint16_t protocol, Mac48Address src, Mac48Address dst)
168 {
170  NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetInstanceTypeId ().GetName ()
171  << ", packet=" << packet << ", protocol="<<protocol
172  << ", src=" << src << ", dst=" << dst << ")");
173  Learn (src, incomingPort);
174 
175  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
176  iter != m_ports.end (); iter++)
177  {
178  Ptr<NetDevice> port = *iter;
179  if (port != incomingPort)
180  {
181  NS_LOG_LOGIC ("LearningBridgeForward (" << src << " => " << dst << "): "
182  << incomingPort->GetInstanceTypeId ().GetName ()
183  << " --> " << port->GetInstanceTypeId ().GetName ()
184  << " (UID " << packet->GetUid () << ").");
185  port->SendFrom (packet->Copy (), src, dst, protocol);
186  }
187  }
188 }
189 
191 {
193  if (m_enableLearning)
194  {
195  LearnedState &state = m_learnState[source];
196  state.associatedPort = port;
198  }
199 }
200 
202 {
204  if (m_enableLearning)
205  {
206  Time now = Simulator::Now ();
207  std::map<Mac48Address, LearnedState>::iterator iter =
208  m_learnState.find (source);
209  if (iter != m_learnState.end ())
210  {
211  LearnedState &state = iter->second;
212  if (state.expirationTime > now)
213  {
214  return state.associatedPort;
215  }
216  else
217  {
218  m_learnState.erase (iter);
219  }
220  }
221  }
222  return NULL;
223 }
224 
225 uint32_t
227 {
229  return m_ports.size ();
230 }
231 
232 
235 {
237  return m_ports[n];
238 }
239 
240 void
242 {
244  NS_ASSERT (bridgePort != this);
245  if (!Mac48Address::IsMatchingType (bridgePort->GetAddress ()))
246  {
247  NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be added to bridge.");
248  }
249  if (!bridgePort->SupportsSendFrom ())
250  {
251  NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to bridge.");
252  }
253  if (m_address == Mac48Address ())
254  {
255  m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
256  }
257 
258  NS_LOG_DEBUG ("RegisterProtocolHandler for " << bridgePort->GetInstanceTypeId ().GetName ());
260  0, bridgePort, true);
261  m_ports.push_back (bridgePort);
262  m_channel->AddChannel (bridgePort->GetChannel ());
263 }
264 
265 void
266 BridgeNetDevice::SetIfIndex (const uint32_t index)
267 {
269  m_ifIndex = index;
270 }
271 
272 uint32_t
274 {
276  return m_ifIndex;
277 }
278 
281 {
283  return m_channel;
284 }
285 
286 void
288 {
291 }
292 
293 Address
295 {
297  return m_address;
298 }
299 
300 bool
301 BridgeNetDevice::SetMtu (const uint16_t mtu)
302 {
304  m_mtu = mtu;
305  return true;
306 }
307 
308 uint16_t
310 {
312  return m_mtu;
313 }
314 
315 
316 bool
318 {
320  return true;
321 }
322 
323 
324 void
326 {}
327 
328 
329 bool
331 {
333  return true;
334 }
335 
336 
337 Address
339 {
341  return Mac48Address ("ff:ff:ff:ff:ff:ff");
342 }
343 
344 bool
346 {
348  return true;
349 }
350 
351 Address
353 {
354  NS_LOG_FUNCTION (this << multicastGroup);
355  Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
356  return multicast;
357 }
358 
359 
360 bool
362 {
364  return false;
365 }
366 
367 bool
369 {
371  return true;
372 }
373 
374 
375 bool
376 BridgeNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
377 {
379  return SendFrom (packet, m_address, dest, protocolNumber);
380 }
381 
382 bool
383 BridgeNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
384 {
387 
388  // try to use the learned state if data is unicast
389  if (!dst.IsGroup ())
390  {
391  Ptr<NetDevice> outPort = GetLearnedState (dst);
392  if (outPort != NULL)
393  {
394  outPort->SendFrom (packet, src, dest, protocolNumber);
395  return true;
396  }
397  }
398 
399  // data was not unicast or no state has been learned for that mac
400  // address => flood through all ports.
401  for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
402  iter != m_ports.end (); iter++)
403  {
404  Ptr<NetDevice> port = *iter;
405  port->SendFrom (packet, src, dest, protocolNumber);
406  }
407 
408  return true;
409 }
410 
411 
412 Ptr<Node>
414 {
416  return m_node;
417 }
418 
419 
420 void
422 {
424  m_node = node;
425 }
426 
427 
428 bool
430 {
432  return true;
433 }
434 
435 
436 void
438 {
440  m_rxCallback = cb;
441 }
442 
443 void
445 {
447  m_promiscRxCallback = cb;
448 }
449 
450 bool
452 {
454  return true;
455 }
456 
458 {
459  NS_LOG_FUNCTION (this << addr);
460  return Mac48Address::GetMulticast (addr);
461 }
462 
463 } // 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:95
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)
AttributeValue implementation for Boolean.
Definition: boolean.h:34
virtual bool IsBridge(void) const
Return true if the net device is acting as a bridge.
Ptr< NetDevice > GetLearnedState(Mac48Address source)
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void ForwardBroadcast(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
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
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:81
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:380
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:1072
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:272
#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)
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:338
#define NS_FATAL_ERROR(msg)
Fatal error handling.
Definition: fatal-error.h:100
Packet addressed to multicast group.
Definition: net-device.h:278
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
virtual void SetAddress(Address address)
Set the address of this interface.
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Packet addressed oo us.
Definition: net-device.h:274
NetDevice::PromiscReceiveCallback m_promiscRxCallback
virtual void AddLinkChangeCallback(Callback< void > callback)
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:90
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:439
static Mac48Address GetMulticast(Ipv4Address address)
Ptr< NetDevice > GetBridgePort(uint32_t n) const
AttributeValue implementation for Time.
Definition: nstime.h:921
std::vector< Ptr< NetDevice > > m_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:1290
virtual Address GetBroadcast(void) const
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
static Mac48Address ConvertFrom(const Address &address)
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
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
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:280
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:922
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:223
virtual Ptr< Node > GetNode(void) const
virtual void DoDispose(void)
Destructor implementation.
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:219
std::map< Mac48Address, LearnedState > m_learnState
Describes an IPv6 address.
Definition: ipv6-address.h:47
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void ForwardUnicast(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
Network layer to device interface.
Definition: net-device.h:75
Packet addressed to all.
Definition: net-device.h:276
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:236
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:859
Ptr< BridgeChannel > m_channel
uint32_t GetNBridgePorts(void) const
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:51
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
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)