--- a/CHANGES.html Wed Nov 18 12:42:33 2009 +0000
+++ a/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.
--- a/src/internet-stack/ipv4-l3-protocol.cc Wed Nov 18 12:42:33 2009 +0000
+++ a/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)
{
--- a/src/internet-stack/ipv4-l3-protocol.h Wed Nov 18 12:42:33 2009 +0000
+++ a/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;
--- a/src/node/ipv4.cc Wed Nov 18 12:42:33 2009 +0000
+++ a/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),
--- a/src/node/ipv4.h Wed Nov 18 12:42:33 2009 +0000
+++ a/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
--- a/src/routing/list-routing/ipv4-list-routing.cc Wed Nov 18 12:42:33 2009 +0000
+++ a/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.