diff --git a/src/internet-stack/ipv4-interface.cc b/src/internet-stack/ipv4-interface.cc index b7fbd7828..ac841e96c 100644 --- a/src/internet-stack/ipv4-interface.cc +++ b/src/internet-stack/ipv4-interface.cc @@ -56,6 +56,7 @@ Ipv4Interface::GetTypeId (void) */ Ipv4Interface::Ipv4Interface () : m_ifup (false), + m_forwarding (true), m_metric (1), m_node (0), m_device (0), @@ -160,6 +161,20 @@ Ipv4Interface::SetDown (void) m_ifup = false; } +bool +Ipv4Interface::IsForwarding (void) const +{ + NS_LOG_FUNCTION_NOARGS (); + return m_forwarding; +} + +void +Ipv4Interface::SetForwarding (bool val) +{ + NS_LOG_FUNCTION_NOARGS (); + m_forwarding = val; +} + void Ipv4Interface::Send (Ptr p, Ipv4Address dest) { diff --git a/src/internet-stack/ipv4-interface.h b/src/internet-stack/ipv4-interface.h index f3041a780..0dcf732bb 100644 --- a/src/internet-stack/ipv4-interface.h +++ b/src/internet-stack/ipv4-interface.h @@ -105,6 +105,16 @@ public: */ void SetDown (void); + /** + * \returns true if this interface is enabled for IP forwarding of input datagrams + */ + bool IsForwarding (void) const; + + /** + * \param val Whether to enable or disable IP forwarding for input datagrams + */ + void SetForwarding (bool val); + /** * \param p packet to send * \param dest next hop address of packet. @@ -146,6 +156,7 @@ private: typedef std::list::iterator Ipv4InterfaceAddressListI; bool m_ifup; + bool m_forwarding; // IN_DEV_FORWARD uint16_t m_metric; Ipv4InterfaceAddressList m_ifaddrs; Ptr m_node; diff --git a/src/internet-stack/ipv4-l3-protocol.cc b/src/internet-stack/ipv4-l3-protocol.cc index ea6762321..17e6dd190 100644 --- a/src/internet-stack/ipv4-l3-protocol.cc +++ b/src/internet-stack/ipv4-l3-protocol.cc @@ -251,6 +251,7 @@ Ipv4L3Protocol::AddInterface (Ptr device) Ptr interface = CreateObject (); interface->SetNode (m_node); interface->SetDevice (device); + interface->SetForwarding (m_ipForward); return AddIpv4Interface (interface); } @@ -412,7 +413,7 @@ Ipv4L3Protocol::Receive( Ptr device, Ptr p, uint16_t pr MakeCallback (&Ipv4L3Protocol::IpForward, this), MakeCallback (&Ipv4L3Protocol::IpMulticastForward, this), MakeCallback (&Ipv4L3Protocol::LocalDeliver, this), - MakeNullCallback , const Ipv4Header &> () + MakeCallback (&Ipv4L3Protocol::RouteInputError, this) ); } @@ -845,16 +846,39 @@ Ipv4L3Protocol::SetDown (uint32_t ifaceIndex) } } +bool +Ipv4L3Protocol::IsForwarding (uint32_t i) const +{ + NS_LOG_FUNCTION (this << i); + Ptr interface = GetInterface (i); + NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ()); + return interface->IsForwarding (); +} + +void +Ipv4L3Protocol::SetForwarding (uint32_t i, bool val) +{ + NS_LOG_FUNCTION (this << i); + Ptr interface = GetInterface (i); + interface->SetForwarding (val); +} + Ptr Ipv4L3Protocol::GetNetDevice (uint32_t i) { + NS_LOG_FUNCTION (this << i); return GetInterface (i)-> GetDevice (); } void Ipv4L3Protocol::SetIpForward (bool forward) { + NS_LOG_FUNCTION (this << forward); m_ipForward = forward; + for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) + { + (*i)->SetForwarding (forward); + } } bool @@ -863,5 +887,13 @@ Ipv4L3Protocol::GetIpForward (void) const return m_ipForward; } +void +Ipv4L3Protocol::RouteInputError (Ptr p, const Ipv4Header & ipHeader, Socket::SocketErrno sockErrno) +{ + NS_LOG_FUNCTION (this << p << ipHeader << sockErrno); + NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno); + m_dropTrace (p); +} + }//namespace ns3 diff --git a/src/internet-stack/ipv4-l3-protocol.h b/src/internet-stack/ipv4-l3-protocol.h index f39bc6cef..1dc09df4f 100644 --- a/src/internet-stack/ipv4-l3-protocol.h +++ b/src/internet-stack/ipv4-l3-protocol.h @@ -152,6 +152,8 @@ public: bool IsUp (uint32_t i) const; void SetUp (uint32_t i); void SetDown (uint32_t i); + bool IsForwarding (uint32_t i) const; + void SetForwarding (uint32_t i, bool val); Ptr GetNetDevice (uint32_t i); @@ -198,6 +200,8 @@ private: const Ipv4Header &header); void LocalDeliver (Ptr p, Ipv4Header const&ip, uint32_t iif); + void RouteInputError (Ptr p, const Ipv4Header & ipHeader, Socket::SocketErrno sockErrno); + uint32_t AddIpv4Interface (Ptr interface); void SetupLoopback (void); Ptr GetIcmp (void) const; diff --git a/src/node/ipv4-routing-protocol.h b/src/node/ipv4-routing-protocol.h index 1e1074b05..aa5d2eb4f 100644 --- a/src/node/ipv4-routing-protocol.h +++ b/src/node/ipv4-routing-protocol.h @@ -51,7 +51,7 @@ public: typedef Callback, Ptr, const Ipv4Header &> UnicastForwardCallback; typedef Callback, Ptr, const Ipv4Header &> MulticastForwardCallback; typedef Callback, const Ipv4Header &, uint32_t > LocalDeliverCallback; - typedef Callback, const Ipv4Header &> ErrorCallback; + typedef Callback, const Ipv4Header &, Socket::SocketErrno > ErrorCallback; /** * \brief Query routing cache for an existing route, for an outbound packet diff --git a/src/node/ipv4.cc b/src/node/ipv4.cc index 8bf9a32f2..8ec7b14dd 100644 --- a/src/node/ipv4.cc +++ b/src/node/ipv4.cc @@ -32,7 +32,7 @@ Ipv4::GetTypeId (void) { static TypeId tid = TypeId ("ns3::Ipv4") .SetParent () - .AddAttribute ("IpForward", "If enabled, node can act as unicast router.", + .AddAttribute ("IpForward", "Globally enable or disable IP forwarding for all current and future Ipv4 devices.", BooleanValue (true), MakeBooleanAccessor (&Ipv4::SetIpForward, &Ipv4::GetIpForward), diff --git a/src/node/ipv4.h b/src/node/ipv4.h index e399b552c..301b87769 100644 --- a/src/node/ipv4.h +++ b/src/node/ipv4.h @@ -235,6 +235,20 @@ public: */ virtual void SetDown (uint32_t interface) = 0; + /** + * \param interface Interface number of Ipv4 interface + * \returns true if IP forwarding enabled for input datagrams on this device + */ + virtual bool IsForwarding (uint32_t interface) const = 0; + + /** + * \param interface Interface number of Ipv4 interface + * \param val Value to set the forwarding flag + * + * If set to true, IP forwarding is enabled for input datagrams on this device + */ + virtual void SetForwarding (uint32_t interface, bool val) = 0; + static const uint32_t IF_ANY = 0xffffffff; private: diff --git a/src/routing/global-routing/global-router-interface.cc b/src/routing/global-routing/global-router-interface.cc index 60ed2dfd4..d7043a51d 100644 --- a/src/routing/global-routing/global-router-interface.cc +++ b/src/routing/global-routing/global-router-interface.cc @@ -605,19 +605,20 @@ GlobalRouter::DiscoverLSAs (void) // associated with a bridge. We are only going to involve devices with // IP addresses in routing. // - bool isIp = false; + bool isForwarding = false; for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j ) { - if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j)) + if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j) && + ipv4Local->IsForwarding (j)) { - isIp = true; + isForwarding = true; break; } } - if (!isIp) + if (!isForwarding) { - NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface, skipping"); + NS_LOG_LOGIC ("Net device " << ndLocal << "has no IP interface or is not enabled for forwarding, skipping"); continue; } @@ -630,6 +631,7 @@ GlobalRouter::DiscoverLSAs (void) // If the device is a point to point link, we treat it separately. In // that case, there may be zero, one, or two link records added. // + if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () ) { NS_LOG_LOGIC ("Broadcast link"); diff --git a/src/routing/list-routing/ipv4-list-routing.cc b/src/routing/list-routing/ipv4-list-routing.cc index 348a9dae4..394523848 100644 --- a/src/routing/list-routing/ipv4-list-routing.cc +++ b/src/routing/list-routing/ipv4-list-routing.cc @@ -104,6 +104,8 @@ Ipv4ListRouting::RouteInput (Ptr p, const Ipv4Header &header, Ptr< NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv4->GetObject ()->GetId ()); NS_ASSERT (m_ipv4 != 0); + // Check if input device supports IP + NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); // Multicast recognition; handle local delivery here @@ -177,6 +179,13 @@ Ipv4ListRouting::RouteInput (Ptr p, const Ipv4Header &header, Ptr< NS_LOG_LOGIC ("Address "<< addr << " not a match"); } } + // Check if input device supports IP forwarding + if (m_ipv4->IsForwarding (iif) == false) + { + NS_LOG_LOGIC ("Forwarding disabled for this interface"); + ecb (p, header, Socket::ERROR_NOROUTETOHOST); + return false; + } // Next, try to find a route for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin ();