blob: 1272ab1d328eac22c90ad93d58e1121dc3946a6a [file] [log] [blame]
#include <list>
#include <cmath>
#include "nlsr.hpp"
#include "nexthop-list.hpp"
#include "fib.hpp"
namespace nlsr {
using namespace std;
using namespace ndn;
static bool
fibEntryNameCompare(const FibEntry& fibEntry, const string& name)
{
return fibEntry.getName() == name ;
}
void
Fib::cancelScheduledExpiringEvent(Nlsr& pnlsr, EventId eid)
{
pnlsr.getScheduler().cancelEvent(eid);
}
ndn::EventId
Fib::scheduleEntryRefreshing(Nlsr& pnlsr, const string& name, int32_t feSeqNum,
int32_t refreshTime)
{
std::cout << "Fib::scheduleEntryRefreshing Called" << std::endl;
std::cout << "Name: " << name << " Seq Num: " << feSeqNum << std::endl;
return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
ndn::bind(&Fib::refreshEntry, this,
boost::ref(pnlsr),
name, feSeqNum));
}
void
Fib::refreshEntry(Nlsr& nlsr, const string& name, int32_t feSeqNum)
{
std::cout << "Fib::refreshEntry Called" << std::endl;
std::cout << "Name: " << name << " Seq Num: " << feSeqNum << std::endl;
std::list<FibEntry>::iterator it = std::find_if(m_table.begin(),
m_table.end(),
bind(&fibEntryNameCompare, _1, name));
if (it != m_table.end())
{
std::cout << "Entry found with Seq Num: " << feSeqNum << std::endl;
if (it->getSeqNo() == feSeqNum)
{
std::cout << "Refreshing the FIB entry" << std::endl;
for (std::list<NextHop>::iterator nhit =
(*it).getNexthopList().getNextHops().begin();
nhit != (*it).getNexthopList().getNextHops().end(); nhit++)
{
// add entry to NDN-FIB
registerPrefixInNfd(it->getName(), nhit->getConnectingFace(), std::ceil(nhit->getRouteCost()));
}
// increase sequence number and schedule refresh again
it->setSeqNo(feSeqNum + 1);
it->setExpiringEventId(scheduleEntryRefreshing(nlsr,
it->getName() ,
it->getSeqNo(),
m_refreshTime));
}
}
}
void
Fib::remove(Nlsr& pnlsr, const std::string& name)
{
std::list<FibEntry>::iterator it = std::find_if(m_table.begin(),
m_table.end(),
bind(&fibEntryNameCompare, _1, name));
if (it != m_table.end())
{
for (std::list<NextHop>::iterator nhit =
(*it).getNexthopList().getNextHops().begin();
nhit != (*it).getNexthopList().getNextHops().end(); nhit++)
{
//remove entry from NDN-FIB
if (!pnlsr.getAdjacencyList().isNeighbor(it->getName()))
{
unregisterPrefixFromNfd(it->getName(), nhit->getConnectingFace());
}
else
{
if(pnlsr.getAdjacencyList().getAdjacent(it->getName()).getConnectingFace() !=
nhit->getConnectingFace())
{
unregisterPrefixFromNfd(it->getName(), nhit->getConnectingFace());
}
}
}
std::cout << "Cancellling Scheduled event" << std::endl;
std::cout << "Name: " << name << "Seq num: " << it->getSeqNo() << std::endl;
cancelScheduledExpiringEvent(pnlsr, (*it).getExpiringEventId());
m_table.erase(it);
}
}
void
Fib::update(Nlsr& pnlsr, const string& name, NexthopList& nextHopList)
{
std::cout << "Fib::updateFib Called" << std::endl;
int startFace = 0;
int endFace = getNumberOfFacesForName(nextHopList,
pnlsr.getConfParameter().getMaxFacesPerPrefix());
std::list<FibEntry>::iterator it = std::find_if(m_table.begin(),
m_table.end(),
bind(&fibEntryNameCompare, _1, name));
if (it == m_table.end())
{
if (nextHopList.getSize() > 0)
{
nextHopList.sort();
FibEntry newEntry(name);
std::list<NextHop> nhl = nextHopList.getNextHops();
std::list<NextHop>::iterator nhit = nhl.begin();
for (int i = startFace; i < endFace && nhit != nhl.end(); ++nhit, i++)
{
newEntry.getNexthopList().addNextHop((*nhit));
//Add entry to NDN-FIB
registerPrefixInNfd(name, nhit->getConnectingFace(), std::ceil(nhit->getRouteCost()));
}
newEntry.getNexthopList().sort();
newEntry.setTimeToRefresh(m_refreshTime);
newEntry.setSeqNo(1);
newEntry.setExpiringEventId(scheduleEntryRefreshing(pnlsr,
name , 1, m_refreshTime));
m_table.push_back(newEntry);
}
}
else
{
std::cout << "Old FIB Entry" << std::endl;
if (nextHopList.getSize() > 0)
{
nextHopList.sort();
if (!it->isEqualNextHops(nextHopList))
{
std::list<NextHop> nhl = nextHopList.getNextHops();
std::list<NextHop>::iterator nhit = nhl.begin();
// Add first Entry to NDN-FIB
registerPrefixInNfd(name, nhit->getConnectingFace(), std::ceil(nhit->getRouteCost()));
removeHop(pnlsr, it->getNexthopList(), nhit->getConnectingFace(), name);
it->getNexthopList().reset();
it->getNexthopList().addNextHop((*nhit));
++startFace;
++nhit;
for (int i = startFace; i < endFace && nhit != nhl.end(); ++nhit, i++)
{
it->getNexthopList().addNextHop((*nhit));
//Add Entry to NDN_FIB
registerPrefixInNfd(name, nhit->getConnectingFace(), std::ceil(nhit->getRouteCost()));
}
}
it->setTimeToRefresh(m_refreshTime);
std::cout << "Cancellling Scheduled event" << std::endl;
std::cout << "Name: " << name << "Seq num: " << it->getSeqNo() << std::endl;
cancelScheduledExpiringEvent(pnlsr, it->getExpiringEventId());
it->setSeqNo(it->getSeqNo() + 1);
(*it).setExpiringEventId(scheduleEntryRefreshing(pnlsr,
it->getName() ,
it->getSeqNo(), m_refreshTime));
}
else
{
remove(pnlsr, name);
}
}
}
void
Fib::clean(Nlsr& pnlsr)
{
for (std::list<FibEntry>::iterator it = m_table.begin(); it != m_table.end();
++it)
{
std::cout << "Cancellling Scheduled event" << std::endl;
std::cout << "Name: " << it->getName() << "Seq num: " << it->getSeqNo() << std::endl;
cancelScheduledExpiringEvent(pnlsr, (*it).getExpiringEventId());
for (std::list<NextHop>::iterator nhit =
(*it).getNexthopList().getNextHops().begin();
nhit != (*it).getNexthopList().getNextHops().end(); nhit++)
{
//Remove entry from NDN-FIB
if (!pnlsr.getAdjacencyList().isNeighbor(it->getName()))
{
unregisterPrefixFromNfd(it->getName(), nhit->getConnectingFace());
}
else
{
if(pnlsr.getAdjacencyList().getAdjacent(it->getName()).getConnectingFace() !=
nhit->getConnectingFace())
{
unregisterPrefixFromNfd(it->getName(), nhit->getConnectingFace());
}
}
}
}
if (m_table.size() > 0)
{
m_table.clear();
}
}
int
Fib::getNumberOfFacesForName(NexthopList& nextHopList, uint32_t maxFacesPerPrefix)
{
int endFace = 0;
if ((maxFacesPerPrefix == 0) || (nextHopList.getSize() <= maxFacesPerPrefix))
{
return nextHopList.getSize();
}
else
{
return maxFacesPerPrefix;
}
return endFace;
}
void
Fib::removeHop(Nlsr& pnlsr, NexthopList& nl, uint32_t doNotRemoveHopFaceId,
const std::string& name)
{
for (std::list<NextHop>::iterator it = nl.getNextHops().begin();
it != nl.getNextHops().end(); ++it)
{
if (it->getConnectingFace() != doNotRemoveHopFaceId)
{
//Remove FIB Entry from NDN-FIB
if (!pnlsr.getAdjacencyList().isNeighbor(name))
{
unregisterPrefixFromNfd(name, it->getConnectingFace());
}
else
{
if(pnlsr.getAdjacencyList().getAdjacent(name).getConnectingFace() !=
it->getConnectingFace())
{
unregisterPrefixFromNfd(name, it->getConnectingFace());
}
}
}
}
}
void
Fib::registerPrefixInNfd(const std::string& namePrefix, uint64_t faceId, uint64_t faceCost)
{
ndn::nfd::ControlParameters controlParameters;
controlParameters
.setName(namePrefix)
.setCost(faceCost)
.setFaceId(faceId)
.setExpirationPeriod(ndn::time::milliseconds(m_refreshTime*1000))
.setOrigin(128);
m_controller.start<ndn::nfd::RibRegisterCommand>(controlParameters,
ndn::bind(&Fib::onSuccess, this, _1,
"Successful in name registration"),
ndn::bind(&Fib::onFailure, this, _1, _2,
"Failed in name registration"));
}
void
Fib::unregisterPrefixFromNfd(const std::string& namePrefix, uint64_t faceId)
{
ndn::nfd::ControlParameters controlParameters;
controlParameters
.setName(namePrefix)
.setFaceId(faceId)
.setOrigin(128);
m_controller.start<ndn::nfd::RibUnregisterCommand>(controlParameters,
ndn::bind(&Fib::onSuccess, this, _1,
"Successful in unregistering name"),
ndn::bind(&Fib::onFailure, this, _1, _2,
"Failed in unregistering name"));
}
void
Fib::onSuccess(const ndn::nfd::ControlParameters& commandSuccessResult, const std::string& message)
{
std::cout << message << ": " << commandSuccessResult << std::endl;
}
void
Fib::onFailure(uint32_t code, const std::string& error, const std::string& message)
{
std::cout << message << ": " << error << " (code: " << code << ")";
}
void
Fib::print()
{
cout << "-------------------FIB-----------------------------" << endl;
for (std::list<FibEntry>::iterator it = m_table.begin(); it != m_table.end();
++it)
{
cout << (*it);
}
}
} //namespace nlsr