more multicast plumbing
authorCraig Dowell <craigdo@ee.washington.edu>
Mon, 13 Aug 2007 12:08:01 -0700
changeset 1432 3aef7d7a71c2
parent 1431 3760d52ef5d1
child 1433 a6fb891b59fd
more multicast plumbing
examples/csma-multicast.cc
src/applications/onoff-application.cc
src/devices/csma/csma-ipv4-topology.cc
src/devices/csma/csma-ipv4-topology.h
src/internet-node/arp-ipv4-interface.cc
src/internet-node/ipv4-l3-protocol.cc
src/internet-node/ipv4-l3-protocol.h
src/internet-node/ipv4-static-routing.cc
src/internet-node/ipv4-static-routing.h
src/node/ipv4-address.cc
src/node/ipv4.h
--- a/examples/csma-multicast.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/examples/csma-multicast.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -65,7 +65,7 @@
 {
   // Users may find it convenient to turn on explicit debugging
   // for selected modules; the below lines suggest how to do this
-#if 0 
+#if 0
   DebugComponentEnable("Me");
   DebugComponentEnable("Object");
   DebugComponentEnable("Queue");
@@ -87,16 +87,9 @@
 #endif
 
   DebugComponentEnable("Me");
-  DebugComponentEnable("OnOffApplication");
-  DebugComponentEnable("UdpSocket");
+  DebugComponentEnable("CsmaChannel");
+  DebugComponentEnable("CsmaNetDevice");
   DebugComponentEnable("UdpL4Protocol");
-  DebugComponentEnable("Ipv4L3Protocol");
-  DebugComponentEnable("Ipv4StaticRouting");
-  DebugComponentEnable("CsmaNetDevice");
-  DebugComponentEnable("CsmaChannel");
-  DebugComponentEnable("Ipv4Interface");
-  DebugComponentEnable("ArpIpv4Interface");
-  DebugComponentEnable("Ipv4LoopbackInterface");
 
   // Set up some default values for the simulation.  Use the Bind()
   // technique to tell the system what subclass of Queue to use,
@@ -125,29 +118,47 @@
       DataRate(5000000), MilliSeconds(2));
 
   NS_DEBUG("Build Topology.");
-  uint32_t n0ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n0, channel0, 
-                                         Eui48Address("10:54:23:54:23:50"));
-  uint32_t n1ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n1, channel0,
-                                         Eui48Address("10:54:23:54:23:51"));
-  uint32_t n2ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n2, channel0,
-                                         Eui48Address("10:54:23:54:23:52"));
-  uint32_t n3ifIndex = CsmaIpv4Topology::AddIpv4CsmaNode (n3, channel0,
-                                         Eui48Address("10:54:23:54:23:53"));
+  uint32_t netDeviceNumberNode0 = CsmaIpv4Topology::AddIpv4CsmaNode (n0, 
+    channel0, Eui48Address("10:54:23:54:23:50"));
+  uint32_t netDeviceNumberNode1 = CsmaIpv4Topology::AddIpv4CsmaNode (n1, 
+    channel0, Eui48Address("10:54:23:54:23:51"));
+  uint32_t netDeviceNumberNode2 = CsmaIpv4Topology::AddIpv4CsmaNode (n2, 
+    channel0, Eui48Address("10:54:23:54:23:52"));
+  uint32_t netDeviceNumberNode3 = CsmaIpv4Topology::AddIpv4CsmaNode (n3, 
+    channel0, Eui48Address("10:54:23:54:23:53"));
+
+  NS_DEBUG ("netDeviceNumberNode0 = " << netDeviceNumberNode0);
+  NS_DEBUG ("netDeviceNumberNode1 = " << netDeviceNumberNode1);
+  NS_DEBUG ("netDeviceNumberNode2 = " << netDeviceNumberNode2);
+  NS_DEBUG ("netDeviceNumberNode3 = " << netDeviceNumberNode3);
 
   // Later, we add IP addresses.  
   NS_DEBUG("Assign IP Addresses.");
