A Discrete-Event Network Simulator
API
bridge-net-device.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * Author: Gustavo Carneiro <gjc@inescporto.pt>
16  */
17 #include "bridge-net-device.h"
18 
19 #include "ns3/boolean.h"
20 #include "ns3/channel.h"
21 #include "ns3/log.h"
22 #include "ns3/node.h"
23 #include "ns3/packet.h"
24 #include "ns3/simulator.h"
25 #include "ns3/uinteger.h"
26 
33 namespace ns3
34 {
35 
36 NS_LOG_COMPONENT_DEFINE("BridgeNetDevice");
37 
38 NS_OBJECT_ENSURE_REGISTERED(BridgeNetDevice);
39 
40 TypeId
42 {
43  static TypeId tid =
44  TypeId("ns3::BridgeNetDevice")
46  .SetGroupName("Bridge")
47  .AddConstructor<BridgeNetDevice>()
48  .AddAttribute("Mtu",
49  "The MAC-level Maximum Transmission Unit",
50  UintegerValue(1500),
52  MakeUintegerChecker<uint16_t>())
53  .AddAttribute("EnableLearning",
54  "Enable the learning mode of the Learning Bridge",
55  BooleanValue(true),
58  .AddAttribute("ExpirationTime",
59  "Time it takes for learned MAC state entry to expire.",
60  TimeValue(Seconds(300)),
62  MakeTimeChecker());
63  return tid;
64 }
65 
67  : m_node(nullptr),
68  m_ifIndex(0)
69 {
71  m_channel = CreateObject<BridgeChannel>();
72 }
73 
75 {
77 }
78 
79 void
81 {
83  for (std::vector<Ptr<NetDevice>>::iterator iter = m_ports.begin(); iter != m_ports.end();
84  iter++)
85  {
86  *iter = nullptr;
87  }
88  m_ports.clear();
89  m_channel = nullptr;
90  m_node = nullptr;
92 }
93 
94 void
96  Ptr<const Packet> packet,
97  uint16_t protocol,
98  const Address& src,
99  const Address& dst,
100  PacketType packetType)
101 {
103  NS_LOG_DEBUG("UID is " << packet->GetUid());
104 
107 
109  {
110  m_promiscRxCallback(this, packet, protocol, src, dst, packetType);
111  }
112 
113  switch (packetType)
114  {
115  case PACKET_HOST:
116  if (dst48 == m_address)
117  {
118  Learn(src48, incomingPort);
119  m_rxCallback(this, packet, protocol, src);
120  }
121  break;
122 
123  case PACKET_BROADCAST:
124  case PACKET_MULTICAST:
125  m_rxCallback(this, packet, protocol, src);
126  ForwardBroadcast(incomingPort, packet, protocol, src48, dst48);
127  break;
128 
129  case PACKET_OTHERHOST:
130  if (dst48 == m_address)
131  {
132  Learn(src48, incomingPort);
133  m_rxCallback(this, packet, protocol, src);
134  }
135  else
136  {
137  ForwardUnicast(incomingPort, packet, protocol, src48, dst48);
138  }
139  break;
140  }
141 }
142 
143 void
145  Ptr<const Packet> packet,
146  uint16_t protocol,
147  Mac48Address src,
148  Mac48Address dst)
149 {
151  NS_LOG_DEBUG("LearningBridgeForward (incomingPort="
152  << incomingPort->GetInstanceTypeId().GetName() << ", packet=" << packet
153  << ", protocol=" << protocol << ", src=" << src << ", dst=" << dst << ")");
154 
155  Learn(src, incomingPort);
156  Ptr<NetDevice> outPort = GetLearnedState(dst);
157  if (outPort && outPort != incomingPort)
158  {
159  NS_LOG_LOGIC("Learning bridge state says to use port `"
160  << outPort->GetInstanceTypeId().GetName() << "'");
161  outPort->SendFrom(packet->Copy(), src, dst, protocol);
162  }
163  else
164  {
165  NS_LOG_LOGIC("No learned state: send through all ports");
166  for (std::vector<Ptr<NetDevice>>::iterator iter = m_ports.begin(); iter != m_ports.end();
167  iter++)
168  {
169  Ptr<NetDevice> port = *iter;
170  if (port != incomingPort)
171  {
172  NS_LOG_LOGIC("LearningBridgeForward ("
173  << src << " => " << dst
174  << "): " << incomingPort->GetInstanceTypeId().GetName() << " --> "
175  << port->GetInstanceTypeId().GetName() << " (UID " << packet->GetUid()
176  << ").");
177  port->SendFrom(packet->Copy(), src, dst, protocol);
178  }
179  }
180  }
181 }
182 
183 void
185  Ptr<const Packet> packet,
186  uint16_t protocol,
187  Mac48Address src,
188  Mac48Address dst)
189 {
191  NS_LOG_DEBUG("LearningBridgeForward (incomingPort="
192  << incomingPort->GetInstanceTypeId().GetName() << ", packet=" << packet
193  << ", protocol=" << protocol << ", src=" << src << ", dst=" << dst << ")");
194  Learn(src, incomingPort);
195 
196  for (std::vector<Ptr<NetDevice>>::iterator iter = m_ports.begin(); iter != m_ports.end();
197  iter++)
198  {
199  Ptr<NetDevice> port = *iter;
200  if (port != incomingPort)
201  {
202  NS_LOG_LOGIC("LearningBridgeForward (" << src << " => " << dst << "): "
203  << incomingPort->GetInstanceTypeId().GetName()
204  << " --> " << port->GetInstanceTypeId().GetName()
205  << " (UID " << packet->GetUid() << ").");
206  port->SendFrom(packet->Copy(), src, dst, protocol);
207  }
208  }
209 }
210 
211 void
213 {
215  if (m_enableLearning)
216  {
217  LearnedState& state = m_learnState[source];
218  state.associatedPort = port;
220  }
221 }
222 
225 {
227  if (m_enableLearning)
228  {
229  Time now = Simulator::Now();
230  std::map<Mac48Address, LearnedState>::iterator iter = m_learnState.find(source);
231  if (iter != m_learnState.end())
232  {
233  LearnedState& state = iter->second;
234  if (state.expirationTime > now)
235  {
236  return state.associatedPort;
237  }
238  else
239  {
240  m_learnState.erase(iter);
241  }
242  }
243  }
244  return nullptr;
245 }
246 
247 uint32_t
249 {
251  return m_ports.size();
252 }
253 
256 {
258  return m_ports[n];
259 }
260 
261 void
263 {
265  NS_ASSERT(bridgePort != this);
266  if (!Mac48Address::IsMatchingType(bridgePort->GetAddress()))
267  {
268  NS_FATAL_ERROR("Device does not support eui 48 addresses: cannot be added to bridge.");
269  }
270  if (!bridgePort->SupportsSendFrom())
271  {
272  NS_FATAL_ERROR("Device does not support SendFrom: cannot be added to bridge.");
273  }
274  if (m_address == Mac48Address())
275  {
276  m_address = Mac48Address::ConvertFrom(bridgePort->GetAddress());
277  }
278 
279  NS_LOG_DEBUG("RegisterProtocolHandler for " << bridgePort->GetInstanceTypeId().GetName());
281  0,
282  bridgePort,
283  true);
284  m_ports.push_back(bridgePort);
285  m_channel->AddChannel(bridgePort->GetChannel());
286 }
287 
288 void
289 BridgeNetDevice::SetIfIndex(const uint32_t index)
290 {
292  m_ifIndex = index;
293 }
294 
295 uint32_t
297 {
299  return m_ifIndex;
300 }
301 
304 {
306  return m_channel;
307 }
308 
309 void
311 {
314 }
315 
316 Address
318 {
320  return m_address;
321 }
322 
323 bool
324 BridgeNetDevice::SetMtu(const uint16_t mtu)
325 {
327  m_mtu = mtu;
328  return true;
329 }
330 
331 uint16_t
333 {
335  return m_mtu;
336 }
337 
338 bool
340 {
342  return true;
343 }
344 
345 void
347 {
348 }
349 
350 bool
352 {
354  return true;
355 }
356 
357 Address
359 {
361  return Mac48Address("ff:ff:ff:ff:ff:ff");
362 }
363 
364 bool
366 {
368  return true;
369 }
370 
371 Address
373 {
374  NS_LOG_FUNCTION(this << multicastGroup);
375  Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
376  return multicast;
377 }
378 
379 bool
381 {
383  return false;
384 }
385 
386 bool
388 {
390  return true;
391 }
392 
393 bool
394 BridgeNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
395 {
397  return SendFrom(packet, m_address, dest, protocolNumber);
398 }
399 
400 bool
402  const Address& src,
403  const Address& dest,
404  uint16_t protocolNumber)
405 {
408 
409  // try to use the learned state if data is unicast
410  if (!dst.IsGroup())
411  {
412  Ptr<NetDevice> outPort = GetLearnedState(dst);
413  if (outPort)
414  {
415  outPort->SendFrom(packet, src, dest, protocolNumber);
416  return true;
417  }
418  }
419 
420  // data was not unicast or no state has been learned for that mac
421  // address => flood through all ports.
422  Ptr<Packet> pktCopy;
423  for (std::vector<Ptr<NetDevice>>::iterator iter = m_ports.begin(); iter != m_ports.end();
424  iter++)
425  {
426  pktCopy = packet->Copy();
427  Ptr<NetDevice> port = *iter;
428  port->SendFrom(pktCopy, src, dest, protocolNumber);
429  }
430 
431  return true;
432 }
433 
434 Ptr<Node>
436 {
438  return m_node;
439 }
440 
441 void
443 {
445  m_node = node;
446 }
447 
448 bool
450 {
452  return true;
453 }
454 
455 void
457 {
459  m_rxCallback = cb;
460 }
461 
462 void
464 {
466  m_promiscRxCallback = cb;
467 }
468 
469 bool
471 {
473  return true;
474 }
475 
476 Address
478 {
479  NS_LOG_FUNCTION(this << addr);
480  return Mac48Address::GetMulticast(addr);
481 }
482 
483 } // namespace ns3
ns3::BridgeNetDevice declaration.
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Boolean.
Definition: boolean.h:37
a virtual net device that bridges multiple LAN segments
bool IsBroadcast() const override
Ptr< BridgeChannel > m_channel
virtual bridged channel
void ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &source, const Address &destination, PacketType packetType)
Receives a packet from one bridged port.
bool IsBridge() const override
Return true if the net device is acting as a bridge.
Ptr< Node > m_node
node owning this NetDevice
std::map< Mac48Address, LearnedState > m_learnState
Container for known address statuses.
Address GetBroadcast() const override
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
uint32_t m_ifIndex
Interface index.
bool SupportsSendFrom() const override
Mac48Address m_address
MAC address of the NetDevice.
uint16_t GetMtu() const override
bool NeedsArp() const override
NetDevice::ReceiveCallback m_rxCallback
receive callback
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
static TypeId GetTypeId()
Get the type ID.
std::vector< Ptr< NetDevice > > m_ports
bridged ports
Time m_expirationTime
time it takes for learned MAC state to expire
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
bool IsMulticast() const override
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
void DoDispose() override
Destructor implementation.
uint32_t GetIfIndex() const override
void ForwardUnicast(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
Forwards a unicast packet.
Ptr< NetDevice > GetLearnedState(Mac48Address source)
Gets the port associated to a source address.
bool m_enableLearning
true if the bridge will learn the node status
void AddBridgePort(Ptr< NetDevice > bridgePort)
Add a 'port' to a bridge device.
void Learn(Mac48Address source, Ptr< NetDevice > port)
Learns the port a MAC address is sending from.
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
void SetNode(Ptr< Node > node) override
bool SetMtu(const uint16_t mtu) override
uint16_t m_mtu
MTU of the bridged NetDevice.
Ptr< Channel > GetChannel() const override
Address GetAddress() const override
Ptr< NetDevice > GetBridgePort(uint32_t n) const
Gets the n-th bridged port.
void SetIfIndex(const uint32_t index) override
void AddLinkChangeCallback(Callback< void > callback) override
Ptr< Node > GetNode() const override
bool IsLinkUp() const override
NetDevice::PromiscReceiveCallback m_promiscRxCallback
promiscuous receive callback
void SetAddress(Address address) override
Set the address of this interface.
uint32_t GetNBridgePorts() const
Gets the number of bridged 'ports', i.e., the NetDevices currently bridged.
void ForwardBroadcast(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, Mac48Address src, Mac48Address dst)
Forwards a broadcast or a multicast packet.
void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb) override
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Describes an IPv6 address.
Definition: ipv6-address.h:50
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
Network layer to device interface.
Definition: net-device.h:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
@ PACKET_HOST
Packet addressed to us.
Definition: net-device.h:301
@ PACKET_OTHERHOST
Packet addressed to someone else.
Definition: net-device.h:307
@ PACKET_BROADCAST
Packet addressed to all.
Definition: net-device.h:303
@ PACKET_MULTICAST
Packet addressed to multicast group.
Definition: net-device.h:305
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:242
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
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:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
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:1424
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:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:707
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:535
Structure holding the status of an address.
Time expirationTime
time it takes for learned MAC state to expire
Ptr< NetDevice > associatedPort
port associated with the address