A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
27/**
28 * \file
29 * \ingroup bridge
30 * ns3::BridgeNetDevice implementation.
31 */
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("BridgeNetDevice");
37
38NS_OBJECT_ENSURE_REGISTERED(BridgeNetDevice);
39
40TypeId
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)),
63 return tid;
64}
65
67 : m_node(nullptr),
68 m_ifIndex(0)
69{
71 m_channel = CreateObject<BridgeChannel>();
72}
73
75{
77}
78
79void
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
93void
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
142void
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
181void
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
208void
210{
213 {
214 LearnedState& state = m_learnState[source];
215 state.associatedPort = port;
217 }
218}
219
222{
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
246{
248 return m_ports.size();
249}
250
253{
255 return m_ports[n];
256}
257
258void
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
285void
287{
289 m_ifIndex = index;
290}
291
294{
296 return m_ifIndex;
297}
298
301{
303 return m_channel;
304}
305
306void
308{
311}
312
315{
317 return m_address;
318}
319
320bool
321BridgeNetDevice::SetMtu(const uint16_t mtu)
322{
324 m_mtu = mtu;
325 return true;
326}
327
328uint16_t
330{
332 return m_mtu;
333}
334
335bool
337{
339 return true;
340}
341
342void
344{
345}
346
347bool
349{
351 return true;
352}
353
356{
359}
360
361bool
363{
365 return true;
366}
367
370{
371 NS_LOG_FUNCTION(this << multicastGroup);
372 Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
373 return multicast;
374}
375
376bool
378{
380 return false;
381}
382
383bool
385{
387 return true;
388}
389
390bool
391BridgeNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
392{
394 return SendFrom(packet, m_address, dest, protocolNumber);
395}
396
397bool
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
432{
434 return m_node;
435}
436
437void
439{
441 m_node = node;
442}
443
444bool
446{
448 return true;
449}
450
451void
453{
455 m_rxCallback = cb;
456}
457
458void
460{
463}
464
465bool
467{
469 return true;
470}
471
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
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
Callback template class.
Definition: callback.h:438
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)
static Mac48Address GetBroadcast()
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:231
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
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
AttributeValue implementation for Time.
Definition: nstime.h:1413
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1434
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
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:1326
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:704
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