+  // XXX BUGBUG
+  // Need a better way to get the interface index.  The point-to-point topology
+  // as implemented can't return the index since it creates interfaces on both
+  // sides (i.e., AddIpv4Addresses, not AddIpv4Address).  Need a method on
+  // Ipv4 to find the interface index corresponding to a given ipv4 address.
+  uint32_t ifIndexNode0 = CsmaIpv4Topology::AddIpv4Address (n0, 
+    netDeviceNumberNode0, Ipv4Address ("10.1.1.1"), 
+    Ipv4Mask ("255.255.255.0"));
 
-  CsmaIpv4Topology::AddIpv4Address (
-      n0, n0ifIndex, Ipv4Address("10.1.1.1"), Ipv4Mask("255.255.255.0"));
+  uint32_t ifIndexNode1 = CsmaIpv4Topology::AddIpv4Address (n1, 
+    netDeviceNumberNode1, Ipv4Address ("10.1.1.2"), 
+    Ipv4Mask ("255.255.255.0"));
 
-  CsmaIpv4Topology::AddIpv4Address (
-      n1, n1ifIndex, Ipv4Address("10.1.1.2"), Ipv4Mask("255.255.255.0"));
+  uint32_t ifIndexNode2 = CsmaIpv4Topology::AddIpv4Address (n2, 
+    netDeviceNumberNode2, Ipv4Address ("10.1.1.3"), 
+    Ipv4Mask ("255.255.255.0"));
+  
+  uint32_t ifIndexNode3 = CsmaIpv4Topology::AddIpv4Address (n3, 
+    netDeviceNumberNode3, Ipv4Address ("10.1.1.4"), 
+    Ipv4Mask ("255.255.255.0"));
 
-  CsmaIpv4Topology::AddIpv4Address (
-      n2, n2ifIndex, Ipv4Address("10.1.1.3"), Ipv4Mask("255.255.255.0"));
-  
-  CsmaIpv4Topology::AddIpv4Address (
-      n3, n3ifIndex, Ipv4Address("10.1.1.4"), Ipv4Mask("255.255.255.0"));
+  NS_DEBUG ("ifIndexNode0 = " << ifIndexNode0);
+  NS_DEBUG ("ifIndexNode1 = " << ifIndexNode1);
+  NS_DEBUG ("ifIndexNode2 = " << ifIndexNode2);
+  NS_DEBUG ("ifIndexNode3 = " << ifIndexNode3);
 
   // Configure multicasting
   NS_DEBUG("Configure multicasting.");
@@ -158,22 +169,21 @@
   ipv4 = n0->QueryInterface<Ipv4> (Ipv4::iid);
 
   std::vector<uint32_t> outputInterfaces (1);
-  outputInterfaces[0] = n0ifIndex;
+  outputInterfaces[0] = ifIndexNode0;
 
   ipv4->AddMulticastRoute (multicastSource, multicastGroup, 0, 
     outputInterfaces);
 
   ipv4 = n1->QueryInterface<Ipv4> (Ipv4::iid);
-  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
+  //  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
 
   ipv4 = n2->QueryInterface<Ipv4> (Ipv4::iid);
-  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
+  //  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
 
   ipv4 = n3->QueryInterface<Ipv4> (Ipv4::iid);
-  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
+  //  ipv4->JoinMulticastGroup (multicastSource, multicastGroup);
 
-  // Create the OnOff application to send UDP datagrams of size
-  // 210 bytes at a rate of 448 Kb/s
+  // Create the OnOff application to send UDP datagrams
   // from n0 to the multicast group
   NS_DEBUG("Create Applications.");
   Ptr<OnOffApplication> ooff = Create<OnOffApplication> (
@@ -181,10 +191,12 @@
     InetSocketAddress (multicastGroup, 80), 
     "Udp",
     ConstantVariable(1), 
-    ConstantVariable(0));
+    ConstantVariable(0),
+    DataRate ("128b/s"),
+    128);
   // Start the application
