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