Ipv4L3ClickProtocol implemented and integrated
authorLalith Suresh <suresh.lalith@gmail.com>
Thu, 10 Jun 2010 19:59:22 +0530
changeset 6308 cfc9f271c1e5
parent 6307 7e31f546794a
child 6309 43978698d3a9
Ipv4L3ClickProtocol implemented and integrated
scratch/nsclick-test-full.cc
src/internet-stack/ipv4-l3-click-protocol.cc
src/internet-stack/ipv4-l3-click-protocol.h
src/internet-stack/ipv4-l3-protocol.cc
src/internet-stack/ipv4-l3-protocol.h
src/internet-stack/tcp-l4-protocol.cc
src/internet-stack/udp-l4-protocol.cc
src/internet-stack/wscript
src/routing/click/ipv4-click-routing.cc
--- a/scratch/nsclick-test-full.cc	Tue Jun 08 11:46:17 2010 +0530
+++ b/scratch/nsclick-test-full.cc	Thu Jun 10 19:59:22 2010 +0530
@@ -6,6 +6,7 @@
 #include "ns3/ipv4-click-routing.h"
 #include "ns3/arp-l3-protocol.h"
 #include "ns3/ipv4-l3-protocol.h"
+#include "ns3/ipv4-l3-click-protocol.h"
 #include "ns3/udp-l4-protocol.h"
 #include "ns3/tcp-l4-protocol.h"
 
@@ -49,7 +50,7 @@
   node->AggregateObject (arp);
 
   // Setup Ipv4L3Protocol
-  Ptr<Ipv4L3Protocol> ipv4l3 = CreateObject<Ipv4L3Protocol> ();
+  Ptr<Ipv4L3ClickProtocol> ipv4l3 = CreateObject<Ipv4L3ClickProtocol> ();
   node->AggregateObject (ipv4l3);
 
   // Setup Click instance
@@ -88,6 +89,7 @@
 
   Ptr<Ipv4> ipv4click = csmaNodes.Get (0)->GetObject<Ipv4> ();
   Ptr<Ipv4ClickRouting> click = DynamicCast <Ipv4ClickRouting> (ipv4click->GetRoutingProtocol ());
+  click->SetClickRoutingTableElement ("u/rt");
   click->DoStart ();
 
 
@@ -100,8 +102,8 @@
   OnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
   onOffHelper.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1)));
   onOffHelper.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0)));
-  onOffHelper.SetAttribute ("PacketSize", UintegerValue (512));
-  onOffHelper.SetAttribute ("MaxBytes", UintegerValue (513));
+//  onOffHelper.SetAttribute ("PacketSize", UintegerValue (512));
+//  onOffHelper.SetAttribute ("MaxBytes", UintegerValue (513));
 
   ApplicationContainer appcont;
 
@@ -109,8 +111,8 @@
   onOffHelper.SetAttribute ("Remote", remoteAddress);
   appcont.Add (onOffHelper.Install (csmaNodes.Get (0)));
 
-  appcont.Start (Seconds (40.0));
-  appcont.Stop (Seconds (45.0));
+  appcont.Start (Seconds (5.0));
+  appcont.Stop (Seconds (10.0));
 
 /*
   TypeId tid = TypeId::LookupByName ("ns3::TcpSocketFactory");
@@ -129,7 +131,7 @@
 */
   csma.EnablePcap ("click-test", csmaDevices, false);
 
-  Simulator::Stop (Seconds(50.0));
+  Simulator::Stop (Seconds(20.0));
   Simulator::Run();
   return 0;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l3-click-protocol.cc	Thu Jun 10 19:59:22 2010 +0530
