Bug 1911 - AODV can not work on nodes with more than one NetDevice

This commit is contained in:
Tommaso Pecorella
2014-09-13 19:23:39 +02:00
parent 4ea5aa6f01
commit 9b1f7c5b4b
2 changed files with 99 additions and 6 deletions

View File

@@ -283,6 +283,12 @@ RoutingProtocol::DoDispose ()
iter->first->Close ();
}
m_socketAddresses.clear ();
for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::iterator iter =
m_socketSubnetBroadcastAddresses.begin (); iter != m_socketSubnetBroadcastAddresses.end (); iter++)
{
iter->first->Close ();
}
m_socketSubnetBroadcastAddresses.clear ();
Ipv4RoutingProtocol::DoDispose ();
}
@@ -619,12 +625,28 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i)
socket->SetAttribute ("IpTtl", UintegerValue (1));
m_socketAddresses.insert (std::make_pair (socket, iface));
// create also a subnet broadcast socket
socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl", UintegerValue (1));
m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
// Add local broadcast record to the routing table
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
/*hops=*/ 1, /*next hop=*/ iface.GetBroadcast (), /*lifetime=*/ Simulator::GetMaximumSimulationTime ());
m_routingTable.AddRoute (rt);
if (l3->GetInterface (i)->GetArpCache ())
{
m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
}
// Allow neighbor manager use this interface for layer 2 feedback if possible
Ptr<WifiNetDevice> wifi = dev->GetObject<WifiNetDevice> ();
if (wifi == 0)
@@ -634,7 +656,6 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i)
return;
mac->TraceConnectWithoutContext ("TxErrHeader", m_nb.GetTxErrorCallback ());
m_nb.AddArpCache (l3->GetInterface (i)->GetArpCache ());
}
void
@@ -662,6 +683,13 @@ RoutingProtocol::NotifyInterfaceDown (uint32_t i)
NS_ASSERT (socket);
socket->Close ();
m_socketAddresses.erase (socket);
// Close socket
socket = FindSubnetBroadcastSocketWithInterfaceAddress (m_ipv4->GetAddress (i, 0));
NS_ASSERT (socket);
socket->Close ();
m_socketSubnetBroadcastAddresses.erase (socket);
if (m_socketAddresses.empty ())
{
NS_LOG_LOGIC ("No aodv interfaces");
@@ -693,12 +721,22 @@ RoutingProtocol::NotifyAddAddress (uint32_t i, Ipv4InterfaceAddress address)
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv,this));
// Bind to any IP address so that broadcasts can be received
socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
socket->SetAllowBroadcast (true);
m_socketAddresses.insert (std::make_pair (socket, iface));
// create also a subnet directed broadcast socket
socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl", UintegerValue (1));
m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
// Add local broadcast record to the routing table
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (
m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
@@ -722,7 +760,16 @@ RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address)
if (socket)
{
m_routingTable.DeleteAllRoutesFromInterface (address);
socket->Close ();
m_socketAddresses.erase (socket);
Ptr<Socket> unicastSocket = FindSubnetBroadcastSocketWithInterfaceAddress (address);
if (unicastSocket)
{
unicastSocket->Close ();
m_socketAddresses.erase (unicastSocket);
}
Ptr<Ipv4L3Protocol> l3 = m_ipv4->GetObject<Ipv4L3Protocol> ();
if (l3->GetNAddresses (i))
{
@@ -733,10 +780,23 @@ RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address)
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
// Bind to any IP address so that broadcasts can be received
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), AODV_PORT));
socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl", UintegerValue (1));
m_socketAddresses.insert (std::make_pair (socket, iface));
// create also a unicast socket
socket = Socket::CreateSocket (GetObject<Node> (),
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
socket->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl", UintegerValue (1));
m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
// Add local broadcast record to the routing table
Ptr<NetDevice> dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
RoutingTableEntry rt (/*device=*/ dev, /*dst=*/ iface.GetBroadcast (), /*know seqno=*/ true, /*seqno=*/ 0, /*iface=*/ iface,
@@ -937,7 +997,20 @@ RoutingProtocol::RecvAodv (Ptr<Socket> socket)
Ptr<Packet> packet = socket->RecvFrom (sourceAddress);
InetSocketAddress inetSourceAddr = InetSocketAddress::ConvertFrom (sourceAddress);
Ipv4Address sender = inetSourceAddr.GetIpv4 ();
Ipv4Address receiver = m_socketAddresses[socket].GetLocal ();
Ipv4Address receiver;
if (m_socketAddresses.find (socket) != m_socketAddresses.end ())
{
receiver = m_socketAddresses[socket].GetLocal ();
}
else if(m_socketSubnetBroadcastAddresses.find (socket) != m_socketSubnetBroadcastAddresses.end ())
{
receiver = m_socketSubnetBroadcastAddresses[socket].GetLocal ();
}
else
{
NS_ASSERT_MSG (false, "Received a packet from an unknown socket");
}
NS_LOG_DEBUG ("AODV node " << this << " received a AODV packet from " << sender << " to " << receiver);
UpdateRouteToNeighbor (sender, receiver);
@@ -1838,5 +1911,21 @@ RoutingProtocol::FindSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) con
return socket;
}
Ptr<Socket>
RoutingProtocol::FindSubnetBroadcastSocketWithInterfaceAddress (Ipv4InterfaceAddress addr ) const
{
NS_LOG_FUNCTION (this << addr);
for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
m_socketSubnetBroadcastAddresses.begin (); j != m_socketSubnetBroadcastAddresses.end (); ++j)
{
Ptr<Socket> socket = j->first;
Ipv4InterfaceAddress iface = j->second;
if (iface == addr)
return socket;
}
Ptr<Socket> socket;
return socket;
}
}
}

View File

@@ -140,8 +140,10 @@ private:
/// IP protocol
Ptr<Ipv4> m_ipv4;
/// Raw socket per each IP interface, map socket -> iface address (IP + mask)
/// Raw unicast socket per each IP interface, map socket -> iface address (IP + mask)
std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketAddresses;
/// Raw subnet directed broadcast socket per each IP interface, map socket -> iface address (IP + mask)
std::map< Ptr<Socket>, Ipv4InterfaceAddress > m_socketSubnetBroadcastAddresses;
/// Loopback device used to defer RREQ until packet will be fully formed
Ptr<NetDevice> m_lo;
@@ -191,8 +193,10 @@ private:
void UpdateRouteToNeighbor (Ipv4Address sender, Ipv4Address receiver);
/// Check that packet is send from own interface
bool IsMyOwnAddress (Ipv4Address src);
/// Find socket with local interface address iface
/// Find unicast socket with local interface address iface
Ptr<Socket> FindSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
/// Find subnet directed broadcast socket with local interface address iface
Ptr<Socket> FindSubnetBroadcastSocketWithInterfaceAddress (Ipv4InterfaceAddress iface) const;
/// Process hello message
void ProcessHello (RrepHeader const & rrepHeader, Ipv4Address receiverIfaceAddr);
/// Create loopback route for given header