Bug 2208 - Interface index based L4 protocols
This commit is contained in:
@@ -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
|
||||
------------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user