X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fethertap.cc;h=85d6370beefd8c0f43359176bcf5766efa533055;hb=da3c3bfa98e7cf81010a476b0b6ceba4c936f417;hp=0b6ab97fc91fe0170f530f92b4935140dd14d8e3;hpb=abc76f20cb98c90e8dab416dd16dfd4a954013ba;p=gem5.git diff --git a/src/dev/ethertap.cc b/src/dev/ethertap.cc index 0b6ab97fc..85d6370be 100644 --- a/src/dev/ethertap.cc +++ b/src/dev/ethertap.cc @@ -50,7 +50,6 @@ #include "dev/etherint.hh" #include "dev/etherpkt.hh" #include "dev/ethertap.hh" -#include "params/EtherTap.hh" using namespace std; @@ -127,13 +126,17 @@ class TapEvent : public PollEvent virtual void process(int revent) { tap->process(revent); } }; -EtherTap::EtherTap(const string &name, EtherDump *d, int port, int bufsz) - : EtherInt(name), event(NULL), socket(-1), buflen(bufsz), dump(d), - txEvent(this) +EtherTap::EtherTap(const Params *p) + : EtherObject(p), event(NULL), socket(-1), buflen(p->bufsz), dump(p->dump), + interface(NULL), txEvent(this) { + if (ListenSocket::allDisabled()) + fatal("All listeners are disabled! EtherTap can't work!"); + buffer = new char[buflen]; - listener = new TapListener(this, port); + listener = new TapListener(this, p->port); listener->listen(); + interface = new EtherTapInt(name() + ".interface", this); } EtherTap::~EtherTap() @@ -179,10 +182,14 @@ EtherTap::recvPacket(EthPacketPtr packet) DPRINTF(Ethernet, "EtherTap output len=%d\n", packet->length); DDUMP(EthernetData, packet->data, packet->length); uint32_t len = htonl(packet->length); - write(socket, &len, sizeof(len)); - write(socket, packet->data, packet->length); + ssize_t ret = write(socket, &len, sizeof(len)); + if (ret != sizeof(len)) + return false; + ret = write(socket, packet->data, packet->length); + if (ret != packet->length) + return false; - recvDone(); + interface->recvDone(); return true; } @@ -235,11 +242,11 @@ EtherTap::process(int revent) DPRINTF(Ethernet, "EtherTap input len=%d\n", packet->length); DDUMP(EthernetData, packet->data, packet->length); - if (!sendPacket(packet)) { + if (!interface->sendPacket(packet)) { DPRINTF(Ethernet, "bus busy...buffer for retransmission\n"); packetBuffer.push(packet); if (!txEvent.scheduled()) - txEvent.schedule(curTick + retryTime); + schedule(txEvent, curTick + retryTime); } else if (dump) { dump->dump(packet); } @@ -253,7 +260,7 @@ EtherTap::retransmit() return; EthPacketPtr packet = packetBuffer.front(); - if (sendPacket(packet)) { + if (interface->sendPacket(packet)) { if (dump) dump->dump(packet); DPRINTF(Ethernet, "EtherTap retransmit\n"); @@ -262,9 +269,21 @@ EtherTap::retransmit() } if (!packetBuffer.empty() && !txEvent.scheduled()) - txEvent.schedule(curTick + retryTime); + schedule(txEvent, curTick + retryTime); +} + +EtherInt* +EtherTap::getEthPort(const std::string &if_name, int idx) +{ + if (if_name == "tap") { + if (interface->getPeer()) + panic("Interface already connected to\n"); + return interface; + } + return NULL; } + //===================================================================== void @@ -316,12 +335,5 @@ EtherTap::unserialize(Checkpoint *cp, const std::string §ion) EtherTap * EtherTapParams::create() { - EtherTap *tap = new EtherTap(name, dump, port, bufsz); - - if (peer) { - tap->setPeer(peer); - peer->setPeer(tap); - } - - return tap; + return new EtherTap(this); }