Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <omnetpp.h>
00017 #include <string.h>
00018
00019 #include "MPLS.h"
00020 #include "Utils.h"
00021
00022 #include "InterfaceTableAccess.h"
00023 #include "RoutingTableAccess.h"
00024 #include "LIBTableAccess.h"
00025 #include "IClassifier.h"
00026
00027
00028
00029 #include "LDP.h"
00030 #include "TCPSegment.h"
00031 #define ICMP_TRAFFIC 6
00032
00033
00034 Define_Module(MPLS);
00035
00036 void MPLS::initialize(int stage)
00037 {
00038 if (stage!=3)
00039 return;
00040
00041 lt = LIBTableAccess().get();
00042 ift = InterfaceTableAccess().get();
00043
00044 pct = check_and_cast<IClassifier*>(getParentModule()->getSubmodule(par("classifier")));
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 }
00062
00063 void MPLS::handleMessage(cMessage * msg)
00064 {
00065 if (!strcmp(msg->getArrivalGate()->getName(), "ifIn"))
00066 {
00067 EV << "Processing message from L2: " << msg << endl;
00068 processPacketFromL2(msg);
00069 }
00070 else if (!strcmp(msg->getArrivalGate()->getName(), "netwIn"))
00071 {
00072 EV << "Processing message from L3: " << msg << endl;
00073 processPacketFromL3(msg);
00074 }
00075 else
00076 {
00077 error("unexpected message: %s", msg->getName());
00078 }
00079 }
00080
00081 void MPLS::sendToL2(cMessage *msg, int gateIndex)
00082 {
00083 send(msg, "ifOut", gateIndex);
00084 }
00085
00086 void MPLS::processPacketFromL3(cMessage * msg)
00087 {
00088 IPDatagram *ipdatagram = check_and_cast<IPDatagram *>(msg);
00089
00090
00091
00092 if (ipdatagram->getTransportProtocol() == IP_PROT_TCP)
00093 {
00094 TCPSegment *seg = check_and_cast<TCPSegment*>(ipdatagram->getEncapsulatedMsg());
00095 if (seg->getDestPort() == LDP_PORT || seg->getSrcPort() == LDP_PORT)
00096 {
00097 ASSERT(!ipdatagram->hasPar("color"));
00098 ipdatagram->addPar("color") = LDP_TRAFFIC;
00099 }
00100 }
00101 else if (ipdatagram->getTransportProtocol() == IP_PROT_ICMP)
00102 {
00103
00104 if (!ipdatagram->hasPar("color"))
00105 ipdatagram->addPar("color") = ICMP_TRAFFIC;
00106 }
00107
00108
00109 labelAndForwardIPDatagram(ipdatagram);
00110 }
00111
00112 bool MPLS::tryLabelAndForwardIPDatagram(IPDatagram *ipdatagram)
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->getInterfaceByName(outInterface.c_str())->getNetworkLayerGateIndex();
00127
00128 MPLSPacket *mplsPacket = new MPLSPacket(ipdatagram->getName());
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
00139 ipdatagram = check_and_cast<IPDatagram*>(mplsPacket->decapsulate());
00140 delete mplsPacket;
00141 sendToL2(ipdatagram, outgoingPort);
00142 }
00143 else
00144 sendToL2(mplsPacket, outgoingPort);
00145
00146 return true;
00147 }
00148
00149 void MPLS::labelAndForwardIPDatagram(IPDatagram *ipdatagram)
00150 {
00151 if (tryLabelAndForwardIPDatagram(ipdatagram))
00152 return;
00153
00154
00155
00156
00157 EV << "FEC not resolved, doing regular L3 routing" << endl;
00158
00159 int gateIndex = ipdatagram->getArrivalGate()->getIndex();
00160
00161 sendToL2(ipdatagram, gateIndex);
00162 }
00163
00164 void MPLS::doStackOps(MPLSPacket *mplsPacket, const LabelOpVector& outLabel)
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 }
00195
00196 void MPLS::processPacketFromL2(cMessage *msg)
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
00208
00209
00210 if (!tryLabelAndForwardIPDatagram(ipdatagram))
00211 {
00212 int gateIndex = ipdatagram->getArrivalGate()->getIndex();
00213 send(ipdatagram, "netwOut", gateIndex);
00214 }
00215 }
00216 else
00217 {
00218 error("Unknown message received");
00219 }
00220 }
00221
00222 void MPLS::processMPLSPacketFromL2(MPLSPacket *mplsPacket)
00223 {
00224 int gateIndex = mplsPacket->getArrivalGate()->getIndex();
00225 InterfaceEntry *ie = ift->getInterfaceByNetworkLayerGateIndex(gateIndex);
00226 std::string senderInterface = ie->getName();
00227 ASSERT(mplsPacket->hasLabel());
00228 int oldLabel = mplsPacket->getTopLabel();
00229
00230 EV << "Received " << mplsPacket << " from L2, label=" << oldLabel << " inInterface=" << senderInterface << endl;
00231
00232 if (oldLabel==-1)
00233 {
00234
00235
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->getInterfaceByName(outInterface.c_str())->getNetworkLayerGateIndex();
00258
00259 doStackOps(mplsPacket, outLabel);
00260
00261 if (mplsPacket->hasLabel())
00262 {
00263
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
00277
00278 sendToL2(mplsPacket, outgoingPort);
00279 }
00280 else
00281 {
00282
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 }