Bug 2208 - Interface index based L4 protocols

This commit is contained in:
Tommaso Pecorella
2015-11-07 18:30:30 +01:00
parent 7907f2154e
commit c0e874e0d3
5 changed files with 243 additions and 32 deletions

View File

@@ -28,9 +28,12 @@ New user-visible features
or porting implementations from the Linux kernel, 2) Fast Retransmit and Fast
recovery algorithms, compliant to RFCs, are shared by all TCP variants, unlike
previous releases. 3) TCP Hybla and TCP HighSpeed have been added.
- (general) The PrintRoutingTable* functions now print the following informations
- (routing) The PrintRoutingTable* functions now print the following informations
each time they are called: 1) the node ID, 2) the global time, 3) the local time
4) the routing protocol type
- (internet) L4 protocols (e.g., TCP, UDP, ICMP, etc.) can be demultiplexed by IP
according to the incoming interface. In other words, it is now possible to
use specialized L4 protocols according to the interface.
Bugs fixed
----------
@@ -45,6 +48,8 @@ Bugs fixed
- Bug 2183 - LiIonEnergySourceHelper is not in the energy wscript
- Bug 2185 - WiFi MacLow may respond to errored frames that it should ignore
- Bug 2195 - Udp[*]Client can't send packets to broadcast address
- Bug 2207 - Print node ID and time when printing routing tables
- Bug 2208 - Interface index based L4 protocols
Known issues
------------

View File

