Update README and add contrib dir
This commit is contained in:
427
contrib/ethernet/model/switch-net-device.cc
Normal file
427
contrib/ethernet/model/switch-net-device.cc
Normal file
@@ -0,0 +1,427 @@
|
||||
#include "switch-net-device.h"
|
||||
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/log.h"
|
||||
#include "ns3/node.h"
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/names.h"
|
||||
#include "ns3/random-variable-stream.h"
|
||||
|
||||
#include "ns3/ethernet-header2.h"
|
||||
#include "ns3/net-device.h"
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \ingroup ethernet
|
||||
* ns3::SwitchNetDevice implementation.
|
||||
*/
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE("SwitchNetDevice");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED(SwitchNetDevice);
|
||||
|
||||
TypeId
|
||||
SwitchNetDevice::GetTypeId()
|
||||
{
|
||||
static TypeId tid =
|
||||
TypeId("ns3::SwitchNetDevice")
|
||||
.SetParent<NetDevice>()
|
||||
.SetGroupName("Ethernet")
|
||||
.AddConstructor<SwitchNetDevice>()
|
||||
.AddAttribute("Mtu",
|
||||
"The MAC-level Maximum Transmission Unit",
|
||||
UintegerValue(1500),
|
||||
MakeUintegerAccessor(&SwitchNetDevice::SetMtu, &SwitchNetDevice::GetMtu),
|
||||
MakeUintegerChecker<uint16_t>())
|
||||
.AddAttribute("MinForwardingLatency",
|
||||
"The minimum latency experienced by the packet during forwarding",
|
||||
TimeValue(Seconds(0)),
|
||||
MakeTimeAccessor(&SwitchNetDevice::m_minForwardingLatency),
|
||||
MakeTimeChecker())
|
||||
.AddAttribute("MaxForwardingLatency",
|
||||
"The maximun latency experienced by the packet during forwarding",
|
||||
TimeValue(Seconds(0)),
|
||||
MakeTimeAccessor(&SwitchNetDevice::m_maxForwardingLatency),
|
||||
MakeTimeChecker())
|
||||
.AddAttribute("MaxPortNumber",
|
||||
"The maximum number of port",
|
||||
UintegerValue(65535),
|
||||
MakeUintegerAccessor(&SwitchNetDevice::m_maxPortNumber),
|
||||
MakeUintegerChecker<uint16_t>())
|
||||
.AddAttribute("MaxFdbEntryNumber",
|
||||
"The maximum number of entry in the forwarding database",
|
||||
UintegerValue(65535),
|
||||
MakeUintegerAccessor(&SwitchNetDevice::m_maxFdbEntryNumber),
|
||||
MakeUintegerChecker<uint16_t>());
|
||||
return tid;
|
||||
}
|
||||
|
||||
SwitchNetDevice::SwitchNetDevice()
|
||||
: m_node(nullptr),
|
||||
m_ifIndex(0)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_channel = CreateObject<SwitchChannel>();
|
||||
}
|
||||
|
||||
SwitchNetDevice::~SwitchNetDevice()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::DoDispose()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
for (auto iter = m_ports.begin(); iter != m_ports.end(); iter++)
|
||||
{
|
||||
*iter = nullptr;
|
||||
}
|
||||
m_ports.clear();
|
||||
m_forwardingTable.clear();
|
||||
m_channel = nullptr;
|
||||
m_node = nullptr;
|
||||
NetDevice::DoDispose();
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::ReceiveFromDevice(Ptr<NetDevice> incomingPort,
|
||||
Ptr<const Packet> packet,
|
||||
uint16_t protocol,
|
||||
const Address& src,
|
||||
const Address& dst,
|
||||
PacketType packetType)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
NS_LOG_DEBUG("UID is " << packet->GetUid());
|
||||
|
||||
Mac48Address src48 = Mac48Address::ConvertFrom(src);
|
||||
Mac48Address dst48 = Mac48Address::ConvertFrom(dst);
|
||||
|
||||
if (!m_promiscRxCallback.IsNull())
|
||||
{
|
||||
m_promiscRxCallback(this, packet, protocol, src, dst, packetType);
|
||||
}
|
||||
switch (packetType)
|
||||
{
|
||||
case PACKET_HOST:
|
||||
if (dst48 == m_address)
|
||||
{
|
||||
m_rxCallback(this, packet, protocol, src);
|
||||
}
|
||||
break;
|
||||
case PACKET_MULTICAST:
|
||||
case PACKET_BROADCAST:
|
||||
m_rxCallback(this, packet, protocol, src);
|
||||
ForwardBroadcast(incomingPort, packet, protocol, src48, dst48);
|
||||
break;
|
||||
|
||||
case PACKET_OTHERHOST:
|
||||
if (dst48 == m_address)
|
||||
{
|
||||
m_rxCallback(this, packet, protocol, src);
|
||||
}
|
||||
else
|
||||
{
|
||||
Forward(incomingPort, packet, protocol, src48, dst48);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::Forward(Ptr<NetDevice> incomingPort,
|
||||
Ptr<const Packet> packet,
|
||||
uint16_t protocol,
|
||||
Mac48Address src,
|
||||
Mac48Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
Ptr<Packet> originalPacket = packet->Copy();
|
||||
EthernetHeader2 header;
|
||||
originalPacket->RemoveHeader(header);
|
||||
uint16_t vid = header.GetVid();
|
||||
//NS_LOG_INFO(Names::FindName(this) << " Look in forwarding table for Pkt #" << packet->GetUid());
|
||||
std::vector<Ptr<NetDevice>> outPorts = GetOutputPortsFromForwardingTable(dst, vid);
|
||||
EventId e;
|
||||
int s = outPorts.size();
|
||||
for(int i=0; i < s; i++){
|
||||
//Avoid sending on the incomingPort
|
||||
if(outPorts[i] != incomingPort){
|
||||
Ptr<UniformRandomVariable> randVar = CreateObject<UniformRandomVariable>();
|
||||
Time forwardingLatency = NanoSeconds(randVar->GetValue(m_minForwardingLatency.GetNanoSeconds(), m_maxForwardingLatency.GetNanoSeconds()));
|
||||
Simulator::Schedule(forwardingLatency, &NetDevice::SendFrom, outPorts[i], packet->Copy(), src, dst, protocol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::ForwardBroadcast(Ptr<NetDevice> incomingPort,
|
||||
Ptr<const Packet> packet,
|
||||
uint16_t protocol,
|
||||
Mac48Address src,
|
||||
Mac48Address dst)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
|
||||
Forward(incomingPort, packet, protocol, src, dst);
|
||||
}
|
||||
|
||||
std::vector<Ptr<NetDevice>>
|
||||
SwitchNetDevice::GetOutputPortsFromForwardingTable(Mac48Address dest, uint16_t vid)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
int s = m_forwardingTable.size();
|
||||
for(int i=0; i < s; i++){
|
||||
if(m_forwardingTable[i].dest == dest and m_forwardingTable[i].vid==vid){
|
||||
// NS_LOG_INFO(Names::FindName(this) << " Forwarding Table : Match on vid "<< vid << " for " << m_forwardingTable[i].associatedPorts.size() << " output port(s) ");
|
||||
return m_forwardingTable[i].associatedPorts;
|
||||
}
|
||||
}
|
||||
// NS_LOG_INFO(Names::FindName(this) << " Forwarding Table : No Match on vid "<< vid);
|
||||
return {};
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::AddForwardingTableEntry(Mac48Address dest, uint16_t vid, std::vector<Ptr<NetDevice>> outPorts)
|
||||
{
|
||||
NS_LOG_FUNCTION(this);
|
||||
NS_ASSERT_MSG(m_forwardingTable.size() < m_maxFdbEntryNumber, "Trying to add more forwarding database entry than the " << m_maxFdbEntryNumber << " available.");
|
||||
PortsToVidAssociation entry = {dest, vid, outPorts};
|
||||
m_forwardingTable.insert(m_forwardingTable.end(), entry);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SwitchNetDevice::GetNSwitchPorts() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_ports.size();
|
||||
}
|
||||
|
||||
Ptr<NetDevice>
|
||||
SwitchNetDevice::GetSwitchPort(uint32_t n) const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_ports[n];
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::AddSwitchPort(Ptr<NetDevice> switchPort)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
NS_ASSERT_MSG(m_ports.size() < m_maxPortNumber, "Trying to add more switch port than the " << m_maxPortNumber << " available.");
|
||||
//NS_ASSERT(switchPort != this);
|
||||
if (!Mac48Address::IsMatchingType(switchPort->GetAddress()))
|
||||
{
|
||||
NS_FATAL_ERROR("Device does not support eui 48 addresses: cannot be added to switch.");
|
||||
}
|
||||
if (!switchPort->SupportsSendFrom())
|
||||
{
|
||||
NS_FATAL_ERROR("Device does not support SendFrom: cannot be added to switch.");
|
||||
}
|
||||
if (m_address == Mac48Address())
|
||||
{
|
||||
m_address = Mac48Address::ConvertFrom(switchPort->GetAddress());
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG("RegisterProtocolHandler for " << switchPort->GetInstanceTypeId().GetName());
|
||||
m_node->RegisterProtocolHandler(MakeCallback(&SwitchNetDevice::ReceiveFromDevice, this),
|
||||
0,
|
||||
switchPort,
|
||||
true);
|
||||
m_ports.push_back(switchPort);
|
||||
m_channel->AddChannel(switchPort->GetChannel());
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::SetIfIndex(const uint32_t index)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_ifIndex = index;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SwitchNetDevice::GetIfIndex() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_ifIndex;
|
||||
}
|
||||
|
||||
Ptr<Channel>
|
||||
SwitchNetDevice::GetChannel() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_channel;
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::SetAddress(Address address)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_address = Mac48Address::ConvertFrom(address);
|
||||
}
|
||||
|
||||
Address
|
||||
SwitchNetDevice::GetAddress() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_address;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::SetMtu(const uint16_t mtu)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_mtu = mtu;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
SwitchNetDevice::GetMtu() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_mtu;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::IsLinkUp() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::AddLinkChangeCallback(Callback<void> callback)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::IsBroadcast() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
SwitchNetDevice::GetBroadcast() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return Mac48Address("ff:ff:ff:ff:ff:ff");
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::IsMulticast() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
SwitchNetDevice::GetMulticast(Ipv4Address multicastGroup) const
|
||||
{
|
||||
NS_LOG_FUNCTION(this << multicastGroup);
|
||||
Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
|
||||
return multicast;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::IsPointToPoint() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::IsBridge() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return SendFrom(packet, m_address, dest, protocolNumber);
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::SendFrom(Ptr<Packet> packet,
|
||||
const Address& source,
|
||||
const Address& dest,
|
||||
uint16_t protocolNumber)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
Mac48Address src = Mac48Address::ConvertFrom(source);
|
||||
Mac48Address dst = Mac48Address::ConvertFrom(dest);
|
||||
|
||||
|
||||
Ptr<Packet> originalPacket = packet->Copy();
|
||||
EthernetHeader2 header;
|
||||
originalPacket->RemoveHeader(header);
|
||||
uint16_t vid = header.GetVid();
|
||||
|
||||
std::vector<Ptr<NetDevice>> outPorts = GetOutputPortsFromForwardingTable(dst, vid);
|
||||
int s = outPorts.size();
|
||||
for(int i=0; i < s; i++){
|
||||
outPorts[i]->SendFrom(packet->Copy(), src, dst, protocolNumber);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Ptr<Node>
|
||||
SwitchNetDevice::GetNode() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return m_node;
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::SetNode(Ptr<Node> node)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_node = node;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::NeedsArp() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::SetReceiveCallback(NetDevice::ReceiveCallback cb)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_rxCallback = cb;
|
||||
}
|
||||
|
||||
void
|
||||
SwitchNetDevice::SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
m_promiscRxCallback = cb;
|
||||
}
|
||||
|
||||
bool
|
||||
SwitchNetDevice::SupportsSendFrom() const
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS();
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
SwitchNetDevice::GetMulticast(Ipv6Address addr) const
|
||||
{
|
||||
NS_LOG_FUNCTION(this << addr);
|
||||
return Mac48Address::GetMulticast(addr);
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
Reference in New Issue
Block a user