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
