diff --git a/model/ipv4-global-routing-unordered-nexthops.cc b/model/ipv4-global-routing-unordered-nexthops.cc
new file mode 100644
index 0000000..720be8d
--- /dev/null
+++ b/model/ipv4-global-routing-unordered-nexthops.cc
@@ -0,0 +1,311 @@
+// -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*-
+//
+// Copyright (c) 2008 University of Washington
+//
+// 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
+//
+
+#include "ns3/names.h"
+#include "ns3/node.h"
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/object.h"
+#include "ns3/packet.h"
+#include "ns3/net-device.h"
+#include "ns3/ipv4-route.h"
+#include "ipv4-global-routing-unordered-nexthops.h"
+
+#include <iomanip>
+
+NS_LOG_COMPONENT_DEFINE ("Ipv4GlobalRoutingUnorderedNexthops");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (Ipv4GlobalRoutingUnorderedNexthops);
+
+TypeId 
+Ipv4GlobalRoutingUnorderedNexthops::GetTypeId (void)
+{ 
+  static TypeId tid = TypeId ("ns3::Ipv4GlobalRoutingUnorderedNexthops")
+    .SetParent<Ipv4GlobalRouting> ()
+    .AddConstructor<Ipv4GlobalRoutingUnorderedNexthops> ()
+  ;
+  return tid;
+}
+
+Ipv4GlobalRoutingUnorderedNexthops::Ipv4GlobalRoutingUnorderedNexthops ()
+: m_numLogicalEntries (1)
+{
+}
+
+void
+Ipv4GlobalRoutingUnorderedNexthops::FixRoutes ()
+{
+  for (Ipv4AddressTrieMap::iterator route = m_routes.begin ();
+       route != m_routes.end ();
+       route ++)
+    {
+      if (route->second->size () < m_numLogicalEntries)
+        {
+          NS_LOG_WARN ("Not all entries got a new routing entry. Making one based on previous set");
+          route->second->push_back (route->second->back ());
+          route->second->back ().SetMetric (UINT32_MAX); // just to ensure we have consistency across the sets
+        }
+    }
+  m_numLogicalEntries ++;
+}
+
+void
+Ipv4GlobalRoutingUnorderedNexthops::AddRouteTo (Ipv4Address dest, 
+                                                Ipv4Mask destMask, 
+                                                Ipv4Address nextHop, 
+                                                uint32_t interface,
+                                                uint32_t metric/*=0*/)
+{
+  NS_LOG_FUNCTION (dest << destMask << nextHop << interface << metric);
+  
+  // First, make sure we don't try to add route to ourselves
+  int32_t iface = m_ipv4->GetInterfaceForPrefix (dest, destMask);
+  NS_LOG_LOGIC ("Iface " << iface << " for " << dest);
+  if (destMask != Ipv4Mask::GetZero () && iface >= 0)
+    {
+      NS_LOG_LOGIC ("Do not add route to ourselves");
+      return;
+    }
+
+  // Second, there is no reason to add p2p route that equals to the next hop
+  if (destMask == Ipv4Mask::GetOnes () && dest == nextHop)
+    {
+      NS_LOG_LOGIC ("Ignore route to nexthop via nexhop");
+      return;
+    }
+
+  Ptr<EntryContainer> nextHops = 0;
+  
+  Ipv4AddressTrieMap::iterator route =
+    m_routes.find (dest.CombineMask (destMask));
+  if (route == m_routes.end ())
+    {
+      nextHops = Create<EntryContainer> ();
+      m_routes[dest.CombineMask (destMask)] = nextHops;
+    }
+  else
+    {
+      nextHops = route->second;
+    }
+
+  // NS_LOG_ERROR ("numLogicalEntries: " << m_numLogicalEntries << ", nextHops->size: " << nextHops->size ());
+  NS_ASSERT_MSG (nextHops->size ()==m_numLogicalEntries ||
+                 nextHops->size ()==m_numLogicalEntries-1,
+                 "Number of entries in nextHops should be either equal to number of logical entries, or one smaller");
+
+  if (nextHops->size ()==m_numLogicalEntries-1)
+    {
+      // new entry
+      nextHops->push_back (Ipv4RoutingTableEntry::CreateNetworkRouteTo (dest, destMask, nextHop, interface, metric));
+    }
+  else
+    {
+      if (nextHops->back ().GetMetric () > metric)
+        {
+          // update entry if new metric is smaller
+          nextHops->back () = Ipv4RoutingTableEntry::CreateNetworkRouteTo (dest, destMask, nextHop, interface, metric);
+        }
+    }
+}
+
+Ptr<Ipv4Route>
+Ipv4GlobalRoutingUnorderedNexthops::LookupGlobal (uint32_t entryNum, Ipv4Address dest, Ptr<NetDevice> oif)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_LOG_LOGIC ("Looking for route for destination " << dest);
+
+  NS_ASSERT_MSG (m_numLogicalEntries > 0,
+    "Number of logical entries should be at least one");
+
+  NS_ASSERT_MSG (entryNum < m_numLogicalEntries,
+               "Number of requested logical entry should be smaller than total number of logical entries");
+  
+  Ipv4AddressTrieMap::const_iterator longest_prefix_map = m_routes.longest_prefix_match (dest);
+  if (longest_prefix_map == m_routes.end ())
+    {
+      return 0;
+    }
+
+  const Ipv4RoutingTableEntry & entry = (*longest_prefix_map->second)[entryNum];
+  
+  if (oif != 0 && oif == m_ipv4->GetNetDevice (entry.GetInterface ()))
+    {
+      NS_LOG_LOGIC ("Route points to the incoming interface. Return empty route");
+      return 0;
+    }
+  
+  // create a Ipv4Route object from the selected routing table entry
+  Ptr<Ipv4Route> rtentry = Create<Ipv4Route> ();
+  rtentry->SetDestination (entry.GetDest ());
+  rtentry->SetSource (m_ipv4->GetAddress (entry.GetInterface (), 0).GetLocal ());
+  rtentry->SetGateway (entry.GetGateway ());
+  rtentry->SetOutputDevice (m_ipv4->GetNetDevice (entry.GetInterface ()));
+  return rtentry;
+}
+
+void
+Ipv4GlobalRoutingUnorderedNexthops::DeleteRoutes ()
+{
+  m_routes.clear ();
+}
+
+void
+Ipv4GlobalRoutingUnorderedNexthops::PrintRoutingTable (Ptr<OutputStreamWrapper> stream) const
+{
+  std::ostream* os = stream->GetStream ();
+  if (m_routes.size () > 0)
+    {
+      *os << "Destination    Iface(Metric),...,Iface(Metric)" << std::endl;
+      for (Ipv4AddressTrieMap::const_iterator i=m_routes.begin (); i != m_routes.end (); i++)
+        {
+          if (i->second->size ()==0) continue;
+          const Ipv4RoutingTableEntry &route = i->second->front ();
+
+          std::ostringstream dest;
+          dest << route.GetDest () << "/" << route.GetDestNetworkMask().GetPrefixLength ();
+          *os << std::setiosflags (std::ios::left) << std::setw (15) << dest.str ();
+
+          for (EntryContainer::iterator entry = i->second->begin ();
+               entry != i->second->end ();
+               entry ++)
+            {
+              if (entry != i->second->begin ())
+                *os << ",";
+              *os << entry->GetInterface () << "(" << entry->GetMetric () << ")";
+            }
+
+          *os << std::endl;
+        }
+    }
+}
+
+Ptr<Ipv4Route>
+Ipv4GlobalRoutingUnorderedNexthops::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
+                                          Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
+{
+//
+// 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.
+//
+  if (header.GetDestination ().IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination-- returning false");
+      return 0; // Let other routing protocols try to handle this
+    }
+//
+// See if this is a unicast packet we have a route for.
+//
+  NS_LOG_LOGIC ("Unicast destination- looking up");
+  Ptr<Ipv4Route> rtentry = LookupGlobal (0, header.GetDestination (), oif);
+  if (rtentry)
+    {
+      sockerr = Socket::ERROR_NOTERROR;
+    }
+  else
+    {
+      sockerr = Socket::ERROR_NOROUTETOHOST;
+    }
+  return rtentry;
+}
+
+bool 
+Ipv4GlobalRoutingUnorderedNexthops::RouteInput (Ptr<const Packet> p, const Ipv4Header &header,
+                                         Ptr<const NetDevice> idev,
+                                         UnicastForwardCallback ucb, MulticastForwardCallback mcb,
+                                         LocalDeliverCallback lcb, ErrorCallback ecb)
+{ 
+
+  NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev);
+  // Check if input device supports IP
+  NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
+  uint32_t iif = m_ipv4->GetInterfaceForDevice (idev);
+
+  if (header.GetDestination ().IsMulticast ())
+    {
+      NS_LOG_LOGIC ("Multicast destination-- returning false");
+      return false; // Let other routing protocols try to handle this
+    }
+
+  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");
+        }
+    }
+  // 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
+  NS_LOG_LOGIC ("Unicast destination- looking up global route");
+  Ptr<Ipv4Route> rtentry = LookupGlobal (0, header.GetDestination ());
+  if (rtentry != 0)
+    {
+      NS_LOG_LOGIC ("Found unicast destination- calling unicast callback");
+      ucb (rtentry, p, header);
+      return true;
+    }
+  else
+    {
+      NS_LOG_LOGIC ("Did not find unicast destination- returning false");
+      return false; // Let other routing protocols try to handle this
+                    // route request.
+    }
+}
+
+} // namespace ns3
