#include <MPLS.h>
Protected Member Functions | |
virtual void | initialize (int stage) |
virtual int | numInitStages () const |
virtual void | handleMessage (cMessage *msg) |
Private Member Functions | |
void | processPacketFromL3 (cMessage *msg) |
void | processPacketFromL2 (cMessage *msg) |
void | processMPLSPacketFromL2 (MPLSPacket *mplsPacket) |
bool | tryLabelAndForwardIPDatagram (IPDatagram *ipdatagram) |
void | labelAndForwardIPDatagram (IPDatagram *ipdatagram) |
void | sendToL2 (cMessage *msg, int gateIndex) |
void | doStackOps (MPLSPacket *mplsPacket, const LabelOpVector &outLabel) |
Private Attributes | |
simtime_t | delay1 |
LIBTable * | lt |
InterfaceTable * | ift |
IClassifier * | pct |
void MPLS::doStackOps | ( | MPLSPacket * | mplsPacket, | |
const LabelOpVector & | outLabel | |||
) | [private] |
00165 { 00166 unsigned int n = outLabel.size(); 00167 00168 EV << "doStackOps: " << outLabel << endl; 00169 00170 ASSERT(n >= 0); 00171 00172 for (unsigned int i = 0; i < n; i++) 00173 { 00174 switch (outLabel[i].optcode) 00175 { 00176 case PUSH_OPER: 00177 mplsPacket->pushLabel(outLabel[i].label); 00178 break; 00179 00180 case SWAP_OPER: 00181 ASSERT(mplsPacket->hasLabel()); 00182 mplsPacket->swapLabel(outLabel[i].label); 00183 break; 00184 00185 case POP_OPER: 00186 ASSERT(mplsPacket->hasLabel()); 00187 mplsPacket->popLabel(); 00188 break; 00189 00190 default: 00191 error("Unknown MPLS OptCode %d", outLabel[i].optcode); 00192 } 00193 } 00194 }
void MPLS::handleMessage | ( | cMessage * | msg | ) | [protected, virtual] |
00064 { 00065 if (!strcmp(msg->arrivalGate()->name(), "ifIn")) 00066 { 00067 EV << "Processing message from L2: " << msg << endl; 00068 processPacketFromL2(msg); 00069 } 00070 else if (!strcmp(msg->arrivalGate()->name(), "netwIn")) 00071 { 00072 EV << "Processing message from L3: " << msg << endl; 00073 processPacketFromL3(msg); 00074 } 00075 else 00076 { 00077 error("unexpected message: %s", msg->name()); 00078 } 00079 }
void MPLS::initialize | ( | int | stage | ) | [protected, virtual] |
00037 { 00038 if (stage!=3) // interfaceTable must be initialized 00039 return; 00040 00041 lt = LIBTableAccess().get(); 00042 ift = InterfaceTableAccess().get(); 00043 00044 pct = check_and_cast<IClassifier*>(parentModule()->submodule(par("classifier"))); 00045 00046 /* 00047 * we now send plain IPDatagrams instead of packets with label=-1 00048 * and we thus do not need this extra configuration 00049 * 00050 labelIf.resize(ift->numInterfaces()); 00051 cStringTokenizer tokenizer(par("peers")); 00052 const char *token; 00053 while ((token = tokenizer.nextToken())!=NULL) 00054 { 00055 ASSERT(ift->interfaceByName(token)); 00056 int n = ift->interfaceByName(token)->outputPort(); 00057 ASSERT(n >= 0 && n < labelIf.size()); 00058 labelIf[n] = true; 00059 } 00060 */ 00061 }
void MPLS::labelAndForwardIPDatagram | ( | IPDatagram * | ipdatagram | ) | [private] |
00150 { 00151 if (tryLabelAndForwardIPDatagram(ipdatagram)) 00152 return; 00153 00154 // handling our outgoing IP traffic that didn't match any FEC/LSP 00155 // do not use labelAndForwardIPDatagram for packets arriving to ingress! 00156 00157 EV << "FEC not resolved, doing regular L3 routing" << endl; 00158 00159 int gateIndex = ipdatagram->arrivalGate()->index(); 00160 00161 sendToL2(ipdatagram, gateIndex); 00162 }
void MPLS::processMPLSPacketFromL2 | ( | MPLSPacket * | mplsPacket | ) | [private] |
00223 { 00224 int gateIndex = mplsPacket->arrivalGate()->index(); 00225 InterfaceEntry *ie = ift->interfaceByNetworkLayerGateIndex(gateIndex); 00226 std::string senderInterface = ie->name(); 00227 ASSERT(mplsPacket->hasLabel()); 00228 int oldLabel = mplsPacket->topLabel(); 00229 00230 EV << "Received " << mplsPacket << " from L2, label=" << oldLabel << " inInterface=" << senderInterface << endl; 00231 00232 if (oldLabel==-1) 00233 { 00234 // This is a IP native packet (RSVP/TED traffic) 00235 // Decapsulate the message and pass up to L3 00236 EV << ": decapsulating and sending up\n"; 00237 00238 IPDatagram *ipdatagram = check_and_cast<IPDatagram *>(mplsPacket->decapsulate()); 00239 delete mplsPacket; 00240 send(ipdatagram, "netwOut", gateIndex); 00241 return; 00242 } 00243 00244 LabelOpVector outLabel; 00245 std::string outInterface; 00246 int color; 00247 00248 bool found = lt->resolveLabel(senderInterface, oldLabel, outLabel, outInterface, color); 00249 if (!found) 00250 { 00251 EV << "discarding packet, incoming label not resolved" << endl; 00252 00253 delete mplsPacket; 00254 return; 00255 } 00256 00257 int outgoingPort = ift->interfaceByName(outInterface.c_str())->networkLayerGateIndex(); 00258 00259 doStackOps(mplsPacket, outLabel); 00260 00261 if (mplsPacket->hasLabel()) 00262 { 00263 // forward labeled packet 00264 00265 EV << "forwarding packet to " << outInterface << endl; 00266 00267 if (mplsPacket->hasPar("color")) 00268 { 00269 mplsPacket->par("color") = color; 00270 } 00271 else 00272 { 00273 mplsPacket->addPar("color") = color; 00274 } 00275 00276 //ASSERT(labelIf[outgoingPort]); 00277 00278 sendToL2(mplsPacket, outgoingPort); 00279 } 00280 else 00281 { 00282 // last label popped, decapsulate and send out IP datagram 00283 00284 EV << "decapsulating IP datagram" << endl; 00285 00286 IPDatagram *nativeIP = check_and_cast<IPDatagram *>(mplsPacket->decapsulate()); 00287 delete mplsPacket; 00288 00289 if (outgoingPort != -1) 00290 { 00291 sendToL2(nativeIP, outgoingPort); 00292 } 00293 else 00294 { 00295 send(nativeIP, "netwOut", gateIndex); 00296 } 00297 } 00298 }
void MPLS::processPacketFromL2 | ( | cMessage * | msg | ) | [private] |
00197 { 00198 IPDatagram *ipdatagram = dynamic_cast<IPDatagram *>(msg); 00199 MPLSPacket *mplsPacket = dynamic_cast<MPLSPacket *>(msg); 00200 00201 if (mplsPacket) 00202 { 00203 processMPLSPacketFromL2(mplsPacket); 00204 } 00205 else if (ipdatagram) 00206 { 00207 // IP datagram arrives at Ingress router. We'll try to classify it 00208 // and add an MPLS header 00209 00210 if (!tryLabelAndForwardIPDatagram(ipdatagram)) 00211 { 00212 int gateIndex = ipdatagram->arrivalGate()->index(); 00213 send(ipdatagram, "netwOut", gateIndex); 00214 } 00215 } 00216 else 00217 { 00218 error("Unknown message received"); 00219 } 00220 }
void MPLS::processPacketFromL3 | ( | cMessage * | msg | ) | [private] |
00087 { 00088 IPDatagram *ipdatagram = check_and_cast<IPDatagram *>(msg); 00089 //int gateIndex = msg->arrivalGate()->index(); 00090 00091 // XXX temporary solution, until TCPSocket and IP are extended to support nam tracing 00092 if (ipdatagram->transportProtocol() == IP_PROT_TCP) 00093 { 00094 TCPSegment *seg = check_and_cast<TCPSegment*>(ipdatagram->encapsulatedMsg()); 00095 if (seg->destPort() == LDP_PORT || seg->srcPort() == LDP_PORT) 00096 { 00097 ASSERT(!ipdatagram->hasPar("color")); 00098 ipdatagram->addPar("color") = LDP_TRAFFIC; 00099 } 00100 } 00101 else if (ipdatagram->transportProtocol() == IP_PROT_ICMP) 00102 { 00103 // ASSERT(!ipdatagram->hasPar("color")); XXX this did not hold sometimes... 00104 if (!ipdatagram->hasPar("color")) 00105 ipdatagram->addPar("color") = ICMP_TRAFFIC; 00106 } 00107 // XXX end of temporary area 00108 00109 labelAndForwardIPDatagram(ipdatagram); 00110 }
void MPLS::sendToL2 | ( | cMessage * | msg, | |
int | gateIndex | |||
) | [private] |
bool MPLS::tryLabelAndForwardIPDatagram | ( | IPDatagram * | ipdatagram | ) | [private] |
00113 { 00114 LabelOpVector outLabel; 00115 std::string outInterface; 00116 int color; 00117 00118 if (!pct->lookupLabel(ipdatagram, outLabel, outInterface, color)) 00119 { 00120 EV << "no mapping exists for this packet" << endl; 00121 return false; 00122 } 00123 00124 ASSERT(outLabel.size() > 0); 00125 00126 int outgoingPort = ift->interfaceByName(outInterface.c_str())->networkLayerGateIndex(); 00127 00128 MPLSPacket *mplsPacket = new MPLSPacket(ipdatagram->name()); 00129 mplsPacket->encapsulate(ipdatagram); 00130 doStackOps(mplsPacket, outLabel); 00131 00132 EV << "forwarding packet to " << outInterface << endl; 00133 00134 mplsPacket->addPar("color") = color; 00135 00136 if (!mplsPacket->hasLabel()) 00137 { 00138 // yes, this may happen - if we'are both ingress and egress 00139 ipdatagram = check_and_cast<IPDatagram*>(mplsPacket->decapsulate()); // XXX FIXME superfluous encaps/decaps 00140 delete mplsPacket; 00141 sendToL2(ipdatagram, outgoingPort); 00142 } 00143 else 00144 sendToL2(mplsPacket, outgoingPort); 00145 00146 return true; 00147 }
simtime_t MPLS::delay1 [private] |
InterfaceTable* MPLS::ift [private] |
IClassifier* MPLS::pct [private] |