|
INET Framework for OMNeT++/OMNEST
|
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 }