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 (auto iter = m_ports.begin(); iter != m_ports.end(); iter++)
84  {
85  *iter = nullptr;
86  }
87  m_ports.clear();
88  m_channel = nullptr;
89  m_node = nullptr;
91 }
92 
93 void
95  Ptr<const Packet> packet,
96  uint16_t protocol,
97  const Address& src,
98  const Address& dst,
99  PacketType packetType)
100 {
102  NS_LOG_DEBUG("UID is " << packet->GetUid());
103 
106 
108  {
109  m_promiscRxCallback(this, packet, protocol, src, dst, packetType);
110  }
111 
112  switch (packetType)
113  {
114  case PACKET_HOST:
115  if (dst48 == m_address)
116  {
117  Learn(src48, incomingPort);
118  m_rxCallback(this, packet, protocol, src);
119  }
120  break;
121 
122  case PACKET_BROADCAST:
123  case PACKET_MULTICAST:
124  m_rxCallback(this, packet, protocol, src);
125  ForwardBroadcast(incomingPort, packet, protocol, src48, dst48);
126  break;
127 
128  case PACKET_OTHERHOST:
129  if (dst48 == m_address)
130  {
131  Learn(src48, incomingPort);
132  m_rxCallback(this, packet, protocol, src);
133  }
134  else
135  {
136  ForwardUnicast(incomingPort, packet, protocol, src48, dst48);
137  }
138  break;
139  }
140 }
141 
142 void
144  Ptr<const Packet> packet,
145  uint16_t protocol,
146  Mac48Address src,
147  Mac48Address dst)
148 {
150  NS_LOG_DEBUG("LearningBridgeForward (incomingPort="
151  << incomingPort->GetInstanceTypeId().GetName() << ", packet=" << packet
152  << ", protocol=" << protocol << ", src=" << src << ", dst=" << dst << ")");
153 
154  Learn(src, incomingPort);
155  Ptr<NetDevice> outPort = GetLearnedState(dst);
156  if (outPort && outPort != incomingPort)
157  {
158  NS_LOG_LOGIC("Learning bridge state says to use port `"
159  << outPort->GetInstanceTypeId().GetName() << "'");
160  outPort->SendFrom(packet->Copy(), src, dst, protocol);
161  }
162  else
163  {
164  NS_LOG_LOGIC("No learned state: send through all ports");
165  for (auto iter = m_ports.begin(); iter != m_ports.end(); iter++)
166  {
167  Ptr<NetDevice> port = *iter;
168  if (port != incomingPort)
169  {
170  NS_LOG_LOGIC("LearningBridgeForward ("
171  << src << " => " << dst
172  << "): " << incomingPort->GetInstanceTypeId().GetName() << " --> "
173  << port->GetInstanceTypeId().GetName() << " (UID " << packet->GetUid()
174  << ").");
175  port->SendFrom(packet->Copy(), src, dst, protocol);
176  }
177  }
178  }
179 }
180 
181 void
183  Ptr<const Packet> packet,
184  uint16_t protocol,
185  Mac48Address src,
186  Mac48Address dst)
187 {
189  NS_LOG_DEBUG("LearningBridgeForward (incomingPort="
190  << incomingPort->GetInstanceTypeId().GetName() << ", packet=" << packet
191  << ", protocol=" << protocol << ", src=" << src << ", dst=" << dst << ")");
192  Learn(src, incomingPort);
193 
194  for (auto iter = m_ports.begin(); iter != m_ports.end(); iter++)
195  {
196  Ptr<NetDevice> port = *iter;
197  if (port != incomingPort)
198  {
199  NS_LOG_LOGIC("LearningBridgeForward (" << src << " => " << dst << "): "
200  << incomingPort->GetInstanceTypeId().GetName()
201  << " --> " << port->GetInstanceTypeId().GetName()
202  << " (UID " << packet->GetUid() << ").");
203  port->SendFrom(packet->Copy(), src, dst, protocol);
204  }
205  }
206 }
207 
208 void
210 {
212  if (m_enableLearning)
213  {
214  LearnedState& state = m_learnState[source];
215  state.associatedPort = port;
217  }
218 }
219 
222 {
224  if (m_enableLearning)
225  {
226  Time now = Simulator::Now();
227  auto iter = m_learnState.find(source);
228  if (iter != m_learnState.end())
229  {
230  LearnedState& state = iter->second;
231  if (state.expirationTime > now)
232  {
233  return state.associatedPort;
234  }
235  else
236  {
237  m_learnState.erase(iter);
238  }
239  }
240  }
241  return nullptr;
242 }
243 
244 uint32_t
246 {
248  return m_ports.size();
249 }
250 
253 {
255  return m_ports[n];
256 }
257 
258 void
260 {
262  NS_ASSERT(bridgePort != this);
263  if (!Mac48Address::IsMatchingType(bridgePort->GetAddress()))
264  {
265  NS_FATAL_ERROR("Device does not support eui 48 addresses: cannot be added to bridge.");
266  }
267  if (!bridgePort->SupportsSendFrom())
268  {
269  NS_FATAL_ERROR("Device does not support SendFrom: cannot be added to bridge.");
270  }
271  if (m_address == Mac48Address())
272  {
273  m_address = Mac48Address::ConvertFrom(bridgePort->GetAddress());
274  }
275 
276  NS_LOG_DEBUG("RegisterProtocolHandler for " << bridgePort->GetInstanceTypeId().GetName());
278  0,
279  bridgePort,
280  true);
281  m_ports.push_back(bridgePort);
282  m_channel->AddChannel(bridgePort->GetChannel());
283 }
284 
285 void
286 BridgeNetDevice::SetIfIndex(const uint32_t index)
287 {
289  m_ifIndex = index;
290 }
291 
292 uint32_t
294 {
296  return m_ifIndex;
297 }
298 
301 {
303  return m_channel;
304 }
305 
306 void
308 {
311 }
312 
313 Address
315 {
317  return m_address;
318 }
319 
320 bool
321 BridgeNetDevice::SetMtu(const uint16_t mtu)
322 {
324  m_mtu = mtu;
325  return true;
326 }
327 
328 uint16_t
330 {
332  return m_mtu;
333 }
334 
335 bool
337 {
339  return true;
340 }
341 
342 void
344 {
345 }
346 
347 bool
349 {
351  return true;
352 }
353 
354 Address
356 {
358  return Mac48Address("ff:ff:ff:ff:ff:ff");
359 }
360 
361 bool
363 {
365  return true;
366 }
367 
368 Address
370 {
371  NS_LOG_FUNCTION(this << multicastGroup);
372  Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
373  return multicast;
374 }
375 
376 bool
378 {
380  return false;
381 }
382 
383 bool
385 {
387  return true;
388 }
389 
390 bool
391 BridgeNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
392 {
394  return SendFrom(packet, m_address, dest, protocolNumber);
395 }
396 
397 bool
399  const Address& src,
400  const Address& dest,
401  uint16_t protocolNumber)
402 {
405 
406  // try to use the learned state if data is unicast
407  if (!dst.IsGroup())
408  {
409  Ptr<NetDevice> outPort = GetLearnedState(dst);
410  if (outPort)
411  {
412  outPort->SendFrom(packet, src, dest, protocolNumber);
413  return true;
414  }
415  }
416 
417  // data was not unicast or no state has been learned for that mac
418  // address => flood through all ports.
419  Ptr<Packet> pktCopy;
420  for (auto iter = m_ports.begin(); iter != m_ports.end(); iter++)
421  {
422  pktCopy = packet->Copy();
423  Ptr<NetDevice> port = *iter;
424  port->SendFrom(pktCopy, src, dest, protocolNumber);
425  }
426 
427  return true;
428 }
429 
430 Ptr<Node>
432 {
434  return m_node;
435 }
436 
437 void
439 {
441  m_node = node;
442 }
443 
444 bool
446 {
448  return true;
449 }
450 
451 void
453 {
455  m_rxCallback = cb;
456 }
457 
458 void
460 {
462  m_promiscRxCallback = cb;
463 }
464 
465 bool
467 {
469  return true;
470 }
471 
472 Address
474 {
475  NS_LOG_FUNCTION(this << addr);
476  return Mac48Address::GetMulticast(addr);
477 }
478 
479 } // namespace ns3
ns3::BridgeNetDevice declaration.
a polymophic address class
Definition: address.h:101
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:569
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
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:238
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
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:77
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:44
#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
#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:1326
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
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:704
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
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