-  ooff->Start(Seconds(1.0));
-  ooff->Stop (Seconds(10.0));
+  ooff->Start(Seconds(1.));
+  ooff->Stop (Seconds(10.));
 
   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
   // Trace output will be sent to the csma-one-subnet.tr file
--- a/src/applications/onoff-application.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/applications/onoff-application.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -199,9 +199,12 @@
   if (m_totBytes < m_maxBytes)
     {
       uint32_t bits = m_pktSize * 8 - m_residualBits;
+      NS_DEBUG("OnOffApplication::ScheduleNextTx (): bits = " << bits);
       Time nextTime(Seconds (bits / 
         static_cast<double>(m_cbrRate.GetBitRate()))); // Time till next packet
-      m_sendEvent = Simulator::Schedule(nextTime, &OnOffApplication::SendPacket, this);
+      NS_DEBUG("OnOffApplication::ScheduleNextTx (): nextTime = " << nextTime);
+      m_sendEvent = Simulator::Schedule(nextTime, 
+                                        &OnOffApplication::SendPacket, this);
     }
   else
     { // All done, cancel any pending events
@@ -214,6 +217,8 @@
   NS_DEBUG("OnOffApplication::ScheduleStartEvent ()");
 
   Time offInterval = Seconds(m_offTime->GetValue());
+  NS_DEBUG("OnOffApplication::ScheduleStartEvent (): "
+    "start at " << offInterval);
   m_startStopEvent = Simulator::Schedule(offInterval, &OnOffApplication::StartSending, this);
 }
 
--- a/src/devices/csma/csma-ipv4-topology.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/devices/csma/csma-ipv4-topology.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -91,24 +91,22 @@
   nd1->Attach (ch);
 }
 
-void
-CsmaIpv4Topology::AddIpv4Address(Ptr<Node> n1,
-                                 int ndNum,
-                                 const Ipv4Address& addr1,
-                                 const Ipv4Mask& netmask1)
+uint32_t
+CsmaIpv4Topology::AddIpv4Address(
+  Ptr<Node>             node,
+  uint32_t              netDeviceNumber,
+  const Ipv4Address     address,
+  const Ipv4Mask        mask)
 {
-  // Duplex link is assumed to be subnetted as a /30
-  // May run this unnumbered in the future?
-  Ipv4Mask netmask(netmask1);
+  Ptr<NetDevice> nd = node->GetDevice(netDeviceNumber);
 
-  Ptr<NetDevice> nd1 = n1->GetDevice(ndNum);
+  Ptr<Ipv4> ipv4 = node->QueryInterface<Ipv4> (Ipv4::iid);
+  uint32_t ifIndex = ipv4->AddInterface (nd);
 
-  Ptr<Ipv4> ip1 = n1->QueryInterface<Ipv4> (Ipv4::iid);
-  uint32_t index1 = ip1->AddInterface (nd1);
-
-  ip1->SetAddress (index1, addr1);
-  ip1->SetNetworkMask (index1, netmask);
-  ip1->SetUp (index1);
+  ipv4->SetAddress (ifIndex, address);
+  ipv4->SetNetworkMask (ifIndex, mask);
+  ipv4->SetUp (ifIndex);
+  return ifIndex;
 }
 
 void
