--- a
+++ b/src/policies/DIF/RA/Forwarding/DistanceVector/DistanceVectorPolicy.cc
@@ -0,0 +1,307 @@
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// 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 Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this program.  If not, see http://www.gnu.org/licenses/.
+//
+
+// Author: Kewin Rausch (kewin.rausch@create-net.org)
+
+#include "DistanceVectorPolicy.h"
+#include "PDUFwdTabGenerator.h"
+#include "PDUFTGUpdate.h"
+#include "DVPInfo.h"
+
+Define_Module(DistanceVectorPolicy);
+
+//
+// Class constructor/destructors stuff.
+//
+
+DistanceVectorPolicy::DistanceVectorPolicy()
+{
+    updateT = 0;
+}
+
+DistanceVectorPolicy::~DistanceVectorPolicy()
+{
+    // Do nothing...
+}
+
+//
+// Class procedures sorted by name.
+//
+
+void DistanceVectorPolicy::computeForwardingTable()
+{
+    if(!fwdtg)
+    {
+        return;
+    }
+
+    NetworkState * netState = fwdtg->getNetworkState();
+    NeighborState * neiState = fwdtg->getNeighborhoodState();
+
+    // So, when we need to build up the forwarding table from scratch then
+    // we start from our neighbors alone.
+    //
+
+    // Maintain only information about the neighborhood.
+    for(NIter it = netState->begin(); it != netState->end(); ++it )
+    {
+        bool rem = false;
+
+        DVPInfo * i = (DVPInfo *)(*it);
+
+        for(EIter et = neiState->begin(); et != neiState->end(); ++et )
+        {
+            PDUFTGNeighbor * e = (*et);
+
+            // It's not a neighbor.
+            if(!(e->getDestAddr() == i->getDestination()))
+            {
+                rem = true;
+                break;
+            }
+            // It's a neighbor! Repopulate the forwarding table.
+            else
+            {
+                fwdtg->getForwardingTable()->insert(e->getDestAddr(), e->getQosId(), e->getPort());
+            }
+        }
+
+        if(rem)
+        {
+            // Remove this information from our network state.
+            netState->remove(i);
+        }
+    }
+}
+
+PDUFTGInfo * DistanceVectorPolicy::flowExists(Address addr, unsigned short qos)
+{
+    for(NIter it = fwdtg->getNetworkState()->begin(); it != fwdtg->getNetworkState()->end(); ++it )
+    {
+        DVPInfo * fsi = (DVPInfo * )(*it);
+
+        // Equal condition; same source reach same destination with same qos constrain.
+        if(fsi->getDestination() == addr &&
+            fsi->getQoSID() == qos)
+        {
+            return fsi;
+        }
+    }
+
+    return NULL;
+}
+
+unsigned int DistanceVectorPolicy::getUpdateTimeout()
+{
+    return updateT;
+}
+
+void DistanceVectorPolicy::handleMessage(cMessage *msg)
+{
+    NeighborState * n;
+
+    if(msg->isSelfMessage())
+    {
+        switch(msg->getKind())
+        {
+        case PDUFTG_SELFMSG_FSUPDATE:
+            /* Stop condition. */
+            if(getUpdateTimeout() == 0)
+            {
+                break;
+            }
+
+            n = fwdtg->getNeighborhoodState();
+
+            for(EIter it = n->begin(); it != n->end(); ++it)
+            {
+                PDUFTGNeighbor * info = (*it);
+
+                // Finally send the update.
+                fwdtg->signalForwardingInfoUpdate(
+                    new PDUFTGUpdate(
+                        fwdtg->getIpcAddress(),
+                        info->getDestAddr(),
+                        fwdtg->getNetworkState()));
+            }
+
+            scheduleAt(
+                simTime() + getUpdateTimeout(),
+                new cMessage("UpdateRequested", PDUFTG_SELFMSG_FSUPDATE));
+
+            break;
+        default:
+            break;
+        }
+
+        delete msg;
+    }
+}
+
+void DistanceVectorPolicy::initialize()
+{
+    // Display active policy name.
+    PDUFTGPolicy::initialize();
+
+    // Default timeout 30 seconds.
+    setUpdateTimeout(30);
+
+    // Start the forwarding update timer routine.
+    scheduleAt(
+        simTime() + getUpdateTimeout(),
+        new cMessage("FwdTimerInit", PDUFTG_SELFMSG_FSUPDATE));
+}
+
+void DistanceVectorPolicy::insertNewFlow(Address addr, short unsigned int qos, RMTPort * port)
+{
+    // Callable from other modules.
+    Enter_Method("insertNewFlow()");
+
+    if(!fwdtg)
+    {
+        return;
+    }
+
+    // We're interested in flows to element of my DIF.
+    if(addr.getDifName() == fwdtg->getIpcAddress().getDifName())
+    {
+        DVPInfo * flowInfo;
+
+        flowInfo = (DVPInfo *)flowExists(addr, qos);
+
+        // Flow present? Strange!!!
+        if(flowInfo)
+        {
+            pduftg_debug("Flow for " << addr << " already present!");
+        }
+
+        flowInfo = new DVPInfo(
+            fwdtg->getIpcAddress(),
+            addr,
+            qos,
+            1);
+
+        // Update the network state too.
+        fwdtg->getNetworkState()->push_back(flowInfo);
+
+        // Insert what you consider a neighbor.
+        fwdtg->insertNeighbor(addr, qos, port);
+
+        // Add the entry in the table.
+        fwdtg->getForwardingTable()->insert(addr, qos, port);
+
+        // Debug the actual state of the network.
+        pduftg_debug(fwdtg->getIpcAddress().info() << "> " <<
+            fwdtg->netInfo());
+    }
+}
+
+void DistanceVectorPolicy::mergeForwardingInfo(PDUFTGUpdate * info)
+{
+    NetworkState * arrived = info->getInfo();
+
+    // Scan the arrived informations.
+    for(NIter i = arrived->begin(); i != arrived->end(); ++i)
+    {
+        bool insert = false;
+
+        DVPInfo * eval = (DVPInfo *)(*i);
+        // Info here are stored with us as source.
+        DVPInfo * info = (DVPInfo *)flowExists(
+            eval->getDestination(),
+            eval->getQoSID());
+
+        // Do not consider info over yourself.
+        if(eval->getDestination().getApname().getName() ==
+            fwdtg->getIpcAddress().getApname().getName())
+        {
+            continue;
+        }
+
+        // We already have such information.
+        if(info)
+        {
+            // It's a better metric?
+            if(eval->getMetric() + 1 < info->getMetric())
+            {
+                fwdtg->getForwardingTable()->remove(info->getDestination(), info->getQoSID());
+                removeFlow(eval->getDestination(), eval->getQoSID());
+
+                insert = true;
+            }
+        }
+        else
+        // The info does not exists.
+        {
+            insert = true;
+        }
+
+        if(insert)
+        {
+            // It's a better metric; pass through this sender from now on...
+            PDUFTGNeighbor * en = fwdtg->neighborExists(eval->getSource());
+
+            if(!en)
+            {
+                EV << "Could not reach " << eval->getDestination() << " from " << fwdtg->getIpcAddress().getApname().getName() << "???\n";
+                continue;
+            }
+
+            RMTPort * p = en->getPort();
+            DVPInfo * newi = new DVPInfo(
+                fwdtg->getIpcAddress(),
+                eval->getDestination(),
+                eval->getQoSID(),
+                eval->getMetric() + 1);
+
+            // Insert the entry into the tables.
+            fwdtg->getNetworkState()->push_back(newi);
+            fwdtg->getForwardingTable()->insert(eval->getDestination(), eval->getQoSID(), p);
+        }
+    }
+
+    // Debug the actual state of the network.
+    pduftg_debug(fwdtg->getIpcAddress().info() << "> " <<
+        fwdtg->netInfo());
+}
+
+PDUFTGUpdate * DistanceVectorPolicy::prepareFSUpdate(Address destination)
+{
+    PDUFTGUpdate * ret = new PDUFTGUpdate();
+    Address a = fwdtg->getIpcAddress();
+
+    ret->setSource(a);
+    ret->setDestination(destination);
+    ret->setInfo(fwdtg->getNetworkState());
+
+    return ret;
+}
+
+void DistanceVectorPolicy::removeFlow(Address addr, unsigned short qos)
+{
+    // Select the info with your information evaluation procedure.
+    PDUFTGInfo * netinfo = flowExists(addr, qos);
+
+    if(!netinfo)
+    {
+        fwdtg->getNetworkState()->remove(netinfo);
+    }
+}
+
+
+void DistanceVectorPolicy::setUpdateTimeout(unsigned int sec)
+{
+    updateT = sec;
+}