|
|
| 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 |
|