Gabe Black has submitted this change and it was merged. (
https://gem5-review.googlesource.com/3646 )
Change subject: dev: Add a version of EtherTap which uses the tap driver.
......................................................................
dev: Add a version of EtherTap which uses the tap driver.
The object is called EtherTap (as opposed to EtherTapStub, what the former
EtherTap was renamed to), and its existance is gated on the linux/if_tun.h
header file existing. That's probably overly strict, but it will hopefully
be minimally likely to break the build for other systems.
Change-Id: Ie03507fadf0d843a4d4d52f283c44a416c6f2a74
Reviewed-on: https://gem5-review.googlesource.com/3646
Reviewed-by: Nathan Binkert <[email protected]>
Maintainer: Nathan Binkert <[email protected]>
---
M SConstruct
M src/dev/net/Ethernet.py
M src/dev/net/ethertap.cc
M src/dev/net/ethertap.hh
4 files changed, 127 insertions(+), 0 deletions(-)
Approvals:
Nathan Binkert: Looks good to me, approved; Looks good to me, approved
diff --git a/SConstruct b/SConstruct
index 65179f1..ef7af0f 100755
--- a/SConstruct
+++ b/SConstruct
@@ -1101,6 +1101,11 @@
print "Info: Compatible header file <linux/kvm.h> not found, " \
"disabling KVM support."
+# Check if the TUN/TAP driver is available.
+have_tuntap = conf.CheckHeader('linux/if_tun.h', '<>')
+if not have_tuntap:
+ print "Info: Compatible header file <linux/if_tun.h> not found."
+
# x86 needs support for xsave. We test for the structure here since we
# won't be able to run new tests by the time we know which ISA we're
# targeting.
@@ -1233,6 +1238,9 @@
BoolVariable('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
BoolVariable('CP_ANNOTATE', 'Enable critical path annotation
capability', False),
BoolVariable('USE_KVM', 'Enable hardware virtualized (KVM) CPU
models', have_kvm),
+ BoolVariable('USE_TUNTAP',
+ 'Enable using a tap device to bridge to the host network',
+ have_tuntap),
BoolVariable('BUILD_GPU', 'Build the compute-GPU model', False),
EnumVariable('PROTOCOL', 'Coherence protocol for Ruby', 'None',
all_protocols),
@@ -1477,6 +1485,11 @@
"target ISA combination"
env['USE_KVM'] = False
+ if env['USE_TUNTAP']:
+ if not have_tuntap:
+ print "Warning: Can't connect EtherTap with a tap device."
+ env['USE_TUNTAP'] = False
+
if env['BUILD_GPU']:
env.Append(CPPDEFINES=['BUILD_GPU'])
diff --git a/src/dev/net/Ethernet.py b/src/dev/net/Ethernet.py
index 68867c0..71665c5 100644
--- a/src/dev/net/Ethernet.py
+++ b/src/dev/net/Ethernet.py
@@ -38,6 +38,7 @@
#
# Authors: Nathan Binkert
+from m5.defines import buildEnv
from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
@@ -103,6 +104,14 @@
dump = Param.EtherDump(NULL, "dump object")
tap = SlavePort("Ethernet interface to connect to gem5's network")
+if buildEnv['USE_TUNTAP']:
+ class EtherTap(EtherTapBase):
+ type = 'EtherTap'
+ cxx_header = "dev/net/ethertap.hh"
+ tun_clone_device = Param.String('/dev/net/tun',
+ "Path to the tun clone device
node")
+ tap_device_name = Param.String('gem5-tap', "Tap device name")
+
class EtherTapStub(EtherTapBase):
type = 'EtherTapStub'
cxx_header = "dev/net/ethertap.hh"
diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc
index f08de0e..0c027b6 100644
--- a/src/dev/net/ethertap.cc
+++ b/src/dev/net/ethertap.cc
@@ -38,9 +38,24 @@
#include <sys/param.h>
#endif
+
+#if USE_TUNTAP && defined(__linux__)
+#if 1 // Hide from the style checker since these have to be out of order.
+#include <sys/socket.h> // Has to be included before if.h for some reason.
+
+#endif
+
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+#endif
+
+#include <fcntl.h>
#include <netinet/in.h>
+#include <sys/ioctl.h>
#include <unistd.h>
+#include <cstring>
#include <deque>
#include <string>
@@ -377,6 +392,65 @@
}
+#if USE_TUNTAP
+
+EtherTap::EtherTap(const Params *p) : EtherTapBase(p)
+{
+ int fd = open(p->tun_clone_device.c_str(), O_RDWR);
+ if (fd < 0)
+ panic("Couldn't open %s.\n", p->tun_clone_device);
+
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ strncpy(ifr.ifr_name, p->tap_device_name.c_str(), IFNAMSIZ);
+
+ if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0)
+ panic("Failed to access tap device %s.\n", ifr.ifr_name);
+ // fd now refers to the tap device.
+ tap = fd;
+ pollFd(tap);
+}
+
+EtherTap::~EtherTap()
+{
+ stopPolling();
+ close(tap);
+ tap = -1;
+}
+
+void
+EtherTap::recvReal(int revent)
+{
+ if (revent & POLLERR)
+ panic("Error polling for tap data.\n");
+
+ if (!(revent & POLLIN))
+ return;
+
+ ssize_t ret = read(tap, buffer, buflen);
+ if (ret < 0)
+ panic("Failed to read from tap device.\n");
+
+ sendSimulated(buffer, ret);
+}
+
+bool
+EtherTap::sendReal(const void *data, size_t len)
+{
+ if (write(tap, data, len) != len)
+ panic("Failed to write data to tap device.\n");
+ return true;
+}
+
+EtherTap *
+EtherTapParams::create()
+{
+ return new EtherTap(this);
+}
+
+#endif
+
EtherTapStub *
EtherTapStubParams::create()
{
diff --git a/src/dev/net/ethertap.hh b/src/dev/net/ethertap.hh
index 718af18..96cc471 100644
--- a/src/dev/net/ethertap.hh
+++ b/src/dev/net/ethertap.hh
@@ -39,9 +39,16 @@
#include <string>
#include "base/pollevent.hh"
+#include "config/use_tuntap.hh"
#include "dev/net/etherint.hh"
#include "dev/net/etherobject.hh"
#include "dev/net/etherpkt.hh"
+
+#if USE_TUNTAP
+#include "params/EtherTap.hh"
+
+#endif
+
#include "params/EtherTapStub.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
@@ -176,4 +183,28 @@
};
+#if USE_TUNTAP
+class EtherTap : public EtherTapBase
+{
+ public:
+ typedef EtherTapParams Params;
+ EtherTap(const Params *p);
+ ~EtherTap();
+
+ const Params *
+ params() const
+ {
+ return dynamic_cast<const Params *>(_params);
+ }
+
+
+ protected:
+ int tap;
+
+ void recvReal(int revent) override;
+ bool sendReal(const void *data, size_t len) override;
+};
+#endif
+
+
#endif // __DEV_NET_ETHERTAP_HH__
--
To view, visit https://gem5-review.googlesource.com/3646
To unsubscribe, visit https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Ie03507fadf0d843a4d4d52f283c44a416c6f2a74
Gerrit-Change-Number: 3646
Gerrit-PatchSet: 4
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-Reviewer: Gabe Black <[email protected]>
Gerrit-Reviewer: Nathan Binkert <[email protected]>
Gerrit-CC: Jason Lowe-Power <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev