etherswitch.hh revision 12087
111317Sm.alian1369@gmail.com/* 211317Sm.alian1369@gmail.com * Copyright (c) 2014 The Regents of The University of Michigan 311317Sm.alian1369@gmail.com * All rights reserved. 411317Sm.alian1369@gmail.com * 511317Sm.alian1369@gmail.com * Redistribution and use in source and binary forms, with or without 611317Sm.alian1369@gmail.com * modification, are permitted provided that the following conditions are 711317Sm.alian1369@gmail.com * met: redistributions of source code must retain the above copyright 811317Sm.alian1369@gmail.com * notice, this list of conditions and the following disclaimer; 911317Sm.alian1369@gmail.com * redistributions in binary form must reproduce the above copyright 1011317Sm.alian1369@gmail.com * notice, this list of conditions and the following disclaimer in the 1111317Sm.alian1369@gmail.com * documentation and/or other materials provided with the distribution; 1211317Sm.alian1369@gmail.com * neither the name of the copyright holders nor the names of its 1311317Sm.alian1369@gmail.com * contributors may be used to endorse or promote products derived from 1411317Sm.alian1369@gmail.com * this software without specific prior written permission. 1511317Sm.alian1369@gmail.com * 1611317Sm.alian1369@gmail.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1711317Sm.alian1369@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1811317Sm.alian1369@gmail.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1911317Sm.alian1369@gmail.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2011317Sm.alian1369@gmail.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2111317Sm.alian1369@gmail.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2211317Sm.alian1369@gmail.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2311317Sm.alian1369@gmail.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2411317Sm.alian1369@gmail.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2511317Sm.alian1369@gmail.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2611317Sm.alian1369@gmail.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711317Sm.alian1369@gmail.com * 2811317Sm.alian1369@gmail.com * Authors: Anthony Gutierrez 2911317Sm.alian1369@gmail.com * Mohammad Alian 3011317Sm.alian1369@gmail.com */ 3111317Sm.alian1369@gmail.com 3211317Sm.alian1369@gmail.com/* @file 3311317Sm.alian1369@gmail.com * Device model for an ethernet switch 3411317Sm.alian1369@gmail.com */ 3511317Sm.alian1369@gmail.com 3611317Sm.alian1369@gmail.com#ifndef __DEV_ETHERSWITCH_HH__ 3711317Sm.alian1369@gmail.com#define __DEV_ETHERSWITCH_HH__ 3811317Sm.alian1369@gmail.com 3911533Sm.alian1369@gmail.com#include <map> 4011533Sm.alian1369@gmail.com#include <set> 4111317Sm.alian1369@gmail.com 4211317Sm.alian1369@gmail.com#include "base/inet.hh" 4311317Sm.alian1369@gmail.com#include "dev/net/etherint.hh" 4411317Sm.alian1369@gmail.com#include "dev/net/etherlink.hh" 4511317Sm.alian1369@gmail.com#include "dev/net/etherobject.hh" 4611317Sm.alian1369@gmail.com#include "dev/net/etherpkt.hh" 4711317Sm.alian1369@gmail.com#include "dev/net/pktfifo.hh" 4811317Sm.alian1369@gmail.com#include "params/EtherSwitch.hh" 4911317Sm.alian1369@gmail.com#include "sim/eventq.hh" 5011317Sm.alian1369@gmail.com 5111317Sm.alian1369@gmail.comclass EtherSwitch : public EtherObject 5211317Sm.alian1369@gmail.com{ 5311317Sm.alian1369@gmail.com public: 5411317Sm.alian1369@gmail.com typedef EtherSwitchParams Params; 5511317Sm.alian1369@gmail.com 5611317Sm.alian1369@gmail.com EtherSwitch(const Params *p); 5711317Sm.alian1369@gmail.com ~EtherSwitch(); 5811317Sm.alian1369@gmail.com 5911317Sm.alian1369@gmail.com const Params * params() const 6011317Sm.alian1369@gmail.com { 6111317Sm.alian1369@gmail.com return dynamic_cast<const Params*>(_params); 6211317Sm.alian1369@gmail.com } 6311317Sm.alian1369@gmail.com 6411341Sandreas.hansson@arm.com EtherInt *getEthPort(const std::string &if_name, int idx) override; 6511317Sm.alian1369@gmail.com 6611317Sm.alian1369@gmail.com protected: 6711317Sm.alian1369@gmail.com /** 6811317Sm.alian1369@gmail.com * Model for an Ethernet switch port 6911317Sm.alian1369@gmail.com */ 7011533Sm.alian1369@gmail.com class Interface : public EtherInt, public Serializable 7111317Sm.alian1369@gmail.com { 7211317Sm.alian1369@gmail.com public: 7311317Sm.alian1369@gmail.com Interface(const std::string &name, EtherSwitch *_etherSwitch, 7411317Sm.alian1369@gmail.com uint64_t outputBufferSize, Tick delay, Tick delay_var, 7511533Sm.alian1369@gmail.com double rate, unsigned id); 7611317Sm.alian1369@gmail.com /** 7711317Sm.alian1369@gmail.com * When a packet is received from a device, route it 7811317Sm.alian1369@gmail.com * through an (several) output queue(s) 7911317Sm.alian1369@gmail.com */ 8011317Sm.alian1369@gmail.com bool recvPacket(EthPacketPtr packet); 8111317Sm.alian1369@gmail.com /** 8211317Sm.alian1369@gmail.com * enqueue packet to the outputFifo 8311317Sm.alian1369@gmail.com */ 8411533Sm.alian1369@gmail.com void enqueue(EthPacketPtr packet, unsigned senderId); 8511317Sm.alian1369@gmail.com void sendDone() {} 8611317Sm.alian1369@gmail.com Tick switchingDelay(); 8711317Sm.alian1369@gmail.com 8811317Sm.alian1369@gmail.com Interface* lookupDestPort(Net::EthAddr destAddr); 8911317Sm.alian1369@gmail.com void learnSenderAddr(Net::EthAddr srcMacAddr, Interface *sender); 9011317Sm.alian1369@gmail.com 9111533Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const; 9211533Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp); 9311317Sm.alian1369@gmail.com 9411317Sm.alian1369@gmail.com private: 9511317Sm.alian1369@gmail.com const double ticksPerByte; 9611317Sm.alian1369@gmail.com const Tick switchDelay; 9711317Sm.alian1369@gmail.com const Tick delayVar; 9811533Sm.alian1369@gmail.com const unsigned interfaceId; 9911533Sm.alian1369@gmail.com 10011317Sm.alian1369@gmail.com EtherSwitch *parent; 10111533Sm.alian1369@gmail.com protected: 10211533Sm.alian1369@gmail.com struct PortFifoEntry : public Serializable 10311533Sm.alian1369@gmail.com { 10411533Sm.alian1369@gmail.com PortFifoEntry(EthPacketPtr pkt, Tick recv_tick, unsigned id) 10511533Sm.alian1369@gmail.com : packet(pkt), recvTick(recv_tick), srcId(id) {} 10611533Sm.alian1369@gmail.com 10711533Sm.alian1369@gmail.com EthPacketPtr packet; 10811533Sm.alian1369@gmail.com Tick recvTick; 10911533Sm.alian1369@gmail.com // id of the port that the packet has been received from 11011533Sm.alian1369@gmail.com unsigned srcId; 11111533Sm.alian1369@gmail.com ~PortFifoEntry() 11211533Sm.alian1369@gmail.com { 11311533Sm.alian1369@gmail.com packet = nullptr; 11411533Sm.alian1369@gmail.com recvTick = 0; 11511533Sm.alian1369@gmail.com srcId = 0; 11611533Sm.alian1369@gmail.com } 11711533Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const; 11811533Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp); 11911533Sm.alian1369@gmail.com }; 12011533Sm.alian1369@gmail.com 12111533Sm.alian1369@gmail.com class PortFifo : public Serializable 12211533Sm.alian1369@gmail.com { 12311533Sm.alian1369@gmail.com protected: 12411533Sm.alian1369@gmail.com struct EntryOrder { 12511533Sm.alian1369@gmail.com bool operator() (const PortFifoEntry& lhs, 12611533Sm.alian1369@gmail.com const PortFifoEntry& rhs) const 12711533Sm.alian1369@gmail.com { 12811533Sm.alian1369@gmail.com if (lhs.recvTick == rhs.recvTick) 12911533Sm.alian1369@gmail.com return lhs.srcId < rhs.srcId; 13011533Sm.alian1369@gmail.com else 13111533Sm.alian1369@gmail.com return lhs.recvTick < rhs.recvTick; 13211533Sm.alian1369@gmail.com } 13311533Sm.alian1369@gmail.com }; 13411533Sm.alian1369@gmail.com std::set<PortFifoEntry, EntryOrder> fifo; 13511533Sm.alian1369@gmail.com 13611533Sm.alian1369@gmail.com const std::string objName; 13711533Sm.alian1369@gmail.com const unsigned _maxsize; 13811533Sm.alian1369@gmail.com unsigned _size; 13911533Sm.alian1369@gmail.com 14011533Sm.alian1369@gmail.com public: 14111533Sm.alian1369@gmail.com PortFifo(const std::string &name, int max) 14211533Sm.alian1369@gmail.com :objName(name), _maxsize(max), _size(0) {} 14311533Sm.alian1369@gmail.com ~PortFifo() {} 14411533Sm.alian1369@gmail.com 14511533Sm.alian1369@gmail.com const std::string name() { return objName; } 14611533Sm.alian1369@gmail.com // Returns the available capacity of the fifo. 14711533Sm.alian1369@gmail.com // It can return a negative value because in "push" function 14811533Sm.alian1369@gmail.com // we first push the received packet into the fifo and then 14911533Sm.alian1369@gmail.com // check if we exceed the available capacity (if avail() < 0) 15011533Sm.alian1369@gmail.com // and remove packets from the end of fifo 15111533Sm.alian1369@gmail.com int avail() const { return _maxsize - _size; } 15211533Sm.alian1369@gmail.com 15311533Sm.alian1369@gmail.com EthPacketPtr front() { return fifo.begin()->packet; } 15411533Sm.alian1369@gmail.com bool empty() const { return _size == 0; } 15511533Sm.alian1369@gmail.com unsigned size() const { return _size; } 15611533Sm.alian1369@gmail.com 15711533Sm.alian1369@gmail.com /** 15811533Sm.alian1369@gmail.com * Push a packet into the fifo 15911533Sm.alian1369@gmail.com * and sort the packets with same recv tick by port id 16011533Sm.alian1369@gmail.com */ 16111533Sm.alian1369@gmail.com bool push(EthPacketPtr ptr, unsigned senderId); 16211533Sm.alian1369@gmail.com void pop(); 16311533Sm.alian1369@gmail.com void clear(); 16411533Sm.alian1369@gmail.com /** 16511533Sm.alian1369@gmail.com * Serialization stuff 16611533Sm.alian1369@gmail.com */ 16711533Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const; 16811533Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp); 16911533Sm.alian1369@gmail.com }; 17011317Sm.alian1369@gmail.com /** 17111317Sm.alian1369@gmail.com * output fifo at each interface 17211317Sm.alian1369@gmail.com */ 17311533Sm.alian1369@gmail.com PortFifo outputFifo; 17411317Sm.alian1369@gmail.com void transmit(); 17512087Sspwilson2@wisc.edu EventFunctionWrapper txEvent; 17611317Sm.alian1369@gmail.com }; 17711317Sm.alian1369@gmail.com 17811317Sm.alian1369@gmail.com struct SwitchTableEntry { 17911317Sm.alian1369@gmail.com Interface *interface; 18011317Sm.alian1369@gmail.com Tick lastUseTime; 18111317Sm.alian1369@gmail.com }; 18211317Sm.alian1369@gmail.com 18311317Sm.alian1369@gmail.com private: 18411317Sm.alian1369@gmail.com // time to live for MAC address mappings 18511317Sm.alian1369@gmail.com const double ttl; 18611317Sm.alian1369@gmail.com // all interfaces of the switch 18711317Sm.alian1369@gmail.com std::vector<Interface*> interfaces; 18811317Sm.alian1369@gmail.com // table that maps MAC address to interfaces 18911317Sm.alian1369@gmail.com std::map<uint64_t, SwitchTableEntry> forwardingTable; 19011317Sm.alian1369@gmail.com 19111317Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const override; 19211317Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp) override; 19311317Sm.alian1369@gmail.com}; 19411317Sm.alian1369@gmail.com 19511317Sm.alian1369@gmail.com#endif // __DEV_ETHERSWITCH_HH__ 196