etherswitch.hh revision 13784
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/etherpkt.hh" 4611317Sm.alian1369@gmail.com#include "dev/net/pktfifo.hh" 4711317Sm.alian1369@gmail.com#include "params/EtherSwitch.hh" 4811317Sm.alian1369@gmail.com#include "sim/eventq.hh" 4913766Sgabeblack@google.com#include "sim/sim_object.hh" 5011317Sm.alian1369@gmail.com 5113784Sgabeblack@google.comclass EtherSwitch : public SimObject 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 6413784Sgabeblack@google.com Port &getPort(const std::string &if_name, 6513784Sgabeblack@google.com PortID idx=InvalidPortID) override; 6611317Sm.alian1369@gmail.com 6711317Sm.alian1369@gmail.com protected: 6811317Sm.alian1369@gmail.com /** 6911317Sm.alian1369@gmail.com * Model for an Ethernet switch port 7011317Sm.alian1369@gmail.com */ 7111533Sm.alian1369@gmail.com class Interface : public EtherInt, public Serializable 7211317Sm.alian1369@gmail.com { 7311317Sm.alian1369@gmail.com public: 7411317Sm.alian1369@gmail.com Interface(const std::string &name, EtherSwitch *_etherSwitch, 7511317Sm.alian1369@gmail.com uint64_t outputBufferSize, Tick delay, Tick delay_var, 7611533Sm.alian1369@gmail.com double rate, unsigned id); 7711317Sm.alian1369@gmail.com /** 7811317Sm.alian1369@gmail.com * When a packet is received from a device, route it 7911317Sm.alian1369@gmail.com * through an (several) output queue(s) 8011317Sm.alian1369@gmail.com */ 8111317Sm.alian1369@gmail.com bool recvPacket(EthPacketPtr packet); 8211317Sm.alian1369@gmail.com /** 8311317Sm.alian1369@gmail.com * enqueue packet to the outputFifo 8411317Sm.alian1369@gmail.com */ 8511533Sm.alian1369@gmail.com void enqueue(EthPacketPtr packet, unsigned senderId); 8611317Sm.alian1369@gmail.com void sendDone() {} 8711317Sm.alian1369@gmail.com Tick switchingDelay(); 8811317Sm.alian1369@gmail.com 8911317Sm.alian1369@gmail.com Interface* lookupDestPort(Net::EthAddr destAddr); 9011317Sm.alian1369@gmail.com void learnSenderAddr(Net::EthAddr srcMacAddr, Interface *sender); 9111317Sm.alian1369@gmail.com 9211533Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const; 9311533Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp); 9411317Sm.alian1369@gmail.com 9511317Sm.alian1369@gmail.com private: 9611317Sm.alian1369@gmail.com const double ticksPerByte; 9711317Sm.alian1369@gmail.com const Tick switchDelay; 9811317Sm.alian1369@gmail.com const Tick delayVar; 9911533Sm.alian1369@gmail.com const unsigned interfaceId; 10011533Sm.alian1369@gmail.com 10111317Sm.alian1369@gmail.com EtherSwitch *parent; 10211533Sm.alian1369@gmail.com protected: 10311533Sm.alian1369@gmail.com struct PortFifoEntry : public Serializable 10411533Sm.alian1369@gmail.com { 10511533Sm.alian1369@gmail.com PortFifoEntry(EthPacketPtr pkt, Tick recv_tick, unsigned id) 10611533Sm.alian1369@gmail.com : packet(pkt), recvTick(recv_tick), srcId(id) {} 10711533Sm.alian1369@gmail.com 10811533Sm.alian1369@gmail.com EthPacketPtr packet; 10911533Sm.alian1369@gmail.com Tick recvTick; 11011533Sm.alian1369@gmail.com // id of the port that the packet has been received from 11111533Sm.alian1369@gmail.com unsigned srcId; 11211533Sm.alian1369@gmail.com ~PortFifoEntry() 11311533Sm.alian1369@gmail.com { 11411533Sm.alian1369@gmail.com packet = nullptr; 11511533Sm.alian1369@gmail.com recvTick = 0; 11611533Sm.alian1369@gmail.com srcId = 0; 11711533Sm.alian1369@gmail.com } 11811533Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const; 11911533Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp); 12011533Sm.alian1369@gmail.com }; 12111533Sm.alian1369@gmail.com 12211533Sm.alian1369@gmail.com class PortFifo : public Serializable 12311533Sm.alian1369@gmail.com { 12411533Sm.alian1369@gmail.com protected: 12511533Sm.alian1369@gmail.com struct EntryOrder { 12611533Sm.alian1369@gmail.com bool operator() (const PortFifoEntry& lhs, 12711533Sm.alian1369@gmail.com const PortFifoEntry& rhs) const 12811533Sm.alian1369@gmail.com { 12911533Sm.alian1369@gmail.com if (lhs.recvTick == rhs.recvTick) 13011533Sm.alian1369@gmail.com return lhs.srcId < rhs.srcId; 13111533Sm.alian1369@gmail.com else 13211533Sm.alian1369@gmail.com return lhs.recvTick < rhs.recvTick; 13311533Sm.alian1369@gmail.com } 13411533Sm.alian1369@gmail.com }; 13511533Sm.alian1369@gmail.com std::set<PortFifoEntry, EntryOrder> fifo; 13611533Sm.alian1369@gmail.com 13711533Sm.alian1369@gmail.com const std::string objName; 13811533Sm.alian1369@gmail.com const unsigned _maxsize; 13911533Sm.alian1369@gmail.com unsigned _size; 14011533Sm.alian1369@gmail.com 14111533Sm.alian1369@gmail.com public: 14211533Sm.alian1369@gmail.com PortFifo(const std::string &name, int max) 14311533Sm.alian1369@gmail.com :objName(name), _maxsize(max), _size(0) {} 14411533Sm.alian1369@gmail.com ~PortFifo() {} 14511533Sm.alian1369@gmail.com 14611533Sm.alian1369@gmail.com const std::string name() { return objName; } 14711533Sm.alian1369@gmail.com // Returns the available capacity of the fifo. 14811533Sm.alian1369@gmail.com // It can return a negative value because in "push" function 14911533Sm.alian1369@gmail.com // we first push the received packet into the fifo and then 15011533Sm.alian1369@gmail.com // check if we exceed the available capacity (if avail() < 0) 15111533Sm.alian1369@gmail.com // and remove packets from the end of fifo 15211533Sm.alian1369@gmail.com int avail() const { return _maxsize - _size; } 15311533Sm.alian1369@gmail.com 15411533Sm.alian1369@gmail.com EthPacketPtr front() { return fifo.begin()->packet; } 15511533Sm.alian1369@gmail.com bool empty() const { return _size == 0; } 15611533Sm.alian1369@gmail.com unsigned size() const { return _size; } 15711533Sm.alian1369@gmail.com 15811533Sm.alian1369@gmail.com /** 15911533Sm.alian1369@gmail.com * Push a packet into the fifo 16011533Sm.alian1369@gmail.com * and sort the packets with same recv tick by port id 16111533Sm.alian1369@gmail.com */ 16211533Sm.alian1369@gmail.com bool push(EthPacketPtr ptr, unsigned senderId); 16311533Sm.alian1369@gmail.com void pop(); 16411533Sm.alian1369@gmail.com void clear(); 16511533Sm.alian1369@gmail.com /** 16611533Sm.alian1369@gmail.com * Serialization stuff 16711533Sm.alian1369@gmail.com */ 16811533Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const; 16911533Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp); 17011533Sm.alian1369@gmail.com }; 17111317Sm.alian1369@gmail.com /** 17211317Sm.alian1369@gmail.com * output fifo at each interface 17311317Sm.alian1369@gmail.com */ 17411533Sm.alian1369@gmail.com PortFifo outputFifo; 17511317Sm.alian1369@gmail.com void transmit(); 17612087Sspwilson2@wisc.edu EventFunctionWrapper txEvent; 17711317Sm.alian1369@gmail.com }; 17811317Sm.alian1369@gmail.com 17911317Sm.alian1369@gmail.com struct SwitchTableEntry { 18011317Sm.alian1369@gmail.com Interface *interface; 18111317Sm.alian1369@gmail.com Tick lastUseTime; 18211317Sm.alian1369@gmail.com }; 18311317Sm.alian1369@gmail.com 18411317Sm.alian1369@gmail.com private: 18511317Sm.alian1369@gmail.com // time to live for MAC address mappings 18611317Sm.alian1369@gmail.com const double ttl; 18711317Sm.alian1369@gmail.com // all interfaces of the switch 18811317Sm.alian1369@gmail.com std::vector<Interface*> interfaces; 18911317Sm.alian1369@gmail.com // table that maps MAC address to interfaces 19011317Sm.alian1369@gmail.com std::map<uint64_t, SwitchTableEntry> forwardingTable; 19111317Sm.alian1369@gmail.com 19211317Sm.alian1369@gmail.com void serialize(CheckpointOut &cp) const override; 19311317Sm.alian1369@gmail.com void unserialize(CheckpointIn &cp) override; 19411317Sm.alian1369@gmail.com}; 19511317Sm.alian1369@gmail.com 19611317Sm.alian1369@gmail.com#endif // __DEV_ETHERSWITCH_HH__ 197