#ifndef SWITCH_NET_DEVICE_H #define SWITCH_NET_DEVICE_H #include "switch-channel.h" #include "ns3/net-device.h" #include "ns3/mac48-address.h" #include "ns3/net-device.h" #include "ns3/nstime.h" #include "ns3/simulator.h" #include #include #include /** * \file * \ingroup ethernet * ns3::SwitchNetDevice declaration. */ namespace ns3 { class Node; /** * \brief a virtual net device that bridges multiple LAN segments * * The SwitchNetDevice object is a "virtual" netdevice that aggregates * multiple "real" netdevices and implements the data plane forwarding * part of IEEE 802.1D. By adding a SwitchNetDevice to a Node, it * will act as a "switch" to multiple LAN segments. * * \attention The switch netdevice don't implement a "Learning bridge" algorithm * or Spanning Tree Protocol as described in 802.1D * * \attention Switching is designed to work only with Ethernet NetDevices * modelling IEEE 802-style technologies, such as EthernetNetDevice */ /** * \ingroup ethernet * \brief a virtual net device that bridges multiple LAN segments */ class SwitchNetDevice : public NetDevice { public: /** * \brief Get the type ID. * \return the object TypeId */ static TypeId GetTypeId(); SwitchNetDevice(); ~SwitchNetDevice() override; // Delete copy constructor and assignment operator to avoid misuse SwitchNetDevice(const SwitchNetDevice&) = delete; SwitchNetDevice& operator=(const SwitchNetDevice&) = delete; /** * \brief Add a 'port' to a switch device * \param switchPort the NetDevice to add * * This method adds a new switch port to a SwitchNetDevice, so that * the new switch port NetDevice becomes part of the switch and L2 * frames start being forwarded to/from this NetDevice. * * \attention The netdevice that is being added as switch port must * _not_ have an IP address. In order to add IP connectivity to a * bridging node you must enable IP on the SwitchNetDevice itself, * never on its port netdevices. */ void AddSwitchPort(Ptr switchPort); /** * \brief Gets the number of switched 'ports', i.e., the NetDevices currently switched. * * \return the number of switched ports. */ uint32_t GetNSwitchPorts() const; /** * \brief Gets the n-th switched port. * \param n the port index * \return the n-th switched NetDevice */ Ptr GetSwitchPort(uint32_t n) const; // inherited from NetDevice base class. void SetIfIndex(const uint32_t index) override; uint32_t GetIfIndex() const override; Ptr GetChannel() const override; void SetAddress(Address address) override; Address GetAddress() const override; bool SetMtu(const uint16_t mtu) override; uint16_t GetMtu() const override; bool IsLinkUp() const override; void AddLinkChangeCallback(Callback callback) override; bool IsBroadcast() const override; Address GetBroadcast() const override; bool IsMulticast() const override; Address GetMulticast(Ipv4Address multicastGroup) const override; bool IsPointToPoint() const override; bool IsBridge() const override; bool Send(Ptr packet, const Address& dest, uint16_t protocolNumber) override; bool SendFrom(Ptr packet, const Address& source, const Address& dest, uint16_t protocolNumber) override; Ptr GetNode() const override; void SetNode(Ptr node) override; bool NeedsArp() const override; void SetReceiveCallback(NetDevice::ReceiveCallback cb) override; void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb) override; bool SupportsSendFrom() const override; Address GetMulticast(Ipv6Address addr) const override; /** * \brief Add a entry to the forwarding table * \param dest destination mac * \param vid Vlan ID * \param outPorts vector of output port */ void AddForwardingTableEntry(Mac48Address dest, uint16_t vid, std::vector> outPorts); protected: void DoDispose() override; /** * \brief Receives a packet from one switched port. * \param device the originating port * \param packet the received packet * \param protocol the packet protocol (e.g., Ethertype) * \param source the packet source * \param destination the packet destination * \param packetType the packet type (e.g., host, broadcast, etc.) */ void ReceiveFromDevice(Ptr device, Ptr packet, uint16_t protocol, const Address& source, const Address& destination, PacketType packetType); /** * \brief Forwards a packet * \param incomingPort the packet incoming port * \param packet the packet * \param protocol the packet protocol (e.g., Ethertype) * \param src the packet source * \param dst the packet destination */ void Forward(Ptr incomingPort, Ptr packet, uint16_t protocol, Mac48Address src, Mac48Address dst); /** * \brief Forwards a broadcast or a multicast packet * \param incomingPort the packet incoming port * \param packet the packet * \param protocol the packet protocol (e.g., Ethertype) * \param src the packet source * \param dst the packet destination */ void ForwardBroadcast(Ptr incomingPort, Ptr packet, uint16_t protocol, Mac48Address src, Mac48Address dst); /** * \brief Get the output ports from the forwarding table * \param dest destination mac * \param vid Vlan ID * \return output ports */ std::vector> GetOutputPortsFromForwardingTable(Mac48Address dest, uint16_t vid); private: NetDevice::ReceiveCallback m_rxCallback; //!< receive callback NetDevice::PromiscReceiveCallback m_promiscRxCallback; //!< promiscuous receive callback Mac48Address m_address; //!< MAC address of the NetDevice /** * \ingroup ethernet * Structure holding the association between ports and vid for a mac destination address */ struct PortsToVidAssociation { Mac48Address dest; uint16_t vid; std::vector> associatedPorts; }; std::vector m_forwardingTable; //!< Container for forwarding table Ptr m_node; //!< node owning this NetDevice Ptr m_channel; //!< virtual bridged channel std::vector> m_ports; //!< switched ports uint32_t m_ifIndex; //!< Interface index uint16_t m_mtu; //!< MTU of the switched NetDevice Time m_minForwardingLatency; Time m_maxForwardingLatency; uint16_t m_maxPortNumber; uint16_t m_maxFdbEntryNumber; }; } // namespace ns3 #endif /* SWITCH_NET_DEVICE_H */