diff --git a/helper/boost-graph-ndn-global-routing-helper.hpp b/helper/boost-graph-ndn-global-routing-helper.hpp
index 49b724e..588f436 100644
--- a/helper/boost-graph-ndn-global-routing-helper.hpp
+++ b/helper/boost-graph-ndn-global-routing-helper.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2011-2015  Regents of the University of California.
+ * Copyright (c) 2011-2019  Regents of the University of California.
  *
  * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
  * contributors.
@@ -30,7 +30,9 @@
 
 #include "ns3/ndnSIM/model/ndn-global-router.hpp"
 
+#include "ns3/node.h"
 #include "ns3/node-list.h"
+#include "ns3/channel.h"
 #include "ns3/channel-list.h"
 
 #include <list>
diff --git a/helper/lfid/abstract-fib.cpp b/helper/lfid/abstract-fib.cpp
new file mode 100644
index 0000000..c4d736f
--- /dev/null
+++ b/helper/lfid/abstract-fib.cpp
@@ -0,0 +1,188 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#include "abstract-fib.hpp"
+
+#include <algorithm>
+
+#include "ns3/names.h"
+#include "ns3/ndnSIM/NFD/daemon/fw/forwarder.hpp"
+#include "ns3/ndnSIM/model/ndn-global-router.hpp"
+#include "ns3/ndnSIM/model/ndn-l3-protocol.hpp"
+#include "ns3/node.h"
+
+namespace ns3 {
+namespace ndn {
+
+using std::set;
+
+AbstractFib::AbstractFib(const Ptr<GlobalRouter> own, int numNodes)
+  : nodeId{static_cast<int>(own->GetObject<ns3::Node>()->GetId())}
+  , nodeName{ns3::Names::FindName(own->GetObject<ns3::Node>())}
+  , numberOfNodes{numNodes}
+  , nodeDegree{static_cast<int>(own->GetIncidencies().size())}
+  , ownRouter{own}
+  , upwardCounter{0}
+  , totalNhCounter{0}
+{
+  checkInputs();
+
+  createEmptyFib();
+}
+
+void
+AbstractFib::checkInputs()
+{
+  if (nodeDegree <= 0) {
+    std::cerr << nodeName << " has a degree of " << nodeDegree << "!\n\n";
+  }
+
+  const auto MAX_SIZE{1e5};
+  NS_ABORT_UNLESS(nodeId >= 0 && nodeId <= MAX_SIZE);
+  NS_ABORT_UNLESS(nodeName.size() > 0 && nodeName.size() <= MAX_SIZE);
+  NS_ABORT_UNLESS(nodeDegree >= 0 && nodeDegree <= MAX_SIZE);
+  NS_ABORT_UNLESS(numberOfNodes > 1 && numberOfNodes <= MAX_SIZE);
+}
+
+void
+AbstractFib::createEmptyFib()
+{
+  // Create empty FIB:
+  for (int dstId = 0; dstId < numberOfNodes; dstId++) {
+    if (dstId == nodeId) {
+      continue;
+    }
+    perDstFib.insert({dstId, {}});
+    upwardPerDstFib.insert({dstId, {}});
+  }
+}
+
+Ptr<GlobalRouter>
+AbstractFib::getGR() const
+{
+  return ownRouter;
+}
+
+// Setters:
+void
+AbstractFib::insert(int dstId, const FibNextHop& nh)
+{
+  NS_ABORT_UNLESS(nh.getType() == NextHopType::DOWNWARD || nh.getType() == NextHopType::UPWARD);
+  NS_ABORT_UNLESS(nh.getNexthopId() != nodeId);
+
+  bool inserted1 = perDstFib.at(dstId).insert(nh).second;
+  BOOST_VERIFY(inserted1); // Check if it didn't exist yet.
+  totalNhCounter++;
+
+  if (nh.getType() == NextHopType::UPWARD) {
+    bool inserted2 = upwardPerDstFib.at(dstId).insert(nh).second;
+    BOOST_VERIFY(inserted2);
+    upwardCounter++;
+  }
+}
+
+size_t
+AbstractFib::erase(int dstId, int nhId)
+{
+  auto& fib{perDstFib.at(dstId)};
+
+  auto fibNh = std::find_if(fib.begin(), fib.end(),
+                            [&](const FibNextHop& item) { return item.getNexthopId() == nhId; });
+
+  // Element doesn't exist:
+  if (fibNh == fib.end()) {
+
+    // TODO: Figure out why this happens.
+    return 0;
+  }
+
+  NS_ABORT_UNLESS(fibNh != perDstFib.at(dstId).end());
+  NS_ABORT_UNLESS(fibNh->getType() == NextHopType::UPWARD);
+  totalNhCounter--;
+
+  fib.erase(fibNh);
+  auto numErased2 = upwardPerDstFib.at(dstId).erase(*fibNh);
+  NS_ABORT_UNLESS(numErased2 == 1);
+  upwardCounter--;
+
+  return numErased2;
+}
+
+// O(1)
+const set<FibNextHop>&
+AbstractFib::getNexthops(int dstId) const
+{
+  NS_ABORT_MSG_IF(dstId == nodeId, "Requested destination id is the same as current nodeId!");
+  NS_ABORT_MSG_IF(perDstFib.count(dstId) == 0,
+                  "Node " << nodeId << " No nexthops for dst: " << dstId << "!");
+  NS_ABORT_UNLESS(perDstFib.count(dstId) != 0);
+  return perDstFib.at(dstId);
+}
+
+const set<FibNextHop>&
+AbstractFib::getUpwardNexthops(int dstId) const
+{
+  NS_ABORT_MSG_IF(dstId == nodeId, "Requested destination id is the same as current nodeId!");
+  NS_ABORT_MSG_IF(perDstFib.count(dstId) == 0,
+                  "Node " << nodeId << " No nexthops for dst: " << dstId << "!");
+  return upwardPerDstFib.at(dstId);
+}
+
+void
+AbstractFib::checkFib() const
+{
+  BOOST_VERIFY(perDstFib.size() > 0);
+
+  for (const auto& fibSet : perDstFib) {
+    const size_t numNhs = fibSet.second.size();
+
+    bool hasDownward{false};
+    std::unordered_set<int> nextHopSet{};
+
+    for (const FibNextHop& nextHop : fibSet.second) {
+      BOOST_VERIFY(nextHop.getCost() > 0 && nextHop.getCost() < FibNextHop::MAX_COST);
+      if (nextHop.getType() == NextHopType::DOWNWARD) {
+        hasDownward = true;
+      }
+
+      // Only one FIB entry per nexthop allowed!
+      BOOST_VERIFY(nextHopSet.count(nextHop.getNexthopId()) == 0);
+      nextHopSet.emplace(nextHop.getNexthopId());
+    }
+    BOOST_VERIFY(hasDownward || numNhs == 0);
+    BOOST_VERIFY(nextHopSet.size() == fibSet.second.size());
+  }
+}
+
+std::ostream&
+operator<<(std::ostream& os, const AbstractFib& fib)
+{
+  for (const auto& entry : fib.perDstFib) {
+    os << "\nFIB node: " << fib.nodeName << fib.nodeId << "\n";
+    os << "Dst: " << entry.first << "\n";
+    for (const auto& nh : entry.second) {
+      os << nh << "\n";
+    }
+  }
+  return os;
+}
+
+} // namespace ndn
+} // namespace ns-3
diff --git a/helper/lfid/abstract-fib.hpp b/helper/lfid/abstract-fib.hpp
new file mode 100644
index 0000000..b5a118f
--- /dev/null
+++ b/helper/lfid/abstract-fib.hpp
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#ifndef LFID_ABS_FIB_H
+#define LFID_ABS_FIB_H
+
+#include <set>
+#include <unordered_map>
+
+#include "ns3/abort.h"
+#include "ns3/ndnSIM/helper/lfid/fib-nexthop.hpp"
+#include "ns3/ptr.h"
+
+namespace ns3 {
+namespace ndn {
+
+class GlobalRouter;
+
+/**
+ * An abstract, lightweight representation of the FIB.
+ */
+class AbstractFib {
+public:
+  using AllNodeFib = std::unordered_map<int, AbstractFib>;
+
+  /**
+   * @param own The GlobalRouter object representing the current router
+   * @param numNodes The total number of nodes in the network
+   */
+  AbstractFib(const Ptr<GlobalRouter> own, int numNodes);
+
+public:
+  // Getters:
+  /**
+   * @return Return set of nexthops per destination
+   */
+  const std::set<FibNextHop>&
+  getNexthops(int dstId) const;
+
+  /**
+   * @return Return set of upward nexthops per destination
+   */
+  const std::set<FibNextHop>&
+  getUpwardNexthops(int dstId) const;
+
+  /**
+   * Make sure that FIB is consistent (each destination has at least one downward nexthop)
+   */
+  void
+  checkFib() const;
+
+  /**
+   * @return Return number nexthops per destination
+   * @pre Also assure that the destination is not equal to the current nodeId.
+   */
+  int
+  numEnabledNhPerDst(int dstId) const
+  {
+    NS_ABORT_UNLESS(dstId != nodeId);
+    return static_cast<int>(getNexthops(dstId).size());
+  }
+
+  int
+  getNodeId() const
+  {
+    return nodeId;
+  }
+
+  Ptr<GlobalRouter>
+  getGR() const;
+
+  std::string
+  getName() const
+  {
+    return nodeName;
+  }
+
+  int
+  getDegree() const
+  {
+    return nodeDegree;
+  }
+
+  int
+  getNumDsts() const
+  {
+    return static_cast<int>(perDstFib.size());
+  }
+
+  bool
+  contains(int dstId) const
+  {
+    return perDstFib.count(dstId) > 0;
+  }
+
+  // Functions for range-based loop:
+  auto
+  begin() const
+  {
+    return perDstFib.cbegin();
+  }
+
+  auto
+  end() const
+  {
+    return perDstFib.cend();
+  }
+
+  // Setters:
+  void
+  insert(int dstId, const FibNextHop& nh);
+
+  size_t
+  erase(int dstId, int nhId);
+
+private:
+  void
+  checkInputs();
+
+  void
+  createEmptyFib();
+
+private:
+  const int nodeId;           // Own node id
+  const std::string nodeName; // Own node name
+  const int numberOfNodes;
+  const int nodeDegree;
+  const Ptr<GlobalRouter> ownRouter;
+
+  int upwardCounter;
+  int totalNhCounter;
+
+  // DstId -> set<FibNextHop>
+  std::unordered_map<int, std::set<FibNextHop>> perDstFib;
+  std::unordered_map<int, std::set<FibNextHop>> upwardPerDstFib;
+
+  friend std::ostream&
+  operator<<(std::ostream&, const AbstractFib& fib);
+};
+
+std::ostream&
+operator<<(std::ostream& os, const AbstractFib& fib);
+
+} // namespace ndn
+} // namespace ns-3
+
+#endif // LFID_ABS_FIB_H
diff --git a/helper/lfid/fib-nexthop.cpp b/helper/lfid/fib-nexthop.cpp
new file mode 100644
index 0000000..dc3b069
--- /dev/null
+++ b/helper/lfid/fib-nexthop.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#include "fib-nexthop.hpp"
+
+#include <boost/functional/hash.hpp>
+#include <ostream>
+
+namespace ns3 {
+namespace ndn {
+
+constexpr int NODE_ID_LIMIT = 1000;
+
+FibNextHop::FibNextHop(int cost, int nhId, int costDelta, NextHopType type)
+{
+  NS_ABORT_UNLESS(cost > 0 && cost <= MAX_COST);
+  NS_ABORT_UNLESS(nhId >= 0 && nhId <= NODE_ID_LIMIT);
+
+  this->m_nhId = nhId;
+  this->m_cost = cost;
+  this->m_type = type;
+  this->m_costDelta = costDelta;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NextHopType& type)
+{
+  switch (type) {
+  case NextHopType::DOWNWARD:
+    return os << "DOWNWARD";
+  case NextHopType::UPWARD:
+    return os << "UPWARD";
+  case NextHopType::DISABLED:
+    return os << "DISABLED";
+  }
+  return os << static_cast<int>(type);
+}
+
+std::ostream&
+operator<<(std::ostream& os, const FibNextHop& a)
+{
+  return os << "Id: " << a.getNexthopId() << ", cost: " << a.m_cost << ", type: " << a.m_type;
+}
+
+} // namespace ndn
+} // namespace ns-3
+
+namespace std {
+
+using ns3::ndn::FibNextHop;
+
+template <>
+struct hash<FibNextHop> {
+  size_t
+  operator()(const FibNextHop& k) const
+  {
+    // Combine hash via boost library
+    std::size_t seed = 0;
+    boost::hash_combine(seed, k.getNexthopId());
+    boost::hash_combine(seed, k.getCost());
+
+    return seed;
+  }
+};
+
+}
diff --git a/helper/lfid/fib-nexthop.hpp b/helper/lfid/fib-nexthop.hpp
new file mode 100644
index 0000000..32a5e2a
--- /dev/null
+++ b/helper/lfid/fib-nexthop.hpp
@@ -0,0 +1,145 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#ifndef LFID_FIB_NH_H
+#define LFID_FIB_NH_H
+
+#include <iosfwd>
+#include <unordered_set>
+
+#include "ns3/abort.h"
+
+namespace ns3 {
+namespace ndn {
+
+enum class NextHopType { DOWNWARD,
+                         UPWARD,
+                         DISABLED };
+
+class FibNextHop {
+public:
+  static constexpr int MAX_COST = 1 * 1000 * 1000;
+
+  /**
+   * @param nhId The nexthop id.
+   * @param cost The link cost of a nexthop. has to be larger than 0!
+   * @param costDelta The cost difference (relative to the shortest path nexthop)
+   * @param type The nexthop type @sa NextHopType
+   */
+  FibNextHop(int cost, int nhId, int costDelta = -1, NextHopType type = NextHopType::DISABLED);
+
+  // Getters
+  int
+  getNexthopId() const
+  {
+    return m_nhId;
+  }
+
+  int
+  getCost() const
+  {
+    return m_cost;
+  }
+
+  int
+  getCostDelta() const
+  {
+    return m_costDelta;
+  }
+
+  NextHopType
+  getType() const
+  {
+    return m_type;
+  }
+
+  // Setters:
+  void
+  setType(const NextHopType& newType)
+  {
+    NS_ABORT_UNLESS(newType != NextHopType::DISABLED);
+    this->m_type = newType;
+  }
+
+  // Only used in old fillFib:
+  void
+  setCost(int newCost, int newCostDelta)
+  {
+    NS_ABORT_UNLESS(newCost > 0);
+    NS_ABORT_UNLESS(newCostDelta >= 0);
+    this->m_cost = newCost;
+    this->m_costDelta = newCostDelta;
+  }
+
+private:
+  // Order of FibNexthop:
+  friend bool
+  operator<(const FibNextHop& own, const FibNextHop& other)
+  {
+    NS_ABORT_UNLESS(own.m_nhId != -1);
+
+    return std::tie(own.m_costDelta, own.m_cost, own.m_nhId)
+           < std::tie(other.m_costDelta, other.m_cost, other.m_nhId);
+  }
+
+  friend bool
+  operator==(const FibNextHop& own, const FibNextHop& other)
+  {
+    if (other.m_nhId == own.m_nhId) {
+      // Check that there are no FibNextHop with identical id, but different cost.
+      NS_ABORT_UNLESS(other.m_cost == own.m_cost);
+      NS_ABORT_UNLESS(other.m_costDelta == own.m_costDelta);
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+
+  friend bool
+  operator!=(const FibNextHop& own, const FibNextHop& other)
+  {
+    return !(own == other);
+  }
+
+  friend std::ostream&
+  operator<<(std::ostream&, const FibNextHop& fib);
+
+private:
+  int m_cost;
+  int m_nhId;
+  NextHopType m_type;
+  int m_costDelta;
+};
+
+std::ostream&
+operator<<(std::ostream& os, const NextHopType& type);
+std::ostream&
+operator<<(std::ostream& os, const FibNextHop& a);
+
+} // namespace ndn
+} // namespace ns-3
+
+namespace std {
+template <>
+struct hash<ns3::ndn::FibNextHop>;
+}
+
+#endif // LFID_FIB_NH_H
diff --git a/helper/lfid/ndn-global-routing-helper-lfid.cpp b/helper/lfid/ndn-global-routing-helper-lfid.cpp
new file mode 100644
index 0000000..13f86ab
--- /dev/null
+++ b/helper/lfid/ndn-global-routing-helper-lfid.cpp
@@ -0,0 +1,201 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#include "ns3/ndnSIM/helper/ndn-global-routing-helper.hpp"
+
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/graph_utility.hpp>
+
+#include "ns3/ndnSIM/helper/boost-graph-ndn-global-routing-helper.hpp"
+#include "ns3/ndnSIM/helper/lfid/abstract-fib.hpp"
+#include "ns3/ndnSIM/helper/lfid/remove-loops.hpp"
+#include "ns3/ndnSIM/helper/ndn-fib-helper.hpp"
+#include "ns3/ndnSIM/model/ndn-global-router.hpp"
+
+NS_LOG_COMPONENT_DEFINE("ndn.GlobalRoutingHelperLfid");
+
+namespace ns3 {
+namespace ndn {
+
+using std::get;
+using std::unordered_map;
+
+void
+GlobalRoutingHelper::CalculateLfidRoutes()
+{
+  BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<boost::NdnGlobalRouterGraph>));
+  BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<boost::NdnGlobalRouterGraph>));
+
+  // Creates graph from nodeList:
+  boost::NdnGlobalRouterGraph graph{};
+
+  AbstractFib::AllNodeFib allNodeFIB;
+
+  // Store mapping nodeId -> faceId -> Ptr<Face>
+  unordered_map<int, unordered_map<nfd::FaceId, shared_ptr<Face>>> faceMap;
+
+  // For all existing nodes:
+  for (auto node = NodeList::Begin(); node != NodeList::End(); node++) {
+
+    int nodeId = static_cast<int>((*node)->GetId());
+    const Ptr<GlobalRouter>& source = (*node)->GetObject<GlobalRouter>();
+
+    AbstractFib nodeFib = AbstractFib{source, static_cast<int>(NodeList::GetNNodes())};
+
+    if (source == nullptr) {
+      NS_LOG_ERROR("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
+      continue;
+    }
+
+    // map: neighborId -> DistancesMap
+    unordered_map<int, boost::DistancesMap> nbSp;
+
+    // map: Destination (GlobalRouter) -> Distance
+    boost::DistancesMap distMap;
+    unordered_map<int, boost::DistancesMap> neighborSpMap;
+
+    dijkstra_shortest_paths(graph, source,
+                            distance_map(boost::ref(distMap))
+                              .distance_inf(boost::WeightInf)
+                              .distance_zero(boost::WeightZero)
+                              .distance_compare(boost::WeightCompare())
+                              .distance_combine(boost::WeightCombine()));
+
+    // 1. Get all neighbors of node.
+    unordered_map<nfd::FaceId, uint64_t> originalMetrics;
+    auto& originalFace = faceMap[nodeId];
+
+    const GlobalRouter::IncidencyList& neighbors = source->GetIncidencies();
+    // Set link weight of all neighbors to infinity
+    for (const auto& neighbor : neighbors) {
+      int nbId = get<2>(neighbor)->GetObject<ns3::Node>()->GetId();
+      NS_ABORT_UNLESS(nbId != nodeId);
+
+      auto& face = get<shared_ptr<Face>>(neighbor);
+      NS_ABORT_UNLESS(face != nullptr);
+
+      originalMetrics[nbId] = face->getMetric();
+      originalFace[nbId] = face; // Is only a copy
+      face->setMetric(get<uint16_t>(boost::WeightInf));
+    }
+
+    // 2. Calculate Dijkstra for neighbors
+    for (const auto& neighbor : neighbors) {
+      const auto& nSource = get<0>(neighbor);
+      const auto& target = get<2>(neighbor);
+
+      int nbId = target->GetObject<ns3::Node>()->GetId();
+      Ptr<GlobalRouter> nbRouter = target;
+
+      NS_ABORT_UNLESS(target != source && nbId != nodeId);
+      NS_ABORT_UNLESS(nSource == source);
+
+      dijkstra_shortest_paths(graph, nbRouter,
+                              distance_map(boost::ref(neighborSpMap[nbId]))
+                                .distance_inf(boost::WeightInf)
+                                .distance_zero(boost::WeightZero)
+                                .distance_compare(boost::WeightCompare())
+                                .distance_combine(boost::WeightCombine()));
+    }
+
+    // 3. Reset link weights
+    for (const auto& neighbor : neighbors) {
+      int nbId = get<2>(neighbor)->GetObject<ns3::Node>()->GetId();
+      NS_ABORT_UNLESS(nbId != nodeId);
+
+      const auto& face = get<shared_ptr<Face>>(neighbor);
+      NS_ABORT_UNLESS(face->getMetric() == get<uint16_t>(boost::WeightInf));
+      face->setMetric(originalMetrics.at(nbId));
+    }
+
+    // 4. Fill Abstract FIB:
+    // For each destination:
+    for (const auto& dstEntry : distMap) {
+      Ptr<GlobalRouter> dstRouter = dstEntry.first;
+      int dstId = dstRouter->GetObject<ns3::Node>()->GetId();
+      if (dstRouter == source)
+        continue; // Skip destination == source.
+
+      int spTotalCost = static_cast<int>(get<uint32_t>(dstEntry.second));
+
+      // For each neighbor:
+      for (const auto& nb : neighborSpMap) {
+        int neighborId = nb.first;
+        const uint32_t nbDist{get<uint32_t>(nb.second.at(dstRouter))};
+
+        int neighborCost = static_cast<int>(nbDist);
+        int neighborTotalCost = neighborCost + static_cast<int>(originalFace.at(neighborId)->getMetric());
+
+        NS_ABORT_UNLESS(neighborTotalCost >= spTotalCost);
+
+        // Skip routers that would loop back
+        if (neighborTotalCost >= static_cast<int>(get<uint16_t>(boost::WeightInf)))
+          continue;
+
+        NextHopType nbType;
+        if (neighborCost < spTotalCost) {
+          nbType = NextHopType::DOWNWARD;
+        }
+        else {
+          nbType = NextHopType::UPWARD;
+        }
+
+        int costDelta = neighborTotalCost - spTotalCost;
+        FibNextHop nh = {neighborTotalCost, neighborId, costDelta, nbType};
+        nodeFib.insert(dstId, nh);
+      }
+
+    } // End for all dsts
+
+    nodeFib.checkFib();
+    allNodeFIB.emplace(nodeId, nodeFib);
+  } // End for all nodes
+
+  ///  4. Remove loops and Deadends ///
+  removeLoops(allNodeFIB, true);
+  removeDeadEnds(allNodeFIB, true);
+
+  // 5. Insert from AbsFIB into real FIB!
+  // For each node in the AbsFIB: Insert into real fib.
+  for (const auto& nodeEntry : allNodeFIB) {
+    int nodeId = nodeEntry.first;
+    const auto& fib = nodeEntry.second;
+
+    // For each destination:
+    for (const auto& dst : fib) {
+      int dstId = dst.first;
+      const auto& dstRouter = allNodeFIB.at(dstId).getGR();
+
+      // Each fibNexthop
+      for (const auto& nh : dst.second) {
+        int neighborId = nh.getNexthopId();
+        int neighborTotalCost = nh.getCost();
+
+        for (const auto& prefix : dstRouter->GetLocalPrefixes()) {
+          Ptr<Node> node = NodeList::GetNode(static_cast<uint32_t>(nodeId));
+          FibHelper::AddRoute(node, *prefix, faceMap.at(nodeId).at(neighborId), neighborTotalCost);
+        }
+      }
+    }
+  }
+}
+
+} // namespace ndn
+} // namespace ns3
diff --git a/helper/lfid/remove-loops.cpp b/helper/lfid/remove-loops.cpp
new file mode 100644
index 0000000..90062d1
--- /dev/null
+++ b/helper/lfid/remove-loops.cpp
@@ -0,0 +1,348 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#include "remove-loops.hpp"
+
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/dijkstra_shortest_paths.hpp>
+#include <boost/graph/properties.hpp>
+#include <boost/property_map/property_map.hpp>
+#include <queue>
+
+#include "ns3/abort.h"
+#include "ns3/ndnSIM/helper/lfid/abstract-fib.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+using std::set;
+using AllNodeFib = AbstractFib::AllNodeFib;
+
+/**
+ * Fill directed graph only with edges existing in the FIB.
+ */
+void
+getDigraphFromFib(DiGraph& dg, const AllNodeFib& allNodeFIB, const int dstId)
+{
+
+  // 1. Erase All Arcs:
+  dg.clear();
+
+  // 2. Add Arcs from FIB
+  for (const auto& node : allNodeFIB) {
+    int nodeId = node.first;
+    if (dstId == nodeId) {
+      continue;
+    }
+
+    for (const auto& fibNh : node.second.getNexthops(dstId)) {
+      NS_ABORT_UNLESS(fibNh.getType() <= NextHopType::UPWARD);
+      boost::add_edge(static_cast<uint64_t>(nodeId), static_cast<uint64_t>(fibNh.getNexthopId()), 1, dg);
+    }
+  }
+}
+
+class NodePrio {
+public:
+  NodePrio(int nodeId, int remainingNh, set<FibNextHop> nhSet)
+    : m_nodeId{nodeId}
+    , m_remainingNh{remainingNh}
+    , m_uwSet{nhSet}
+  {
+    NS_ABORT_UNLESS(remainingNh > 0 && m_uwSet.size() > 0);
+    NS_ABORT_UNLESS(static_cast<int>(m_uwSet.size()) < remainingNh);
+  }
+
+  int
+  getId() const
+  {
+    return m_nodeId;
+  }
+
+  int
+  getRemainingUw() const
+  {
+    return static_cast<int>(m_uwSet.size());
+  }
+
+  /**
+   * Order by Remamining UW NHs, Highest DeltaCost, and then id.
+   */
+  bool
+  operator<(const NodePrio& other) const
+  {
+    return std::make_tuple(m_remainingNh, getHighestCostUw(), m_nodeId)
+           < std::make_tuple(other.m_remainingNh, other.getHighestCostUw(), other.m_nodeId);
+  }
+
+  // Setters:
+  FibNextHop
+  popHighestCostUw()
+  {
+    const FibNextHop& tmp = getHighestCostUw();
+    eraseUw(tmp);
+    return tmp;
+  }
+
+  void
+  reduceRemainingNh()
+  {
+    m_remainingNh--;
+    // Check that remaining nexthops >= remaining uw nexthops.
+    NS_ABORT_UNLESS(m_remainingNh > 0 && m_remainingNh > getRemainingUw());
+  }
+
+private:
+  void
+  eraseUw(FibNextHop nh)
+  {
+    NS_ABORT_UNLESS(m_uwSet.size() > 0);
+    auto success = m_uwSet.erase(nh);
+    NS_ABORT_UNLESS(success == 1);
+  }
+
+  FibNextHop
+  getHighestCostUw() const
+  {
+    NS_ABORT_UNLESS(m_uwSet.size() > 0);
+    NS_ABORT_UNLESS(std::prev(m_uwSet.end()) != m_uwSet.end());
+    return *(std::prev(m_uwSet.end()));
+  }
+
+private:
+  int m_nodeId;
+  int m_remainingNh;
+  set<FibNextHop> m_uwSet;
+
+  friend std::ostream&
+  operator<<(std::ostream&, const NodePrio& node);
+};
+
+std::ostream&
+operator<<(std::ostream& os, const NodePrio& node)
+{
+  return os << "Id: " << node.m_nodeId << ", remaining NH: " << node.m_remainingNh
+            << ", remaining UW: " << node.getRemainingUw() << " ";
+}
+
+int
+removeLoops(AllNodeFib& allNodeFIB, bool printOutput)
+{
+  int removedLoopCounter = 0;
+  int upwardCounter = 0;
+
+  const int NUM_NODES{static_cast<int>(allNodeFIB.size())};
+
+  // Build graph with boost graph library:
+  DiGraph dg{};
+
+  // Add all Arcs that fit into FIB. // O(n)
+  for (int dstId = 0; dstId < NUM_NODES; dstId++) {
+    // 1. Get DiGraph from Fib //
+    getDigraphFromFib(dg, allNodeFIB, dstId);
+
+    // NodeId -> set<UwNexthops>
+    std::priority_queue<NodePrio> q;
+
+    // 2. Put nodes in the queue, ordered by # remaining nexthops, then CostDelta // O(n^2)
+    for (const auto& node : allNodeFIB) {
+      int nodeId{node.first};
+      const AbstractFib& fib{node.second};
+      if (nodeId == dstId) {
+        continue;
+      }
+
+      const auto& uwNhSet = fib.getUpwardNexthops(dstId);
+      if (!uwNhSet.empty()) {
+        upwardCounter += uwNhSet.size();
+
+        int fibSize{fib.numEnabledNhPerDst(dstId)};
+        // NodePrio tmpNode {nodeId, fibSize, uwNhSet};
+        q.emplace(nodeId, fibSize, uwNhSet);
+      }
+    }
+
+    // 3. Iterate PriorityQueue //
+    while (!q.empty()) {
+      NodePrio node = q.top();
+      q.pop();
+
+      int nodeId = node.getId();
+      int nhId = node.popHighestCostUw().getNexthopId();
+
+      // Remove opposite of Uphill link
+      //      int arcId1 {getArcId(arcMap, nhId, nodeId)};
+      auto res = boost::edge(static_cast<uint64_t>(nhId), static_cast<uint64_t>(nodeId), dg);
+
+      auto arc = res.first;
+      bool arcExists = res.second;
+
+      if (arcExists) {
+        boost::remove_edge(arc, dg);
+      }
+
+      // 2. Loop Check: Is the current node still reachable for the uphill nexthop?
+      // Uses BFS:
+      // bool willLoop = bfs(dg).run(dg.nodeFromId(nhId), dg.nodeFromId(nodeId)); // O(m^2n)
+
+      std::vector<int> dists(num_vertices(dg));
+
+      auto weightmap = get(boost::edge_weight, dg);
+
+      const auto& x = boost::edges(dg);
+      for (auto e = x.first; e != x.second; e++) {
+        int weight = get(weightmap, *e);
+        NS_ABORT_UNLESS(weight == 1); // Only use uniform weights.
+      }
+
+      // TODO: Could be replaced by BFS/DFS to improve speed.
+      dijkstra_shortest_paths(dg, static_cast<uint64_t>(nhId),
+                              distance_map(
+                                boost::make_iterator_property_map(dists.begin(), get(boost::vertex_index, dg))));
+
+      bool willLoop = (dists.at(static_cast<size_t>(nodeId)) < (std::numeric_limits<int>::max() - 1));
+
+      // Uphill nexthop loops back to original node
+      if (willLoop) {
+        node.reduceRemainingNh();
+        removedLoopCounter++;
+
+        // Erase FIB entry
+        allNodeFIB.at(node.getId()).erase(dstId, nhId);
+
+        auto res2 = boost::edge(static_cast<uint64_t>(node.getId()), static_cast<uint64_t>(nhId), dg);
+        auto arc2 = res2.first;
+        NS_ABORT_UNLESS(res.second);
+
+        boost::remove_edge(arc2, dg);
+      }
+
+      // Add opposite of UW link back:
+      if (arcExists) {
+        boost::add_edge(static_cast<uint64_t>(nhId), static_cast<uint64_t>(nodeId), 1, dg);
+      }
+
+      // If not has further UW nexthops: Requeue.
+      if (node.getRemainingUw() > 0) {
+        q.push(node);
+      }
+    }
+  }
+
+  if (printOutput) {
+    std::cout << "Found " << upwardCounter << " UW nexthops, Removed " << removedLoopCounter
+              << " Looping UwNhs, Remaining: " << upwardCounter - removedLoopCounter << " NHs\n";
+  }
+  NS_ABORT_UNLESS((upwardCounter - removedLoopCounter) >= 0);
+
+  return removedLoopCounter;
+}
+
+int
+removeDeadEnds(AllNodeFib& allNodeFIB, bool printOutput)
+{
+  int NUM_NODES{static_cast<int>(allNodeFIB.size())};
+  int checkedUwCounter{0};
+  int uwCounter{0};
+  int totalCounter{0};
+  int removedDeadendCounter{0};
+
+  for (int dstId = 0; dstId < NUM_NODES; dstId++) {
+    // NodeId -> FibNexthops (Order important)
+    set<std::pair<int, FibNextHop>> nhSet;
+
+    // 1. Put all uwNexthops in set<NodeId, FibNexhtop>:
+    for (const auto& node : allNodeFIB) {
+      int nodeId{node.first};
+      if (nodeId == dstId) {
+        continue;
+      }
+
+      totalCounter += node.second.getNexthops(dstId).size();
+
+      const auto& uwNhSet = node.second.getUpwardNexthops(dstId);
+      uwCounter += uwNhSet.size();
+      for (const FibNextHop& fibNh : uwNhSet) {
+        nhSet.emplace(nodeId, fibNh);
+      }
+    }
+
+    // FibNexthops ordered by (costDelta, cost, nhId).
+    // Start with nexthop with highest cost:
+    while (!nhSet.empty()) {
+      checkedUwCounter++;
+
+      // Pop from queue:
+      const auto& nhPair = nhSet.begin();
+      NS_ABORT_UNLESS(nhPair != nhSet.end());
+      nhSet.erase(nhPair);
+
+      int nodeId = nhPair->first;
+      const FibNextHop& nh = nhPair->second;
+      AbstractFib& fib = allNodeFIB.at(nodeId);
+
+      if (nh.getNexthopId() == dstId) {
+        continue;
+      }
+
+      int reverseEntries{allNodeFIB.at(nh.getNexthopId()).numEnabledNhPerDst(dstId)};
+
+      // Must have at least one FIB entry.
+      NS_ABORT_UNLESS(reverseEntries > 0);
+
+      // If it has exactly 1 entry -> Is downward back through the upward nexthop!
+      // Higher O-Complexity below:
+      if (reverseEntries <= 1) {
+        removedDeadendCounter++;
+
+        // Erase NhEntry from FIB:
+        fib.erase(dstId, nh.getNexthopId());
+
+        // Push into Queue: All NhEntries that lead to m_nodeId!
+        const auto& nexthops = fib.getNexthops(dstId);
+
+        for (const auto& ownNhs : nexthops) {
+          if (ownNhs.getType() == NextHopType::DOWNWARD && ownNhs.getNexthopId() != dstId) {
+            const auto& reverseNh = allNodeFIB.at(ownNhs.getNexthopId()).getNexthops(dstId);
+
+            for (const auto& y : reverseNh) {
+              if (y.getNexthopId() == nodeId) {
+                NS_ABORT_UNLESS(y.getType() == NextHopType::UPWARD);
+                nhSet.emplace(ownNhs.getNexthopId(), y);
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  if (printOutput) {
+    std::cout << "Checked " << checkedUwCounter << " Upward NHs, Removed " << removedDeadendCounter
+              << " Deadend UwNhs, Remaining: " << uwCounter - removedDeadendCounter << " UW NHs, "
+              << totalCounter - removedDeadendCounter << " total nexthops\n";
+  }
+
+  return removedDeadendCounter;
+}
+
+} // namespace ndn
+} // namespace ns3
diff --git a/helper/lfid/remove-loops.hpp b/helper/lfid/remove-loops.hpp
new file mode 100644
index 0000000..ec2a89e
--- /dev/null
+++ b/helper/lfid/remove-loops.hpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2019 Klaus Schneider, The University of Arizona
+ *
+ * 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: Klaus Schneider <klaus@cs.arizona.edu>
+ */
+
+#ifndef LFID_REMOVE_LOOPS_H
+#define LFID_REMOVE_LOOPS_H
+
+#include <boost/graph/adjacency_list.hpp>
+
+#include "ns3/ndnSIM/helper/lfid/abstract-fib.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+// No Vertex Property
+// Edge Property: Weight.
+using DiGraph =
+  boost::adjacency_list<boost::listS, boost::vecS, boost::bidirectionalS, boost::no_property,
+                        boost::property<boost::edge_weight_t, int>>;
+
+void
+getDigraphFromFib(DiGraph& dg, const AbstractFib::AllNodeFib& allNodeFIB, const int dstId);
+
+int
+removeLoops(AbstractFib::AllNodeFib& allNodeFIB, bool printOutput = true);
+
+int
+removeDeadEnds(AbstractFib::AllNodeFib& allNodeFIB, bool printOutput = true);
+
+} // namespace ndn
+} // namespace ns3
+
+#endif //LFID_REMOVE_LOOPS_H
diff --git a/helper/ndn-global-routing-helper.hpp b/helper/ndn-global-routing-helper.hpp
index b405838..d14b2fe 100644
--- a/helper/ndn-global-routing-helper.hpp
+++ b/helper/ndn-global-routing-helper.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2011-2015  Regents of the University of California.
+ * Copyright (c) 2011-2019  Regents of the University of California.
  *
  * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
  * contributors.
@@ -101,6 +101,19 @@
   CalculateRoutes();
 
   /**
+   * @brief Calculates a set of loop-free multipath routes.
+   *
+   * For full description please see tech tech report "Hop-by-Hop Multipath Routing:
+   * Choosing the Right Nexthop Set" and the associated Github repository:
+   *
+   * https://github.com/schneiderklaus/ndnSIM-routing
+   *
+   * @sa https://named-data.net/publications/techreports/mp_routing_tech_report/
+   */
+  static void
+  CalculateLfidRoutes();
+
+  /**
    * @brief Calculate all possible next-hop independent alternative routes
    *
    * Refer to the implementation for more details.
