Skip to content

Instantly share code, notes, and snippets.

@thehajime
Created June 27, 2014 06:34
Show Gist options
  • Select an option

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

Select an option

Save thehajime/b2efe96e797cd131cac1 to your computer and use it in GitHub Desktop.
diff -r 3aa67e451203 .hgignore
--- a/.hgignore Tue Jul 15 19:53:51 2014 +0900
+++ b/.hgignore Wed Jul 16 12:55:00 2014 +0900
@@ -25,3 +25,4 @@
^GRTAGS
^GSYMS
^GTAGS
+applications
diff -r 3aa67e451203 example/dce-ovs.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/example/dce-ovs.cc Wed Jul 16 12:55:00 2014 +0900
@@ -0,0 +1,272 @@
+#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 "ns3/applications-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;
+
+ GlobalValue::Bind ("ChecksumEnabled", BooleanValue (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;
+ PointToPointHelper p2p;
+ p2p.SetDeviceAttribute ("DataRate", StringValue ("5Gbps"));
+ p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
+ devices = p2p.Install (nodes);
+ p2p.EnablePcapAll ("process-linux");
+
+ CsmaHelper csma;
+ csma.SetChannelAttribute ("DataRate", StringValue ("5Mbps"));
+ csma.SetChannelAttribute ("Delay", StringValue ("2ms"));
+ csma.Install (nodes.Get (1));
+ csma.Install (nodes.Get (1));
+
+
+ DceManagerHelper processManager;
+ //processManager.SetTaskManagerAttribute ("FiberManagerType", StringValue ("UcontextFiberManager"));
+ //processManager.SetLoader ("ns3::DlmLoaderFactory");
+ processManager.SetNetworkStack ("ns3::LinuxSocketFdFactory", "Library", StringValue ("liblinux.so"));
+ processManager.Install (nodes.Get (0));
+ processManager.Install (nodes.Get (1));
+ InternetStackHelper istack;
+ // istack.Install (nodes.Get (0));
+ LinuxStackHelper stack;
+ stack.Install (nodes.Get (0));
+ 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");
+ }
+ RunIp (nodes.Get (1), Seconds (0.1), "link set sim1 up");
+ RunIp (nodes.Get (1), Seconds (0.1), "link set sim2 up");
+
+ DceApplicationHelper process;
+ ApplicationContainer apps;
+
+ // dbtool
+ ::system ("mkdir -p files-1/");
+ ::system ("touch files-1/ovs-vswitchd.conf");
+ ::system ("cp ../openvswitch/vswitchd/vswitch.ovsschema files-1/");
+ ::system ("mkdir -p files-0/etc/");
+ ::system ("cp ../nox/src/etc/nox.meta.json files-0/etc/");
+
+ 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.SetStackSize (1<<20);
+ 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 sim1");
+ apps = process.Install (nodes.Get (1));
+ apps.Start (Seconds (6.0));
+
+ 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 sim2");
+ 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: n-handler-threads
+ 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 Open_vSwitch . other_config:n-handler-threads=1");
+ 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");
+ process.ParseArguments("show");
+ 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));
+
+#if 0
+ OnOffHelper onoff = OnOffHelper ("ns3::LinuxTcpSocketFactory",
+ InetSocketAddress ("10.0.0.1", 6633));
+ onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
+ onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
+ apps = onoff.Install (nodes.Get (1));
+ apps.Start (Seconds (7.0));
+ apps.Stop (Seconds (12.0));
+#endif
+
+ Simulator::Stop (Seconds (100.0));
+ Simulator::Run ();
+ Simulator::Destroy ();
+
+ return 0;
+}
diff -r 3aa67e451203 model/dce-epoll.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/model/dce-epoll.cc Wed Jul 16 12:55:00 2014 +0900
@@ -0,0 +1,161 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Hajime Tazaki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Hajime Tazaki <[email protected]>
+ */
+#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 << fd << event);
+ NS_ASSERT (Current () != 0);
+ Thread *current = Current ();
+
+ UnixFd *unixFd = current->process->openFiles[epfd]->GetFileInc ();
+ LinuxEpollFd *epollFd = (LinuxEpollFd *)unixFd;
+ struct epoll_event *ev;
+
+ switch (op)
+ {
+ case EPOLL_CTL_ADD:
+ ev = (struct epoll_event *)malloc (sizeof (struct epoll_event));
+ memcpy (ev, event, sizeof (struct epoll_event));
+ ev->data.fd = fd;
+ epollFd->evs[fd] = ev;
+ break;
+ case EPOLL_CTL_MOD:
+ memcpy (ev, event, sizeof (struct epoll_event));
+ ev->data.fd = fd;
+ epollFd->evs[fd] = ev;
+ break;
+ case EPOLL_CTL_DEL:
+ ev = epollFd->evs[fd];
+ epollFd->evs.erase (fd);
+ free (ev);
+ 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;
+ }
+
+ NS_LOG_INFO ("set poll " << j << pevent);
+ 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))
+ {
+ memcpy (events, epollFd->evs[fd], sizeof (struct epoll_event));
+ NS_LOG_INFO ("epoll woke up for read with " << fd);
+ pollRet++;
+ }
+ if (POLLOUT & pollFd[j].revents)
+ {
+ memcpy (events, epollFd->evs[fd], sizeof (struct epoll_event));
+ // *events = *epollFd->evs[fd];
+ // events->data.fd = fd;
+ NS_LOG_INFO ("epoll woke up for write with " << fd);
+ pollRet++;
+ }
+ if (POLLPRI & pollFd[j].revents)
+ {
+ memcpy (events, epollFd->evs[fd], sizeof (struct epoll_event));
+ NS_LOG_INFO ("epoll woke up for other with " << fd);
+ // *events = *epollFd->evs[fd];
+ // events->data.fd = fd;
+ pollRet++;
+ }
+
+ events++;
+ }
+ }
+
+ return pollRet;
+}
+
diff -r 3aa67e451203 model/dce-pthread-mutex.cc
--- a/model/dce-pthread-mutex.cc Tue Jul 15 19:53:51 2014 +0900
+++ b/model/dce-pthread-mutex.cc Wed Jul 16 12:55:00 2014 +0900
@@ -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 -r 3aa67e451203 model/dce-pthread.cc
--- a/model/dce-pthread.cc Tue Jul 15 19:53:51 2014 +0900
+++ b/model/dce-pthread.cc Wed Jul 16 12:55:00 2014 +0900
@@ -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 -r 3aa67e451203 model/dce-signal.h
--- a/model/dce-signal.h Tue Jul 15 19:53:51 2014 +0900
+++ b/model/dce-signal.h Wed Jul 16 12:55:00 2014 +0900
@@ -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 -r 3aa67e451203 model/dce-stdlib.cc
--- a/model/dce-stdlib.cc Tue Jul 15 19:53:51 2014 +0900
+++ b/model/dce-stdlib.cc Wed Jul 16 12:55:00 2014 +0900
@@ -118,8 +118,7 @@
}
FILE * dce_tmpfile(void) {
- int fd = dce_mkstemp ("temp");
- return dce_fdopen(fd, "w+");
+ return dce_fopen("temp.dat", "w+");
}
int dce_rename (const char *oldpath, const char *newpath)
diff -r 3aa67e451203 model/libc-dce.cc
--- a/model/libc-dce.cc Tue Jul 15 19:53:51 2014 +0900
+++ b/model/libc-dce.cc Wed Jul 16 12:55:00 2014 +0900
@@ -13,6 +13,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"
@@ -98,6 +99,7 @@
#include <termio.h>
#include <math.h>
#include <assert.h>
+#include <link.h>
extern void __cxa_finalize (void *d);
extern int __cxa_atexit (void (*func)(void *), void *arg, void *d);
diff -r 3aa67e451203 model/libc-ns3.h
--- a/model/libc-ns3.h Tue Jul 15 19:53:51 2014 +0900
+++ b/model/libc-ns3.h Wed Jul 16 12:55:00 2014 +0900
@@ -99,6 +99,7 @@
#ifdef HAVE___SECURE_GETENV
NATIVE (__secure_getenv)
#endif
+NATIVE (secure_getenv)
DCE (putenv)
DCE (setenv)
DCE (unsetenv)
@@ -278,7 +279,7 @@
DCE (fsetpos)
DCE (printf)
NATIVE (fprintf)
-NATIVE (sprintf)
+NATIVE_WITH_ALIAS2 (sprintf, __sprintf_chk)
DCE (asprintf)
DCE (vasprintf)
NATIVE (dprintf)
@@ -377,6 +378,11 @@
// POLL.H
DCE (poll)
+// SYS/EPOLL.H
+DCE (epoll_create)
+DCE (epoll_ctl)
+DCE (epoll_wait)
+
// SIGNAL.H
DCE (signal)
DCE (sigaction)
@@ -419,6 +425,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)
@@ -472,6 +479,7 @@
NATIVE (isdigit)
NATIVE (isxdigit)
NATIVE (isalnum)
+NATIVE (isspace)
// SYS/TIMERFD.H
DCE (timerfd_create)
@@ -610,6 +618,7 @@
NATIVE (ceil)
NATIVE (floor)
+NATIVE (dl_iterate_phdr)
#undef DCE
#undef DCET
#undef DCE_EXPLICIT
diff -r 3aa67e451203 model/linux-epoll-fd.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/model/linux-epoll-fd.cc Wed Jul 16 12:55:00 2014 +0900
@@ -0,0 +1,298 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Hajime Tazaki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Hajime Tazaki <[email protected]>
+ */
+
+#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 -r 3aa67e451203 model/linux-epoll-fd.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/model/linux-epoll-fd.h Wed Jul 16 12:55:00 2014 +0900
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Hajime Tazaki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Hajime Tazaki <[email protected]>
+ */
+
+#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 -r 3aa67e451203 model/pipe-fd.cc
--- a/model/pipe-fd.cc Tue Jul 15 19:53:51 2014 +0900
+++ b/model/pipe-fd.cc Wed Jul 16 12:55:00 2014 +0900
@@ -384,6 +384,10 @@
m_statusFlags = arg;
return 0;
break;
+ case F_GETFD:
+ case F_SETFD:
+ NS_LOG_WARN ("GETFD/SETFD ot implemented on pipe");
+ break;
default:
NS_FATAL_ERROR ("fcntl not implemented on pipe");
return -1;
diff -r 3aa67e451203 model/sys/dce-epoll.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/model/sys/dce-epoll.h Wed Jul 16 12:55:00 2014 +0900
@@ -0,0 +1,39 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014 Hajime Tazaki
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Hajime Tazaki <[email protected]>
+ */
+
+#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 -r 3aa67e451203 test/dce-manager-test.cc
--- a/test/dce-manager-test.cc Tue Jul 15 19:53:51 2014 +0900
+++ b/test/dce-manager-test.cc Wed Jul 16 12:55:00 2014 +0900
@@ -201,6 +201,7 @@
{ "test-random", 0, "", false, false, NS3_STACK|LINUX_STACK|FREEBSD_STACK},
{ "test-local-socket", 0, "", false, false, NS3_STACK|LINUX_STACK|FREEBSD_STACK},
{ "test-poll", 3200, "", true, false, NS3_STACK|LINUX_STACK},
+ { "test-epoll", 3200, "", true, false, NS3_STACK|LINUX_STACK},
{ "test-tcp-socket", 320, "", true, false, NS3_STACK|LINUX_STACK},
{ "test-exec", 0, "", false, true, NS3_STACK|LINUX_STACK|FREEBSD_STACK},
{ "test-raw-socket", 320, "", true, false, NS3_STACK|LINUX_STACK|FREEBSD_STACK},
diff -r 3aa67e451203 test/test-epoll.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/test-epoll.cc Wed Jul 16 12:55:00 2014 +0900
@@ -0,0 +1,163 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/epoll.h>
+#include "test-macros.h"
+
+//
+// http://linuxjm.sourceforge.jp/html/LDP_man-pages/man7/epoll.7.html
+//
+#define BUF_LEN ((size_t) 1024 * 1000)
+#define MAX_EVENTS 10
+static char* readBuf[BUF_LEN];
+static char* writeBuf[BUF_LEN];
+
+static void *
+server1 (void *arg)
+{
+ struct epoll_event ev, events[MAX_EVENTS];
+ int conn_sock, nfds, epollfd;
+ /* Set up listening socket, 'listen_sock' (socket(),
+ bind(), listen()) */
+ int sock, sockin, sockin2;
+ struct sockaddr_in addr, local;
+ int res;
+ int on = 1, n;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ TEST_ASSERT (sock >= 0);
+
+ res = inet_aton ("127.0.0.1", &(addr.sin_addr));
+ TEST_ASSERT_EQUAL (res, 1);
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (1234);
+ res = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+
+ res = bind (sock, (struct sockaddr *) &addr, sizeof(addr));
+ printf ("Server1: bind -> %d, errno:%d\n ", res, errno);
+ TEST_ASSERT_EQUAL (res, 0);
+
+ res = listen (sock, 10);
+ TEST_ASSERT_EQUAL (res, 0);
+
+ // epoll
+ epollfd = epoll_create(10);
+ TEST_ASSERT_UNEQUAL (epollfd, -1);
+
+ ev.events = EPOLLIN;
+ ev.data.fd = sock;
+ res = epoll_ctl (epollfd, EPOLL_CTL_ADD, sock, &ev);
+ TEST_ASSERT_UNEQUAL (res, -1);
+
+ for (;;)
+ {
+ printf ("epoll wait\n");
+ nfds = epoll_wait (epollfd, events, MAX_EVENTS, -1);
+ TEST_ASSERT_UNEQUAL (res, -1);
+
+ printf ("epoll wake\n");
+ for (n = 0; n < nfds; ++n)
+ {
+ if (events[n].data.fd == sock)
+ {
+ conn_sock = accept (sock, NULL, NULL);
+ TEST_ASSERT_UNEQUAL (conn_sock, -1);
+
+ // setnonblocking(conn_sock);
+ ev.events = EPOLLIN | EPOLLET;
+ ev.data.fd = conn_sock;
+ res = epoll_ctl (epollfd, EPOLL_CTL_ADD, conn_sock, &ev);
+ TEST_ASSERT_UNEQUAL (conn_sock, -1);
+ }
+ else
+ {
+ res = read (events[n].data.fd, readBuf, BUF_LEN);
+ TEST_ASSERT_EQUAL (res, 64);
+ }
+ }
+ }
+ return arg;
+}
+
+static void *
+client1 (void *arg)
+{
+ int sock, sock2;
+ struct sockaddr_in addr;
+ int res;
+
+ sock = socket (AF_INET, SOCK_STREAM, 0);
+ TEST_ASSERT (sock >= 0);
+ sock2 = socket (AF_INET, SOCK_STREAM, 0);
+ TEST_ASSERT (sock2 >= 0);
+
+ res = inet_aton ("127.0.0.1", &(addr.sin_addr));
+ TEST_ASSERT_EQUAL (res, 1);
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons (1234);
+
+ sleep (1);
+
+ res = connect (sock, (struct sockaddr *) &addr, sizeof(addr));
+ TEST_ASSERT_EQUAL (res, 0);
+ // sleep (1);
+ // res = connect (sock2, (struct sockaddr *) &addr, sizeof(addr));
+ // TEST_ASSERT_EQUAL (res, 0);
+
+ // Can I Write ?
+ res = write (sock, writeBuf, 64);
+ TEST_ASSERT_EQUAL (res, 64);
+
+ sleep (5);
+ // Read ?
+ // TEST_ASSERT (test_poll_read (sock, 10, true));
+
+ // res = read (sock2, readBuf, BUF_LEN);
+ printf ("Client1: write -> %d \n ",res);
+
+ close (sock);
+ close (sock2);
+
+ printf ("Client1: end\n ");
+
+ return arg;
+}
+
+static void
+launch (void *(*clientStart)(void *), void *(*serverStart)(void *))
+{
+ int status;
+ pthread_t theClient;
+ pthread_t theServer;
+
+ printf ("launch\n ");
+
+ status = pthread_create (&theServer, NULL, serverStart, 0);
+ TEST_ASSERT_EQUAL (status, 0);
+
+ status = pthread_create (&theClient, NULL, clientStart, 0);
+ TEST_ASSERT_EQUAL (status, 0);
+
+ void *threadResult = 0;
+
+ status = pthread_join (theClient, &threadResult);
+ TEST_ASSERT_EQUAL (status, 0);
+
+ status = pthread_join (theServer, &threadResult);
+ TEST_ASSERT_EQUAL (status, 0);
+
+ fflush (stdout);
+ fflush (stderr);
+}
+
+int
+main (int argc, char *argv[])
+{
+
+ launch (server1, client1);
+}
diff -r 3aa67e451203 wscript
--- a/wscript Tue Jul 15 19:53:51 2014 +0900
+++ b/wscript Wed Jul 16 12:55:00 2014 +0900
@@ -262,6 +262,7 @@
['test-fork', []],
['test-local-socket', ['PTHREAD']],
['test-poll', ['PTHREAD']],
+ ['test-epoll', []],
['test-tcp-socket', ['PTHREAD']],
['test-exec', []],
['test-exec-target-1', []],
@@ -460,6 +461,9 @@
target='bin/dce-freebsd',
source=['example/dce-freebsd.cc'])
+ module.add_example(needed = ['core', 'network', 'dce', 'wifi', 'point-to-point', 'csma'],
+ target='bin/dce-ovs',
+ source=['example/dce-ovs.cc'])
# Add a script to build system
def build_a_script(bld, name, needed = [], **kw):
@@ -547,6 +551,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',
@@ -592,6 +597,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