Skip to content

Instantly share code, notes, and snippets.

@thehajime
Last active August 29, 2015 14:02
Show Gist options
  • Select an option

  • Save thehajime/6b349aa1551ccefe273b to your computer and use it in GitHub Desktop.

Select an option

Save thehajime/6b349aa1551ccefe273b to your computer and use it in GitHub Desktop.
preliminary patchset: Openvswitch + NOX support for ns-3 Direct Code Execution
# HG changeset patch
# Parent dbe36400cfc53906ff3cd7af8298dbcc2f95533c
diff --git a/example/dce-ovs.cc b/example/dce-ovs.cc
new file mode 100644
--- /dev/null
+++ b/example/dce-ovs.cc
@@ -0,0 +1,271 @@
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/dce-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/csma-module.h"
+#include "ns3/wifi-module.h"
+#include "ns3/mobility-module.h"
+#include "ns3/internet-module.h"
+#include <fstream>
+
+using namespace ns3;
+NS_LOG_COMPONENT_DEFINE ("DceLinux");
+
+static void RunIp (Ptr<Node> node, Time at, std::string str)
+{
+ DceApplicationHelper process;
+ ApplicationContainer apps;
+ process.SetBinary ("ip");
+ process.SetStackSize (1 << 16);
+ process.ResetArguments ();
+ process.ParseArguments (str.c_str ());
+ apps = process.Install (node);
+ apps.Start (at);
+}
+
+void
+PrintTcpFlags (std::string key, std::string value)
+{
+ NS_LOG_INFO (key << "=" << value);
+}
+
+int main (int argc, char *argv[])
+{
+ CommandLine cmd;
+ char linkType = 'p'; // P2P
+ bool reliable = true;
+
+ cmd.AddValue ("linkType", "Link type: ie : C for CSMA, P for Point to Point and w for Wifi, default to P2P", linkType);
+ cmd.AddValue ("reliable", "If true use TCP transport else UDP, default is TCP", reliable);
+ cmd.Parse (argc, argv);
+ linkType = tolower (linkType);
+ switch (linkType)
+ {
+ case 'c':
+ case 'p':
+ case 'w':
+ break;
+ default:
+ std::cout << "Unknown link type : " << linkType << " ?" << std::endl;
+ return 1;
+ }
+
+ NodeContainer nodes;
+ nodes.Create (2);
+
+ NetDeviceContainer devices;
+
+ switch (linkType)
+ {
+ case 'c':
+ {
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
+ csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
+ devices = csma.Install (nodes);
+ csma.EnablePcapAll ("process-linux");
+ }
+ break;
+
+ case 'p':
+ {
+ PointToPointHelper p2p;
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("5Gbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
+ devices = p2p.Install (nodes);
+ p2p.EnablePcapAll ("process-linux");
+ }
+ break;
+
+ case 'w':
+ {
+ MobilityHelper mobility;
+ Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
+ positionAlloc->Add (Vector (0.0, 0.0, 0.0));
+ positionAlloc->Add (Vector (5.0, 0.0, 0.0));
+ mobility.SetPositionAllocator (positionAlloc);
+ mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
+ mobility.Install (nodes);
+
+ WifiHelper wifi = WifiHelper::Default ();
+ YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
+ YansWifiChannelHelper phyChannel = YansWifiChannelHelper::Default ();
+ NqosWifiMacHelper mac;
+ phy.SetChannel (phyChannel.Create ());
+ mac.SetType ("ns3::AdhocWifiMac");
+ wifi.SetStandard (WIFI_PHY_STANDARD_80211a);
+ devices = wifi.Install (phy, mac, nodes);
+ phy.EnablePcapAll ("process-linux");
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ DceManagerHelper processManager;
+ //processManager.SetTaskManagerAttribute ("FiberManagerType", StringValue ("UcontextFiberManager"));
+ //processManager.SetLoader ("ns3::DlmLoaderFactory");
+ processManager.Install (nodes.Get (0));
+ processManager.SetNetworkStack ("ns3::LinuxSocketFdFactory", "Library", StringValue ("liblinux.so"));
+ processManager.Install (nodes.Get (1));
+ InternetStackHelper istack;
+ istack.Install (nodes.Get (0));
+ LinuxStackHelper stack;
+ stack.Install (nodes.Get (1));
+
+ Ipv4AddressHelper address;
+ address.SetBase ("10.0.0.0", "255.255.255.0");
+ Ipv4InterfaceContainer interfaces = address.Assign (devices);
+
+ //Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ //LinuxStackHelper::PopulateRoutingTables ();
+
+ for (int n = 0; n < 2; n++)
+ {
+ RunIp (nodes.Get (n), Seconds (0.2), "link set lo up");
+ RunIp (nodes.Get (n), Seconds (0.2), "link show");
+ RunIp (nodes.Get (n), Seconds (0.3), "route show table all");
+ RunIp (nodes.Get (n), Seconds (0.4), "addr list");
+ }
+
+ DceApplicationHelper process;
+ ApplicationContainer apps;
+
+ // dbtool
+ ::system ("mkdir -p files-1/");
+ ::system ("touch files-1/ovs-vswitchd.conf");
+ ::system ("cp ./applications/openvswitch/vswitchd/vswitch.ovsschema files-1/");
+
+
+ process.SetBinary ("ovsdb-tool");
+ process.ResetArguments ();
+ process.SetStackSize (1<<16);
+ process.ParseArguments ("--verbose create");
+ process.AddArgument ("/conf.db");
+ process.AddArgument ("/vswitch.ovsschema");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (5.0));
+
+ // db-server
+ process.SetBinary ("ovsdb-server");
+ process.ResetArguments ();
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument ("/conf.db");
+ process.AddArgument("--remote=ptcp:8897");
+ //process.AddArgument("--remote=punix:" + std::string(UNIX_OVSDB_SOCKET_PATH));
+ process.AddArgument("--remote=db:Open_vSwitch,Open_vSwitch,manager_options");
+ //process.AddArgumentck("--pidfile");
+ process.AddArgument("--verbose");
+ //process.AddArgument("--detach");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // vsctl-db
+ process.SetBinary ("ovs-vsctl");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--db=tcp:127.0.0.1:8897");
+ //process.AddArgumentck("--db=unix:"+ std::string(UNIX_OVSDB_SOCKET_PATH));
+ process.AddArgument("--verbose");
+ process.AddArgument("--no-wait");
+ process.AddArgument("init");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // vswitchd
+ process.SetBinary ("ovs-vswitchd");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.AddEnvironment ("EVENT_NOEPOLL", "1");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument("tcp:127.0.0.1:8897");
+ process.AddArgument("--log-file=/ovs-vswitchd.log");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+
+ // vsctl: add-br
+ process.SetBinary ("ovs-vsctl");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument("--log-file=/ovs-vsctl.log");
+ process.AddArgument("--db=tcp:127.0.0.1:8897");
+ process.ParseArguments("add-br switch1");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // vsctl: add-port
+ process.SetBinary ("ovs-vsctl");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument("--log-file=/ovs-vsctl.log");
+ process.AddArgument("--db=tcp:127.0.0.1:8897");
+ process.ParseArguments("add-port switch1 sim0");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // vsctl: set bridge
+ process.SetBinary ("ovs-vsctl");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument("--log-file=/ovs-vsctl.log");
+ process.AddArgument("--db=tcp:127.0.0.1:8897");
+ process.ParseArguments("set bridge switch1");
+ process.AddArgument("protocols=OpenFlow10,OpenFlow12,OpenFlow13");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // vsctl: set-controller
+ process.SetBinary ("ovs-vsctl");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument("--log-file=/ovs-vsctl.log");
+ process.AddArgument("--db=tcp:127.0.0.1:8897");
+ process.AddArgument("set-controller");
+ process.AddArgument("switch1");
+ process.AddArgument("tcp:10.0.0.1:6633");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // vsctl: view command
+ process.SetBinary ("ovs-vsctl");
+ process.ResetArguments ();
+ process.AddEnvironment ("LANG", "C");
+ process.SetStackSize (1<<16);
+ process.AddArgument("--verbose");
+ process.AddArgument("--log-file=/ovs-vsctl.log");
+ process.AddArgument("--db=tcp:127.0.0.1:8897");
+ // process.ParseArguments("dump-flows switch1");
+ process.ParseArguments("get-controller switch1");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ // nox
+ process.SetBinary ("nox_core");
+ process.ResetArguments ();
+ process.SetStackSize (1<<16);
+ process.AddArgument("-v");
+ process.AddArgument("-i");
+ process.AddArgument("ptcp:10.0.0.1:6633");
+ apps = process.Install (nodes.Get (0));
+ apps.Start (Seconds (2.0));
+
+
+ Simulator::Stop (Seconds (200.0));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return 0;
+}
diff --git a/model/dce-epoll.cc b/model/dce-epoll.cc
new file mode 100644
--- /dev/null
+++ b/model/dce-epoll.cc
@@ -0,0 +1,123 @@
+#include "sys/dce-epoll.h"
+#include "utils.h"
+#include "process.h"
+#include "linux-epoll-fd.h"
+#include "dce-poll.h"
+#include "ns3/log.h"
+#include <errno.h>
+#include "file-usage.h"
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("DceEpoll");
+
+int dce_epoll_create (int size)
+{
+ Thread *current = Current ();
+ NS_LOG_FUNCTION (current << UtilsGetNodeId () << size);
+ NS_ASSERT (current != 0);
+
+ int fd = UtilsAllocateFd ();
+ if (fd == -1)
+ {
+ current->err = EMFILE;
+ return -1;
+ }
+
+ UnixFd *unixFd = new LinuxEpollFd (size);
+ unixFd->IncFdCount ();
+ current->process->openFiles[fd] = new FileUsage (fd, unixFd);
+ return fd;
+}
+
+int
+dce_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
+{
+ NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << op << epfd << event);
+ NS_ASSERT (Current () != 0);
+ Thread *current = Current ();
+
+ UnixFd *unixFd = current->process->openFiles[epfd]->GetFileInc ();
+ LinuxEpollFd *epollFd = (LinuxEpollFd *)unixFd;
+
+ switch (op)
+ {
+ case EPOLL_CTL_ADD:
+ case EPOLL_CTL_MOD:
+ epollFd->evs[fd] = event;
+ case EPOLL_CTL_DEL:
+ epollFd->evs.erase (fd);
+ break;
+ default:
+ break;
+ }
+
+ FdDecUsage (epfd);
+ return 0;
+}
+
+int
+dce_epoll_wait(int epfd, struct epoll_event *events,
+ int maxevents, int timeout)
+{
+ NS_LOG_FUNCTION (Current () << UtilsGetNodeId () << epfd << events
+ << maxevents << timeout);
+ NS_ASSERT (Current () != 0);
+ Thread *current = Current ();
+
+ UnixFd *unixFd = current->process->openFiles[epfd]->GetFileInc ();
+ LinuxEpollFd *epollFd = (LinuxEpollFd *)unixFd;
+
+ struct pollfd pollFd[maxevents];
+ int j = 0;
+
+ for (std::map<int, struct epoll_event *>::iterator i = epollFd->evs.begin ();
+ i != epollFd->evs.end (); ++i)
+ {
+ struct epoll_event *ev = (*i).second;
+ int pevent = 0;
+ if (ev->events & EPOLLIN)
+ {
+ pevent |= POLLIN;
+ }
+ if (ev->events & EPOLLOUT)
+ {
+ pevent |= POLLOUT;
+ }
+
+ pollFd[j].events = pevent;
+ pollFd[j].fd = (*i).first;
+ pollFd[j++].revents = 0;
+ }
+
+ int pollRet = dce_poll (pollFd, maxevents, timeout);
+ if (pollRet > 0)
+ {
+ pollRet = 0;
+ for (j = 0; j < maxevents; j++)
+ {
+ int fd = pollFd[j].fd;
+
+ if ((POLLIN & pollFd[j].revents) || (POLLHUP & pollFd[j].revents)
+ || (POLLERR & pollFd[j].revents))
+ {
+ events = epollFd->evs[fd];
+ pollRet++;
+ }
+ if (POLLOUT & pollFd[j].revents)
+ {
+ events = epollFd->evs[fd];
+ pollRet++;
+ }
+ if (POLLPRI & pollFd[j].revents)
+ {
+ events = epollFd->evs[fd];
+ pollRet++;
+ }
+
+ events++;
+ }
+ }
+
+ return pollRet;
+}
+
diff --git a/model/dce-errno.h b/model/dce-errno.h
--- a/model/dce-errno.h
+++ b/model/dce-errno.h
@@ -10,6 +10,7 @@
#define dce_errno (*dce___errno_location ())
int * dce___errno_location (void);
+uint16_t **dce___ctype_b_loc (void);
#ifdef __cplusplus
}
diff --git a/model/dce-global-variables.cc b/model/dce-global-variables.cc
--- a/model/dce-global-variables.cc
+++ b/model/dce-global-variables.cc
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <locale.h>
#include "dce-global-variables.h"
#include "process.h"
#include "utils.h"
diff --git a/model/dce-manager.cc b/model/dce-manager.cc
--- a/model/dce-manager.cc
+++ b/model/dce-manager.cc
@@ -522,6 +522,7 @@
struct Thread *thread = new Thread ();
NS_LOG_DEBUG ("Create " << thread);
thread->err = 0;
+ //thread->locale = _nl_global_locale;
thread->tid = AllocateTid (process);
thread->process = process;
thread->isDetached = false;
diff --git a/model/dce-pthread-mutex.cc b/model/dce-pthread-mutex.cc
--- a/model/dce-pthread-mutex.cc
+++ b/model/dce-pthread-mutex.cc
@@ -100,7 +100,8 @@
struct PthreadMutexAttr *attr = (struct PthreadMutexAttr *)attribute;
if (attr != 0
&& attr->type != PTHREAD_MUTEX_RECURSIVE
- && attr->type != PTHREAD_MUTEX_NORMAL)
+ && attr->type != PTHREAD_MUTEX_NORMAL
+ && attr->type != PTHREAD_MUTEX_ERRORCHECK)
{
return EINVAL;
}
diff --git a/model/dce-pthread.cc b/model/dce-pthread.cc
--- a/model/dce-pthread.cc
+++ b/model/dce-pthread.cc
@@ -403,6 +403,20 @@
return 0;
}
+int
+dce_pthread_setname_np (pthread_t th, const char *name)
+{
+ Thread *current = Current ();
+ NS_LOG_FUNCTION (current << UtilsGetNodeId () << PthreadToPid (th)
+ << PthreadToTid (th) << name);
+ NS_ASSERT (current != 0);
+ Thread *thread = current->process->manager->SearchThread (PthreadToPid (th),
+ PthreadToTid (th));
+
+ // XXX: set name
+ return 0;
+}
+
#if 0
int dce_pthread_sigmask (int how, const sigset_t *restrict set,
sigset_t *restrict oset)
diff --git a/model/dce-signal.h b/model/dce-signal.h
--- a/model/dce-signal.h
+++ b/model/dce-signal.h
@@ -21,6 +21,7 @@
void dce___stack_chk_fail (void);
int dce_sigprocmask (int how, const sigset_t *set, sigset_t *oldset);
int dce_sigwait (const sigset_t *set, int *sig);
+int dce_pthread_setname_np (pthread_t thread, const char *name);
#ifdef __cplusplus
}
diff --git a/model/libc-dce.cc b/model/libc-dce.cc
--- a/model/libc-dce.cc
+++ b/model/libc-dce.cc
@@ -17,6 +17,7 @@
#include "sys/dce-stat.h"
#include "sys/dce-select.h"
#include "sys/dce-timerfd.h"
+#include "sys/dce-epoll.h"
#include "dce-unistd.h"
#include "dce-netdb.h"
#include "dce-pthread.h"
diff --git a/model/libc-global-variables.cc b/model/libc-global-variables.cc
--- a/model/libc-global-variables.cc
+++ b/model/libc-global-variables.cc
@@ -1,8 +1,11 @@
#undef __OPTIMIZE__
#include <stdio.h>
#include <netinet/in.h>
+#include <locale.h>
#include "libc-globals.h"
+//extern struct __locale_struct _nl_global_locale;
+
FILE *stdin;
FILE *stdout;
FILE *stderr;
@@ -18,6 +21,10 @@
char *__progname = 0;
char *dce_proginvname = 0;
char *dce_proginvnameshort = 0;
+__thread __locale_t __libc_tsd_LOCALE;
+__thread const uint16_t *__libc_tsd_CTYPE_B;
+// __thread int32_t *__libc_tsd_CTYPE_TOLOWER;
+// __thread int32_t *__libc_tsd_CTYPE_TOUPPER;
#define weak_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((weak, alias (# name)))
diff --git a/model/libc-ns3.h b/model/libc-ns3.h
--- a/model/libc-ns3.h
+++ b/model/libc-ns3.h
@@ -111,6 +111,7 @@
#ifdef HAVE___SECURE_GETENV
NATIVE (__secure_getenv)
#endif
+NATIVE (secure_getenv)
DCE (putenv)
DCE (setenv)
DCE (unsetenv)
@@ -291,7 +292,8 @@
DCE (fsetpos)
DCE (printf)
NATIVE (fprintf)
-NATIVE (sprintf)
+//NATIVE (sprintf)
+NATIVE_WITH_ALIAS2 (sprintf, __sprintf_chk)
DCE (asprintf)
DCE (vasprintf)
NATIVE (dprintf)
@@ -390,6 +392,11 @@
// POLL.H
DCE (poll)
+// SYS/EPOLL.H
+DCE (epoll_create)
+DCE (epoll_ctl)
+DCE (epoll_wait)
+
// SIGNAL.H
DCE (signal)
DCE (sigaction)
@@ -432,6 +439,7 @@
DCE_EXPLICIT (pthread_cond_wait, int, pthread_cond_t*, pthread_mutex_t*)
DCE (pthread_condattr_destroy)
DCE (pthread_condattr_init)
+DCE (pthread_setname_np)
NATIVE (pthread_rwlock_init)
NATIVE (pthread_rwlock_unlock)
NATIVE (pthread_rwlock_wrlock)
diff --git a/model/libc-setup.cc b/model/libc-setup.cc
--- a/model/libc-setup.cc
+++ b/model/libc-setup.cc
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
+#include <locale.h>
#include "libc-globals.h"
#include "dce-global-variables.h"
@@ -12,6 +13,9 @@
extern char *__progname;
//extern char *program_invocation_name;
// extern char *__program_invocation_short_name;
+extern __thread __locale_t __libc_tsd_LOCALE;
+__thread __locale_t tmp_locale;
+//extern __thread __locale_t __libc_tsd_LOCALE __attribute__ ((weak, alias ("tmp_locale")));
extern "C" {
@@ -33,6 +37,7 @@
globals.pprogram_invocation_name = &program_invocation_name;
globals.pprogram_invocation_short_name = &program_invocation_short_name;
+ // __libc_tsd_LOCALE = uselocale (LC_GLOBAL_LOCALE);
typedef void (*dce_global_variables_setup_t)(struct DceGlobalVariables *);
((dce_global_variables_setup_t)g_libc.dce_global_variables_setup_fn)(&globals);
}
diff --git a/model/linux-epoll-fd.cc b/model/linux-epoll-fd.cc
new file mode 100644
--- /dev/null
+++ b/model/linux-epoll-fd.cc
@@ -0,0 +1,278 @@
+#include "linux-epoll-fd.h"
+#include "utils.h"
+#include "process.h"
+#include "dce-manager.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "task-manager.h"
+#include <errno.h>
+#include <sys/mman.h>
+#include <poll.h>
+
+NS_LOG_COMPONENT_DEFINE ("LinuxEpollFd");
+
+namespace ns3 {
+
+LinuxEpollFd::LinuxEpollFd (int size)
+ : m_waiter (0)
+{
+ // std::map <int, struct epoll_event *> epollEvs;
+}
+
+int
+LinuxEpollFd::Close (void)
+{
+ if (m_waiter != 0)
+ {
+ m_waiter->process->manager->Wakeup (m_waiter);
+ }
+ return 0;
+}
+
+ssize_t
+LinuxEpollFd::Write (const void *buf, size_t count)
+{
+ NS_LOG_FUNCTION (this << buf << count);
+ Thread *current = Current ();
+ current->err = EINVAL;
+ return -1;
+}
+ssize_t
+LinuxEpollFd::Read (void *buf, size_t count)
+{
+ Thread *current = Current ();
+ if (count < 8)
+ {
+ current->err = EINVAL;
+ return -1;
+ }
+ m_waiter = current;
+ current->process->manager->Wait ();
+ m_waiter = 0;
+
+ return 0;
+}
+ssize_t
+LinuxEpollFd::Recvmsg (struct msghdr *msg, int flags)
+{
+ NS_LOG_FUNCTION (this << msg << flags);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+ssize_t
+LinuxEpollFd::Sendmsg (const struct msghdr *msg, int flags)
+{
+ NS_LOG_FUNCTION (this << msg << flags);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+bool
+LinuxEpollFd::Isatty (void) const
+{
+ return false;
+}
+int
+LinuxEpollFd::Setsockopt (int level, int optname,
+ const void *optval, socklen_t optlen)
+{
+ NS_LOG_FUNCTION (this << level << optname << optval << optlen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Getsockopt (int level, int optname,
+ void *optval, socklen_t *optlen)
+{
+ NS_LOG_FUNCTION (this << level << optname << optval << optlen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Getsockname (struct sockaddr *name, socklen_t *namelen)
+{
+ NS_LOG_FUNCTION (this << name << namelen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Getpeername (struct sockaddr *name, socklen_t *namelen)
+{
+ NS_LOG_FUNCTION (this << name << namelen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Ioctl (unsigned long request, char *argp)
+{
+ //XXX
+ return -1;
+}
+int
+LinuxEpollFd::Bind (const struct sockaddr *my_addr, socklen_t addrlen)
+{
+ NS_LOG_FUNCTION (this << my_addr << addrlen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Connect (const struct sockaddr *my_addr, socklen_t addrlen)
+{
+ NS_LOG_FUNCTION (this << my_addr << addrlen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Listen (int backlog)
+{
+ NS_LOG_FUNCTION (this << backlog);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Shutdown (int how)
+{
+ NS_LOG_FUNCTION (this << how);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+int
+LinuxEpollFd::Accept (struct sockaddr *my_addr, socklen_t *addrlen)
+{
+ NS_LOG_FUNCTION (this << my_addr << addrlen);
+ Thread *current = Current ();
+ current->err = ENOTSOCK;
+ return -1;
+}
+void *
+LinuxEpollFd::Mmap (void *start, size_t length, int prot, int flags, off64_t offset)
+{
+ NS_LOG_FUNCTION (this << start << length << prot << flags << offset);
+ Thread *current = Current ();
+ current->err = EINVAL;
+ return MAP_FAILED;
+}
+off64_t
+LinuxEpollFd::Lseek (off64_t offset, int whence)
+{
+ NS_LOG_FUNCTION (this << offset << whence);
+ Thread *current = Current ();
+ current->err = ESPIPE;
+ return -1;
+}
+int
+LinuxEpollFd::Fxstat (int ver, struct ::stat *buf)
+{
+ NS_LOG_FUNCTION (this << buf);
+ //XXX: I do not know what I should write here.
+ // but this call is expected to succeed by the kernel.
+ return 0;
+}
+int
+LinuxEpollFd::Fxstat64 (int ver, struct ::stat64 *buf)
+{
+ NS_LOG_FUNCTION (this << buf);
+ //XXX: I do not know what I should write here.
+ // but this call is expected to succeed by the kernel.
+ return 0;
+}
+int
+LinuxEpollFd::Fcntl (int cmd, unsigned long arg)
+{
+ // XXX: this really needs to be fixed
+ return 0;
+}
+int
+LinuxEpollFd::Settime (int flags,
+ const struct itimerspec *new_value,
+ struct itimerspec *old_value)
+{
+ NS_LOG_FUNCTION (this << Current () << flags << new_value << old_value);
+ NS_ASSERT (Current () != 0);
+ Thread *current = Current ();
+ current->err = EINVAL;
+ return -1;
+}
+int
+LinuxEpollFd::Gettime (struct itimerspec *cur_value) const
+{
+ NS_LOG_FUNCTION (this << Current () << cur_value);
+ NS_ASSERT (Current () != 0);
+ Thread *current = Current ();
+ current->err = EINVAL;
+ return -1;
+}
+
+bool
+LinuxEpollFd::CanRecv (void) const
+{
+ // XXX ?
+ return false;
+}
+bool
+LinuxEpollFd::CanSend (void) const
+{
+ return false;
+}
+bool
+LinuxEpollFd::HangupReceived (void) const
+{
+ return false;
+}
+int
+LinuxEpollFd::Poll (PollTable* ptable)
+{
+ int ret = 0;
+
+ if (CanRecv ())
+ {
+ ret |= POLLIN;
+ }
+ if (CanSend ())
+ {
+ ret |= POLLOUT;
+ }
+ if (HangupReceived ())
+ {
+ ret |= POLLHUP;
+ }
+
+ if (ptable)
+ {
+ ptable->PollWait (this);
+ }
+
+ return ret;
+}
+
+int
+LinuxEpollFd::Ftruncate (off_t length)
+{
+ Thread *current = Current ();
+ NS_ASSERT (current != 0);
+ NS_LOG_FUNCTION (this << current << length);
+
+ current->err = EINVAL;
+ return -1;
+}
+
+int
+LinuxEpollFd::Fsync (void)
+{
+ Thread *current = Current ();
+ NS_LOG_FUNCTION (this << current);
+ NS_ASSERT (current != 0);
+ current->err = EBADF;
+ return -1;
+}
+
+} // namespace ns3
diff --git a/model/linux-epoll-fd.h b/model/linux-epoll-fd.h
new file mode 100644
--- /dev/null
+++ b/model/linux-epoll-fd.h
@@ -0,0 +1,58 @@
+#ifndef LINUX_EPOLL_FD_H
+#define LINUX_EPOLL_FD_H
+
+#include "unix-fd.h"
+#include "process.h"
+#include "ns3/nstime.h"
+#include "ns3/event-id.h"
+
+namespace ns3 {
+
+class LinuxEpollFd : public UnixFd
+{
+public:
+ LinuxEpollFd (int size);
+
+ virtual int Close (void);
+ virtual ssize_t Write (const void *buf, size_t count);
+ virtual ssize_t Read (void *buf, size_t count);
+ virtual ssize_t Recvmsg (struct msghdr *msg, int flags);
+ virtual ssize_t Sendmsg (const struct msghdr *msg, int flags);
+ virtual bool Isatty (void) const;
+ virtual int Setsockopt (int level, int optname,
+ const void *optval, socklen_t optlen);
+ virtual int Getsockopt (int level, int optname,
+ void *optval, socklen_t *optlen);
+ virtual int Getsockname (struct sockaddr *name, socklen_t *namelen);
+ virtual int Getpeername (struct sockaddr *name, socklen_t *namelen);
+ virtual int Ioctl (unsigned long request, char *argp);
+ virtual int Bind (const struct sockaddr *my_addr, socklen_t addrlen);
+ virtual int Connect (const struct sockaddr *my_addr, socklen_t addrlen);
+ virtual int Listen (int backlog);
+ virtual int Shutdown (int how);
+ virtual int Accept (struct sockaddr *my_addr, socklen_t *addrlen);
+ virtual void * Mmap (void *start, size_t length, int prot, int flags, off64_t offset);
+ virtual off64_t Lseek (off64_t offset, int whence);
+ virtual int Fxstat (int ver, struct ::stat *buf);
+ virtual int Fxstat64 (int ver, struct ::stat64 *buf);
+ virtual int Fcntl (int cmd, unsigned long arg);
+ virtual int Settime (int flags,
+ const struct itimerspec *new_value,
+ struct itimerspec *old_value);
+ virtual int Gettime (struct itimerspec *cur_value) const;
+ virtual int Ftruncate (off_t length);
+
+ virtual bool CanRecv (void) const;
+ virtual bool CanSend (void) const;
+ virtual bool HangupReceived (void) const;
+ virtual int Poll (PollTable* ptable);
+ virtual int Fsync (void);
+
+ std::map <int, struct epoll_event *> evs;
+private:
+ Thread * m_waiter;
+};
+
+} // namespace ns3
+
+#endif /* LINUX_EPOLL_FD_H */
diff --git a/model/process.h b/model/process.h
--- a/model/process.h
+++ b/model/process.h
@@ -213,6 +213,8 @@
void *exitValue;
/* errno of the thread. */
int err;
+ /* locale of the thread. */
+ __locale_t locale;
/* thread id. */
uint16_t tid;
Task *task;
diff --git a/model/sys/dce-epoll.h b/model/sys/dce-epoll.h
new file mode 100644
--- /dev/null
+++ b/model/sys/dce-epoll.h
@@ -0,0 +1,19 @@
+#ifndef DCE_EPOLL_H
+#define DCE_EPOLL_H
+
+#include <sys/epoll.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int dce_epoll_create (int size);
+int dce_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
+int dce_epoll_wait(int epfd, struct epoll_event *events,
+ int maxevents, int timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* DCE_EPOLL_H */
diff --git a/wscript b/wscript
--- a/wscript
+++ b/wscript
@@ -483,6 +483,15 @@
target='bin/dce-freebsd',
source=['example/dce-freebsd.cc'])
+ module.add_example(needed = ['core', 'network', 'dce'],
+ target='bin/dce-python',
+ linkflags = ['-Wl,--dynamic-linker=' + os.path.abspath (bld.env['ELF_LOADER_PATH'] + '/ldso')],
+ source=['example/dce-python.cc'])
+
+ module.add_example(needed = ['core', 'network', 'dce', 'wifi', 'point-to-point', 'csma'],
+ target='bin/dce-ovs',
+# linkflags = ['-Wl,--dynamic-linker=' + os.path.abspath (bld.env['ELF_LOADER_PATH'] + '/ldso')],
+ source=['example/dce-ovs.cc'])
# Add a script to build system
def build_a_script(bld, name, needed = [], **kw):
@@ -570,6 +579,7 @@
'model/unix-datagram-socket-fd.cc',
'model/unix-stream-socket-fd.cc',
'model/unix-timer-fd.cc',
+ 'model/linux-epoll-fd.cc',
'model/dce-fd.cc',
'model/dce-stdio.cc',
'model/dce-pthread.cc',
@@ -615,6 +625,7 @@
'model/wait-queue.cc',
'model/file-usage.cc',
'model/dce-poll.cc',
+ 'model/dce-epoll.cc',
'model/ipv4-dce-routing.cc',
'model/dce-credentials.cc',
'model/dce-pwd.cc',
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment