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
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 (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
94void
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
143void
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
183void
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
211void
213{
216 {
217 LearnedState& state = m_learnState[source];
218 state.associatedPort = port;
220 }
221}
222
225{
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
249{
251 return m_ports.size();
252}
253
256{
258 return m_ports[n];
259}
260
261void
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
288void
290{
292 m_ifIndex = index;
293}
294
297{
299 return m_ifIndex;
300}
301
304{
306 return m_channel;
307}
308
309void
311{
314}
315
318{
320 return m_address;
321}
322
323bool
324BridgeNetDevice::SetMtu(const uint16_t mtu)
325{
327 m_mtu = mtu;
328 return true;
329}
330
331uint16_t
333{
335 return m_mtu;
336}
337
338bool
340{
342 return true;
343}
344
345void
347{
348}
349
350bool
352{
354 return true;
355}
356
359{
361 return Mac48Address("ff:ff:ff:ff:ff:ff");
362}
363
364bool
366{
368 return true;
369}
370
373{
374 NS_LOG_FUNCTION(this << multicastGroup);
375 Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
376 return multicast;
377}
378
379bool
381{
383 return false;
384}
385
386bool
388{
390 return true;
391}
392
393bool
394BridgeNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
395{
397 return SendFrom(packet, m_address, dest, protocolNumber);
398}
399
400bool
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
436{
438 return m_node;
439}
440
441void
443{
445 m_node = node;
446}
447
448bool
450{
452 return true;
453}
454
455void
457{
459 m_rxCallback = cb;
460}
461
462void
464{
467}
468
469bool
471{
473 return true;
474}
475
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
Callback template class.
Definition: callback.h:438
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
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:242
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
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:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
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:86
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition: nstime.h:1444
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1424
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:1336
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:702
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