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