SimpleClassifier.cc

Go to the documentation of this file.
00001 //
00002 // (C) 2005 Vojtech Janota
00003 //
00004 // This library is free software, you can redistribute it
00005 // and/or modify
00006 // it under  the terms of the GNU Lesser General Public License
00007 // as published by the Free Software Foundation;
00008 // either version 2 of the License, or any later version.
00009 // The library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00012 // See the GNU Lesser General Public License for more details.
00013 //
00014 
00015 #include <iostream>
00016 #include "SimpleClassifier.h"
00017 #include "XMLUtils.h"
00018 #include "RoutingTableAccess.h"
00019 #include "LIBTableAccess.h"
00020 #include "RSVPAccess.h"
00021 #include "LIBTable.h"
00022 
00023 Define_Module(SimpleClassifier);
00024 
00025 void SimpleClassifier::initialize(int stage)
00026 {
00027     // we have to wait until routerId gets assigned in stage 3
00028     if (stage!=4)
00029         return;
00030 
00031     maxLabel = 0;
00032 
00033     RoutingTableAccess routingTableAccess;
00034     IRoutingTable *rt = routingTableAccess.get();
00035     routerId = rt->getRouterId();
00036 
00037     LIBTableAccess libTableAccess;
00038     lt = libTableAccess.get();
00039 
00040     RSVPAccess rsvpAccess;
00041     rsvp = rsvpAccess.get();
00042 
00043     readTableFromXML(par("conf").xmlValue());
00044 
00045     WATCH_VECTOR(bindings);
00046 }
00047 
00048 void SimpleClassifier::handleMessage(cMessage *)
00049 {
00050     ASSERT(false);
00051 }
00052 
00053 // IClassifier implementation (method invoked by MPLS)
00054 
00055 bool SimpleClassifier::lookupLabel(IPDatagram *ipdatagram, LabelOpVector& outLabel, std::string& outInterface, int& color)
00056 {
00057     // never label OSPF(TED) and RSVP traffic
00058 
00059     switch(ipdatagram->getTransportProtocol())
00060     {
00061         case IP_PROT_OSPF:
00062         case IP_PROT_RSVP:
00063             return false;
00064 
00065         default:
00066             ;
00067     }
00068 
00069     // forwarding decision for non-labeled datagrams
00070 
00071     std::vector<FECEntry>::iterator it;
00072     for (it = bindings.begin(); it != bindings.end(); it++)
00073     {
00074         if (!it->dest.isUnspecified() && !it->dest.equals(ipdatagram->getDestAddress()))
00075             continue;
00076 
00077         if (!it->src.isUnspecified() && !it->src.equals(ipdatagram->getSrcAddress()))
00078             continue;
00079 
00080         EV << "packet belongs to fecid=" << it->id << endl;
00081 
00082         if (it->inLabel < 0)
00083             return false;
00084 
00085         return lt->resolveLabel("", it->inLabel, outLabel, outInterface, color);
00086     }
00087 
00088     return false;
00089 }
00090 
00091 // IRSVPClassifier implementation (method invoked by RSVP)
00092 
00093 void SimpleClassifier::bind(const SessionObj_t& session, const SenderTemplateObj_t& sender, int inLabel)
00094 {
00095     std::vector<FECEntry>::iterator it;
00096     for (it = bindings.begin(); it != bindings.end(); it++)
00097     {
00098         if (it->session != session)
00099             continue;
00100 
00101         if (it->sender != sender)
00102             continue;
00103 
00104         it->inLabel = inLabel;
00105     }
00106 }
00107 
00108 // IScriptable implementation (method invoked by ScenarioManager)
00109 
00110 void SimpleClassifier::processCommand(const cXMLElement& node)
00111 {
00112     if (!strcmp(node.getTagName(), "bind-fec"))
00113     {
00114         readItemFromXML(&node);
00115     }
00116     else
00117         ASSERT(false);
00118 }
00119 
00120 
00121 // binding configuration
00122 
00123 void SimpleClassifier::readTableFromXML(const cXMLElement *fectable)
00124 {
00125     ASSERT(fectable);
00126     ASSERT(!strcmp(fectable->getTagName(), "fectable"));
00127     checkTags(fectable, "fecentry");
00128     cXMLElementList list = fectable->getChildrenByTagName("fecentry");
00129     for (cXMLElementList::iterator it=list.begin(); it != list.end(); it++)
00130         readItemFromXML(*it);
00131 }
00132 
00133 void SimpleClassifier::readItemFromXML(const cXMLElement *fec)
00134 {
00135     ASSERT(fec);
00136     ASSERT(!strcmp(fec->getTagName(), "fecentry") || !strcmp(fec->getTagName(), "bind-fec"));
00137 
00138     int fecid = getParameterIntValue(fec, "id");
00139 
00140     std::vector<FECEntry>::iterator it = findFEC(fecid);
00141 
00142     if (getUniqueChildIfExists(fec, "label"))
00143     {
00144         // bind-fec to label
00145         checkTags(fec, "id label destination source");
00146 
00147         EV << "binding to a given label" << endl;
00148 
00149         FECEntry newFec;
00150 
00151         newFec.id = fecid;
00152         newFec.dest = getParameterIPAddressValue(fec, "destination");
00153         newFec.src = getParameterIPAddressValue(fec, "source", IPAddress());
00154 
00155         newFec.inLabel = getParameterIntValue(fec, "label");
00156 
00157         if (it == bindings.end())
00158         {
00159             // create new binding
00160             bindings.push_back(newFec);
00161         }
00162         else
00163         {
00164             // update existing binding
00165             *it = newFec;
00166         }
00167     }
00168     else if (getUniqueChildIfExists(fec, "lspid"))
00169     {
00170         // bind-fec to LSP
00171         checkTags(fec, "id destination source tunnel_id extended_tunnel_id endpoint lspid");
00172 
00173         EV << "binding to a given path" << endl;
00174 
00175         FECEntry newFec;
00176 
00177         newFec.id = fecid;
00178         newFec.dest = getParameterIPAddressValue(fec, "destination");
00179         newFec.src = getParameterIPAddressValue(fec, "source", IPAddress());
00180 
00181         newFec.session.Tunnel_Id = getParameterIntValue(fec, "tunnel_id");
00182         newFec.session.Extended_Tunnel_Id = getParameterIPAddressValue(fec, "extened_tunnel_id", routerId).getInt();
00183         newFec.session.DestAddress = getParameterIPAddressValue(fec, "endpoint", newFec.dest); // ??? always use newFec.dest ???
00184 
00185         newFec.sender.Lsp_Id = getParameterIntValue(fec, "lspid");
00186         newFec.sender.SrcAddress = routerId;
00187 
00188         newFec.inLabel = rsvp->getInLabel(newFec.session, newFec.sender);
00189 
00190         if (it == bindings.end())
00191         {
00192             // create new binding
00193             bindings.push_back(newFec);
00194         }
00195         else
00196         {
00197             // update existing binding
00198             *it = newFec;
00199         }
00200     }
00201     else
00202     {
00203         // un-bind
00204         checkTags(fec, "id");
00205 
00206         if (it != bindings.end())
00207         {
00208             bindings.erase(it);
00209         }
00210     }
00211 }
00212 
00213 std::vector<SimpleClassifier::FECEntry>::iterator SimpleClassifier::findFEC(int fecid)
00214 {
00215     std::vector<FECEntry>::iterator it;
00216     for (it = bindings.begin(); it != bindings.end(); it++)
00217     {
00218         if (it->id != fecid)
00219             continue;
00220 
00221         break;
00222     }
00223     return it;
00224 }
00225 
00226 std::ostream& operator<<(std::ostream& os, const SimpleClassifier::FECEntry& fec)
00227 {
00228     os << "id:" << fec.id;
00229     os << "    dest:" << fec.dest;
00230     os << "    src:" << fec.src;
00231     os << "    session:" << fec.session;
00232     os << "    sender:" << fec.sender;
00233     os << "    inLabel:" << fec.inLabel;
00234     return os;
00235 }