A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
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
NS_LOG_COMPONENT_DEFINE
(
"BridgeNetDevice"
);
28
29
namespace
ns3 {
30
31
NS_OBJECT_ENSURE_REGISTERED
(BridgeNetDevice);
32
33
34
TypeId
35
BridgeNetDevice::GetTypeId
(
void
)
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),
42
MakeUintegerAccessor (&
BridgeNetDevice::SetMtu
,
43
&
BridgeNetDevice::GetMtu
),
44
MakeUintegerChecker<uint16_t> ())
45
.AddAttribute (
"EnableLearning"
,
46
"Enable the learning mode of the Learning Bridge"
,
47
BooleanValue
(
true
),
48
MakeBooleanAccessor (&
BridgeNetDevice::m_enableLearning
),
49
MakeBooleanChecker ())
50
.AddAttribute (
"ExpirationTime"
,
51
"Time it takes for learned MAC state entry to expire."
,
52
TimeValue
(
Seconds
(300)),
53
MakeTimeAccessor (&
BridgeNetDevice::m_expirationTime
),
54
MakeTimeChecker ())
55
;
56
return
tid;
57
}
58
59
60
BridgeNetDevice::BridgeNetDevice
()
61
: m_node (0),
62
m_ifIndex (0)
63
{
64
NS_LOG_FUNCTION_NOARGS
();
65
m_channel
= CreateObject<BridgeChannel> ();
66
}
67
68
BridgeNetDevice::~BridgeNetDevice
()
69
{
70
NS_LOG_FUNCTION_NOARGS
();
71
}
72
73
void
74
BridgeNetDevice::DoDispose
()
75
{
76
NS_LOG_FUNCTION_NOARGS
();
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;
84
NetDevice::DoDispose
();
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
{
91
NS_LOG_FUNCTION_NOARGS
();
92
NS_LOG_DEBUG
(
"UID is "
<< packet->
GetUid
());
93
94
Mac48Address
src48 =
Mac48Address::ConvertFrom
(src);
95
Mac48Address
dst48 =
Mac48Address::ConvertFrom
(dst);
96
97
if
(!
m_promiscRxCallback
.
IsNull
())
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
131
BridgeNetDevice::ForwardUnicast
(
Ptr<NetDevice>
incomingPort,
Ptr<const Packet>
packet,
132
uint16_t protocol,
Mac48Address
src,
Mac48Address
dst)
133
{
134
NS_LOG_FUNCTION_NOARGS
();
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
166
BridgeNetDevice::ForwardBroadcast
(
Ptr<NetDevice>
incomingPort,
Ptr<const Packet>
packet,
167
uint16_t protocol,
Mac48Address
src,
Mac48Address
dst)
168
{
169
NS_LOG_FUNCTION_NOARGS
();
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
190
void
BridgeNetDevice::Learn
(
Mac48Address
source,
Ptr<NetDevice>
port
)
191
{
192
NS_LOG_FUNCTION_NOARGS
();
193
if
(
m_enableLearning
)
194
{
195
LearnedState
&state =
m_learnState
[source];
196
state.
associatedPort
=
port
;
197
state.
expirationTime
=
Simulator::Now
() +
m_expirationTime
;
198
}
199
}
200
201
Ptr<NetDevice>
BridgeNetDevice::GetLearnedState
(
Mac48Address
source)
202
{
203
NS_LOG_FUNCTION_NOARGS
();
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
226
BridgeNetDevice::GetNBridgePorts
(
void
)
const
227
{
228
NS_LOG_FUNCTION_NOARGS
();
229
return
m_ports
.size ();
230
}
231
232
233
Ptr<NetDevice>
234
BridgeNetDevice::GetBridgePort
(uint32_t n)
const
235
{
236
NS_LOG_FUNCTION_NOARGS
();
237
return
m_ports
[n];
238
}
239
240
void
241
BridgeNetDevice::AddBridgePort
(
Ptr<NetDevice>
bridgePort)
242
{
243
NS_LOG_FUNCTION_NOARGS
();
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
());
259
m_node
->
RegisterProtocolHandler
(
MakeCallback
(&
BridgeNetDevice::ReceiveFromDevice
,
this
),
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
{
268
NS_LOG_FUNCTION_NOARGS
();
269
m_ifIndex
= index;
270
}
271
272
uint32_t
273
BridgeNetDevice::GetIfIndex
(
void
)
const
274
{
275
NS_LOG_FUNCTION_NOARGS
();
276
return
m_ifIndex
;
277
}
278
279
Ptr<Channel>
280
BridgeNetDevice::GetChannel
(
void
)
const
281
{
282
NS_LOG_FUNCTION_NOARGS
();
283
return
m_channel
;
284
}
285
286
void
287
BridgeNetDevice::SetAddress
(
Address
address)
288
{
289
NS_LOG_FUNCTION_NOARGS
();
290
m_address
=
Mac48Address::ConvertFrom
(address);
291
}
292
293
Address
294
BridgeNetDevice::GetAddress
(
void
)
const
295
{
296
NS_LOG_FUNCTION_NOARGS
();
297
return
m_address
;
298
}
299
300
bool
301
BridgeNetDevice::SetMtu
(
const
uint16_t mtu)
302
{
303
NS_LOG_FUNCTION_NOARGS
();
304
m_mtu
= mtu;
305
return
true
;
306
}
307
308
uint16_t
309
BridgeNetDevice::GetMtu
(
void
)
const
310
{
311
NS_LOG_FUNCTION_NOARGS
();
312
return
m_mtu
;
313
}
314
315
316
bool
317
BridgeNetDevice::IsLinkUp
(
void
)
const
318
{
319
NS_LOG_FUNCTION_NOARGS
();
320
return
true
;
321
}
322
323
324
void
325
BridgeNetDevice::AddLinkChangeCallback
(
Callback<void>
callback)
326
{}
327
328
329
bool
330
BridgeNetDevice::IsBroadcast
(
void
)
const
331
{
332
NS_LOG_FUNCTION_NOARGS
();
333
return
true
;
334
}
335
336
337
Address
338
BridgeNetDevice::GetBroadcast
(
void
)
const
339
{
340
NS_LOG_FUNCTION_NOARGS
();
341
return
Mac48Address
(
"ff:ff:ff:ff:ff:ff"
);
342
}
343
344
bool
345
BridgeNetDevice::IsMulticast
(
void
)
const
346
{
347
NS_LOG_FUNCTION_NOARGS
();
348
return
true
;
349
}
350
351
Address
352
BridgeNetDevice::GetMulticast
(
Ipv4Address
multicastGroup)
const
353
{
354
NS_LOG_FUNCTION
(
this
<< multicastGroup);
355
Mac48Address
multicast =
Mac48Address::GetMulticast
(multicastGroup);
356
return
multicast;
357
}
358
359
360
bool
361
BridgeNetDevice::IsPointToPoint
(
void
)
const
362
{
363
NS_LOG_FUNCTION_NOARGS
();
364
return
false
;
365
}
366
367
bool
368
BridgeNetDevice::IsBridge
(
void
)
const
369
{
370
NS_LOG_FUNCTION_NOARGS
();
371
return
true
;
372
}
373
374
375
bool
376
BridgeNetDevice::Send
(
Ptr<Packet>
packet,
const
Address
& dest, uint16_t protocolNumber)
377
{
378
NS_LOG_FUNCTION_NOARGS
();
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
{
385
NS_LOG_FUNCTION_NOARGS
();
386
Mac48Address
dst =
Mac48Address::ConvertFrom
(dest);
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>
413
BridgeNetDevice::GetNode
(
void
)
const
414
{
415
NS_LOG_FUNCTION_NOARGS
();
416
return
m_node
;
417
}
418
419
420
void
421
BridgeNetDevice::SetNode
(
Ptr<Node>
node)
422
{
423
NS_LOG_FUNCTION_NOARGS
();
424
m_node
= node;
425
}
426
427
428
bool
429
BridgeNetDevice::NeedsArp
(
void
)
const
430
{
431
NS_LOG_FUNCTION_NOARGS
();
432
return
true
;
433
}
434
435
436
void
437
BridgeNetDevice::SetReceiveCallback
(
NetDevice::ReceiveCallback
cb)
438
{
439
NS_LOG_FUNCTION_NOARGS
();
440
m_rxCallback
= cb;
441
}
442
443
void
444
BridgeNetDevice::SetPromiscReceiveCallback
(
NetDevice::PromiscReceiveCallback
cb)
445
{
446
NS_LOG_FUNCTION_NOARGS
();
447
m_promiscRxCallback
= cb;
448
}
449
450
bool
451
BridgeNetDevice::SupportsSendFrom
()
const
452
{
453
NS_LOG_FUNCTION_NOARGS
();
454
return
true
;
455
}
456
457
Address
BridgeNetDevice::GetMulticast
(
Ipv6Address
addr)
const
458
{
459
NS_LOG_FUNCTION
(
this
<< addr);
460
return
Mac48Address::GetMulticast
(addr);
461
}
462
463
}
// namespace ns3
src
bridge
model
bridge-net-device.cc
Generated on Tue May 14 2013 11:08:16 for ns-3 by
1.8.1.2