Bug 1911 - AODV can not work on nodes with more than one NetDevice
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user