@@ -0,0 +1,727 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Lalith Suresh
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lalith Suresh  <suresh.lalith@gmail.com>
+ */
+
+#include "ipv4-l3-click-protocol.h"
+#include "ns3/ipv4-click-routing.h"
+#include "ns3/node.h"
+#include "ns3/socket.h"
+
+#include "ipv4-raw-socket-impl.h"
+#include "arp-l3-protocol.h"
+#include "ipv4-l4-protocol.h"
+#include "icmpv4-l4-protocol.h"
+#include "loopback-net-device.h"
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4L3ClickProtocol");
+
+namespace ns3 {
+
+const uint16_t Ipv4L3ClickProtocol::PROT_NUMBER = 0x0800;
+
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4L3ClickProtocol);
+
+TypeId
+Ipv4L3ClickProtocol::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::Ipv4L3ClickProtocol")
+    .SetParent<Ipv4> ()
+    .AddConstructor<Ipv4L3ClickProtocol> ()
+
+    ;
+  return tid;
+}
+
+Ipv4L3ClickProtocol::Ipv4L3ClickProtocol ()
+  : m_identification (0)
+{}
+
+Ipv4L3ClickProtocol::~Ipv4L3ClickProtocol ()
+{}
+
+void
+Ipv4L3ClickProtocol::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+  for (L4List_t::iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+    {
+      *i = 0;
+    }
+  m_protocols.clear ();
+
+  for (Ipv4InterfaceList::iterator i = m_interfaces.begin (); i != m_interfaces.end (); ++i)
+    {
+      *i = 0;
+    }
+  m_interfaces.clear ();
+  m_sockets.clear ();
+  m_node = 0;
+  m_routingProtocol = 0;
+  Object::DoDispose ();
+}
+
+void
+Ipv4L3ClickProtocol::NotifyNewAggregate ()
+{
+  if (m_node == 0)
+    {
+      Ptr<Node>node = this->GetObject<Node>();
+      // verify that it's a valid node and that
+      // the node has not been set before
+      if (node != 0)
+        {
+          this->SetNode (node);
+        }
+    }
+  Object::NotifyNewAggregate ();
+}
+
+void
+Ipv4L3ClickProtocol::SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol)
+{
+  NS_LOG_FUNCTION (this);
+  m_routingProtocol = routingProtocol;
+  m_routingProtocol->SetIpv4 (this);
+}
+
+
+Ptr<Ipv4RoutingProtocol>
+Ipv4L3ClickProtocol::GetRoutingProtocol (void) const
+{
+  return m_routingProtocol;
+}
+
+Ptr<Ipv4Interface>
+Ipv4L3ClickProtocol::GetInterface (uint32_t index) const
+{
+  NS_LOG_FUNCTION (this << index);
+  if (index < m_interfaces.size ())
+    {
+      return m_interfaces[index];
+    }
+  return 0;
+}
+
+uint32_t
+Ipv4L3ClickProtocol::GetNInterfaces (void) const
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  return m_interfaces.size ();
+}
+
+int32_t
+Ipv4L3ClickProtocol::GetInterfaceForAddress (
+  Ipv4Address address) const
+{
+  NS_LOG_FUNCTION (this << address);
+
+  int32_t interface = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end ();
+       i++, interface++)
+    {
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
+        {
+          if ((*i)->GetAddress (j).GetLocal () == address)
+            {
+              return interface;
+            }
+        }
+    }
+
+  return -1;
+}
+
+int32_t
+Ipv4L3ClickProtocol::GetInterfaceForPrefix (
+  Ipv4Address address,
+  Ipv4Mask mask) const
+{
+  NS_LOG_FUNCTION (this << address << mask);
+
+  int32_t interface = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end ();
+       i++, interface++)
+    {
+      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
+        {
+          if ((*i)->GetAddress (j).GetLocal ().CombineMask (mask) == address.CombineMask (mask))
+            {
+              return interface;
+            }
+        }
+    }
+
+  return -1;
+}
+
+int32_t
+Ipv4L3ClickProtocol::GetInterfaceForDevice (
+  Ptr<const NetDevice> device) const
+{
+  NS_LOG_FUNCTION (this << device->GetIfIndex());
+
+  int32_t interface = 0;
+  for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin ();
+       i != m_interfaces.end ();
+       i++, interface++)
+    {
+      if ((*i)->GetDevice () == device)
+        {
+          return interface;
+        }
+    }
+
+  return -1;
+}
+
+bool
+Ipv4L3ClickProtocol::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
+Ipv4L3ClickProtocol::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
+Ipv4L3ClickProtocol::GetIpForward (void) const
+{
+  return m_ipForward;
+}
+
+void
+Ipv4L3ClickProtocol::SetWeakEsModel (bool model)
+{
+  m_weakEsModel = model;
+}
+
+bool
+Ipv4L3ClickProtocol::GetWeakEsModel (void) const
+{
+  return m_weakEsModel;
+}
+
+Ptr<NetDevice>
+Ipv4L3ClickProtocol::GetNetDevice (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  return GetInterface (i)-> GetDevice ();
+}
+
+void
+Ipv4L3ClickProtocol::SetupLoopback (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
+  Ptr<LoopbackNetDevice> device = 0;
+  // First check whether an existing LoopbackNetDevice exists on the node
+  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
+    {
+      if (device = DynamicCast<LoopbackNetDevice> (m_node->GetDevice (i)))
+        {
+          break;
+        }
+    }
+  if (device == 0)
+    {
+      device = CreateObject<LoopbackNetDevice> ();
+      m_node->AddDevice (device);
+    }
+  interface->SetDevice (device);
+  interface->SetNode (m_node);
+  Ipv4InterfaceAddress ifaceAddr = Ipv4InterfaceAddress (Ipv4Address::GetLoopback (), Ipv4Mask::GetLoopback ());
+  interface->AddAddress (ifaceAddr);
+  uint32_t index = AddIpv4Interface (interface);
+  Ptr<Node> node = GetObject<Node> ();
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                 Ipv4L3ClickProtocol::PROT_NUMBER, device);
+  interface->SetUp ();
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyInterfaceUp (index);
+    }
+}
+
+Ptr<Socket>
+Ipv4L3ClickProtocol::CreateRawSocket (void)
+{
+  NS_LOG_FUNCTION (this);
+  Ptr<Ipv4RawSocketImpl> socket = CreateObject<Ipv4RawSocketImpl> ();
+  socket->SetNode (m_node);
+  m_sockets.push_back (socket);
+  return socket;
+}
+void
+Ipv4L3ClickProtocol::DeleteRawSocket (Ptr<Socket> socket)
+{
+  NS_LOG_FUNCTION (this << socket);
+  for (SocketList::iterator i = m_sockets.begin (); i != m_sockets.end (); ++i)
+    {
+      if ((*i) == socket)
+        {
+          m_sockets.erase (i);
+          return;
+        }
+    }
+  return;
+}
+
+
+void
+Ipv4L3ClickProtocol::SetNode (Ptr<Node> node)
+{
+  m_node = node;
+  // Add a LoopbackNetDevice if needed, and an Ipv4Interface on top of it
+  SetupLoopback ();
+}
+
+bool
+Ipv4L3ClickProtocol::AddAddress (uint32_t i, Ipv4InterfaceAddress address)
+{
+  NS_LOG_FUNCTION (this << i << address);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  bool retVal = interface->AddAddress (address);
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyAddAddress (i, address);
+    }
+  return retVal;
+}
+
+Ipv4InterfaceAddress
+Ipv4L3ClickProtocol::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
+{
+  NS_LOG_FUNCTION (this << interfaceIndex << addressIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (interfaceIndex);
+  return interface->GetAddress (addressIndex);
+}
+
+uint32_t
+Ipv4L3ClickProtocol::GetNAddresses (uint32_t interface) const
+{
+  NS_LOG_FUNCTION (this << interface);
+  Ptr<Ipv4Interface> iface = GetInterface (interface);
+  return iface->GetNAddresses ();
+}
+
+bool
+Ipv4L3ClickProtocol::RemoveAddress (uint32_t i, uint32_t addressIndex)
+{
+  NS_LOG_FUNCTION (this << i << addressIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  Ipv4InterfaceAddress address = interface->RemoveAddress (addressIndex);
+  if (address != Ipv4InterfaceAddress ())
+    {
+      if (m_routingProtocol != 0)
+        {
+          m_routingProtocol->NotifyRemoveAddress (i, address);
+        }
+      return true;
+    }
+  return false;
+}
+
+Ipv4Address
+Ipv4L3ClickProtocol::SelectSourceAddress (Ptr<const NetDevice> device,
+    Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope)
+{
+  NS_LOG_FUNCTION (device << dst << scope);
+  Ipv4Address addr ("0.0.0.0");
+  Ipv4InterfaceAddress iaddr;
+  bool found = false;
+
+  if (device != 0)
+    {
+      int32_t i = GetInterfaceForDevice (device);
+      NS_ASSERT_MSG (i >= 0, "No device found on node");
+      for (uint32_t j = 0; j < GetNAddresses (i); j++)
+        {
+          iaddr = GetAddress (i, j);
+          if (iaddr.IsSecondary ()) continue;
+          if (iaddr.GetScope () > scope) continue;
+          if (dst.CombineMask (iaddr.GetMask ())  == iaddr.GetLocal ().CombineMask (iaddr.GetMask ()) )
+            {
+              return iaddr.GetLocal ();
+            }
+          if (!found)
+            {
+              addr = iaddr.GetLocal ();
+              found = true;
+            }
+        }
+    }
+  if (found)
+    {
+      return addr;
+    }
+
+  // Iterate among all interfaces
+  for (uint32_t i = 0; i < GetNInterfaces (); i++)
+    {
+      for (uint32_t j = 0; j < GetNAddresses (i); j++)
+        {
+          iaddr = GetAddress (i, j);
+          if (iaddr.IsSecondary ()) continue;
+          if (iaddr.GetScope () != Ipv4InterfaceAddress::LINK
+              && iaddr.GetScope () <= scope)
+            {
+              return iaddr.GetLocal ();
+            }
+        }
+    }
+  NS_LOG_WARN ("Could not find source address for " << dst << " and scope "
+    << scope << ", returning 0");
+  return addr;
+}
+
+void
+Ipv4L3ClickProtocol::SetMetric (uint32_t i, uint16_t metric)
+{
+  NS_LOG_FUNCTION (i << metric);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetMetric (metric);
+}
+
+uint16_t
+Ipv4L3ClickProtocol::GetMetric (uint32_t i) const
+{
+  NS_LOG_FUNCTION (i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetMetric ();
+}
+
+uint16_t
+Ipv4L3ClickProtocol::GetMtu (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->GetDevice ()->GetMtu ();
+}
+
+bool
+Ipv4L3ClickProtocol::IsUp (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  return interface->IsUp ();
+}
+
+void
+Ipv4L3ClickProtocol::SetUp (uint32_t i)
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetUp ();
+
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyInterfaceUp (i);
+    }
+}
+
+void
+Ipv4L3ClickProtocol::SetDown (uint32_t ifaceIndex)
+{
+  NS_LOG_FUNCTION (this << ifaceIndex);
+  Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
+  interface->SetDown ();
+
+  if (m_routingProtocol != 0)
+    {
+      m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
+    }
+}
+
+bool
+Ipv4L3ClickProtocol::IsForwarding (uint32_t i) const
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
+  return interface->IsForwarding ();
+}
+
+void
+Ipv4L3ClickProtocol::SetForwarding (uint32_t i, bool val)
+{
+  NS_LOG_FUNCTION (this << i);
+  Ptr<Ipv4Interface> interface = GetInterface (i);
+  interface->SetForwarding (val);
+}
+
+uint32_t
+Ipv4L3ClickProtocol::AddInterface (Ptr<NetDevice> device)
+{
+  NS_LOG_FUNCTION (this << &device);
+
+  Ptr<Node> node = GetObject<Node> ();
+
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                 Ipv4L3ClickProtocol::PROT_NUMBER, device);
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
+                                 ArpL3Protocol::PROT_NUMBER, device);
+
+  Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
+  interface->SetNode (m_node);
+  interface->SetDevice (device);
+  interface->SetForwarding (m_ipForward);
+  return AddIpv4Interface (interface);
+}
+
+uint32_t
+Ipv4L3ClickProtocol::AddIpv4Interface (Ptr<Ipv4Interface>interface)
+{
+  NS_LOG_FUNCTION (this << interface);
+  uint32_t index = m_interfaces.size ();
+  m_interfaces.push_back (interface);
+  return index;
+}
+
+// XXX when should we set ip_id?   check whether we are incrementing
+// m_identification on packets that may later be dropped in this stack
+// and whether that deviates from Linux
+Ipv4Header
+Ipv4L3ClickProtocol::BuildHeader (
+            Ipv4Address source,
+            Ipv4Address destination,
+            uint8_t protocol,
+            uint16_t payloadSize,
+            uint8_t ttl,
+            bool mayFragment)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Ipv4Header ipHeader;
+  ipHeader.SetSource (source);
+  ipHeader.SetDestination (destination);
+  ipHeader.SetProtocol (protocol);
+  ipHeader.SetPayloadSize (payloadSize);
+  ipHeader.SetTtl (ttl);
+  if (mayFragment == true)
+    {
+      ipHeader.SetMayFragment ();
+      ipHeader.SetIdentification (m_identification);
+      m_identification ++;
+    }
+  else
+    {
+      ipHeader.SetDontFragment ();
+      // TBD:  set to zero here; will cause traces to change
+      ipHeader.SetIdentification (m_identification);
+      m_identification ++;
+    }
+  if (Node::ChecksumEnabled ())
+    {
+      ipHeader.EnableChecksum ();
+    }
+  return ipHeader;
+}
+
+void
+Ipv4L3ClickProtocol::Send (Ptr<Packet> packet,
+            Ipv4Address source,
+            Ipv4Address destination,
+            uint8_t protocol,
+            Ptr<Ipv4Route> route)
+{
+  NS_LOG_FUNCTION (this << packet << source << destination << uint32_t(protocol) << route);
+
+  Ipv4Header ipHeader;
+  bool mayFragment = true;
+  uint8_t ttl = m_defaultTtl;
+  SocketIpTtlTag tag;
+  bool found = packet->RemovePacketTag (tag);
+  if (found)
+    {
+      ttl = tag.GetTtl ();
+    }
+
+  ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
+  if (Node::ChecksumEnabled ())
+   {
+     ipHeader.EnableChecksum ();
+   }
+  packet->AddHeader (ipHeader);
+  click->Send (packet->Copy (), source, destination);
+  return;
+}
+void
+Ipv4L3ClickProtocol::Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
+                         const Address &to, NetDevice::PacketType packetType)
+{
+  Ptr<Packet> packet = p->Copy ();
+
+  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ());
+  click->Receive (packet->Copy (), Mac48Address::ConvertFrom (device->GetAddress ()), Mac48Address::ConvertFrom (to));
+ 
+}
+
+void
+Ipv4L3ClickProtocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
+{
+  NS_LOG_FUNCTION (this << packet << &ip);
+  Ptr<Packet> p = packet->Copy (); // need to pass a non-const packet up
+
+  m_localDeliverTrace (ip, packet, iif);
+
+  Ptr<Ipv4L4Protocol> protocol = GetProtocol (ip.GetProtocol ());
+  if (protocol != 0)
+    {
+      // we need to make a copy in the unlikely event we hit the
+      // RX_ENDPOINT_UNREACH codepath
+      Ptr<Packet> copy = p->Copy ();
+      enum Ipv4L4Protocol::RxStatus status =
+        protocol->Receive (p, ip.GetSource (), ip.GetDestination (), GetInterface (iif));
+      switch (status) {
+      case Ipv4L4Protocol::RX_OK:
+        // fall through
+      case Ipv4L4Protocol::RX_ENDPOINT_CLOSED:
+        // fall through
+      case Ipv4L4Protocol::RX_CSUM_FAILED:
+        break;
+      case Ipv4L4Protocol::RX_ENDPOINT_UNREACH:
+        if (ip.GetDestination ().IsBroadcast () == true ||
+          ip.GetDestination ().IsMulticast () == true)
+          {
+            break;  // Do not reply to broadcast or multicast
+          }
+        // Another case to suppress ICMP is a subnet-directed broadcast
+        bool subnetDirected = false;
+        for (uint32_t i = 0; i < GetNAddresses (iif); i++)
+          {
+            Ipv4InterfaceAddress addr = GetAddress (iif, i);
+            if (addr.GetLocal ().CombineMask (addr.GetMask ()) == ip.GetDestination().CombineMask (addr.GetMask ()) &&
+              ip.GetDestination ().IsSubnetDirectedBroadcast (addr.GetMask ()))
+              {
+                subnetDirected = true;
+              }
+          }
+        if (subnetDirected == false)
+          {
+            GetIcmp ()->SendDestUnreachPort (ip, copy);
+          }
+      }
+    }
+}
+
+Ptr<Icmpv4L4Protocol>
+Ipv4L3ClickProtocol::GetIcmp (void) const
+{
+  Ptr<Ipv4L4Protocol> prot = GetProtocol (Icmpv4L4Protocol::GetStaticProtocolNumber ());
+  if (prot != 0)
+    {
+      return prot->GetObject<Icmpv4L4Protocol> ();
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+void
+Ipv4L3ClickProtocol::Insert(Ptr<Ipv4L4Protocol> protocol)
+{
+  m_protocols.push_back (protocol);
+}
+
+Ptr<Ipv4L4Protocol>
+Ipv4L3ClickProtocol::GetProtocol(int protocolNumber) const
+{
+  for (L4List_t::const_iterator i = m_protocols.begin(); i != m_protocols.end(); ++i)
+    {
+      if ((*i)->GetProtocolNumber () == protocolNumber)
+  {
+    return *i;
+  }
+    }
+  return 0;
+}
+
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/internet-stack/ipv4-l3-click-protocol.h	Thu Jun 10 19:59:22 2010 +0530
@@ -0,0 +1,149 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Lalith Suresh
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Lalith Suresh  <suresh.lalith@gmail.com>
+ */
+
+#include "ns3/ipv4.h"
+#include "ns3/net-device.h"
+#include "ns3/packet.h"
+#include "ns3/ipv4-routing-protocol.h"
+#include "ns3/traced-callback.h"
+#include "ns3/ipv4-interface.h"
+#include "ns3/log.h"
+
+namespace ns3{
+
+class Packet;
+class NetDevice;
+class Ipv4Interface;
+class Ipv4Address;
+class Ipv4Header;
+class Ipv4RoutingTableEntry;
+class Ipv4Route;
+class Node;
+class Socket;
+class Ipv4RawSocketImpl;
+class Ipv4L4Protocol;
+class Icmpv4L4Protocol;
+
+class Ipv4L3ClickProtocol : public Ipv4
+{
+public:
+  static TypeId GetTypeId (void);
+  static const uint16_t PROT_NUMBER;
+    
+  Ipv4L3ClickProtocol();
+  virtual ~Ipv4L3ClickProtocol();
+
+  // functions defined in base class Ipv4
+
+  void SetRoutingProtocol (Ptr<Ipv4RoutingProtocol> routingProtocol);
+  Ptr<Ipv4RoutingProtocol> GetRoutingProtocol (void) const;
+
+  void Insert(Ptr<Ipv4L4Protocol> protocol);
+
+  uint32_t AddInterface (Ptr<NetDevice> device);
+  Ptr<Ipv4Interface> GetInterface (uint32_t i) const;
+  uint32_t GetNInterfaces (void) const;
+
+  int32_t GetInterfaceForAddress (Ipv4Address addr) const;
+  int32_t GetInterfaceForPrefix (Ipv4Address addr, Ipv4Mask mask) const;
+  int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const;
+  bool IsDestinationAddress (Ipv4Address address, uint32_t iif) const;
+
+  Ptr<Ipv4L4Protocol> GetProtocol(int protocolNumber) const;
+
+  Ptr<NetDevice> GetNetDevice (uint32_t i);
+
+  bool AddAddress (uint32_t i, Ipv4InterfaceAddress address);
+  Ipv4InterfaceAddress GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const;
+  uint32_t GetNAddresses (uint32_t interface) const;
+  bool RemoveAddress (uint32_t interfaceIndex, uint32_t addressIndex);
+  Ipv4Address SelectSourceAddress (Ptr<const NetDevice> device,
+    Ipv4Address dst, Ipv4InterfaceAddress::InterfaceAddressScope_e scope);
+
+  uint32_t AddIpv4Interface (Ptr<Ipv4Interface> interface);
+  void SetNode (Ptr<Node> node);
+
+  void SetMetric (uint32_t i, uint16_t metric);
+  uint16_t GetMetric (uint32_t i) const;
+  uint16_t GetMtu (uint32_t i) const;
+  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<Icmpv4L4Protocol> GetIcmp (void) const;
+  void SetupLoopback (void);
+
+  Ptr<Socket> CreateRawSocket (void);
+  void DeleteRawSocket (Ptr<Socket> socket);
+
+  void Send (Ptr<Packet> packet, Ipv4Address source,
+       Ipv4Address destination, uint8_t protocol, Ptr<Ipv4Route> route);
+  void Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
+                const Address &to, NetDevice::PacketType packetType);
+
+  void LocalDeliver (Ptr<const Packet> p, Ipv4Header const&ip, uint32_t iif);
+
+protected:
+
+  virtual void DoDispose (void);
+  /**
+   * This function will notify other components connected to the node that a new stack member is now connected
+   * This will be used to notify Layer 3 protocol of layer 4 protocol stack to connect them together.
+   */
+  virtual void NotifyNewAggregate ();
+
+private:
+  Ipv4Header BuildHeader (
+            Ipv4Address source,
+            Ipv4Address destination,
+            uint8_t protocol,
+            uint16_t payloadSize,
+            uint8_t ttl,
+            bool mayFragment);
+
+  virtual void SetIpForward (bool forward);
+  virtual bool GetIpForward (void) const;
+  virtual void SetWeakEsModel (bool model);
+  virtual bool GetWeakEsModel (void) const;
+
+  typedef std::vector<Ptr<Ipv4Interface> > Ipv4InterfaceList;
+  typedef std::list<Ptr<Ipv4RawSocketImpl> > SocketList;
+  typedef std::list<Ptr<Ipv4L4Protocol> > L4List_t;
+
+  Ptr<Ipv4RoutingProtocol> m_routingProtocol;
+  bool m_ipForward;
+  bool m_weakEsModel;
+  L4List_t m_protocols;
+  Ipv4InterfaceList m_interfaces;
+  uint8_t m_defaultTtl;
+  uint16_t m_identification;
+
+  Ptr<Node> m_node;
+
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_sendOutgoingTrace;
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_unicastForwardTrace;
+  TracedCallback<const Ipv4Header &, Ptr<const Packet>, uint32_t> m_localDeliverTrace;
+
+  SocketList m_sockets;
+};
+
+} //namespace ns3
--- a/src/internet-stack/ipv4-l3-protocol.cc	Tue Jun 08 11:46:17 2010 +0530
+++ b/src/internet-stack/ipv4-l3-protocol.cc	Thu Jun 10 19:59:22 2010 +0530
@@ -32,7 +32,6 @@
 #include "ns3/ipv4-header.h"
 #include "ns3/boolean.h"
 #include "ns3/ipv4-routing-table-entry.h"
-#include "ns3/ipv4-click-routing.h"
 
 #include "loopback-net-device.h"
 #include "arp-l3-protocol.h"
@@ -251,21 +250,10 @@
   NS_LOG_FUNCTION (this << &device);
 
   Ptr<Node> node = GetObject<Node> ();
-  
-  if (DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ()))
-    {
-      node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::ReceiveExternal, this), 
-                                     Ipv4L3Protocol::PROT_NUMBER, device);
-      node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::ReceiveExternal, this),
-                                     ArpL3Protocol::PROT_NUMBER, device);
-    }
-  else
-    {
-      node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this), 
-                                      Ipv4L3Protocol::PROT_NUMBER, device);
-      node->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
-                                     ArpL3Protocol::PROT_NUMBER, device);
-    }
+  node->RegisterProtocolHandler (MakeCallback (&Ipv4L3Protocol::Receive, this), 
+                                 Ipv4L3Protocol::PROT_NUMBER, device);
+  node->RegisterProtocolHandler (MakeCallback (&ArpL3Protocol::Receive, PeekPointer (GetObject<ArpL3Protocol> ())),
+                                 ArpL3Protocol::PROT_NUMBER, device);
 
   Ptr<Ipv4Interface> interface = CreateObject<Ipv4Interface> ();
   interface->SetNode (m_node);
