|
32 |
#include "ns3/ipv4.h" |
32 |
#include "ns3/ipv4.h" |
33 |
#include "ns3/simulator.h" |
33 |
#include "ns3/simulator.h" |
34 |
#include "ns3/realtime-simulator-impl.h" |
34 |
#include "ns3/realtime-simulator-impl.h" |
35 |
#include "ns3/system-thread.h" |
35 |
#include "ns3/unix-fd-reader.h" |
36 |
#include "ns3/uinteger.h" |
36 |
#include "ns3/uinteger.h" |
37 |
|
37 |
|
38 |
#include <sys/wait.h> |
38 |
#include <sys/wait.h> |
|
65 |
|
65 |
|
66 |
namespace ns3 { |
66 |
namespace ns3 { |
67 |
|
67 |
|
|
|
68 |
FdReader::Data TapBridgeFdReader::DoRead (void) |
69 |
{ |
70 |
NS_LOG_FUNCTION_NOARGS (); |
71 |
|
72 |
uint32_t bufferSize = 65536; |
73 |
uint8_t *buf = (uint8_t *)malloc (bufferSize); |
74 |
NS_ABORT_MSG_IF (buf == 0, "malloc() failed"); |
75 |
|
76 |
NS_LOG_LOGIC ("Calling read on tap device fd " << m_fd); |
77 |
ssize_t len = read (m_fd, buf, bufferSize); |
78 |
if (len <= 0) |
79 |
{ |
80 |
NS_LOG_INFO ("TapBridgeFdReader::DoRead(): done"); |
81 |
free (buf); |
82 |
buf = 0; |
83 |
len = 0; |
84 |
} |
85 |
|
86 |
return FdReader::Data (buf, len); |
87 |
} |
88 |
|
68 |
#define TAP_MAGIC 95549 |
89 |
#define TAP_MAGIC 95549 |
69 |
|
90 |
|
70 |
NS_OBJECT_ENSURE_REGISTERED (TapBridge); |
91 |
NS_OBJECT_ENSURE_REGISTERED (TapBridge); |
|
135 |
m_sock (-1), |
156 |
m_sock (-1), |
136 |
m_startEvent (), |
157 |
m_startEvent (), |
137 |
m_stopEvent (), |
158 |
m_stopEvent (), |
138 |
m_readThread (0), |
159 |
m_fdReader (0), |
139 |
m_ns3AddressRewritten (false) |
160 |
m_ns3AddressRewritten (false) |
140 |
{ |
161 |
{ |
141 |
NS_LOG_FUNCTION_NOARGS (); |
162 |
NS_LOG_FUNCTION_NOARGS (); |
|
147 |
{ |
168 |
{ |
148 |
NS_LOG_FUNCTION_NOARGS (); |
169 |
NS_LOG_FUNCTION_NOARGS (); |
149 |
|
170 |
|
|
|
171 |
StopTapDevice (); |
172 |
|
150 |
delete [] m_packetBuffer; |
173 |
delete [] m_packetBuffer; |
151 |
m_packetBuffer = 0; |
174 |
m_packetBuffer = 0; |
152 |
|
175 |
|
|
235 |
// |
258 |
// |
236 |
// Now spin up a read thread to read packets from the tap device. |
259 |
// Now spin up a read thread to read packets from the tap device. |
237 |
// |
260 |
// |
238 |
NS_ABORT_MSG_IF (m_readThread != 0,"TapBridge::StartTapDevice(): Receive thread is already running"); |
261 |
NS_ABORT_MSG_IF (m_fdReader != 0,"TapBridge::StartTapDevice(): Receive thread is already running"); |
239 |
NS_LOG_LOGIC ("Spinning up read thread"); |
262 |
NS_LOG_LOGIC ("Spinning up read thread"); |
240 |
|
263 |
|
241 |
m_readThread = Create<SystemThread> (MakeCallback (&TapBridge::ReadThread, this)); |
264 |
m_fdReader = Create<TapBridgeFdReader> (); |
242 |
m_readThread->Start (); |
265 |
m_fdReader->Start (m_sock, MakeCallback (&TapBridge::ReadCallback, this)); |
243 |
} |
266 |
} |
244 |
|
267 |
|
245 |
void |
268 |
void |
|
247 |
{ |
270 |
{ |
248 |
NS_LOG_FUNCTION_NOARGS (); |
271 |
NS_LOG_FUNCTION_NOARGS (); |
249 |
|
272 |
|
250 |
close (m_sock); |
273 |
if (m_fdReader != 0) |
251 |
m_sock = -1; |
274 |
{ |
|
|
275 |
m_fdReader->Stop (); |
276 |
m_fdReader = 0; |
277 |
} |
252 |
|
278 |
|
253 |
NS_ASSERT_MSG (m_readThread != 0, "TapBridge::StopTapDevice(): Receive thread is not running"); |
279 |
if (m_sock != -1) |
254 |
|
280 |
{ |
255 |
NS_LOG_LOGIC ("Joining read thread"); |
281 |
close (m_sock); |
256 |
m_readThread->Join (); |
282 |
m_sock = -1; |
257 |
m_readThread = 0; |
283 |
} |
258 |
} |
284 |
} |
259 |
|
285 |
|
260 |
void |
286 |
void |
|
636 |
} |
662 |
} |
637 |
|
663 |
|
638 |
void |
664 |
void |
639 |
TapBridge::ReadThread (void) |
665 |
TapBridge::ReadCallback (uint8_t *buf, ssize_t len) |
640 |
{ |
666 |
{ |
641 |
NS_LOG_FUNCTION_NOARGS (); |
667 |
NS_LOG_FUNCTION_NOARGS (); |
642 |
|
668 |
|
|
|
669 |
NS_ASSERT_MSG (buf != 0, "invalid buf argument"); |
670 |
NS_ASSERT_MSG (len > 0, "invalid len argument"); |
671 |
|
643 |
// |
672 |
// |
644 |
// It's important to remember that we're in a completely different thread |
673 |
// It's important to remember that we're in a completely different thread |
645 |
// than the simulator is running in. We need to synchronize with that |
674 |
// than the simulator is running in. We need to synchronize with that |
646 |
// other thread to get the packet up into ns-3. What we will need to do |
675 |
// other thread to get the packet up into ns-3. What we will need to do |
647 |
// is to schedule a method to deal with the packet using the multithreaded |
676 |
// is to schedule a method to deal with the packet using the multithreaded |
648 |
// simulator we are most certainly running. However, I just said it -- we |
677 |
// simulator we are most certainly running. However, I just said it -- we |
649 |
// are talking about two threads here, so it is very, very dangerous to do |
678 |
// are talking about two threads here, so it is very, very dangerous to do |
650 |
// any kind of reference counting on a shared object. Just don't do it. |
679 |
// any kind of reference counting on a shared object. Just don't do it. |
651 |
// So what we're going to do is to allocate a buffer on the heap and pass |
680 |
// So what we're going to do is pass the buffer allocated on the heap |
652 |
// that buffer into the ns-3 context thread where it will create the packet. |
681 |
// into the ns-3 context thread where it will create the packet. |
653 |
// |
682 |
// |
654 |
int32_t len = -1; |
|
|
655 |
|
683 |
|
656 |
for (;;) |
684 |
NS_LOG_INFO ("TapBridge::ReadCallback(): Received packet on node " << m_nodeId); |
657 |
{ |
685 |
NS_LOG_INFO ("TapBridge::ReadCallback(): Scheduling handler"); |
658 |
uint32_t bufferSize = 65536; |
686 |
NS_ASSERT_MSG (m_rtImpl, "TapBridge::ReadCallback(): Realtime simulator implementation pointer not set"); |
659 |
uint8_t *buf = (uint8_t *)malloc (bufferSize); |
687 |
m_rtImpl->ScheduleRealtimeNowWithContext (m_nodeId, MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len)); |
660 |
NS_ABORT_MSG_IF (buf == 0, "TapBridge::ReadThread(): malloc packet buffer failed"); |
|
|
661 |
NS_LOG_LOGIC ("Calling read on tap device socket fd " << m_sock); |
662 |
len = read (m_sock, buf, bufferSize); |
663 |
|
664 |
if (len == -1) |
665 |
{ |
666 |
NS_LOG_INFO ("TapBridge::ReadThread(): Returning"); |
667 |
free (buf); |
668 |
buf = 0; |
669 |
return; |
670 |
} |
671 |
|
672 |
NS_LOG_INFO ("TapBridge::ReadThread(): Received packet on node " << m_nodeId); |
673 |
NS_LOG_INFO ("TapBridge::ReadThread(): Scheduling handler"); |
674 |
NS_ASSERT_MSG (m_rtImpl, "EmuNetDevice::ReadThread(): Realtime simulator implementation pointer not set"); |
675 |
m_rtImpl->ScheduleRealtimeNowWithContext (m_nodeId, MakeEvent (&TapBridge::ForwardToBridgedDevice, this, buf, len)); |
676 |
buf = 0; |
677 |
} |
678 |
} |
688 |
} |
679 |
|
689 |
|
680 |
void |
690 |
void |
681 |
TapBridge::ForwardToBridgedDevice (uint8_t *buf, uint32_t len) |
691 |
TapBridge::ForwardToBridgedDevice (uint8_t *buf, ssize_t len) |
682 |
{ |
692 |
{ |
683 |
NS_LOG_FUNCTION (buf << len); |
693 |
NS_LOG_FUNCTION (buf << len); |
684 |
|
694 |
|