etherswitch.hh revision 11533
1/* 2 * Copyright (c) 2014 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Anthony Gutierrez 29 * Mohammad Alian 30 */ 31 32/* @file 33 * Device model for an ethernet switch 34 */ 35 36#ifndef __DEV_ETHERSWITCH_HH__ 37#define __DEV_ETHERSWITCH_HH__ 38 39#include <map> 40#include <set> 41 42#include "base/inet.hh" 43#include "dev/net/etherint.hh" 44#include "dev/net/etherlink.hh" 45#include "dev/net/etherobject.hh" 46#include "dev/net/etherpkt.hh" 47#include "dev/net/pktfifo.hh" 48#include "params/EtherSwitch.hh" 49#include "sim/eventq.hh" 50 51class EtherSwitch : public EtherObject 52{ 53 public: 54 typedef EtherSwitchParams Params; 55 56 EtherSwitch(const Params *p); 57 ~EtherSwitch(); 58 59 const Params * params() const 60 { 61 return dynamic_cast<const Params*>(_params); 62 } 63 64 EtherInt *getEthPort(const std::string &if_name, int idx) override; 65 66 protected: 67 /** 68 * Model for an Ethernet switch port 69 */ 70 class Interface : public EtherInt, public Serializable 71 { 72 public: 73 Interface(const std::string &name, EtherSwitch *_etherSwitch, 74 uint64_t outputBufferSize, Tick delay, Tick delay_var, 75 double rate, unsigned id); 76 /** 77 * When a packet is received from a device, route it 78 * through an (several) output queue(s) 79 */ 80 bool recvPacket(EthPacketPtr packet); 81 /** 82 * enqueue packet to the outputFifo 83 */ 84 void enqueue(EthPacketPtr packet, unsigned senderId); 85 void sendDone() {} 86 Tick switchingDelay(); 87 88 Interface* lookupDestPort(Net::EthAddr destAddr); 89 void learnSenderAddr(Net::EthAddr srcMacAddr, Interface *sender); 90 91 void serialize(CheckpointOut &cp) const; 92 void unserialize(CheckpointIn &cp); 93 94 private: 95 const double ticksPerByte; 96 const Tick switchDelay; 97 const Tick delayVar; 98 const unsigned interfaceId; 99 100 EtherSwitch *parent; 101 protected: 102 struct PortFifoEntry : public Serializable 103 { 104 PortFifoEntry(EthPacketPtr pkt, Tick recv_tick, unsigned id) 105 : packet(pkt), recvTick(recv_tick), srcId(id) {} 106 107 EthPacketPtr packet; 108 Tick recvTick; 109 // id of the port that the packet has been received from 110 unsigned srcId; 111 ~PortFifoEntry() 112 { 113 packet = nullptr; 114 recvTick = 0; 115 srcId = 0; 116 } 117 void serialize(CheckpointOut &cp) const; 118 void unserialize(CheckpointIn &cp); 119 }; 120 121 class PortFifo : public Serializable 122 { 123 protected: 124 struct EntryOrder { 125 bool operator() (const PortFifoEntry& lhs, 126 const PortFifoEntry& rhs) const 127 { 128 if (lhs.recvTick == rhs.recvTick) 129 return lhs.srcId < rhs.srcId; 130 else 131 return lhs.recvTick < rhs.recvTick; 132 } 133 }; 134 std::set<PortFifoEntry, EntryOrder> fifo; 135 136 const std::string objName; 137 const unsigned _maxsize; 138 unsigned _size; 139 140 public: 141 PortFifo(const std::string &name, int max) 142 :objName(name), _maxsize(max), _size(0) {} 143 ~PortFifo() {} 144 145 const std::string name() { return objName; } 146 // Returns the available capacity of the fifo. 147 // It can return a negative value because in "push" function 148 // we first push the received packet into the fifo and then 149 // check if we exceed the available capacity (if avail() < 0) 150 // and remove packets from the end of fifo 151 int avail() const { return _maxsize - _size; } 152 153 EthPacketPtr front() { return fifo.begin()->packet; } 154 bool empty() const { return _size == 0; } 155 unsigned size() const { return _size; } 156 157 /** 158 * Push a packet into the fifo 159 * and sort the packets with same recv tick by port id 160 */ 161 bool push(EthPacketPtr ptr, unsigned senderId); 162 void pop(); 163 void clear(); 164 /** 165 * Serialization stuff 166 */ 167 void serialize(CheckpointOut &cp) const; 168 void unserialize(CheckpointIn &cp); 169 }; 170 /** 171 * output fifo at each interface 172 */ 173 PortFifo outputFifo; 174 void transmit(); 175 EventWrapper<Interface, &Interface::transmit> txEvent; 176 }; 177 178 struct SwitchTableEntry { 179 Interface *interface; 180 Tick lastUseTime; 181 }; 182 183 private: 184 // time to live for MAC address mappings 185 const double ttl; 186 // all interfaces of the switch 187 std::vector<Interface*> interfaces; 188 // table that maps MAC address to interfaces 189 std::map<uint64_t, SwitchTableEntry> forwardingTable; 190 191 void serialize(CheckpointOut &cp) const override; 192 void unserialize(CheckpointIn &cp) override; 193}; 194 195#endif // __DEV_ETHERSWITCH_HH__ 196