# HG changeset patch # User Tom Henderson # Date 1258617712 28800 # Node ID 3ae01ecdc952c2574166da92807257316a40a2d4 # Parent 7f0de9a416ea6ff9928955ac3c9361b4b9334268 Add new method for determining whether Ipv4 dest address is mine; add attribute to control rfc1122 behavior diff -r 7f0de9a416ea -r 3ae01ecdc952 CHANGES.html --- a/CHANGES.html Wed Nov 18 12:42:33 2009 +0000 +++ b/CHANGES.html Thu Nov 19 00:01:52 2009 -0800 @@ -59,9 +59,10 @@ by the ns-3 logging system to report the execution context of each log line.
  • Object::DoStart: Users who need to complete their object setup at the start of a simulation can override this virtual method, perform their adhoc setup, and then, must chain up to their parent. -
  • Aod hoc On-Demand Distance Vector (AODV) routing model, RFC 3561
  • +
  • Ipv4::IsDestinationAddress (Ipv4Address address, uint32_t iif) Method added to support checks of whether a destination address should be accepted +as one of the host's own addresses. RFC 1122 Strong/Weak end system behavior can be changed with a new attribute (WeakEsModel) in class Ipv4.
  • diff -r 7f0de9a416ea -r 3ae01ecdc952 src/internet-stack/ipv4-l3-protocol.cc --- a/src/internet-stack/ipv4-l3-protocol.cc Wed Nov 18 12:42:33 2009 +0000 +++ b/src/internet-stack/ipv4-l3-protocol.cc Thu Nov 19 00:01:52 2009 -0800 @@ -355,6 +355,70 @@ return -1; } +bool +Ipv4L3Protocol::IsDestinationAddress (Ipv4Address address, uint32_t iif) const +{ + NS_LOG_FUNCTION (this << address << " " << iif); + + // First check the incoming interface for a unicast address match + for (uint32_t i = 0; i < GetNAddresses (iif); i++) + { + Ipv4InterfaceAddress iaddr = GetAddress (iif, i); + if (address == iaddr.GetLocal ()) + { + NS_LOG_LOGIC ("For me (destination " << address << " match)"); + return true; + } + if (address == iaddr.GetBroadcast ()) + { + NS_LOG_LOGIC ("For me (interface broadcast address)"); + return true; + } + } + + if (address.IsMulticast ()) + { +#ifdef NOTYET + if (MulticastCheckGroup (iif, address )) +#endif + if (true) + { + NS_LOG_LOGIC ("For me (Ipv4Addr multicast address"); + return true; + } + } + + if (address.IsBroadcast ()) + { + NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)"); + return true; + } + + if (GetWeakEsModel ()) // Check other interfaces + { + for (uint32_t j = 0; j < GetNInterfaces (); j++) + { + if (j == uint32_t (iif)) continue; + for (uint32_t i = 0; i < GetNAddresses (j); i++) + { + Ipv4InterfaceAddress iaddr = GetAddress (j, i); + if (address == iaddr.GetLocal ()) + { + NS_LOG_LOGIC ("For me (destination " << address << " match) on another interface"); + return true; + } + // This is a small corner case: match another interface's broadcast address + if (address == iaddr.GetBroadcast ()) + { + NS_LOG_LOGIC ("For me (interface broadcast address on another interface)"); + return true; + } + } + } + } + return false; +} + void Ipv4L3Protocol::Receive( Ptr device, Ptr p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType) @@ -901,6 +965,18 @@ return m_ipForward; } +void +Ipv4L3Protocol::SetWeakEsModel (bool model) +{ + m_weakEsModel = model; +} + +bool +Ipv4L3Protocol::GetWeakEsModel (void) const +{ + return m_weakEsModel; +} + void Ipv4L3Protocol::RouteInputError (Ptr p, const Ipv4Header & ipHeader, Socket::SocketErrno sockErrno) { diff -r 7f0de9a416ea -r 3ae01ecdc952 src/internet-stack/ipv4-l3-protocol.h --- a/src/internet-stack/ipv4-l3-protocol.h Wed Nov 18 12:42:33 2009 +0000 +++ b/src/internet-stack/ipv4-l3-protocol.h Thu Nov 19 00:01:52 2009 -0800 @@ -170,6 +170,7 @@ int32_t GetInterfaceForAddress (Ipv4Address addr) const; int32_t GetInterfaceForPrefix (Ipv4Address addr, Ipv4Mask mask) const; int32_t GetInterfaceForDevice (Ptr device) const; + bool IsDestinationAddress (Ipv4Address address, uint32_t iif) const; bool AddAddress (uint32_t i, Ipv4InterfaceAddress address); Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const; @@ -200,8 +201,11 @@ Ipv4L3Protocol(const Ipv4L3Protocol &); Ipv4L3Protocol &operator = (const Ipv4L3Protocol &); + // class Ipv4 attributes virtual void SetIpForward (bool forward); virtual bool GetIpForward (void) const; + virtual void SetWeakEsModel (bool model); + virtual bool GetWeakEsModel (void) const; Ipv4Header BuildHeader ( Ipv4Address source, @@ -239,6 +243,7 @@ typedef std::list > L4List_t; bool m_ipForward; + bool m_weakEsModel; L4List_t m_protocols; Ipv4InterfaceList m_interfaces; uint8_t m_defaultTtl; diff -r 7f0de9a416ea -r 3ae01ecdc952 src/node/ipv4.cc --- a/src/node/ipv4.cc Wed Nov 18 12:42:33 2009 +0000 +++ b/src/node/ipv4.cc Thu Nov 19 00:01:52 2009 -0800 @@ -37,6 +37,12 @@ MakeBooleanAccessor (&Ipv4::SetIpForward, &Ipv4::GetIpForward), MakeBooleanChecker ()) + .AddAttribute ("WeakEsModel", + "RFC1122 term for whether host accepts datagram with a dest. address on another interface", + BooleanValue (true), + MakeBooleanAccessor (&Ipv4::SetWeakEsModel, + &Ipv4::GetWeakEsModel), + MakeBooleanChecker ()) #if 0 .AddAttribute ("MtuDiscover", "If enabled, every outgoing ip packet will have the DF flag set.", BooleanValue (false), diff -r 7f0de9a416ea -r 3ae01ecdc952 src/node/ipv4.h --- a/src/node/ipv4.h Wed Nov 18 12:42:33 2009 +0000 +++ b/src/node/ipv4.h Thu Nov 19 00:01:52 2009 -0800 @@ -123,11 +123,33 @@ * This method searches the list of interfaces for one that holds a * particular address. This call takes an IP address as a parameter and * returns the interface number of the first interface that has been assigned - * that address, or -1 if not found. There must be an exact match. + * that address, or -1 if not found. There must be an exact match; this + * method will not match broadcast or multicast addresses. */ virtual int32_t GetInterfaceForAddress (Ipv4Address address) const = 0; /** + * \brief Determine whether address and interface corresponding to + * received packet can be accepted for local delivery + * + * \param address The IP address being considered + * \param iif The incoming Ipv4 interface index + * + * This method can be used to determine whether a received packet has + * an acceptable address for local delivery on the host. The address + * may be a unicast, multicast, or broadcast address. This method will + * return true if address is an exact match of a unicast address on + * one of the host's interfaces (see below), if address corresponds to + * a multicast group that the host has joined (and the incoming device + * is acceptable), or if address corresponds to a broadcast address. + * + * If the Ipv4 attribute WeakEsModel is true, the unicast address may + * match any of the Ipv4 addresses on any interface. If the attribute is + * false, the address must match one assigned to the incoming device. + */ + virtual bool IsDestinationAddress (Ipv4Address address, uint32_t iif) const = 0; + + /** * \brief Return the interface number of first interface found that * has an Ipv4 address within the prefix specified by the input * address and mask parameters @@ -257,6 +279,8 @@ // Indirect the Ipv4 attributes through private pure virtual methods virtual void SetIpForward (bool forward) = 0; virtual bool GetIpForward (void) const = 0; + virtual void SetWeakEsModel (bool model) = 0; + virtual bool GetWeakEsModel (void) const = 0; }; } // namespace ns3 diff -r 7f0de9a416ea -r 3ae01ecdc952 src/routing/list-routing/ipv4-list-routing.cc --- a/src/routing/list-routing/ipv4-list-routing.cc Wed Nov 18 12:42:33 2009 +0000 +++ b/src/routing/list-routing/ipv4-list-routing.cc Thu Nov 19 00:01:52 2009 -0800 @@ -121,75 +121,21 @@ NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); - // Multicast recognition; handle local delivery here - // - if (header.GetDestination().IsMulticast ()) + retVal = m_ipv4->IsDestinationAddress (header.GetDestination (), iif); + if (retVal == true) { -#ifdef NOTYET - if (m_ipv4->MulticastCheckGroup (iif, header.GetDestination ())) -#endif - if (true) + NS_LOG_LOGIC ("Address "<< header.GetDestination () << " is a match for local delivery"); + if (header.GetDestination ().IsMulticast ()) { - NS_LOG_LOGIC ("Multicast packet for me-- local deliver"); Ptr packetCopy = p->Copy(); - // Here may want to disable lcb callback in recursive RouteInput - // call below lcb (packetCopy, header, iif); - // Fall through-- we may also need to forward this retVal = true; + // Fall through } - for (Ipv4RoutingProtocolList::const_iterator rprotoIter = - m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); - rprotoIter++) + else { - NS_LOG_LOGIC ("Multicast packet for me-- trying to forward"); - if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) - { - retVal = true; - } - } - return retVal; - } - - if (header.GetDestination ().IsBroadcast ()) - { - NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)"); - // TODO: Local Deliver for broadcast - // TODO: Forward broadcast - } - - // TODO: Configurable option to enable RFC 1222 Strong End System Model - // Right now, we will be permissive and allow a source to send us - // a packet to one of our other interface addresses; that is, the - // destination unicast address does not match one of the iif addresses, - // but we check our other interfaces. This could be an option - // (to remove the outer loop immediately below and just check iif). - for (uint32_t j = 0; j < m_ipv4->GetNInterfaces (); j++) - { - for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++) - { - Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i); - Ipv4Address addr = iaddr.GetLocal (); - if (addr.IsEqual (header.GetDestination ())) - { - if (j == iif) - { - NS_LOG_LOGIC ("For me (destination " << addr << " match)"); - } - else - { - NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ()); - } - lcb (p, header, iif); - return true; - } - if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ())) - { - NS_LOG_LOGIC ("For me (interface broadcast address)"); - lcb (p, header, iif); - return true; - } - NS_LOG_LOGIC ("Address "<< addr << " not a match"); + lcb (p, header, iif); + return true; } } // Check if input device supports IP forwarding @@ -200,14 +146,24 @@ return false; } // Next, try to find a route + // If we have already delivered a packet locally (e.g. multicast) + // we suppress further downstream local delivery by nulling the callback + LocalDeliverCallback downstreamLcb = lcb; + if (retVal == true) + { + downstreamLcb = MakeNullCallback, const Ipv4Header &, uint32_t > (); + } for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); rprotoIter++) { - if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) + if (retVal == false) { - return true; + if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, downstreamLcb, ecb)) + { + return true; + } } } // No routing protocol has found a route.