--- a/src/devices/csma/csma-ipv4-topology.h	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/devices/csma/csma-ipv4-topology.h	Mon Aug 13 12:08:01 2007 -0700
@@ -94,18 +94,23 @@
 
 
   /** 
-   * \param n1 Node
-   * \param ndNum NetDevice number with which to associate address
-   * \param addr1 Ipv4 Address for ndNum of n1
-   * \param network network mask for ndNum of node n1
+   * \brief Create an Ipv4 interface for a net device and assign an 
+   * Ipv4Address to that interface.
+   *
+   * \param node The node to which to add the new address and corresponding 
+   *        interface.
+   * \param netDeviceNumber The NetDevice index number with which to associate
+   *        the address.
+   * \param address The Ipv4 Address for the interface.
+   * \param network The network mask for the interface
    * 
    * Add an Ipv4Address to the Ipv4 interface associated with the
-   * ndNum CsmaIpv4NetDevices on the provided
-   * CsmaIpv4Channel
+   * ndNum CsmaIpv4NetDevices on the provided CsmaIpv4Channel
    */
-  static void AddIpv4Address(Ptr<Node> n1, int ndNum, 
-                             const Ipv4Address& addr1,
-                             const Ipv4Mask& netmask1);
+  static uint32_t AddIpv4Address(Ptr<Node> node,
+                                 uint32_t netDeviceNumber, 
+                                 const Ipv4Address address,
+                                 const Ipv4Mask mask);
 
   /**
    * \param nd1 Node
--- a/src/internet-node/arp-ipv4-interface.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/internet-node/arp-ipv4-interface.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -81,6 +81,14 @@
           hardwareDestination = GetDevice ()->GetBroadcast ();
           found = true;
         }
+      else if (dest.IsMulticast ())
+        {
+          NS_DEBUG ("ArpIpv4Interface::SendTo (): IsMulticast");
+          // XXX BUGBUG
+          // Need real multicast addresses
+          hardwareDestination = GetDevice ()->GetBroadcast ();
+          found = true;
+        }
       else
         {
           NS_DEBUG ("ArpIpv4Interface::SendTo (): ARP Lookup");
--- a/src/internet-node/ipv4-l3-protocol.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/internet-node/ipv4-l3-protocol.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -246,12 +246,26 @@
 }
 
 void
-Ipv4L3Protocol::Lookup (Ipv4Header const &ipHeader,
-                        Packet packet,
-                        Ipv4RoutingProtocol::RouteReplyCallback routeReply)
+Ipv4L3Protocol::Lookup (
+  Ipv4Header const &ipHeader,
+  Packet packet,
+  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
 {
-  NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << ", " << &packet <<
-    &routeReply << ")");
+  NS_DEBUG("Ipv4L3Protocol::Lookup (" << &ipHeader << 
+    ", " << &packet << &routeReply << ")");
+
+  Lookup (Ipv4RoutingProtocol::IF_INDEX_ANY, ipHeader, packet, routeReply);
+}
+
+void
+Ipv4L3Protocol::Lookup (
+  uint32_t ifIndex,
+  Ipv4Header const &ipHeader,
+  Packet packet,
+  Ipv4RoutingProtocol::RouteReplyCallback routeReply)
+{
+  NS_DEBUG("Ipv4L3Protocol::Lookup (" << ifIndex << ", " << &ipHeader << 
+    ", " << &packet << &routeReply << ")");
 
   for (Ipv4RoutingProtocolList::const_iterator rprotoIter = 
          m_routingProtocols.begin ();
@@ -259,7 +273,8 @@
        rprotoIter++)
     {
       NS_DEBUG("Ipv4L3Protocol::Lookup (): Requesting route");
-      if ((*rprotoIter).second->RequestRoute (ipHeader, packet, routeReply))
+      if ((*rprotoIter).second->RequestRoute (ifIndex, ipHeader, packet, 
+                                              routeReply))
         return;
     }
 
@@ -405,7 +420,9 @@
     protocol << ", " << from << ")");
 
   uint32_t index = 0;
-  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); 
+       i != m_interfaces.end (); 
+       i++)
     {
       if ((*i)->GetDevice () == device)
         {
@@ -423,7 +440,7 @@
       return;
     }
 
-  if (Forwarding (packet, ipHeader, device)) 
+  if (Forwarding (index, packet, ipHeader, device)) 
     {
       return;
     }
@@ -521,10 +538,14 @@
 }
 
 bool
-Ipv4L3Protocol::Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device)
+Ipv4L3Protocol::Forwarding (
+  uint32_t ifIndex, 
+  Packet const &packet, 
+  Ipv4Header &ipHeader, 
+  Ptr<NetDevice> device)
 {
-  NS_DEBUG("Ipv4L3Protocol::Forwarding (" << &packet << ", " << &ipHeader << 
-    ", " << device << ")");
+  NS_DEBUG("Ipv4L3Protocol::Forwarding (" << ifIndex << ", " << &packet << 
+    ", " << &ipHeader << ", " << device << ")");
 
   for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
        i != m_interfaces.end (); i++) 
@@ -579,7 +600,7 @@
   ipHeader.SetTtl (ipHeader.GetTtl () - 1);
 
   NS_DEBUG("Ipv4L3Protocol::Forwarding (): Forwarding packet.");
-  Lookup (ipHeader, packet,
+  Lookup (ifIndex, ipHeader, packet,
           MakeCallback (&Ipv4L3Protocol::SendRealOut, this));
 //
 // If this is a to a multicast address and this node is a member of the 
--- a/src/internet-node/ipv4-l3-protocol.h	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/internet-node/ipv4-l3-protocol.h	Mon Aug 13 12:08:01 2007 -0700
@@ -195,12 +195,19 @@
   virtual void DoDispose (void);
 
 private:
+  void Lookup (uint32_t ifIndex,
+               Ipv4Header const &ipHeader,
+               Packet packet,
+               Ipv4RoutingProtocol::RouteReplyCallback routeReply);
 
   void SendRealOut (bool found,
                     Ipv4Route const &route,
                     Packet packet,
                     Ipv4Header const &ipHeader);
-  bool Forwarding (Packet const &packet, Ipv4Header &ipHeader, Ptr<NetDevice> device);
+  bool Forwarding (uint32_t ifIndex, 
+                   Packet const &packet, 
+                   Ipv4Header &ipHeader, 
+                   Ptr<NetDevice> device);
   void ForwardUp (Packet p, Ipv4Header const&ip);
   uint32_t AddIpv4Interface (Ipv4Interface *interface);
   void SetupLoopback (void);
--- a/src/internet-node/ipv4-static-routing.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/internet-node/ipv4-static-routing.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -196,7 +196,8 @@
 Ipv4MulticastRoute *
 Ipv4StaticRouting::LookupStatic (
   Ipv4Address origin, 
-  Ipv4Address group)
+  Ipv4Address group,
+  uint32_t    ifIndex)
 {
   for (MulticastRoutesI i = m_multicastRoutes.begin (); 
        i != m_multicastRoutes.end (); 
@@ -207,7 +208,11 @@
              origin == Ipv4Address::GetAny ()) &&
           group == route->GetGroup ())
         {
-          return *i;
+          if (ifIndex == Ipv4RoutingProtocol::IF_INDEX_ANY || 
+              ifIndex == route->GetInputInterface ())
+            {
+              return *i;
+            }
         }
     }
   return 0;
@@ -312,9 +317,11 @@
 }
 
 bool
-Ipv4StaticRouting::RequestRoute (Ipv4Header const &ipHeader,
-                                 Packet packet,
-                                 RouteReplyCallback routeReply)
+Ipv4StaticRouting::RequestRoute (
+  uint32_t ifIndex,
+  Ipv4Header const &ipHeader,
+  Packet packet,
+  RouteReplyCallback routeReply)
 {
   NS_DEBUG ("Ipv4StaticRouting::RequestRoute (" << &ipHeader << ", " <<
     &packet << ", " << &routeReply << ")");
@@ -328,27 +335,35 @@
 // First, see if this is a multicast packet we have a route for.  If we
 // have a route, then send the packet down each of the specified interfaces.
 //
-  Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
-                                            ipHeader.GetDestination ());
-  if (mRoute)
+  if (ipHeader.GetDestination ().IsMulticast ())
     {
-      NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast route");
-      for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
+      NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Multicast destination");
+
+      Ipv4MulticastRoute *mRoute = LookupStatic(ipHeader.GetSource (),
+        ipHeader.GetDestination (), ifIndex);
+
+      if (mRoute)
         {
-          Packet p = packet;
-          Ipv4Route route = 
-            Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), 
-              mRoute->GetOutputInterface(i));
           NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
-            "Send via interface " << mRoute->GetOutputInterface(i));
-          routeReply (true, route, p, ipHeader);
-          return true;
+            "Multicast route found");
+          for (uint32_t i = 0; i < mRoute->GetNOutputInterfaces (); ++i)
+            {
+              Packet p = packet;
+              Ipv4Route route = 
+                Ipv4Route::CreateHostRouteTo(ipHeader.GetDestination (), 
+                  mRoute->GetOutputInterface(i));
+              NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): "
+                "Send via interface " << mRoute->GetOutputInterface(i));
+              routeReply (true, route, p, ipHeader);
+              return true;
+            }
         }
+      return false; // Let other routing protocols try to handle this
     }
 //
 // See if this is a unicast packet we have a route for.
 //
-  NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast route");
+  NS_DEBUG ("Ipv4StaticRouting::RequestRoute (): Unicast destination");
   Ipv4Route *route = LookupStatic (ipHeader.GetDestination ());
   if (route != 0)
     {
--- a/src/internet-node/ipv4-static-routing.h	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/internet-node/ipv4-static-routing.h	Mon Aug 13 12:08:01 2007 -0700
@@ -51,7 +51,8 @@
 public:
   Ipv4StaticRouting () : m_defaultRoute (0) {}
 
-  virtual bool RequestRoute (Ipv4Header const &ipHeader,
+  virtual bool RequestRoute (uint32_t ifIndex,
+                             Ipv4Header const &ipHeader,
                              Packet packet,
                              RouteReplyCallback routeReply);
 
@@ -105,7 +106,8 @@
   typedef std::list<Ipv4MulticastRoute *>::iterator MulticastRoutesI;
 
   Ipv4Route *LookupStatic (Ipv4Address dest);
-  Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group);
+  Ipv4MulticastRoute *LookupStatic (Ipv4Address origin, Ipv4Address group,
+                                    uint32_t ifIndex);
 
   HostRoutes m_hostRoutes;
   NetworkRoutes m_networkRoutes;
--- a/src/node/ipv4-address.cc	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/node/ipv4-address.cc	Mon Aug 13 12:08:01 2007 -0700
@@ -171,8 +171,11 @@
 bool 
 Ipv4Address::IsMulticast (void) const
 {
-  // XXX
-  return false;
+//
+// Multicast addresses are defined as ranging from 224.0.0.0 through 
+// 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
+//
+  return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
 }
 
 uint32_t
--- a/src/node/ipv4.h	Sun Aug 12 22:43:25 2007 -0700
+++ b/src/node/ipv4.h	Mon Aug 13 12:08:01 2007 -0700
@@ -70,6 +70,7 @@
   /**
    * \brief Asynchronously requests a route for a given packet and IP header
    *
+   * \param ifIndex The interface index on which the packet was received.
    * \param ipHeader IP header of the packet
    * \param packet packet that is being sent or forwarded
    * \param routeReply callback that will receive the route reply
@@ -99,9 +100,12 @@
    * immediately after the IP header, although most routing do not
    * insert any extra header.
    */
-  virtual bool RequestRoute (const Ipv4Header &ipHeader,
+  virtual bool RequestRoute (uint32_t ifIndex,
+                             const Ipv4Header &ipHeader,
                              Packet packet,
                              RouteReplyCallback routeReply) = 0;
+
+  static const uint32_t IF_INDEX_ANY = 0xffffffff;
 };
 
 /**