@@ -125,26 +125,95 @@ void
Ipv4L3Protocol::Insert (Ptr<IpL4Protocol> protocol)
{
NS_LOG_FUNCTION (this << protocol);
m_protocols.push_back (protocol);
}
Ptr<IpL4Protocol>
Ipv4L3Protocol::GetProtocol (int protocolNumber) const
{
NS_LOG_FUNCTION (this << protocolNumber);
for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
L4ListKey_t key = std::make_pair (protocol->GetProtocolNumber (), -1);
if (m_protocols.find (key) != m_protocols.end ())
{
if ((*i)->GetProtocolNumber () == protocolNumber)
{
return *i;
}
NS_LOG_WARN ("Overwriting default protocol " << int(protocol->GetProtocolNumber ()));
}
return 0;
m_protocols[key] = protocol;
}
void
Ipv4L3Protocol::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
Ipv4L3Protocol::Remove (Ptr<IpL4Protocol> protocol)
{
NS_LOG_FUNCTION (this << protocol);
m_protocols.remove (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
Ipv4L3Protocol::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>
Ipv4L3Protocol::GetProtocol (int protocolNumber) const
{
NS_LOG_FUNCTION (this << protocolNumber);
return GetProtocol (protocolNumber, -1);
}
Ptr<IpL4Protocol>
Ipv4L3Protocol::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;
}
void
@@ -222,7 +291,7 @@ Ipv4L3Protocol::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 ();
@@ -953,7 +1022,7 @@ Ipv4L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uin
m_localDeliverTrace (ipHeader, p, iif);
Ptr<IpL4Protocol> protocol = GetProtocol (ipHeader.GetProtocol ());
Ptr<IpL4Protocol> protocol = GetProtocol (ipHeader.GetProtocol (), iif);
if (protocol != 0)
{
// we need to make a copy in the unlikely event we hit the

View File

@@ -128,6 +128,22 @@ public:
* The caller does not get ownership of the returned pointer.
*/
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 protocolNumber number of protocol to lookup
* in this L4 Demux
@@ -137,6 +153,15 @@ public:
* to forward packets up the stack to the right protocol.
*/
virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const;
/**
* \brief Get L4 protocol by protocol number for the specified interface.
* \param protocolNumber protocol number
* \param interfaceIndex interface index, -1 means "any" interface.
* \return corresponding IpL4Protocol or 0 if not found
*/
virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber, int32_t interfaceIndex) const;
/**
* \param protocol protocol to remove from this demux.
*
@@ -145,6 +170,13 @@ public:
*/
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 ttl default ttl to use
*
@@ -435,10 +467,16 @@ private:
* \brief Container of the IPv4 Raw Sockets.
*/
typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
/**
* \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::list<Ptr<IpL4Protocol> > L4List_t;
typedef std::map<L4ListKey_t, Ptr<IpL4Protocol> > L4List_t;
bool m_ipForward; //!< Forwarding packets (i.e. router mode) state.
bool m_weakEsModel; //!< Weak ES model state

View File

@@ -135,7 +135,7 @@ void Ipv6L3Protocol::DoDispose ()
/* clear protocol and interface list */
for (L4List_t::iterator it = m_protocols.begin (); it != m_protocols.end (); ++it)
{
*it = 0;
it->second = 0;
}
m_protocols.clear ();
@@ -707,26 +707,89 @@ void Ipv6L3Protocol::SetNode (Ptr<Node> node)
void Ipv6L3Protocol::Insert (Ptr<IpL4Protocol> protocol)
{
NS_LOG_FUNCTION (this << protocol);
m_protocols.push_back (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 Ipv6L3Protocol::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 Ipv6L3Protocol::Remove (Ptr<IpL4Protocol> protocol)
{
NS_LOG_FUNCTION (this << protocol);
m_protocols.remove (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 Ipv6L3Protocol::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> Ipv6L3Protocol::GetProtocol (int protocolNumber) const
{
NS_LOG_FUNCTION (this << protocolNumber);
for (L4List_t::const_iterator i = m_protocols.begin (); i != m_protocols.end (); ++i)
return GetProtocol (protocolNumber, -1);
}
Ptr<IpL4Protocol> Ipv6L3Protocol::GetProtocol (int protocolNumber, int32_t interfaceIndex) const
{
NS_LOG_FUNCTION (this << protocolNumber << interfaceIndex);
L4ListKey_t key;
L4List_t::const_iterator i;
if (interfaceIndex >= 0)
{
if ((*i)->GetProtocolNumber () == protocolNumber)
// try the interface-specific protocol.
key = std::make_pair (protocolNumber, interfaceIndex);
i = m_protocols.find (key);
if (i != m_protocols.end ())
{
return *i;
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;
}
@@ -1244,15 +1307,16 @@ void Ipv6L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv6Header const& i
}
else
{
protocol = GetProtocol (nextHeader);
// For ICMPv6 Error packets
Ptr<Packet> malformedPacket = packet->Copy ();
malformedPacket->AddHeader (ip);
protocol = GetProtocol (nextHeader, iif);
if (!protocol)
{
NS_LOG_LOGIC ("Unknown Next Header. Drop!");
// For ICMPv6 Error packets
Ptr<Packet> malformedPacket = packet->Copy ();
malformedPacket->AddHeader (ip);
if (nextHeaderPosition == 0)
{
GetIcmpv6 ()->SendErrorParameterError (malformedPacket, dst, Icmpv6Header::ICMPV6_UNKNOWN_NEXT_HEADER, 40);

View File

@@ -105,24 +105,54 @@ public:
void SetNode (Ptr<Node> node);
/**
* \brief Add an L4 protocol.
* \brief Add a L4 protocol.
* \param protocol L4 protocol
*/
void Insert (Ptr<IpL4Protocol> protocol);
/**
* \brief Remove an L4 protocol.
* \param protocol L4 protocol to remove
* \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);
/**
* \brief Remove a L4 protocol.
* \param protocol L4 protocol to remove.
*/
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);
/**
* \brief Get L4 protocol by protocol number.
* \param protocolNumber protocol number
* \return corresponding Ipv6L4Protocol or 0 if not found
* \return corresponding IpL4Protocol or 0 if not found
*/
virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const;
/**
* \brief Get L4 protocol by protocol number for the specified interface.
* \param protocolNumber protocol number
* \param interfaceIndex interface index, -1 means "any" interface.
* \return corresponding IpL4Protocol or 0 if not found
*/
virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber, int32_t interfaceIndex) const;
/**
* \brief Create raw IPv6 socket.
* \return newly raw socket
@@ -453,10 +483,15 @@ private:
*/
typedef std::list<Ptr<Ipv6RawSocketImpl> > SocketList;
/**
* \brief Container of the IPv6 L4 keys: protocol number, interface index
*/
typedef std::pair<int, int32_t> L4ListKey_t;
/**
* \brief Container of the IPv6 L4 instances.
*/
typedef std::list<Ptr<IpL4Protocol> > L4List_t;
typedef std::map<L4ListKey_t, Ptr<IpL4Protocol> > L4List_t;
/**
* \brief Container of the IPv6 Autoconfigured addresses.