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/etherpkt.hh" 46#include "dev/net/pktfifo.hh" 47#include "params/EtherSwitch.hh" 48#include "sim/eventq.hh" 49#include "sim/sim_object.hh" 50 51class EtherSwitch : public SimObject 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 Port &getPort(const std::string &if_name, 65 PortID idx=InvalidPortID) override; 66 67 protected: 68 /** 69 * Model for an Ethernet switch port 70 */ 71 class Interface : public EtherInt, public Serializable 72 { 73 public: 74 Interface(const std::string &name, EtherSwitch *_etherSwitch, 75 uint64_t outputBufferSize, Tick delay, Tick delay_var, 76 double rate, unsigned id); 77 /** 78 * When a packet is received from a device, route it 79 * through an (several) output queue(s) 80 */ 81 bool recvPacket(EthPacketPtr packet); 82 /** 83 * enqueue packet to the outputFifo 84 */ 85 void enqueue(EthPacketPtr packet, unsigned senderId); 86 void sendDone() {} 87 Tick switchingDelay(); 88 89 Interface* lookupDestPort(Net::EthAddr destAddr); 90 void learnSenderAddr(Net::EthAddr srcMacAddr, Interface *sender); 91 92 void serialize(CheckpointOut &cp) const; 93 void unserialize(CheckpointIn &cp); 94 95 private: 96 const double ticksPerByte; 97 const Tick switchDelay; 98 const Tick delayVar; 99 const unsigned interfaceId; 100 101 EtherSwitch *parent; 102 protected: 103 struct PortFifoEntry : public Serializable 104 { 105 PortFifoEntry(EthPacketPtr pkt, Tick recv_tick, unsigned id) 106 : packet(pkt), recvTick(recv_tick), srcId(id) {} 107 108 EthPacketPtr packet; 109 Tick recvTick; 110 // id of the port that the packet has been received from 111 unsigned srcId; 112 ~PortFifoEntry() 113 { 114 packet = nullptr; 115 recvTick = 0; 116 srcId = 0; 117 } 118 void serialize(CheckpointOut &cp) const; 119 void unserialize(CheckpointIn &cp); 120 }; 121 122 class PortFifo : public Serializable 123 { 124 protected: 125 struct EntryOrder { 126 bool operator() (const PortFifoEntry& lhs, 127 const PortFifoEntry& rhs) const 128 { 129 if (lhs.recvTick == rhs.recvTick) 130 return lhs.srcId < rhs.srcId; 131 else 132 return lhs.recvTick < rhs.recvTick; 133 } 134 }; 135 std::set<PortFifoEntry, EntryOrder> fifo; 136 137 const std::string objName; 138 const unsigned _maxsize; 139 unsigned _size; 140 141 public: 142 PortFifo(const std::string &name, int max) 143 :objName(name), _maxsize(max), _size(0) {} 144 ~PortFifo() {} 145 146 const std::string name() { return objName; } 147 // Returns the available capacity of the fifo. 148 // It can return a negative value because in "push" function 149 // we first push the received packet into the fifo and then 150 // check if we exceed the available capacity (if avail() < 0) 151 // and remove packets from the end of fifo 152 int avail() const { return _maxsize - _size; } 153 154 EthPacketPtr front() { return fifo.begin()->packet; } 155 bool empty() const { return _size == 0; } 156 unsigned size() const { return _size; } 157 158 /** 159 * Push a packet into the fifo 160 * and sort the packets with same recv tick by port id 161 */ 162 bool push(EthPacketPtr ptr, unsigned senderId); 163 void pop(); 164 void clear(); 165 /** 166 * Serialization stuff 167 */ 168 void serialize(CheckpointOut &cp) const; 169 void unserialize(CheckpointIn &cp); 170 }; 171 /** 172 * output fifo at each interface 173 */ 174 PortFifo outputFifo; 175 void transmit(); 176 EventFunctionWrapper txEvent; 177 }; 178 179 struct SwitchTableEntry { 180 Interface *interface; 181 Tick lastUseTime; 182 }; 183 184 private: 185 // time to live for MAC address mappings 186 const double ttl; 187 // all interfaces of the switch 188 std::vector<Interface*> interfaces; 189 // table that maps MAC address to interfaces 190 std::map<uint64_t, SwitchTableEntry> forwardingTable; 191 192 void serialize(CheckpointOut &cp) const override; 193 void unserialize(CheckpointIn &cp) override; 194}; 195 196#endif // __DEV_ETHERSWITCH_HH__ 197