diff --git a/src/internet/model/ipv6-end-point-demux.cc b/src/internet/model/ipv6-end-point-demux.cc index 97460a5aa..9bd886759 100644 --- a/src/internet/model/ipv6-end-point-demux.cc +++ b/src/internet/model/ipv6-end-point-demux.cc @@ -195,6 +195,18 @@ Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup (Ipv6Address daddr, uint1 continue; } + if (endP->GetBoundNetDevice ()) + { + if (endP->GetBoundNetDevice () != incomingInterface->GetDevice ()) + { + NS_LOG_LOGIC ("Skipping endpoint " << &endP + << " because endpoint is bound to specific device and" + << endP->GetBoundNetDevice () + << " does not match packet device " << incomingInterface->GetDevice ()); + continue; + } + } + /* Ipv6Address incomingInterfaceAddr = incomingInterface->GetAddress (); */ NS_LOG_DEBUG ("dest addr " << daddr); diff --git a/src/internet/model/ipv6-end-point.cc b/src/internet/model/ipv6-end-point.cc index 157d10621..c0d561cd5 100644 --- a/src/internet/model/ipv6-end-point.cc +++ b/src/internet/model/ipv6-end-point.cc @@ -78,6 +78,17 @@ uint16_t Ipv6EndPoint::GetPeerPort () return m_peerPort; } +void Ipv6EndPoint::BindToNetDevice (Ptr netdevice) +{ + m_boundnetdevice = netdevice; + return; +} + +Ptr Ipv6EndPoint::GetBoundNetDevice (void) +{ + return m_boundnetdevice; +} + void Ipv6EndPoint::SetPeer (Ipv6Address addr, uint16_t port) { m_peerAddr = addr; diff --git a/src/internet/model/ipv6-end-point.h b/src/internet/model/ipv6-end-point.h index 43a1335ec..9fc8d951a 100644 --- a/src/internet/model/ipv6-end-point.h +++ b/src/internet/model/ipv6-end-point.h @@ -26,6 +26,7 @@ #include "ns3/ipv6-address.h" #include "ns3/callback.h" #include "ns3/ipv6-header.h" +#include "ns3/net-device.h" namespace ns3 { @@ -95,6 +96,38 @@ public: */ void SetPeer (Ipv6Address addr, uint16_t port); + /** + * \brief Bind a socket to specific device. + * + * This method corresponds to using setsockopt() SO_BINDTODEVICE + * of real network or BSD sockets. If set on a socket, this option will + * force packets to leave the bound device regardless of the device that + * IP routing would naturally choose. In the receive direction, only + * packets received from the bound interface will be delivered. + * + * This option has no particular relationship to binding sockets to + * an address via Socket::Bind (). It is possible to bind sockets to a + * specific IP address on the bound interface by calling both + * Socket::Bind (address) and Socket::BindToNetDevice (device), but it + * is also possible to bind to mismatching device and address, even if + * the socket can not receive any packets as a result. + * + * \param netdevice Pointer to Netdevice of desired interface + * \returns nothing + */ + void BindToNetDevice (Ptr netdevice); + + /** + * \brief Returns socket's bound netdevice, if any. + * + * This method corresponds to using getsockopt() SO_BINDTODEVICE + * of real network or BSD sockets. + * + * + * \returns Pointer to interface. + */ + Ptr GetBoundNetDevice (void); + /** * \brief Set the reception callback. * \param callback callback function @@ -175,6 +208,11 @@ private: */ uint16_t m_peerPort; + /** + * \brief The NetDevice the EndPoint is bound to (if any). + */ + Ptr m_boundnetdevice; + /** * \brief The RX callback. */ diff --git a/src/internet/model/ipv6-raw-socket-impl.cc b/src/internet/model/ipv6-raw-socket-impl.cc index 51d556b01..4e3f9be39 100644 --- a/src/internet/model/ipv6-raw-socket-impl.cc +++ b/src/internet/model/ipv6-raw-socket-impl.cc @@ -317,6 +317,15 @@ bool Ipv6RawSocketImpl::ForwardUp (Ptr p, Ipv6Header hdr, Ptr boundNetDevice = Socket::GetBoundNetDevice(); + if (boundNetDevice) + { + if (boundNetDevice != device) + { + return false; + } + } + if ((m_src == Ipv6Address::GetAny () || hdr.GetDestinationAddress () == m_src) && (m_dst == Ipv6Address::GetAny () || hdr.GetSourceAddress () == m_dst) && hdr.GetNextHeader () == m_protocol)