diff options
Diffstat (limited to 'src/dev')
-rw-r--r-- | src/dev/net/Ethernet.py | 9 | ||||
-rw-r--r-- | src/dev/net/ethertap.cc | 74 | ||||
-rw-r--r-- | src/dev/net/ethertap.hh | 31 |
3 files changed, 114 insertions, 0 deletions
diff --git a/src/dev/net/Ethernet.py b/src/dev/net/Ethernet.py index 68867c00f..71665c564 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 @@ class EtherTapBase(EtherObject): 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 f08de0ebf..0c027b621 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 @@ EtherTapStub::sendReal(const void *data, size_t len) } +#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 718af1808..96cc4710c 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 @@ class EtherTapStub : public EtherTapBase }; +#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__ |