X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fdev%2Fethertap.cc;h=85d6370beefd8c0f43359176bcf5766efa533055;hb=35a85a4e86143c5bf23d5b74c14856792a0a624c;hp=2d72383c5c6f83f0d55fbc8b8d28a43d1041a029;hpb=984c2a4ff677803ff7687a178f1dceb1f0204c30;p=gem5.git diff --git a/src/dev/ethertap.cc b/src/dev/ethertap.cc index 2d72383c5..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 "sim/builder.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() @@ -178,11 +181,15 @@ EtherTap::recvPacket(EthPacketPtr packet) DPRINTF(Ethernet, "EtherTap output len=%d\n", packet->length); DDUMP(EthernetData, packet->data, packet->length); - u_int32_t len = htonl(packet->length); - write(socket, &len, sizeof(len)); - write(socket, packet->data, packet->length); + uint32_t len = htonl(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; } @@ -199,11 +206,11 @@ EtherTap::process(int revent) return; } - char *data = buffer + sizeof(u_int32_t); + char *data = buffer + sizeof(uint32_t); if (!(revent & POLLIN)) return; - if (buffer_offset < data_len + sizeof(u_int32_t)) { + if (buffer_offset < data_len + sizeof(uint32_t)) { int len = read(socket, buffer + buffer_offset, buflen - buffer_offset); if (len == 0) { detach(); @@ -213,33 +220,33 @@ EtherTap::process(int revent) buffer_offset += len; if (data_len == 0) - data_len = ntohl(*(u_int32_t *)buffer); + data_len = ntohl(*(uint32_t *)buffer); DPRINTF(Ethernet, "Received data from peer: len=%d buffer_offset=%d " "data_len=%d\n", len, buffer_offset, data_len); } - while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) { + while (data_len != 0 && buffer_offset >= data_len + sizeof(uint32_t)) { EthPacketPtr packet; packet = new EthPacketData(data_len); packet->length = data_len; memcpy(packet->data, data, data_len); - buffer_offset -= data_len + sizeof(u_int32_t); + buffer_offset -= data_len + sizeof(uint32_t); assert(buffer_offset >= 0); if (buffer_offset > 0) { memmove(buffer, data + data_len, buffer_offset); - data_len = ntohl(*(u_int32_t *)buffer); + data_len = ntohl(*(uint32_t *)buffer); } else data_len = 0; 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 @@ -313,35 +332,8 @@ EtherTap::unserialize(Checkpoint *cp, const std::string §ion) //===================================================================== -BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherTap) - - SimObjectParam peer; - SimObjectParam dump; - Param port; - Param bufsz; - -END_DECLARE_SIM_OBJECT_PARAMS(EtherTap) - -BEGIN_INIT_SIM_OBJECT_PARAMS(EtherTap) - - INIT_PARAM_DFLT(peer, "peer interface", NULL), - INIT_PARAM_DFLT(dump, "object to dump network packets to", NULL), - INIT_PARAM_DFLT(port, "tap port", 3500), - INIT_PARAM_DFLT(bufsz, "tap buffer size", 10000) - -END_INIT_SIM_OBJECT_PARAMS(EtherTap) - - -CREATE_SIM_OBJECT(EtherTap) +EtherTap * +EtherTapParams::create() { - EtherTap *tap = new EtherTap(getInstanceName(), dump, port, bufsz); - - if (peer) { - tap->setPeer(peer); - peer->setPeer(tap); - } - - return tap; + return new EtherTap(this); } - -REGISTER_SIM_OBJECT("EtherTap", EtherTap)