diff --git a/CHANGES.html b/CHANGES.html
index 461275248..e7de8cffb 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -130,6 +130,11 @@ is now exported by WifiNetDevice.
Previously, a socket bound to an unicast address received also subnet-directed broadcast packets.
This is not anymore possible.
+
You can now Bind as many socket as you want to an address/port, provided that they are bound to different NetDevices.
+ Moreover, BindToNetDevice does not anymore call Bind. In other terms, Bind and BindToNetDevice can be called
+ in any order.
+ However, it is suggested to use BindToNetDevice before Bind in order to avoid conflicts.
+
Changes to build system:
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 6ef5725d1..9f12bb685 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -112,6 +112,7 @@ Bugs fixed
- Bug 2759 - Packets sent to broadcast address are converted to subnet-directed broadcast
- Bug 2760 - OLSR uses unicast-bound sockets to receive broadcasts
- Bug 2761 - Packet has no Traffic ID for CTS frames when A-MPDU is used
+- Bug 2762 - BindToNetDevice behaviour is not coherent with Linux
Known issues
------------
diff --git a/src/aodv/model/aodv-routing-protocol.cc b/src/aodv/model/aodv-routing-protocol.cc
index dc67f88fb..61f47c270 100644
--- a/src/aodv/model/aodv-routing-protocol.cc
+++ b/src/aodv/model/aodv-routing-protocol.cc
@@ -685,8 +685,8 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i)
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv, this));
- socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
+ socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->SetAllowBroadcast (true);
socket->SetIpRecvTtl (true);
m_socketAddresses.insert (std::make_pair (socket, iface));
@@ -696,8 +696,8 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i)
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->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
socket->SetAllowBroadcast (true);
socket->SetIpRecvTtl (true);
m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
@@ -795,8 +795,8 @@ RoutingProtocol::NotifyAddAddress (uint32_t i, Ipv4InterfaceAddress address)
UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvAodv,this));
- socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
+ socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->SetAllowBroadcast (true);
m_socketAddresses.insert (std::make_pair (socket, iface));
@@ -805,8 +805,8 @@ RoutingProtocol::NotifyAddAddress (uint32_t i, Ipv4InterfaceAddress address)
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->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
socket->SetAllowBroadcast (true);
socket->SetIpRecvTtl (true);
m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
@@ -854,8 +854,8 @@ 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 (iface.GetLocal (), AODV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
+ socket->Bind (InetSocketAddress (iface.GetLocal (), AODV_PORT));
socket->SetAllowBroadcast (true);
socket->SetIpRecvTtl (true);
m_socketAddresses.insert (std::make_pair (socket, iface));
@@ -865,8 +865,8 @@ RoutingProtocol::NotifyRemoveAddress (uint32_t i, Ipv4InterfaceAddress address)
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->Bind (InetSocketAddress (iface.GetBroadcast (), AODV_PORT));
socket->SetAllowBroadcast (true);
socket->SetIpRecvTtl (true);
m_socketSubnetBroadcastAddresses.insert (std::make_pair (socket, iface));
diff --git a/src/dsdv/model/dsdv-routing-protocol.cc b/src/dsdv/model/dsdv-routing-protocol.cc
index c82627fc5..980f24ba3 100644
--- a/src/dsdv/model/dsdv-routing-protocol.cc
+++ b/src/dsdv/model/dsdv-routing-protocol.cc
@@ -976,8 +976,8 @@ RoutingProtocol::NotifyInterfaceUp (uint32_t i)
Ptr socket = Socket::CreateSocket (GetObject (),UdpSocketFactory::GetTypeId ());
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvDsdv,this));
- socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
+ socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
socket->SetAllowBroadcast (true);
socket->SetAttribute ("IpTtl",UintegerValue (1));
m_socketAddresses.insert (std::make_pair (socket,iface));
@@ -1034,8 +1034,8 @@ RoutingProtocol::NotifyAddAddress (uint32_t i,
NS_ASSERT (socket != 0);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvDsdv,this));
// Bind to any IP address so that broadcasts can be received
- socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
socket->BindToNetDevice (l3->GetNetDevice (i));
+ socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), DSDV_PORT));
socket->SetAllowBroadcast (true);
m_socketAddresses.insert (std::make_pair (socket,iface));
Ptr dev = m_ipv4->GetNetDevice (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()));
diff --git a/src/internet-apps/model/dhcp-client.cc b/src/internet-apps/model/dhcp-client.cc
index ee2accfbb..0f6f0d23b 100644
--- a/src/internet-apps/model/dhcp-client.cc
+++ b/src/internet-apps/model/dhcp-client.cc
@@ -192,8 +192,8 @@ DhcpClient::StartApplication (void)
m_socket = Socket::CreateSocket (GetNode (), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 68);
m_socket->SetAllowBroadcast (true);
- m_socket->Bind (local);
m_socket->BindToNetDevice (m_device);
+ m_socket->Bind (local);
}
m_socket->SetRecvCallback (MakeCallback (&DhcpClient::NetHandler, this));
diff --git a/src/internet-apps/model/dhcp-server.cc b/src/internet-apps/model/dhcp-server.cc
index eb641329d..13538b5c6 100644
--- a/src/internet-apps/model/dhcp-server.cc
+++ b/src/internet-apps/model/dhcp-server.cc
@@ -155,8 +155,8 @@ void DhcpServer::StartApplication (void)
m_socket = Socket::CreateSocket (GetNode (), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), PORT);
m_socket->SetAllowBroadcast (true);
- m_socket->Bind (local);
m_socket->BindToNetDevice (ipv4->GetNetDevice (ifIndex));
+ m_socket->Bind (local);
m_socket->SetRecvPktInfo (true);
uint32_t range = m_maxAddress.Get () - m_minAddress.Get () + 1;
diff --git a/src/internet/model/ipv4-end-point-demux.cc b/src/internet/model/ipv4-end-point-demux.cc
index aa6119702..476583781 100644
--- a/src/internet/model/ipv4-end-point-demux.cc
+++ b/src/internet/model/ipv4-end-point-demux.cc
@@ -60,13 +60,14 @@ Ipv4EndPointDemux::LookupPortLocal (uint16_t port)
}
bool
-Ipv4EndPointDemux::LookupLocal (Ipv4Address addr, uint16_t port)
+Ipv4EndPointDemux::LookupLocal (Ptr boundNetDevice, Ipv4Address addr, uint16_t port)
{
NS_LOG_FUNCTION (this << addr << port);
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
if ((*i)->GetLocalPort () == port &&
- (*i)->GetLocalAddress () == addr)
+ (*i)->GetLocalAddress () == addr &&
+ (*i)->GetBoundNetDevice () == boundNetDevice)
{
return true;
}
@@ -107,20 +108,20 @@ Ipv4EndPointDemux::Allocate (Ipv4Address address)
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (uint16_t port)
+Ipv4EndPointDemux::Allocate (Ptr boundNetDevice, uint16_t port)
{
- NS_LOG_FUNCTION (this << port);
+ NS_LOG_FUNCTION (this << port << boundNetDevice);
- return Allocate (Ipv4Address::GetAny (), port);
+ return Allocate (boundNetDevice, Ipv4Address::GetAny (), port);
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
+Ipv4EndPointDemux::Allocate (Ptr boundNetDevice, Ipv4Address address, uint16_t port)
{
- NS_LOG_FUNCTION (this << address << port);
- if (LookupLocal (address, port))
+ NS_LOG_FUNCTION (this << address << port << boundNetDevice);
+ if (LookupLocal (boundNetDevice, address, port) || LookupLocal (0, address, port))
{
- NS_LOG_WARN ("Duplicate address/port; failing.");
+ NS_LOG_WARN ("Duplicated endpoint.");
return 0;
}
Ipv4EndPoint *endPoint = new Ipv4EndPoint (address, port);
@@ -130,19 +131,20 @@ Ipv4EndPointDemux::Allocate (Ipv4Address address, uint16_t port)
}
Ipv4EndPoint *
-Ipv4EndPointDemux::Allocate (Ipv4Address localAddress, uint16_t localPort,
+Ipv4EndPointDemux::Allocate (Ptr boundNetDevice,
+ Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort)
{
- NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+ NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort << boundNetDevice);
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
if ((*i)->GetLocalPort () == localPort &&
(*i)->GetLocalAddress () == localAddress &&
(*i)->GetPeerPort () == peerPort &&
- (*i)->GetPeerAddress () == peerAddress)
+ (*i)->GetPeerAddress () == peerAddress &&
+ ((*i)->GetBoundNetDevice () == boundNetDevice || (*i)->GetBoundNetDevice () == 0))
{
- NS_LOG_WARN ("No way we can allocate this end-point.");
- /* no way we can allocate this end-point. */
+ NS_LOG_WARN ("Duplicated endpoint.");
return 0;
}
}
@@ -323,10 +325,14 @@ Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport,
}
// Here we find the most exact match
- if (!retval4.empty ()) return retval4;
- if (!retval3.empty ()) return retval3;
- if (!retval2.empty ()) return retval2;
- return retval1; // might be empty if no matches
+ EndPoints retval;
+ if (!retval4.empty ()) retval = retval4;
+ else if (!retval3.empty ()) retval = retval3;
+ else if (!retval2.empty ()) retval = retval2;
+ else retval = retval1;
+
+ NS_ABORT_MSG_IF (retval.size () > 1, "Too many endpoints - perhaps you created too many sockets without binding them to different NetDevices.");
+ return retval; // might be empty if no matches
}
Ipv4EndPoint *
diff --git a/src/internet/model/ipv4-end-point-demux.h b/src/internet/model/ipv4-end-point-demux.h
index 1666983f7..935f91ac4 100644
--- a/src/internet/model/ipv4-end-point-demux.h
+++ b/src/internet/model/ipv4-end-point-demux.h
@@ -72,11 +72,12 @@ public:
/**
* \brief Lookup for address and port.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param addr address to test
* \param port port to test
* \return true if there is a match in EndPoints, false otherwise
*/
- bool LookupLocal (Ipv4Address addr, uint16_t port);
+ bool LookupLocal (Ptr boundNetDevice, Ipv4Address addr, uint16_t port);
/**
* \brief lookup for a match with all the parameters.
@@ -130,31 +131,33 @@ public:
/**
* \brief Allocate a Ipv4EndPoint.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param port local port
* \return an Ipv4EndPoint instance
*/
- Ipv4EndPoint *Allocate (uint16_t port);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice, uint16_t port);
/**
* \brief Allocate a Ipv4EndPoint.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param address local address
* \param port local port
* \return an Ipv4EndPoint instance
*/
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice, Ipv4Address address, uint16_t port);
/**
* \brief Allocate a Ipv4EndPoint.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param localAddress local address
* \param localPort local port
* \param peerAddress peer address
* \param peerPort peer port
* \return an Ipv4EndPoint instance
*/
- Ipv4EndPoint *Allocate (Ipv4Address localAddress,
- uint16_t localPort,
- Ipv4Address peerAddress,
- uint16_t peerPort);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice,
+ Ipv4Address localAddress, uint16_t localPort,
+ Ipv4Address peerAddress, uint16_t peerPort);
/**
* \brief Remove a end point.
diff --git a/src/internet/model/ipv6-end-point-demux.cc b/src/internet/model/ipv6-end-point-demux.cc
index d03383313..250a1f4c2 100644
--- a/src/internet/model/ipv6-end-point-demux.cc
+++ b/src/internet/model/ipv6-end-point-demux.cc
@@ -58,13 +58,14 @@ bool Ipv6EndPointDemux::LookupPortLocal (uint16_t port)
return false;
}
-bool Ipv6EndPointDemux::LookupLocal (Ipv6Address addr, uint16_t port)
+bool Ipv6EndPointDemux::LookupLocal (Ptr boundNetDevice, Ipv6Address addr, uint16_t port)
{
NS_LOG_FUNCTION (this << addr << port);
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
- if ((*i)->GetLocalPort () == port
- && (*i)->GetLocalAddress () == addr)
+ if ((*i)->GetLocalPort () == port &&
+ (*i)->GetLocalAddress () == addr &&
+ (*i)->GetBoundNetDevice () == boundNetDevice)
{
return true;
}
@@ -74,7 +75,7 @@ bool Ipv6EndPointDemux::LookupLocal (Ipv6Address addr, uint16_t port)
Ipv6EndPoint* Ipv6EndPointDemux::Allocate ()
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
uint16_t port = AllocateEphemeralPort ();
if (port == 0)
{
@@ -102,19 +103,19 @@ Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address address)
return endPoint;
}
-Ipv6EndPoint* Ipv6EndPointDemux::Allocate (uint16_t port)
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ptr boundNetDevice, uint16_t port)
{
- NS_LOG_FUNCTION (this << port);
+ NS_LOG_FUNCTION (this << boundNetDevice << port);
- return Allocate (Ipv6Address::GetAny (), port);
+ return Allocate (boundNetDevice, Ipv6Address::GetAny (), port);
}
-Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address address, uint16_t port)
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ptr boundNetDevice, Ipv6Address address, uint16_t port)
{
- NS_LOG_FUNCTION (this << address << port);
- if (LookupLocal (address, port))
+ NS_LOG_FUNCTION (this << boundNetDevice << address << port);
+ if (LookupLocal (boundNetDevice, address, port) || LookupLocal (0, address, port))
{
- NS_LOG_WARN ("Duplicate address/port; failing.");
+ NS_LOG_WARN ("Duplicated endpoint.");
return 0;
}
Ipv6EndPoint *endPoint = new Ipv6EndPoint (address, port);
@@ -123,19 +124,20 @@ Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address address, uint16_t port)
return endPoint;
}
-Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address localAddress, uint16_t localPort,
+Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ptr boundNetDevice,
+ Ipv6Address localAddress, uint16_t localPort,
Ipv6Address peerAddress, uint16_t peerPort)
{
- NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
+ NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
- if ((*i)->GetLocalPort () == localPort
- && (*i)->GetLocalAddress () == localAddress
- && (*i)->GetPeerPort () == peerPort
- && (*i)->GetPeerAddress () == peerAddress)
+ if ((*i)->GetLocalPort () == localPort &&
+ (*i)->GetLocalAddress () == localAddress &&
+ (*i)->GetPeerPort () == peerPort &&
+ (*i)->GetPeerAddress () == peerAddress &&
+ ((*i)->GetBoundNetDevice () == boundNetDevice || (*i)->GetBoundNetDevice () == 0))
{
- NS_LOG_WARN ("No way we can allocate this end-point.");
- /* no way we can allocate this end-point. */
+ NS_LOG_WARN ("Duplicated endpoint.");
return 0;
}
}
@@ -150,7 +152,7 @@ Ipv6EndPoint* Ipv6EndPointDemux::Allocate (Ipv6Address localAddress, uint16_t lo
void Ipv6EndPointDemux::DeAllocate (Ipv6EndPoint *endPoint)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
{
if (*i == endPoint)
@@ -275,20 +277,15 @@ Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup (Ipv6Address daddr, uint1
}
}
- /* Here we find the most exact match */
- if (!retval4.empty ())
- {
- return retval4;
- }
- if (!retval3.empty ())
- {
- return retval3;
- }
- if (!retval2.empty ())
- {
- return retval2;
- }
- return retval1; /* might be empty if no matches */
+ // Here we find the most exact match
+ EndPoints retval;
+ if (!retval4.empty ()) retval = retval4;
+ else if (!retval3.empty ()) retval = retval3;
+ else if (!retval2.empty ()) retval = retval2;
+ else retval = retval1;
+
+ NS_ABORT_MSG_IF (retval.size () > 1, "Too many endpoints - perhaps you created too many sockets without binding them to different NetDevices.");
+ return retval; // might be empty if no matches
}
Ipv6EndPoint* Ipv6EndPointDemux::SimpleLookup (Ipv6Address dst, uint16_t dport, Ipv6Address src, uint16_t sport)
@@ -333,7 +330,7 @@ Ipv6EndPoint* Ipv6EndPointDemux::SimpleLookup (Ipv6Address dst, uint16_t dport,
uint16_t Ipv6EndPointDemux::AllocateEphemeralPort ()
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
uint16_t port = m_ephemeral;
int count = m_portLast - m_portFirst;
do
diff --git a/src/internet/model/ipv6-end-point-demux.h b/src/internet/model/ipv6-end-point-demux.h
index 04b960b45..8a0e41dd1 100644
--- a/src/internet/model/ipv6-end-point-demux.h
+++ b/src/internet/model/ipv6-end-point-demux.h
@@ -60,11 +60,12 @@ public:
/**
* \brief Lookup for address and port.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param addr address to test
* \param port port to test
* \return true if there is a match in EndPoints, false otherwise
*/
- bool LookupLocal (Ipv6Address addr, uint16_t port);
+ bool LookupLocal (Ptr boundNetDevice, Ipv6Address addr, uint16_t port);
/**
* \brief lookup for a match with all the parameters.
@@ -111,28 +112,33 @@ public:
/**
* \brief Allocate a Ipv6EndPoint.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param port local port
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint * Allocate (uint16_t port);
+ Ipv6EndPoint * Allocate (Ptr boundNetDevice, uint16_t port);
/**
* \brief Allocate a Ipv6EndPoint.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param address local address
* \param port local port
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint * Allocate (Ipv6Address address, uint16_t port);
+ Ipv6EndPoint * Allocate (Ptr boundNetDevice, Ipv6Address address, uint16_t port);
/**
* \brief Allocate a Ipv6EndPoint.
+ * \param boundNetDevice Bound NetDevice (if any)
* \param localAddress local address
* \param localPort local port
* \param peerAddress peer address
* \param peerPort peer port
* \return an Ipv6EndPoint instance
*/
- Ipv6EndPoint * Allocate (Ipv6Address localAddress, uint16_t localPort, Ipv6Address peerAddress, uint16_t peerPort);
+ Ipv6EndPoint * Allocate (Ptr boundNetDevice,
+ Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort);
/**
* \brief Remove a end point.
diff --git a/src/internet/model/rip.cc b/src/internet/model/rip.cc
index 58ca129c8..cc96ba8e0 100644
--- a/src/internet/model/rip.cc
+++ b/src/internet/model/rip.cc
@@ -144,9 +144,9 @@ void Rip::DoInitialize ()
Ptr theNode = GetObject ();
Ptr socket = Socket::CreateSocket (theNode, tid);
InetSocketAddress local = InetSocketAddress (address.GetLocal (), RIP_PORT);
+ socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
int ret = socket->Bind (local);
NS_ASSERT_MSG (ret == 0, "Bind unsuccessful");
- socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
socket->SetIpRecvTtl (true);
m_sendSocketList[socket] = i;
}
@@ -343,8 +343,8 @@ void Rip::NotifyInterfaceUp (uint32_t i)
Ptr theNode = GetObject ();
Ptr socket = Socket::CreateSocket (theNode, tid);
InetSocketAddress local = InetSocketAddress (address.GetLocal (), RIP_PORT);
- socket->Bind (local);
socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
+ socket->Bind (local);
socket->SetIpRecvTtl (true);
m_sendSocketList[socket] = i;
}
diff --git a/src/internet/model/ripng.cc b/src/internet/model/ripng.cc
index f6335208e..879a14538 100644
--- a/src/internet/model/ripng.cc
+++ b/src/internet/model/ripng.cc
@@ -138,9 +138,9 @@ void RipNg::DoInitialize ()
Ptr theNode = GetObject ();
Ptr socket = Socket::CreateSocket (theNode, tid);
Inet6SocketAddress local = Inet6SocketAddress (address.GetAddress (), RIPNG_PORT);
+ socket->BindToNetDevice (m_ipv6->GetNetDevice (i));
int ret = socket->Bind (local);
NS_ASSERT_MSG (ret == 0, "Bind unsuccessful");
- socket->BindToNetDevice (m_ipv6->GetNetDevice (i));
socket->ShutdownRecv ();
socket->SetIpv6RecvHopLimit (true);
m_sendSocketList[socket] = i;
@@ -314,8 +314,8 @@ void RipNg::NotifyInterfaceUp (uint32_t i)
Ptr theNode = GetObject ();
Ptr socket = Socket::CreateSocket (theNode, tid);
Inet6SocketAddress local = Inet6SocketAddress (address.GetAddress (), RIPNG_PORT);
- socket->Bind (local);
socket->BindToNetDevice (m_ipv6->GetNetDevice (i));
+ socket->Bind (local);
socket->ShutdownRecv ();
socket->SetIpv6RecvHopLimit (true);
m_sendSocketList[socket] = i;
diff --git a/src/internet/model/tcp-l4-protocol.cc b/src/internet/model/tcp-l4-protocol.cc
index 5b060a9d1..280843850 100644
--- a/src/internet/model/tcp-l4-protocol.cc
+++ b/src/internet/model/tcp-l4-protocol.cc
@@ -205,7 +205,7 @@ TcpL4Protocol::CreateSocket (void)
Ipv4EndPoint *
TcpL4Protocol::Allocate (void)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
return m_endPoints->Allocate ();
}
@@ -217,25 +217,27 @@ TcpL4Protocol::Allocate (Ipv4Address address)
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (uint16_t port)
+TcpL4Protocol::Allocate (Ptr boundNetDevice, uint16_t port)
{
- NS_LOG_FUNCTION (this << port);
- return m_endPoints->Allocate (port);
+ NS_LOG_FUNCTION (this << boundNetDevice << port);
+ return m_endPoints->Allocate (boundNetDevice, port);
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+TcpL4Protocol::Allocate (Ptr boundNetDevice, Ipv4Address address, uint16_t port)
{
- NS_LOG_FUNCTION (this << address << port);
- return m_endPoints->Allocate (address, port);
+ NS_LOG_FUNCTION (this << boundNetDevice << address << port);
+ return m_endPoints->Allocate (boundNetDevice, address, port);
}
Ipv4EndPoint *
-TcpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
+TcpL4Protocol::Allocate (Ptr boundNetDevice,
+ Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort)
{
- NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
- return m_endPoints->Allocate (localAddress, localPort,
+ NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
+ return m_endPoints->Allocate (boundNetDevice,
+ localAddress, localPort,
peerAddress, peerPort);
}
@@ -249,7 +251,7 @@ TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
Ipv6EndPoint *
TcpL4Protocol::Allocate6 (void)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
return m_endPoints6->Allocate ();
}
@@ -261,25 +263,27 @@ TcpL4Protocol::Allocate6 (Ipv6Address address)
}
Ipv6EndPoint *
-TcpL4Protocol::Allocate6 (uint16_t port)
+TcpL4Protocol::Allocate6 (Ptr boundNetDevice, uint16_t port)
{
- NS_LOG_FUNCTION (this << port);
- return m_endPoints6->Allocate (port);
+ NS_LOG_FUNCTION (this << boundNetDevice << port);
+ return m_endPoints6->Allocate (boundNetDevice, port);
}
Ipv6EndPoint *
-TcpL4Protocol::Allocate6 (Ipv6Address address, uint16_t port)
+TcpL4Protocol::Allocate6 (Ptr boundNetDevice, Ipv6Address address, uint16_t port)
{
- NS_LOG_FUNCTION (this << address << port);
- return m_endPoints6->Allocate (address, port);
+ NS_LOG_FUNCTION (this << boundNetDevice << address << port);
+ return m_endPoints6->Allocate (boundNetDevice, address, port);
}
Ipv6EndPoint *
-TcpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+TcpL4Protocol::Allocate6 (Ptr boundNetDevice,
+ Ipv6Address localAddress, uint16_t localPort,
Ipv6Address peerAddress, uint16_t peerPort)
{
- NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
- return m_endPoints6->Allocate (localAddress, localPort,
+ NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
+ return m_endPoints6->Allocate (boundNetDevice,
+ localAddress, localPort,
peerAddress, peerPort);
}
diff --git a/src/internet/model/tcp-l4-protocol.h b/src/internet/model/tcp-l4-protocol.h
index 309955a9e..bbf87b5e9 100644
--- a/src/internet/model/tcp-l4-protocol.h
+++ b/src/internet/model/tcp-l4-protocol.h
@@ -128,26 +128,30 @@ public:
Ipv4EndPoint *Allocate (Ipv4Address address);
/**
* \brief Allocate an IPv4 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param port port to use
* \return the Endpoint
*/
- Ipv4EndPoint *Allocate (uint16_t port);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice, uint16_t port);
/**
* \brief Allocate an IPv4 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param address address to use
* \param port port to use
* \return the Endpoint
*/
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice, Ipv4Address address, uint16_t port);
/**
* \brief Allocate an IPv4 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param localAddress local address to use
* \param localPort local port to use
* \param peerAddress remote address to use
* \param peerPort remote port to use
* \return the Endpoint
*/
- Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice,
+ Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort);
/**
* \brief Allocate an IPv6 Endpoint
@@ -162,26 +166,30 @@ public:
Ipv6EndPoint *Allocate6 (Ipv6Address address);
/**
* \brief Allocate an IPv6 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param port port to use
* \return the Endpoint
*/
- Ipv6EndPoint *Allocate6 (uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ptr boundNetDevice, uint16_t port);
/**
* \brief Allocate an IPv6 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param address address to use
* \param port port to use
* \return the Endpoint
*/
- Ipv6EndPoint *Allocate6 (Ipv6Address address, uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ptr boundNetDevice, Ipv6Address address, uint16_t port);
/**
* \brief Allocate an IPv6 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param localAddress local address to use
* \param localPort local port to use
* \param peerAddress remote address to use
* \param peerPort remote port to use
* \return the Endpoint
*/
- Ipv6EndPoint *Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6EndPoint *Allocate6 (Ptr boundNetDevice,
+ Ipv6Address localAddress, uint16_t localPort,
Ipv6Address peerAddress, uint16_t peerPort);
/**
diff --git a/src/internet/model/tcp-socket-base.cc b/src/internet/model/tcp-socket-base.cc
index d9dd7a26f..1a5faa1bb 100644
--- a/src/internet/model/tcp-socket-base.cc
+++ b/src/internet/model/tcp-socket-base.cc
@@ -579,7 +579,7 @@ TcpSocketBase::Bind (const Address &address)
}
else if (ipv4 == Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_tcp->Allocate (port);
+ m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), port);
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
@@ -587,7 +587,7 @@ TcpSocketBase::Bind (const Address &address)
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_tcp->Allocate (ipv4, port);
+ m_endPoint = m_tcp->Allocate (GetBoundNetDevice (), ipv4, port);
}
if (0 == m_endPoint)
{
@@ -606,7 +606,7 @@ TcpSocketBase::Bind (const Address &address)
}
else if (ipv6 == Ipv6Address::GetAny () && port != 0)
{
- m_endPoint6 = m_tcp->Allocate6 (port);
+ m_endPoint6 = m_tcp->Allocate6 (GetBoundNetDevice (), port);
}
else if (ipv6 != Ipv6Address::GetAny () && port == 0)
{
@@ -614,7 +614,7 @@ TcpSocketBase::Bind (const Address &address)
}
else if (ipv6 != Ipv6Address::GetAny () && port != 0)
{
- m_endPoint6 = m_tcp->Allocate6 (ipv6, port);
+ m_endPoint6 = m_tcp->Allocate6 (GetBoundNetDevice (), ipv6, port);
}
if (0 == m_endPoint6)
{
@@ -991,27 +991,15 @@ TcpSocketBase::BindToNetDevice (Ptr netdevice)
{
NS_LOG_FUNCTION (netdevice);
Socket::BindToNetDevice (netdevice); // Includes sanity check
- if (m_endPoint == 0)
+ if (m_endPoint != 0)
{
- if (Bind () == -1)
- {
- NS_ASSERT (m_endPoint == 0);
- return;
- }
- NS_ASSERT (m_endPoint != 0);
+ m_endPoint->BindToNetDevice (netdevice);
}
- m_endPoint->BindToNetDevice (netdevice);
- if (m_endPoint6 == 0)
+ if (m_endPoint6 != 0)
{
- if (Bind6 () == -1)
- {
- NS_ASSERT (m_endPoint6 == 0);
- return;
- }
- NS_ASSERT (m_endPoint6 != 0);
+ m_endPoint6->BindToNetDevice (netdevice);
}
- m_endPoint6->BindToNetDevice (netdevice);
return;
}
@@ -2577,7 +2565,8 @@ TcpSocketBase::CompleteFork (Ptr p, const TcpHeader& h,
// Get port and address from peer (connecting host)
if (InetSocketAddress::IsMatchingType (toAddress))
{
- m_endPoint = m_tcp->Allocate (InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
+ m_endPoint = m_tcp->Allocate (GetBoundNetDevice (),
+ InetSocketAddress::ConvertFrom (toAddress).GetIpv4 (),
InetSocketAddress::ConvertFrom (toAddress).GetPort (),
InetSocketAddress::ConvertFrom (fromAddress).GetIpv4 (),
InetSocketAddress::ConvertFrom (fromAddress).GetPort ());
@@ -2585,7 +2574,8 @@ TcpSocketBase::CompleteFork (Ptr p, const TcpHeader& h,
}
else if (Inet6SocketAddress::IsMatchingType (toAddress))
{
- m_endPoint6 = m_tcp->Allocate6 (Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
+ m_endPoint6 = m_tcp->Allocate6 (GetBoundNetDevice (),
+ Inet6SocketAddress::ConvertFrom (toAddress).GetIpv6 (),
Inet6SocketAddress::ConvertFrom (toAddress).GetPort (),
Inet6SocketAddress::ConvertFrom (fromAddress).GetIpv6 (),
Inet6SocketAddress::ConvertFrom (fromAddress).GetPort ());
diff --git a/src/internet/model/udp-l4-protocol.cc b/src/internet/model/udp-l4-protocol.cc
index d86ce4683..5e78bb653 100644
--- a/src/internet/model/udp-l4-protocol.cc
+++ b/src/internet/model/udp-l4-protocol.cc
@@ -173,7 +173,7 @@ UdpL4Protocol::CreateSocket (void)
Ipv4EndPoint *
UdpL4Protocol::Allocate (void)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
return m_endPoints->Allocate ();
}
@@ -185,24 +185,26 @@ UdpL4Protocol::Allocate (Ipv4Address address)
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (uint16_t port)
+UdpL4Protocol::Allocate (Ptr boundNetDevice, uint16_t port)
{
- NS_LOG_FUNCTION (this << port);
- return m_endPoints->Allocate (port);
+ NS_LOG_FUNCTION (this << boundNetDevice << port);
+ return m_endPoints->Allocate (boundNetDevice, port);
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
+UdpL4Protocol::Allocate (Ptr boundNetDevice, Ipv4Address address, uint16_t port)
{
- NS_LOG_FUNCTION (this << address << port);
- return m_endPoints->Allocate (address, port);
+ NS_LOG_FUNCTION (this << boundNetDevice << address << port);
+ return m_endPoints->Allocate (boundNetDevice, address, port);
}
Ipv4EndPoint *
-UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
+UdpL4Protocol::Allocate (Ptr boundNetDevice,
+ Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort)
{
- NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
- return m_endPoints->Allocate (localAddress, localPort,
+ NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
+ return m_endPoints->Allocate (boundNetDevice,
+ localAddress, localPort,
peerAddress, peerPort);
}
@@ -216,7 +218,7 @@ UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
Ipv6EndPoint *
UdpL4Protocol::Allocate6 (void)
{
- NS_LOG_FUNCTION_NOARGS ();
+ NS_LOG_FUNCTION (this);
return m_endPoints6->Allocate ();
}
@@ -228,25 +230,27 @@ UdpL4Protocol::Allocate6 (Ipv6Address address)
}
Ipv6EndPoint *
-UdpL4Protocol::Allocate6 (uint16_t port)
+UdpL4Protocol::Allocate6 (Ptr boundNetDevice, uint16_t port)
{
- NS_LOG_FUNCTION (this << port);
- return m_endPoints6->Allocate (port);
+ NS_LOG_FUNCTION (this << boundNetDevice << port);
+ return m_endPoints6->Allocate (boundNetDevice, port);
}
Ipv6EndPoint *
-UdpL4Protocol::Allocate6 (Ipv6Address address, uint16_t port)
+UdpL4Protocol::Allocate6 (Ptr boundNetDevice, Ipv6Address address, uint16_t port)
{
- NS_LOG_FUNCTION (this << address << port);
- return m_endPoints6->Allocate (address, port);
+ NS_LOG_FUNCTION (this << boundNetDevice << address << port);
+ return m_endPoints6->Allocate (boundNetDevice, address, port);
}
Ipv6EndPoint *
-UdpL4Protocol::Allocate6 (Ipv6Address localAddress, uint16_t localPort,
- Ipv6Address peerAddress, uint16_t peerPort)
+UdpL4Protocol::Allocate6 (Ptr boundNetDevice,
+ Ipv6Address localAddress, uint16_t localPort,
+ Ipv6Address peerAddress, uint16_t peerPort)
{
- NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
- return m_endPoints6->Allocate (localAddress, localPort,
- peerAddress, peerPort);
+ NS_LOG_FUNCTION (this << boundNetDevice << localAddress << localPort << peerAddress << peerPort);
+ return m_endPoints6->Allocate (boundNetDevice,
+ localAddress, localPort,
+ peerAddress, peerPort);
}
void
diff --git a/src/internet/model/udp-l4-protocol.h b/src/internet/model/udp-l4-protocol.h
index 80cd0a74e..eb456904c 100644
--- a/src/internet/model/udp-l4-protocol.h
+++ b/src/internet/model/udp-l4-protocol.h
@@ -36,6 +36,7 @@ class Ipv4EndPoint;
class Ipv6EndPointDemux;
class Ipv6EndPoint;
class UdpSocketImpl;
+class NetDevice;
/**
* \ingroup internet
@@ -96,26 +97,30 @@ public:
Ipv4EndPoint *Allocate (Ipv4Address address);
/**
* \brief Allocate an IPv4 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param port port to use
* \return the Endpoint
*/
- Ipv4EndPoint *Allocate (uint16_t port);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice, uint16_t port);
/**
* \brief Allocate an IPv4 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param address address to use
* \param port port to use
* \return the Endpoint
*/
- Ipv4EndPoint *Allocate (Ipv4Address address, uint16_t port);
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice, Ipv4Address address, uint16_t port);
/**
* \brief Allocate an IPv4 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param localAddress local address to use
* \param localPort local port to use
* \param peerAddress remote address to use
* \param peerPort remote port to use
* \return the Endpoint
*/
- Ipv4EndPoint *Allocate (Ipv4Address localAddress, uint16_t localPort,
+ Ipv4EndPoint *Allocate (Ptr boundNetDevice,
+ Ipv4Address localAddress, uint16_t localPort,
Ipv4Address peerAddress, uint16_t peerPort);
/**
@@ -131,26 +136,30 @@ public:
Ipv6EndPoint *Allocate6 (Ipv6Address address);
/**
* \brief Allocate an IPv6 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param port port to use
* \return the Endpoint
*/
- Ipv6EndPoint *Allocate6 (uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ptr boundNetDevice, uint16_t port);
/**
* \brief Allocate an IPv6 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param address address to use
* \param port port to use
* \return the Endpoint
*/
- Ipv6EndPoint *Allocate6 (Ipv6Address address, uint16_t port);
+ Ipv6EndPoint *Allocate6 (Ptr boundNetDevice, Ipv6Address address, uint16_t port);
/**
* \brief Allocate an IPv6 Endpoint
+ * \param boundNetDevice Bound NetDevice (if any)
* \param localAddress local address to use
* \param localPort local port to use
* \param peerAddress remote address to use
* \param peerPort remote port to use
* \return the Endpoint
*/
- Ipv6EndPoint *Allocate6 (Ipv6Address localAddress, uint16_t localPort,
+ Ipv6EndPoint *Allocate6 (Ptr boundNetDevice,
+ Ipv6Address localAddress, uint16_t localPort,
Ipv6Address peerAddress, uint16_t peerPort);
/**
diff --git a/src/internet/model/udp-socket-impl.cc b/src/internet/model/udp-socket-impl.cc
index ced2901c1..2721c68a8 100644
--- a/src/internet/model/udp-socket-impl.cc
+++ b/src/internet/model/udp-socket-impl.cc
@@ -233,6 +233,10 @@ UdpSocketImpl::Bind (void)
{
NS_LOG_FUNCTION_NOARGS ();
m_endPoint = m_udp->Allocate ();
+ if (m_boundnetdevice)
+ {
+ m_endPoint->BindToNetDevice (m_boundnetdevice);
+ }
return FinishBind ();
}
@@ -241,6 +245,10 @@ UdpSocketImpl::Bind6 (void)
{
NS_LOG_FUNCTION_NOARGS ();
m_endPoint6 = m_udp->Allocate6 ();
+ if (m_boundnetdevice)
+ {
+ m_endPoint6->BindToNetDevice (m_boundnetdevice);
+ }
return FinishBind ();
}
@@ -251,7 +259,7 @@ UdpSocketImpl::Bind (const Address &address)
if (InetSocketAddress::IsMatchingType (address))
{
- NS_ASSERT_MSG (m_endPoint == 0, "Endpoint already allocated (maybe you used BindToNetDevice before Bind).");
+ NS_ASSERT_MSG (m_endPoint == 0, "Endpoint already allocated.");
InetSocketAddress transport = InetSocketAddress::ConvertFrom (address);
Ipv4Address ipv4 = transport.GetIpv4 ();
@@ -263,7 +271,7 @@ UdpSocketImpl::Bind (const Address &address)
}
else if (ipv4 == Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_udp->Allocate (port);
+ m_endPoint = m_udp->Allocate (GetBoundNetDevice (), port);
}
else if (ipv4 != Ipv4Address::GetAny () && port == 0)
{
@@ -271,17 +279,22 @@ UdpSocketImpl::Bind (const Address &address)
}
else if (ipv4 != Ipv4Address::GetAny () && port != 0)
{
- m_endPoint = m_udp->Allocate (ipv4, port);
+ m_endPoint = m_udp->Allocate (GetBoundNetDevice (), ipv4, port);
}
if (0 == m_endPoint)
{
m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
return -1;
}
+ if (m_boundnetdevice)
+ {
+ m_endPoint->BindToNetDevice (m_boundnetdevice);
+ }
+
}
else if (Inet6SocketAddress::IsMatchingType (address))
{
- NS_ASSERT_MSG (m_endPoint == 0, "Endpoint already allocated (maybe you used BindToNetDevice before Bind).");
+ NS_ASSERT_MSG (m_endPoint == 0, "Endpoint already allocated.");
Inet6SocketAddress transport = Inet6SocketAddress::ConvertFrom (address);
Ipv6Address ipv6 = transport.GetIpv6 ();
@@ -292,7 +305,7 @@ UdpSocketImpl::Bind (const Address &address)
}
else if (ipv6 == Ipv6Address::GetAny () && port != 0)
{
- m_endPoint6 = m_udp->Allocate6 (port);
+ m_endPoint6 = m_udp->Allocate6 (GetBoundNetDevice (), port);
}
else if (ipv6 != Ipv6Address::GetAny () && port == 0)
{
@@ -300,19 +313,32 @@ UdpSocketImpl::Bind (const Address &address)
}
else if (ipv6 != Ipv6Address::GetAny () && port != 0)
{
- m_endPoint6 = m_udp->Allocate6 (ipv6, port);
+ m_endPoint6 = m_udp->Allocate6 (GetBoundNetDevice (), ipv6, port);
}
if (0 == m_endPoint6)
{
m_errno = port ? ERROR_ADDRINUSE : ERROR_ADDRNOTAVAIL;
return -1;
}
+ if (m_boundnetdevice)
+ {
+ m_endPoint6->BindToNetDevice (m_boundnetdevice);
+ }
+
if (ipv6.IsMulticast ())
{
Ptr ipv6l3 = m_node->GetObject ();
if (ipv6l3)
{
- ipv6l3->AddMulticastAddress (ipv6);
+ if (m_boundnetdevice == 0)
+ {
+ ipv6l3->AddMulticastAddress (ipv6);
+ }
+ else
+ {
+ uint32_t index = ipv6l3->GetInterfaceForDevice (m_boundnetdevice);
+ ipv6l3->AddMulticastAddress (m_endPoint6->GetLocalAddress (), index);
+ }
}
}
}
@@ -928,37 +954,46 @@ UdpSocketImpl::BindToNetDevice (Ptr netdevice)
{
NS_LOG_FUNCTION (netdevice);
+ Ptr oldBoundNetDevice = m_boundnetdevice;
+
Socket::BindToNetDevice (netdevice); // Includes sanity check
- if (m_endPoint == 0)
+ if (m_endPoint != 0)
{
- if (Bind () == -1)
- {
- NS_ASSERT (m_endPoint == 0);
- return;
- }
- NS_ASSERT (m_endPoint != 0);
+ m_endPoint->BindToNetDevice (netdevice);
}
- m_endPoint->BindToNetDevice (netdevice);
- if (m_endPoint6 == 0)
+ if (m_endPoint6 != 0)
{
- if (Bind6 () == -1)
- {
- NS_ASSERT (m_endPoint6 == 0);
- return;
- }
- NS_ASSERT (m_endPoint6 != 0);
- }
- m_endPoint6->BindToNetDevice (netdevice);
+ m_endPoint6->BindToNetDevice (netdevice);
- if (m_endPoint6->GetLocalAddress ().IsMulticast ())
- {
- Ptr ipv6l3 = m_node->GetObject ();
- if (ipv6l3)
+ // The following is to fix the multicast distribution inside the node
+ // and to upgrade it to the actual bound NetDevice.
+ if (m_endPoint6->GetLocalAddress ().IsMulticast ())
{
- uint32_t index = ipv6l3->GetInterfaceForDevice (netdevice);
- ipv6l3->RemoveMulticastAddress (m_endPoint6->GetLocalAddress ());
- ipv6l3->AddMulticastAddress (m_endPoint6->GetLocalAddress (), index);
+ Ptr ipv6l3 = m_node->GetObject ();
+ if (ipv6l3)
+ {
+ // Cleanup old one
+ if (oldBoundNetDevice)
+ {
+ uint32_t index = ipv6l3->GetInterfaceForDevice (oldBoundNetDevice);
+ ipv6l3->RemoveMulticastAddress (m_endPoint6->GetLocalAddress (), index);
+ }
+ else
+ {
+ ipv6l3->RemoveMulticastAddress (m_endPoint6->GetLocalAddress ());
+ }
+ // add new one
+ if (netdevice)
+ {
+ uint32_t index = ipv6l3->GetInterfaceForDevice (netdevice);
+ ipv6l3->AddMulticastAddress (m_endPoint6->GetLocalAddress (), index);
+ }
+ else
+ {
+ ipv6l3->AddMulticastAddress (m_endPoint6->GetLocalAddress ());
+ }
+ }
}
}
diff --git a/src/internet/test/ipv4-rip-test.cc b/src/internet/test/ipv4-rip-test.cc
index 84df8ff25..e66c86402 100644
--- a/src/internet/test/ipv4-rip-test.cc
+++ b/src/internet/test/ipv4-rip-test.cc
@@ -665,8 +665,8 @@ Ipv4RipSplitHorizonStrategyTest::DoRun (void)
// Create the UDP sockets
Ptr rxSocketFactory = listener->GetObject ();
Ptr rxSocket = rxSocketFactory->CreateSocket ();
- NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("224.0.0.9"), 520)), 0, "trivial");
rxSocket->BindToNetDevice (listenerDev);
+ NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (InetSocketAddress (Ipv4Address ("224.0.0.9"), 520)), 0, "trivial");
rxSocket->SetRecvCallback (MakeCallback (&Ipv4RipSplitHorizonStrategyTest::ReceivePktProbe, this));
// ------ Now the tests ------------
diff --git a/src/internet/test/ipv6-ripng-test.cc b/src/internet/test/ipv6-ripng-test.cc
index 32d40ac9e..2c42c72ef 100644
--- a/src/internet/test/ipv6-ripng-test.cc
+++ b/src/internet/test/ipv6-ripng-test.cc
@@ -662,8 +662,8 @@ Ipv6RipngSplitHorizonStrategyTest::DoRun (void)
// Create the UDP sockets
Ptr rxSocketFactory = listener->GetObject ();
Ptr rxSocket = rxSocketFactory->CreateSocket ();
- NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("ff02::9"), 521)), 0, "trivial");
rxSocket->BindToNetDevice (listenerDev);
+ NS_TEST_EXPECT_MSG_EQ (rxSocket->Bind (Inet6SocketAddress (Ipv6Address ("ff02::9"), 521)), 0, "trivial");
rxSocket->SetRecvCallback (MakeCallback (&Ipv6RipngSplitHorizonStrategyTest::ReceivePktProbe, this));
// ------ Now the tests ------------
diff --git a/src/network/model/socket.h b/src/network/model/socket.h
index 2493acba9..8b6feb8cb 100644
--- a/src/network/model/socket.h
+++ b/src/network/model/socket.h
@@ -616,16 +616,13 @@ public:
* is also possible to bind to mismatching device and address, even if
* the socket can not receive any packets as a result.
*
- * \warning BindToNetDevice should be used \a after Bind. Otherwise
- * it will perform a Bind itself.
- *
- * \param netdevice Pointer to Netdevice of desired interface
+ * \param netdevice Pointer to NetDevice of desired interface
* \returns nothing
*/
virtual void BindToNetDevice (Ptr netdevice);
/**
- * \brief Returns socket's bound netdevice, if any.
+ * \brief Returns socket's bound NetDevice, if any.
*
* This method corresponds to using getsockopt() SO_BINDTODEVICE
* of real network or BSD sockets.
diff --git a/src/olsr/model/olsr-routing-protocol.cc b/src/olsr/model/olsr-routing-protocol.cc
index 768df682c..1c316882c 100644
--- a/src/olsr/model/olsr-routing-protocol.cc
+++ b/src/olsr/model/olsr-routing-protocol.cc
@@ -368,11 +368,11 @@ void RoutingProtocol::DoInitialize ()
socket->SetAllowBroadcast (true);
InetSocketAddress inetAddr (m_ipv4->GetAddress (i, 0).GetLocal (), OLSR_PORT_NUMBER);
socket->SetRecvCallback (MakeCallback (&RoutingProtocol::RecvOlsr, this));
+ socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
if (socket->Bind (inetAddr))
{
NS_FATAL_ERROR ("Failed to bind() OLSR socket");
}
- socket->BindToNetDevice (m_ipv4->GetNetDevice (i));
socket->SetRecvPktInfo (true);
m_sendSockets[socket] = m_ipv4->GetAddress (i, 0);
diff --git a/src/wave/model/bsm-application.cc b/src/wave/model/bsm-application.cc
index e912641ea..3c46bdcd1 100644
--- a/src/wave/model/bsm-application.cc
+++ b/src/wave/model/bsm-application.cc
@@ -101,8 +101,8 @@ void BsmApplication::StartApplication () // Called at time specified by Start
Ptr recvSink = Socket::CreateSocket (GetNode (m_nodeId), tid);
recvSink->SetRecvCallback (MakeCallback (&BsmApplication::ReceiveWavePacket, this));
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), wavePort);
- recvSink->Bind (local);
recvSink->BindToNetDevice (GetNetDevice (m_nodeId));
+ recvSink->Bind (local);
recvSink->SetAllowBroadcast (true);
// dest is broadcast address