click: align Ipv4L3ClickProtocol with ae25cc3a0f89
this commit also fixes a bug uncovered by the more strict parsing of Ipv4Address strings. In Ipv4ClickRouting::RouteOutput(), it is possible for the string from the click routing table to contain just a single entry, but the code was assuming a space-delimited pair. If only a single entry is returned, the destination is now set to "0.0.0.0".
This commit is contained in:
@@ -483,12 +483,26 @@ Ipv4ClickRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, Ptr<NetD
|
||||
header.GetDestination ().Print (addr);
|
||||
// Probe the Click Routing Table for the required IP
|
||||
// This returns a string of the form "InterfaceID GatewayAddr"
|
||||
NS_LOG_DEBUG ("Probe click routing table for " << addr.str ());
|
||||
std::string s = ReadHandler (m_clickRoutingTableElement, addr.str ());
|
||||
NS_LOG_DEBUG ("string from click routing table: " << s);
|
||||
|
||||
int pos = s.find (" ");
|
||||
|
||||
int interfaceId = atoi (s.substr (0, pos).c_str ());
|
||||
Ipv4Address destination (s.substr (pos + 1).c_str ());
|
||||
size_t pos = s.find (" ");
|
||||
Ipv4Address destination;
|
||||
int interfaceId;
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
// Only an interface ID is found
|
||||
destination = Ipv4Address ("0.0.0.0");
|
||||
interfaceId = atoi (s.c_str ());
|
||||
NS_LOG_DEBUG ("case 1: destination " << destination << " interfaceId " << interfaceId);
|
||||
}
|
||||
else
|
||||
{
|
||||
interfaceId = atoi (s.substr (0, pos).c_str ());
|
||||
Ipv4Address destination (s.substr (pos + 1).c_str ());
|
||||
NS_LOG_DEBUG ("case 2: destination " << destination << " interfaceId " << interfaceId);
|
||||
}
|
||||
|
||||
if (interfaceId != -1)
|
||||
{
|
||||
|
||||
@@ -80,7 +80,7 @@ Ipv4L3ClickProtocol::DoDispose (void)
|
||||
NS_LOG_FUNCTION (this);
|
||||
for (L4List_t::iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
|
||||
{
|
||||
*i = 0;
|
||||
i->second = 0;
|
||||
}
|
||||
m_protocols.clear ();
|
||||
|
||||
@@ -89,6 +89,8 @@ Ipv4L3ClickProtocol::DoDispose (void)
|
||||
*i = 0;
|
||||
}
|
||||
m_interfaces.clear ();
|
||||
m_reverseInterfacesContainer.clear ();
|
||||
|
||||
m_sockets.clear ();
|
||||
m_node = 0;
|
||||
m_routingProtocol = 0;
|
||||
@@ -197,15 +199,10 @@ Ipv4L3ClickProtocol::GetInterfaceForDevice (
|
||||
{
|
||||
NS_LOG_FUNCTION (this << device->GetIfIndex ());
|
||||
|
||||
int32_t interface = 0;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end ();
|
||||
i++, interface++)
|
||||
Ipv4InterfaceReverseContainer::const_iterator iter = m_reverseInterfacesContainer.find (device);
|
||||
if (iter != m_reverseInterfacesContainer.end ())
|
||||
{
|
||||
if ((*i)->GetDevice () == device)
|
||||
{
|
||||
return interface;
|
||||
}
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -458,6 +455,33 @@ Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, Ipv4Address address)
|
||||
return false;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4L3ClickProtocol::SourceAddressSelection (uint32_t interfaceIdx, Ipv4Address dest)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << interfaceIdx << " " << dest);
|
||||
if (GetNAddresses (interfaceIdx) == 1) // common case
|
||||
{
|
||||
return GetAddress (interfaceIdx, 0).GetLocal ();
|
||||
}
|
||||
// no way to determine the scope of the destination, so adopt the
|
||||
// following rule: pick the first available address (index 0) unless
|
||||
// a subsequent address is on link (in which case, pick the primary
|
||||
// address if there are multiple)
|
||||
Ipv4Address candidate = GetAddress (interfaceIdx, 0).GetLocal ();
|
||||
for (uint32_t i = 0; i < GetNAddresses (interfaceIdx); i++)
|
||||
{
|
||||
Ipv4InterfaceAddress test = GetAddress (interfaceIdx, i);
|
||||
if (test.GetLocal ().CombineMask (test.GetMask ()) == dest.CombineMask (test.GetMask ()))
|
||||
{
|
||||
if (test.IsSecondary () == false)
|
||||
{
|
||||
return test.GetLocal ();
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
Ipv4Address
|
||||
Ipv4L3ClickProtocol::SelectSourceAddress (Ptr<const NetDevice> device,
|
||||
Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
|
||||
@@ -630,6 +654,7 @@ Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
|
||||
NS_LOG_FUNCTION (this << interface);
|
||||
uint32_t index = m_interfaces.size ();
|
||||
m_interfaces.push_back (interface);
|
||||
m_reverseInterfacesContainer[interface->GetDevice ()] = index;
|
||||
return index;
|
||||
}
|
||||
|
||||
@@ -757,29 +782,20 @@ Ipv4L3ClickProtocol::Receive ( Ptr<NetDevice> device, Ptr<const Packet> p, uint1
|
||||
{
|
||||
NS_LOG_FUNCTION (this << device << p << from << to);
|
||||
|
||||
NS_LOG_LOGIC ("Packet from " << from << " received on node " <<
|
||||
m_node->GetId ());
|
||||
|
||||
// Forward packet to raw sockets, if any
|
||||
if (protocol == Ipv4L3ClickProtocol::PROT_NUMBER && m_sockets.size () > 0)
|
||||
{
|
||||
Ptr<Packet> packetForRawSocket = p->Copy ();
|
||||
uint32_t interface = 0;
|
||||
Ptr<Ipv4Interface> ipv4Interface;
|
||||
for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
|
||||
i != m_interfaces.end ();
|
||||
i++, interface++)
|
||||
int32_t interface = GetInterfaceForDevice(device);
|
||||
NS_ASSERT_MSG (interface != -1, "Received a packet from an interface that is not known to IPv4");
|
||||
Ptr<Ipv4Interface> ipv4Interface = m_interfaces[interface];
|
||||
if (!ipv4Interface->IsUp ())
|
||||
{
|
||||
ipv4Interface = *i;
|
||||
if (ipv4Interface->GetDevice () == device)
|
||||
{
|
||||
if (ipv4Interface->IsUp ())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_LOG_LOGIC ("Dropping received packet -- interface is down");
|
||||
return;
|
||||
}
|
||||
}
|
||||
NS_LOG_LOGIC ("Dropping received packet -- interface is down");
|
||||
return;
|
||||
}
|
||||
|
||||
Ipv4Header ipHeader;
|
||||
@@ -878,22 +894,97 @@ Ipv4L3ClickProtocol::GetIcmp (void) const
|
||||
void
|
||||
Ipv4L3ClickProtocol::Insert (Ptr<IpL4Protocol> protocol)
|
||||
{
|
||||
m_protocols.push_back (protocol);
|
||||
NS_LOG_FUNCTION (this << protocol);
|
||||
L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
|
||||
if (m_protocols.find (key) != m_protocols.end ())
|
||||
{
|
||||
NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
|
||||
}
|
||||
m_protocols[key] = protocol;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3ClickProtocol::Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << protocol << interfaceIndex);
|
||||
|
||||
L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
|
||||
if (m_protocols.find (key) != m_protocols.end ())
|
||||
{
|
||||
NS_LOG_WARN ("Overwriting protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
|
||||
}
|
||||
m_protocols[key] = protocol;
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3ClickProtocol::Remove (Ptr<IpL4Protocol> protocol)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << protocol);
|
||||
|
||||
L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
|
||||
L4List_t::iterator iter = m_protocols.find (key);
|
||||
if (iter == m_protocols.end ())
|
||||
{
|
||||
NS_LOG_WARN ("Trying to remove an non-existent default protocol " << int(protocol->GetProtocolNumber ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_protocols.erase (key);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4L3ClickProtocol::Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << protocol << interfaceIndex);
|
||||
|
||||
L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), interfaceIndex);
|
||||
L4List_t::iterator iter = m_protocols.find (key);
|
||||
if (iter == m_protocols.end ())
|
||||
{
|
||||
NS_LOG_WARN ("Trying to remove an non-existent protocol " << int(protocol->GetProtocolNumber ()) << " on interface " << int(interfaceIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_protocols.erase (key);
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<IpL4Protocol>
|
||||
Ipv4L3ClickProtocol::GetProtocol (int protocolNumber) const
|
||||
{
|
||||
for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
|
||||
{
|
||||
if ((*i)->GetProtocolNumber () == protocolNumber)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
NS_LOG_FUNCTION (this << protocolNumber);
|
||||
|
||||
return GetProtocol (protocolNumber, -1);
|
||||
}
|
||||
|
||||
Ptr<IpL4Protocol>
|
||||
Ipv4L3ClickProtocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
|
||||
|
||||
L4ListKey_t key;
|
||||
L4List_t::const_iterator i;
|
||||
if (interfaceIndex >= 0)
|
||||
{
|
||||
// try the interface-specific protocol.
|
||||
key = std::make_pair (protocolNumber, interfaceIndex);
|
||||
i = m_protocols.find (key);
|
||||
if (i != m_protocols.end ())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
}
|
||||
// try the generic protocol.
|
||||
key = std::make_pair (protocolNumber, -1);
|
||||
i = m_protocols.find (key);
|
||||
if (i != m_protocols.end ())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
@@ -84,6 +84,36 @@ public:
|
||||
*/
|
||||
void Insert (Ptr<IpL4Protocol> protocol);
|
||||
|
||||
/**
|
||||
* \brief Add a L4 protocol to a specific interface.
|
||||
*
|
||||
* This may be called multiple times for multiple interfaces for the same
|
||||
* protocol. To insert for all interfaces, use the separate
|
||||
* Insert (Ptr<IpL4Protocol> protocol) method.
|
||||
*
|
||||
* Setting a protocol on a specific interface will overwrite the
|
||||
* previously bound protocol.
|
||||
*
|
||||
* \param protocol L4 protocol.
|
||||
* \param interfaceIndex interface index.
|
||||
*/
|
||||
void Insert (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex);
|
||||
|
||||
/**
|
||||
* \param protocol protocol to remove from this demux.
|
||||
*
|
||||
* The input value to this method should be the value
|
||||
* returned from the Ipv4L4Protocol::Insert method.
|
||||
*/
|
||||
void Remove (Ptr<IpL4Protocol> protocol);
|
||||
|
||||
/**
|
||||
* \brief Remove a L4 protocol from a specific interface.
|
||||
* \param protocol L4 protocol to remove.
|
||||
* \param interfaceIndex interface index.
|
||||
*/
|
||||
void Remove (Ptr<IpL4Protocol> protocol, uint32_t interfaceIndex);
|
||||
|
||||
/**
|
||||
* \param protocolNumber number of protocol to lookup
|
||||
* in this L4 Demux
|
||||
@@ -92,7 +122,11 @@ public:
|
||||
* This method is typically called by lower layers
|
||||
* to forward packets up the stack to the right protocol.
|
||||
*/
|
||||
Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const;
|
||||
virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const;
|
||||
|
||||
virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber, int32_t interfaceIndex) const;
|
||||
|
||||
virtual Ipv4Address SourceAddressSelection (uint32_t interface, Ipv4Address dest);
|
||||
|
||||
/**
|
||||
* \param ttl default ttl to use
|
||||
@@ -251,14 +285,26 @@ private:
|
||||
virtual bool GetWeakEsModel (void) const;
|
||||
|
||||
typedef std::vector<Ptr<Ipv4Interface> > Ipv4InterfaceList;
|
||||
/**
|
||||
* \brief Container of NetDevices registered to IPv4 and their interface indexes.
|
||||
*/
|
||||
typedef std::map<Ptr<const NetDevice>, uint32_t > Ipv4InterfaceReverseContainer;
|
||||
typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
|
||||
typedef std::list<Ptr<IpL4Protocol> > L4List_t;
|
||||
/**
|
||||
* \brief Container of the IPv4 L4 keys: protocol number, interface index
|
||||
*/
|
||||
typedef std::pair<int, int32_t> L4ListKey_t;
|
||||
/**
|
||||
* \brief Container of the IPv4 L4 instances.
|
||||
*/
|
||||
typedef std::map<L4ListKey_t, Ptr<IpL4Protocol> > L4List_t;
|
||||
|
||||
Ptr<Ipv4RoutingProtocol> m_routingProtocol;
|
||||
bool m_ipForward;
|
||||
bool m_weakEsModel;
|
||||
L4List_t m_protocols;
|
||||
Ipv4InterfaceList m_interfaces;
|
||||
Ipv4InterfaceReverseContainer m_reverseInterfacesContainer; //!< Container of NetDevice / Interface index associations.
|
||||
uint8_t m_defaultTtl;
|
||||
uint16_t m_identification;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user