@@ -432,24 +420,6 @@
   return false;
 }
 
-void
-Ipv4L3Protocol::ReceiveExternal ( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
-                                  const Address &to, NetDevice::PacketType packetType)
-{
-  Ptr<Packet> packet = p->Copy ();
-/*
-  EthernetHeader ethHeader;
-  ethHeader.SetSource (Mac48Address::ConvertFrom (from));
-  ethHeader.SetDestination (Mac48Address::ConvertFrom (to));
-  ethHeader.SetLengthType (protocol);
-  packet->AddHeader (ethHeader);
-*/
-  // If using an external router, we send the packet to it for handling.
-  Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (GetRoutingProtocol ());
-  click->Receive (packet->Copy (), Mac48Address::ConvertFrom (device->GetAddress ()), Mac48Address::ConvertFrom (to));
-}
-
-
 void 
 Ipv4L3Protocol::Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
                          const Address &to, NetDevice::PacketType packetType)
@@ -562,18 +532,6 @@
       ttl = tag.GetTtl ();
     }
 
-  if (DynamicCast<Ipv4ClickRouting> (m_routingProtocol))
-    {
-      Ipv4Header ipHeader;
-      ipHeader = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, mayFragment);
-      Ptr<Ipv4ClickRouting> click = DynamicCast<Ipv4ClickRouting> (m_routingProtocol);
-      ipHeader.EnableChecksum ();
-      packet->AddHeader (ipHeader);
-      click->Send (packet->Copy (), source, destination);
-      return;
-    }
-
-
   // Handle a few cases:
   // 1) packet is destined to limited broadcast address
   // 2) packet is destined to a subnet-directed broadcast address
