A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tap-bridge.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 University of Washington
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#ifndef TAP_BRIDGE_H
19#define TAP_BRIDGE_H
20
21#include "ns3/address.h"
22#include "ns3/callback.h"
23#include "ns3/data-rate.h"
24#include "ns3/event-id.h"
25#include "ns3/fd-reader.h"
26#include "ns3/mac48-address.h"
27#include "ns3/net-device.h"
28#include "ns3/node.h"
29#include "ns3/nstime.h"
30#include "ns3/packet.h"
31#include "ns3/ptr.h"
32#include "ns3/traced-callback.h"
33
34#include <cstring>
35
36namespace ns3
37{
38
39/**
40 * \ingroup tap-bridge
41 * Class to perform the actual reading from a socket
42 */
44{
45 private:
46 FdReader::Data DoRead() override;
47};
48
49class Node;
50
51/**
52 * \ingroup tap-bridge
53 *
54 * \brief A bridge to make it appear that a real host process is connected to
55 * an ns-3 net device.
56 *
57 * The Tap Bridge lives in a kind of a gray world somewhere between a
58 * Linux host and an ns-3 bridge device. From the Linux perspective,
59 * this code appears as the user mode handler for a Tap net device. That
60 * is, when the Linux host writes to a /dev/tap device (that is either
61 * manually or automatically created depending on basic operating mode
62 * -- more on this later), the write is redirected into the TapBridge that
63 * lives in the ns-3 world; and from this perspective, becomes a read.
64 * In other words, a Linux process writes a packet to a tap device and
65 * this packet is redirected to an ns-3 process where it is received by
66 * the TapBridge as a result of a read operation there. The TapBridge
67 * then sends the packet to the ns-3 net device to which it is bridged.
68 * In the other direction, a packet received by an ns-3 net device is
69 * bridged to the TapBridge (it appears via a callback from that net
70 * device. The TapBridge then takes that packet and writes it back to
71 * the host using the Linux TAP mechanism. This write to the device will
72 * then appear to the Linux host as if a packet has arrived on its
73 * device.
74 *
75 * The upshot is that the Tap Bridge appears to bridge a tap device on a
76 * Linux host in the "real world" to an ns-3 net device in the simulation
77 * and make is appear that a ns-3 net device is actually installed in the
78 * Linux host. In order to do this on the ns-3 side, we need a "ghost
79 * node" in the simulation to hold the bridged ns-3 net device and the
80 * TapBridge. This node should not actually do anything else in the
81 * simulation since its job is simply to make the net device appear in
82 * Linux. This is not just arbitrary policy, it is because:
83 *
84 * - Bits sent to the Tap Bridge from higher layers in the ghost node (using
85 * the TapBridge Send() method) are completely ignored. The Tap Bridge is
86 * not, itself, connected to any network, neither in Linux nor in ns-3;
87 * - The bridged ns-3 net device is has had its receive callback disconnected
88 * from the ns-3 node and reconnected to the Tap Bridge. All data received
89 * by a bridged device will be sent to the Linux host and will not be
90 * received by the node. From the perspective of the ghost node, you can
91 * send over this device but you cannot ever receive.
92 *
93 * Of course, if you understand all of the issues you can take control of
94 * your own destiny and do whatever you want -- we do not actively
95 * prevent you from using the ghost node for anything you decide. You
96 * will be able to perform typical ns-3 operations on the ghost node if
97 * you so desire. The internet stack, for example, must be there and
98 * functional on that node in order to participate in IP address
99 * assignment and global routing. However, as mentioned above,
100 * interfaces talking any Tap Bridge or associated bridged net devices
101 * will not work completely. If you understand exactly what you are
102 * doing, you can set up other interfaces and devices on the ghost node
103 * and use them; or take advantage of the operational send side of the
104 * bridged devices to create traffic generators. We generally recommend
105 * that you treat this node as a ghost of the Linux host and leave it to
106 * itself, though.
107 */
108class TapBridge : public NetDevice
109{
110 public:
111 /**
112 * \brief Get the type ID.
113 * \return the object TypeId
114 */
115 static TypeId GetTypeId();
116
117 /**
118 * Enumeration of the operating modes supported in the class.
119 *
120 */
121 enum Mode
122 {
123 ILLEGAL, //!< mode not set
124 CONFIGURE_LOCAL, //!< ns-3 creates and configures tap device
125 USE_LOCAL, //!< ns-3 uses a pre-created tap, without configuring it
126 USE_BRIDGE, //!< ns-3 uses a pre-created tap, and bridges to a bridging net device
127 };
128
129 TapBridge();
130 ~TapBridge() override;
131
132 /**
133 * \brief Get the bridged net device.
134 *
135 * The bridged net device is the ns-3 device to which this bridge is connected,
136 *
137 * \returns the bridged net device.
138 */
140
141 /**
142 * \brief Set the ns-3 net device to bridge.
143 *
144 * This method tells the bridge which ns-3 net device it should use to connect
145 * the simulation side of the bridge.
146 *
147 * \param bridgedDevice device to set
148 *
149 * \attention The ns-3 net device that is being set as the device must have an
150 * an IP address assigned to it before the simulation is run. This address
151 * will be used to set the hardware address of the host Linux device.
152 */
153 void SetBridgedNetDevice(Ptr<NetDevice> bridgedDevice);
154
155 /**
156 * \brief Set a start time for the device.
157 *
158 * The tap bridge consumes a non-trivial amount of time to start. It starts
159 * up in the context of a scheduled event to ensure that all configuration
160 * has been completed before extracting the configuration (IP addresses, etc.)
161 * In order to allow a more reasonable start-up sequence than a thundering
162 * herd of devices, the time at which each device starts is also configurable
163 * bot via the Attribute system and via this call.
164 *
165 * \param tStart the start time
166 */
167 void Start(Time tStart);
168
169 /**
170 * Set a stop time for the device.
171 *
172 * @param tStop the stop time
173 *
174 * \see TapBridge::Start
175 */
176 void Stop(Time tStop);
177
178 /**
179 * Set the operating mode of this device.
180 *
181 * \param mode The operating mode of this device.
182 */
183 void SetMode(TapBridge::Mode mode);
184
185 /**
186 * Get the operating mode of this device.
187 *
188 * \returns The operating mode of this device.
189 */
191
192 //
193 // The following methods are inherited from NetDevice base class and are
194 // documented there.
195 //
196 void SetIfIndex(const uint32_t index) override;
197 uint32_t GetIfIndex() const override;
198 Ptr<Channel> GetChannel() const override;
199 void SetAddress(Address address) override;
200 Address GetAddress() const override;
201 bool SetMtu(const uint16_t mtu) override;
202 uint16_t GetMtu() const override;
203 bool IsLinkUp() const override;
204 void AddLinkChangeCallback(Callback<void> callback) override;
205 bool IsBroadcast() const override;
206 Address GetBroadcast() const override;
207 bool IsMulticast() const override;
208 Address GetMulticast(Ipv4Address multicastGroup) const override;
209 bool IsPointToPoint() const override;
210 bool IsBridge() const override;
211 bool Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber) override;
212 bool SendFrom(Ptr<Packet> packet,
213 const Address& source,
214 const Address& dest,
215 uint16_t protocolNumber) override;
216 Ptr<Node> GetNode() const override;
217 void SetNode(Ptr<Node> node) override;
218 bool NeedsArp() const override;
221 bool SupportsSendFrom() const override;
222 Address GetMulticast(Ipv6Address addr) const override;
223
224 protected:
225 /**
226 * Call out to a separate process running as suid root in order to get our
227 * tap device created. We do this to avoid having the entire simulation
228 * running as root. If this method returns, we'll have a socket waiting
229 * for us in m_sock that we can use to talk to the tap device.
230 */
231 void DoDispose() override;
232
233 /**
234 * Receives a packet from a bridged Device
235 * \param device the originating port
236 * \param packet the received packet
237 * \param protocol the packet protocol (e.g., Ethertype)
238 * \param src the packet source
239 * \param dst the packet destination
240 * \param packetType the packet type (e.g., host, broadcast, etc.)
241 * \returns true on success
242 */
244 Ptr<const Packet> packet,
245 uint16_t protocol,
246 const Address& src,
247 const Address& dst,
248 PacketType packetType);
249
250 /**
251 * Receives a packet from a bridged Device
252 * \param device the originating port
253 * \param packet the received packet
254 * \param protocol the packet protocol (e.g., Ethertype)
255 * \param src the packet source
256 * \returns true on success
257 */
259 Ptr<const Packet> packet,
260 uint16_t protocol,
261 const Address& src);
262
263 private:
264 /**
265 * Call out to a separate process running as suid root in order to get our
266 * tap device created. We do this to avoid having the entire simulation
267 * running as root. If this method returns, we'll have a socket waiting
268 * for us in m_sock that we can use to talk to the tap device.
269 */
270 void CreateTap();
271
272 /**
273 * Spin up the device
274 */
275 void StartTapDevice();
276
277 /**
278 * Tear down the device
279 */
280 void StopTapDevice();
281
282 /**
283 * Callback to process packets that are read
284 * \param buf input buffer
285 * \param len input buffer length
286 */
287 void ReadCallback(uint8_t* buf, ssize_t len);
288
289 /**
290 * Forward a packet received from the tap device to the bridged ns-3
291 * device
292 *
293 * \param buf A character buffer containing the actual packet bits that were
294 * received from the host.
295 * \param len The length of the buffer.
296 */
297 void ForwardToBridgedDevice(uint8_t* buf, ssize_t len);
298
299 /**
300 * The host we are bridged to is in the evil real world. Do some sanity
301 * checking on a received packet to make sure it isn't too evil for our
302 * poor naive virginal simulator to handle.
303 *
304 * \param packet The packet we received from the host, and which we need
305 * to check.
306 * \param src A pointer to the data structure that will get the source
307 * MAC address of the packet (extracted from the packet Ethernet
308 * header).
309 * \param dst A pointer to the data structure that will get the destination
310 * MAC address of the packet (extracted from the packet Ethernet
311 * header).
312 * \param type A pointer to the variable that will get the packet type from
313 * either the Ethernet header in the case of type interpretation
314 * (DIX framing) or from the 802.2 LLC header in the case of
315 * length interpretation (802.3 framing).
316 * \returns the packet, or null if the packet has been filtered.
317 */
318 Ptr<Packet> Filter(Ptr<Packet> packet, Address* src, Address* dst, uint16_t* type);
319
320 /**
321 * Notifies that the link is up and ready.
322 */
323 void NotifyLinkUp();
324
325 /**
326 * Callback used to hook the standard packet receive callback of the TapBridge
327 * ns-3 net device. This is never called, and therefore no packets will ever
328 * be received forwarded up the IP stack on the ghost node through this device.
329 */
331
332 /**
333 * Callback used to hook the promiscuous packet receive callback of the TapBridge
334 * ns-3 net device. This is never called, and therefore no packets will ever
335 * be received forwarded up the IP stack on the ghost node through this device.
336 *
337 * Note that we intercept the similar callback in the bridged device in order to
338 * do the actual bridging between the bridged ns-3 net device and the Tap device
339 * on the host.
340 */
342
343 /**
344 * Pointer to the (ghost) Node to which we are connected.
345 */
347
348 /**
349 * The ns-3 interface index of this TapBridge net device.
350 */
352
353 /**
354 * The common mtu to use for the net devices
355 */
356 uint16_t m_mtu;
357
358 /**
359 * The socket (actually interpreted as fd) to use to talk to the Tap device on
360 * the real internet host.
361 */
363
364 /**
365 * The ID of the ns-3 event used to schedule the start up of the underlying
366 * host Tap device and ns-3 read thread.
367 */
369
370 /**
371 * The ID of the ns-3 event used to schedule the tear down of the underlying
372 * host Tap device and ns-3 read thread.
373 */
375
376 /**
377 * Includes the ns-3 read thread used to do blocking reads on the fd
378 * corresponding to the host device.
379 */
381
382 /**
383 * The operating mode of the bridge. Tells basically who creates and
384 * configures the underlying network tap.
385 */
387
388 /**
389 * The (unused) MAC address of the TapBridge net device. Since the TapBridge
390 * is implemented as a ns-3 net device, it is required to implement certain
391 * functionality. In this case, the TapBridge is automatically assigned a
392 * MAC address, but it is not used.
393 */
395
396 /**
397 * Time to start spinning up the device
398 */
400
401 /**
402 * Time to start tearing down the device
403 */
405
406 /**
407 * The name of the device to create on the host. If the device name is the
408 * empty string, we allow the host kernel to choose a name.
409 */
410 std::string m_tapDeviceName;
411
412 /**
413 * The IP address to use as the device default gateway on the host.
414 */
416
417 /**
418 * The IP address to use as the device IP on the host.
419 */
421 /**
422 * The MAC address to use as the hardware address on the host; only used
423 * in UseLocal mode. This value comes from the MAC
424 * address assigned to the bridged ns-3 net device and matches the MAC
425 * address of the underlying network TAP which we configured to have the
426 * same value.
427 */
429
430 /**
431 * The network mask to assign to the device created on the host.
432 */
434
435 /**
436 * The ns-3 net device to which we are bridging.
437 */
439 /**
440 * Whether the MAC address of the underlying ns-3 device has already been
441 * rewritten is stored in this variable (for UseLocal/UseBridge mode only).
442 */
444
445 /**
446 * A 64K buffer to hold packet data while it is being sent.
447 */
449
450 /**
451 * a copy of the node id so the read thread doesn't have to GetNode() in
452 * in order to find the node ID. Thread unsafe reference counting in
453 * multithreaded apps is not a good thing.
454 */
456
457 /**
458 * Flag indicating whether or not the link is up. In this case,
459 * whether or not ns-3 is connected to the underlying TAP device
460 * with a file descriptor.
461 */
462 bool m_linkUp{false};
463
464 /**
465 * Flag indicating whether or not the link is up. In this case,
466 * whether or not ns-3 is connected to the underlying TAP device
467 * with a file descriptor.
468 */
470
471 /**
472 * Callbacks to fire if the link changes state (up or down).
473 */
475};
476
477} // namespace ns3
478
479#endif /* TAP_BRIDGE_H */
a polymophic address class
Definition: address.h:101
Callback template class.
Definition: callback.h:438
An identifier for simulation events.
Definition: event-id.h:55
A class that asynchronously reads from a file descriptor.
Definition: fd-reader.h:57
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
Describes an IPv6 address.
Definition: ipv6-address.h:49
an EUI-48 address
Definition: mac48-address.h:46
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
A network Node.
Definition: node.h:57
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Class to perform the actual reading from a socket.
Definition: tap-bridge.h:44
FdReader::Data DoRead() override
The read implementation.
Definition: tap-bridge.cc:55
A bridge to make it appear that a real host process is connected to an ns-3 net device.
Definition: tap-bridge.h:109
void SetBridgedNetDevice(Ptr< NetDevice > bridgedDevice)
Set the ns-3 net device to bridge.
Definition: tap-bridge.cc:939
bool ReceiveFromBridgedDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &src, const Address &dst, PacketType packetType)
Receives a packet from a bridged Device.
Definition: tap-bridge.cc:986
void CreateTap()
Call out to a separate process running as suid root in order to get our tap device created.
Definition: tap-bridge.cc:270
void SetIfIndex(const uint32_t index) override
Definition: tap-bridge.cc:1060
uint32_t m_nodeId
a copy of the node id so the read thread doesn't have to GetNode() in in order to find the node ID.
Definition: tap-bridge.h:455
static TypeId GetTypeId()
Get the type ID.
Definition: tap-bridge.cc:81
bool m_ns3AddressRewritten
Whether the MAC address of the underlying ns-3 device has already been rewritten is stored in this va...
Definition: tap-bridge.h:443
void AddLinkChangeCallback(Callback< void > callback) override
Definition: tap-bridge.cc:1142
uint8_t * m_packetBuffer
A 64K buffer to hold packet data while it is being sent.
Definition: tap-bridge.h:448
bool m_linkUp
Flag indicating whether or not the link is up.
Definition: tap-bridge.h:462
Address GetAddress() const override
Definition: tap-bridge.cc:1088
TracedCallback m_linkChangeCallbacks
Callbacks to fire if the link changes state (up or down).
Definition: tap-bridge.h:474
void SetMode(TapBridge::Mode mode)
Set the operating mode of this device.
Definition: tap-bridge.cc:1095
NetDevice::PromiscReceiveCallback m_promiscRxCallback
Callback used to hook the promiscuous packet receive callback of the TapBridge ns-3 net device.
Definition: tap-bridge.h:341
~TapBridge() override
Definition: tap-bridge.cc:167
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
Definition: tap-bridge.cc:1235
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
Definition: tap-bridge.cc:1206
int m_sock
The socket (actually interpreted as fd) to use to talk to the Tap device on the real internet host.
Definition: tap-bridge.h:362
void StopTapDevice()
Tear down the device.
Definition: tap-bridge.cc:252
Address GetBroadcast() const override
Definition: tap-bridge.cc:1156
uint32_t m_ifIndex
The ns-3 interface index of this TapBridge net device.
Definition: tap-bridge.h:351
bool DiscardFromBridgedDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &src)
Receives a packet from a bridged Device.
Definition: tap-bridge.cc:975
bool NeedsArp() const override
Definition: tap-bridge.cc:1228
void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb) override
Definition: tap-bridge.cc:1242
NetDevice::ReceiveCallback m_rxCallback
Callback used to hook the standard packet receive callback of the TapBridge ns-3 net device.
Definition: tap-bridge.h:330
Mac48Address m_address
The (unused) MAC address of the TapBridge net device.
Definition: tap-bridge.h:394
void Start(Time tStart)
Set a start time for the device.
Definition: tap-bridge.cc:187
bool SetMtu(const uint16_t mtu) override
Definition: tap-bridge.cc:1109
bool IsLinkUp() const override
Definition: tap-bridge.cc:1135
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
Definition: tap-bridge.cc:1178
bool IsBridge() const override
Return true if the net device is acting as a bridge.
Definition: tap-bridge.cc:1185
Ptr< TapBridgeFdReader > m_fdReader
Includes the ns-3 read thread used to do blocking reads on the fd corresponding to the host device.
Definition: tap-bridge.h:380
uint16_t m_mtu
The common mtu to use for the net devices.
Definition: tap-bridge.h:356
void ReadCallback(uint8_t *buf, ssize_t len)
Callback to process packets that are read.
Definition: tap-bridge.cc:712
Ipv4Address m_tapIp
The IP address to use as the device IP on the host.
Definition: tap-bridge.h:420
Ipv4Mask m_tapNetmask
The network mask to assign to the device created on the host.
Definition: tap-bridge.h:433
bool m_verbose
Flag indicating whether or not the link is up.
Definition: tap-bridge.h:469
bool SupportsSendFrom() const override
Definition: tap-bridge.cc:1249
void StartTapDevice()
Spin up the device.
Definition: tap-bridge.cc:210
Ptr< Packet > Filter(Ptr< Packet > packet, Address *src, Address *dst, uint16_t *type)
The host we are bridged to is in the evil real world.
Definition: tap-bridge.cc:870
Mode m_mode
The operating mode of the bridge.
Definition: tap-bridge.h:386
Ptr< Node > m_node
Pointer to the (ghost) Node to which we are connected.
Definition: tap-bridge.h:346
EventId m_stopEvent
The ID of the ns-3 event used to schedule the tear down of the underlying host Tap device and ns-3 re...
Definition: tap-bridge.h:374
void ForwardToBridgedDevice(uint8_t *buf, ssize_t len)
Forward a packet received from the tap device to the bridged ns-3 device.
Definition: tap-bridge.cc:739
void Stop(Time tStop)
Set a stop time for the device.
Definition: tap-bridge.cc:199
void NotifyLinkUp()
Notifies that the link is up and ready.
Definition: tap-bridge.cc:1124
Ptr< NetDevice > m_bridgedDevice
The ns-3 net device to which we are bridging.
Definition: tap-bridge.h:438
bool IsBroadcast() const override
Definition: tap-bridge.cc:1149
Mode
Enumeration of the operating modes supported in the class.
Definition: tap-bridge.h:122
@ USE_BRIDGE
ns-3 uses a pre-created tap, and bridges to a bridging net device
Definition: tap-bridge.h:126
@ ILLEGAL
mode not set
Definition: tap-bridge.h:123
@ USE_LOCAL
ns-3 uses a pre-created tap, without configuring it
Definition: tap-bridge.h:125
@ CONFIGURE_LOCAL
ns-3 creates and configures tap device
Definition: tap-bridge.h:124
void SetAddress(Address address) override
Set the address of this interface.
Definition: tap-bridge.cc:1081
Ptr< Node > GetNode() const override
Definition: tap-bridge.cc:1214
EventId m_startEvent
The ID of the ns-3 event used to schedule the start up of the underlying host Tap device and ns-3 rea...
Definition: tap-bridge.h:368
bool IsMulticast() const override
Definition: tap-bridge.cc:1163
Time m_tStart
Time to start spinning up the device.
Definition: tap-bridge.h:399
Ipv4Address m_tapGateway
The IP address to use as the device default gateway on the host.
Definition: tap-bridge.h:415
TapBridge::Mode GetMode()
Get the operating mode of this device.
Definition: tap-bridge.cc:1102
Ptr< NetDevice > GetBridgedNetDevice()
Get the bridged net device.
Definition: tap-bridge.cc:932
Time m_tStop
Time to start tearing down the device.
Definition: tap-bridge.h:404
void SetNode(Ptr< Node > node) override
Definition: tap-bridge.cc:1221
std::string m_tapDeviceName
The name of the device to create on the host.
Definition: tap-bridge.h:410
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
Definition: tap-bridge.cc:1170
void DoDispose() override
Call out to a separate process running as suid root in order to get our tap device created.
Definition: tap-bridge.cc:180
uint16_t GetMtu() const override
Definition: tap-bridge.cc:1117
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Definition: tap-bridge.cc:1198
Ptr< Channel > GetChannel() const override
Definition: tap-bridge.cc:1074
uint32_t GetIfIndex() const override
Definition: tap-bridge.cc:1067
Mac48Address m_tapMac
The MAC address to use as the hardware address on the host; only used in UseLocal mode.
Definition: tap-bridge.h:428
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Forward calls to a chain of Callback.
a unique identifier for an interface.
Definition: type-id.h:59
Every class exported by the ns3 library is enclosed in the ns3 namespace.
A structure representing data read.
Definition: fd-reader.h:91