@@ -832,12 +790,6 @@
 }
 
 void
-Ipv4L3Protocol::LocalDeliverFromExternal (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
-{
-  LocalDeliver (packet, ip, iif);
-}
-
-void
 Ipv4L3Protocol::LocalDeliver (Ptr<const Packet> packet, Ipv4Header const&ip, uint32_t iif)
 {
   NS_LOG_FUNCTION (this << packet << &ip);
--- a/src/internet-stack/ipv4-l3-protocol.h	Tue Jun 08 11:46:17 2010 +0530
+++ b/src/internet-stack/ipv4-l3-protocol.h	Thu Jun 10 19:59:22 2010 +0530
@@ -150,11 +150,6 @@
   void Receive( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
                 const Address &to, NetDevice::PacketType packetType);
 
-  void ReceiveExternal( Ptr<NetDevice> device, Ptr<const Packet> p, uint16_t protocol, const Address &from,
-                const Address &to, NetDevice::PacketType packetType);
-
-  void LocalDeliverFromExternal (Ptr<const Packet> p, Ipv4Header const&ip, uint32_t iif);
-
   /**
    * \param packet packet to send
    * \param source source address of packet
--- a/src/internet-stack/tcp-l4-protocol.cc	Tue Jun 08 11:46:17 2010 +0530
+++ b/src/internet-stack/tcp-l4-protocol.cc	Thu Jun 10 19:59:22 2010 +0530
@@ -34,6 +34,7 @@
 #include "ipv4-end-point-demux.h"
 #include "ipv4-end-point.h"
 #include "ipv4-l3-protocol.h"
+#include "ipv4-l3-click-protocol.h"
 #include "tcp-socket-factory-impl.h"
 #include "tcp-socket-impl.h"
 #include "rtt-estimator.h"
@@ -379,11 +380,23 @@
       Ptr<Node> node = this->GetObject<Node> ();
       if (node != 0)
         {
-          Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
+          bool isClickNode = false;
+
+          if (DynamicCast<Ipv4L3ClickProtocol> (this->GetObject<Ipv4> ()))
+            isClickNode = true;
+
+          Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
           if (ipv4 != 0)
             {
               this->SetNode (node);
-              ipv4->Insert (this);
+              if (!isClickNode)
+                {
+                  DynamicCast<Ipv4L3Protocol> (ipv4)->Insert (this);
+                }
+              else
+                {
+                  DynamicCast<Ipv4L3ClickProtocol> (ipv4)->Insert (this);
+                }
               Ptr<TcpSocketFactoryImpl> tcpFactory = CreateObject<TcpSocketFactoryImpl> ();
               tcpFactory->SetTcp (this);
               node->AggregateObject (tcpFactory);
@@ -575,8 +588,12 @@
 
   packet->AddHeader (tcpHeader);
 
-  Ptr<Ipv4L3Protocol> ipv4 = 
-    m_node->GetObject<Ipv4L3Protocol> ();
+  bool isClickNode = false;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  if (DynamicCast<Ipv4L3ClickProtocol> (ipv4))
+    isClickNode = true;
+
   if (ipv4 != 0)
     {
       // XXX We've already performed the route lookup in TcpSocketImpl
@@ -596,7 +613,15 @@
           NS_LOG_ERROR ("No IPV4 Routing Protocol");
           route = 0;
         }
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
+
+      if (!isClickNode)
+        {
+          DynamicCast<Ipv4L3Protocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, route);
+        }
+      else
+        {
+          DynamicCast<Ipv4L3ClickProtocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, route);
+        }
     }
 }
 
@@ -623,8 +648,12 @@
 
   packet->AddHeader (outgoingHeader);
 
-  Ptr<Ipv4L3Protocol> ipv4 = 
-    m_node->GetObject<Ipv4L3Protocol> ();
+  bool isClickNode = false;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  if (DynamicCast<Ipv4L3ClickProtocol> (ipv4))
+    isClickNode = true;
+
   if (ipv4 != 0)
     {
       // XXX We've already performed the route lookup in TcpSocketImpl
@@ -643,7 +672,15 @@
           NS_LOG_ERROR ("No IPV4 Routing Protocol");
           route = 0;
         }
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
+
+      if (!isClickNode)
+        {
+          DynamicCast<Ipv4L3Protocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, route);
+        }
+      else
+        {
+          DynamicCast<Ipv4L3ClickProtocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, route);
+        }
     }
   else
     NS_FATAL_ERROR("Trying to use Tcp on a node without an Ipv4 interface");
--- a/src/internet-stack/udp-l4-protocol.cc	Tue Jun 08 11:46:17 2010 +0530
+++ b/src/internet-stack/udp-l4-protocol.cc	Thu Jun 10 19:59:22 2010 +0530
@@ -31,6 +31,7 @@
 #include "ipv4-end-point-demux.h"
 #include "ipv4-end-point.h"
 #include "ipv4-l3-protocol.h"
+#include "ipv4-l3-click-protocol.h"
 #include "udp-socket-impl.h"
 
 NS_LOG_COMPONENT_DEFINE ("UdpL4Protocol");
@@ -82,11 +83,24 @@
       Ptr<Node> node = this->GetObject<Node> ();
       if (node != 0)
         {
-          Ptr<Ipv4L3Protocol> ipv4 = this->GetObject<Ipv4L3Protocol> ();
+          bool isClickNode = false;
+
+          if (DynamicCast<Ipv4L3ClickProtocol> (this->GetObject<Ipv4> ()))
+            isClickNode = true;
+
+          Ptr<Ipv4> ipv4 = this->GetObject<Ipv4> ();
+
           if (ipv4 != 0)
             {
               this->SetNode (node);
-              ipv4->Insert (this);
+              if (!isClickNode)
+                {
+                  DynamicCast<Ipv4L3Protocol> (ipv4)->Insert (this);
+                }
+              else
+                {
+                  DynamicCast<Ipv4L3ClickProtocol> (ipv4)->Insert (this);
+                }
               Ptr<UdpSocketFactoryImpl> udpFactory = CreateObject<UdpSocketFactoryImpl> ();
               udpFactory->SetUdp (this);
               node->AggregateObject (udpFactory);
@@ -255,12 +269,24 @@
 
   packet->AddHeader (udpHeader);
 
-  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+  bool isClickNode = false;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  if (DynamicCast<Ipv4L3ClickProtocol> (ipv4))
+    isClickNode = true;
+
   if (ipv4 != 0)
     {
       NS_LOG_LOGIC ("Sending to IP");
       // Send with null route
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER, 0);
+      if (!isClickNode)
+        {
+          DynamicCast<Ipv4L3Protocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, 0);
+        }
+      else
+        {
+          DynamicCast<Ipv4L3ClickProtocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, 0);
+        }
     }
 }
 
@@ -284,11 +310,23 @@
 
   packet->AddHeader (udpHeader);
 
-  Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
+  bool isClickNode = false;
+  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
+
+  if (DynamicCast<Ipv4L3ClickProtocol> (ipv4))
+    isClickNode = true;
+
   if (ipv4 != 0)
     {
       NS_LOG_LOGIC ("Sending to IP");
-      ipv4->Send (packet, saddr, daddr, PROT_NUMBER, route);
+      if (!isClickNode)
+        {
+          DynamicCast<Ipv4L3Protocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, route);
+        }
+      else
+        {
+          DynamicCast<Ipv4L3ClickProtocol> (ipv4)->Send (packet, saddr, daddr, PROT_NUMBER, route);
+        }
     }
 }
 
--- a/src/internet-stack/wscript	Tue Jun 08 11:46:17 2010 +0530
+++ b/src/internet-stack/wscript	Thu Jun 10 19:59:22 2010 +0530
@@ -81,6 +81,7 @@
         'tcp-header.cc',
         'ipv4-interface.cc',
         'ipv4-l3-protocol.cc',
+        'ipv4-l3-click-protocol.cc',
         'ipv4-end-point.cc',
         'udp-l4-protocol.cc',
         'tcp-l4-protocol.cc',
@@ -132,6 +133,7 @@
         # used by routing
         'ipv4-interface.h',
         'ipv4-l3-protocol.h',
+        'ipv4-l3-click-protocol.h',
         'ipv6-l3-protocol.h',
         'ipv6-extension-header.h',
         'ipv6-option-header.h',
--- a/src/routing/click/ipv4-click-routing.cc	Tue Jun 08 11:46:17 2010 +0530
+++ b/src/routing/click/ipv4-click-routing.cc	Thu Jun 10 19:59:22 2010 +0530
@@ -27,8 +27,7 @@
 #include "ns3/mac48-address.h"
 #include "ns3/ethernet-header.h"
 #include "ns3/ipv4-interface.h"
-#include "ns3/ipv4-l3-protocol.h"
-#include "ns3/arp-l3-protocol.h"
+#include "ns3/ipv4-l3-click-protocol.h"
 #include "ns3/llc-snap-header.h"
 
 #include "ipv4-click-routing.h"
@@ -256,14 +255,14 @@
   if (ifid == 0)
     {
       NS_LOG_DEBUG ("Incoming packet from tap0. Sending Packet up the stack.");
-      Ptr<Ipv4L3Protocol> ipv4l3 = DynamicCast<Ipv4L3Protocol> (m_ipv4);
+      Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
 
       Ptr<Packet> p = Create<Packet> (data, len);
 
       Ipv4Header ipHeader;
       p->RemoveHeader (ipHeader);
 
-      ipv4l3->LocalDeliverFromExternal (p, ipHeader, (uint32_t) ifid);
+      ipv4l3->LocalDeliver (p, ipHeader, (uint32_t) ifid);
     }
   else if (ifid)
     {