Protected Member Functions | Protected Attributes

MPLS Class Reference

#include <MPLS.h>

List of all members.

Protected Member Functions

virtual void initialize (int stage)
virtual int numInitStages () const
virtual void handleMessage (cMessage *msg)
virtual void processPacketFromL3 (cMessage *msg)
virtual void processPacketFromL2 (cMessage *msg)
virtual void processMPLSPacketFromL2 (MPLSPacket *mplsPacket)
virtual bool tryLabelAndForwardIPDatagram (IPDatagram *ipdatagram)
virtual void labelAndForwardIPDatagram (IPDatagram *ipdatagram)
virtual void sendToL2 (cMessage *msg, int gateIndex)
virtual void doStackOps (MPLSPacket *mplsPacket, const LabelOpVector &outLabel)

Protected Attributes

simtime_t delay1
LIBTablelt
IInterfaceTableift
IClassifierpct

Detailed Description

Implements the MPLS protocol; see the NED file for more info.

Definition at line 35 of file MPLS.h.


Member Function Documentation

void MPLS::doStackOps ( MPLSPacket mplsPacket,
const LabelOpVector outLabel 
) [protected, virtual]

Definition at line 164 of file MPLS.cc.

Referenced by processMPLSPacketFromL2(), and tryLabelAndForwardIPDatagram().

{
    unsigned int n = outLabel.size();

    EV << "doStackOps: " << outLabel << endl;

    ASSERT(n >= 0);

    for (unsigned int i = 0; i <  n; i++)
    {
        switch (outLabel[i].optcode)
        {
            case PUSH_OPER:
                mplsPacket->pushLabel(outLabel[i].label);
                break;

            case SWAP_OPER:
                ASSERT(mplsPacket->hasLabel());
                mplsPacket->swapLabel(outLabel[i].label);
                break;

            case POP_OPER:
                ASSERT(mplsPacket->hasLabel());
                mplsPacket->popLabel();
                break;

            default:
                error("Unknown MPLS OptCode %d", outLabel[i].optcode);
        }
    }
}

void MPLS::handleMessage ( cMessage *  msg  )  [protected, virtual]

Definition at line 63 of file MPLS.cc.

{
    if (!strcmp(msg->getArrivalGate()->getName(), "ifIn"))
    {
        EV << "Processing message from L2: " << msg << endl;
        processPacketFromL2(msg);
    }
    else if (!strcmp(msg->getArrivalGate()->getName(), "netwIn"))
    {
        EV << "Processing message from L3: " << msg << endl;
        processPacketFromL3(msg);
    }
    else
    {
        error("unexpected message: %s", msg->getName());
    }
}

void MPLS::initialize ( int  stage  )  [protected, virtual]

Definition at line 36 of file MPLS.cc.

{
    if (stage!=3) // interfaceTable must be initialized
        return;

    lt = LIBTableAccess().get();
    ift = InterfaceTableAccess().get();

    pct = check_and_cast<IClassifier*>(getParentModule()->getSubmodule(par("classifier")));

    /*
     * we now send plain IPDatagrams instead of packets with label=-1
     * and we thus do not need this extra configuration
     *
    labelIf.resize(ift->getNumInterfaces());
    cStringTokenizer tokenizer(par("peers"));
    const char *token;
    while ((token = tokenizer.nextToken())!=NULL)
    {
        ASSERT(ift->getInterfaceByName(token));
        int n = ift->getInterfaceByName(token)->outputPort();
        ASSERT(n >= 0 && n < labelIf.size());
        labelIf[n] = true;
    }
    */
}

void MPLS::labelAndForwardIPDatagram ( IPDatagram *  ipdatagram  )  [protected, virtual]

Definition at line 149 of file MPLS.cc.

Referenced by processPacketFromL3().

{
    if (tryLabelAndForwardIPDatagram(ipdatagram))
        return;

    // handling our outgoing IP traffic that didn't match any FEC/LSP
    // do not use labelAndForwardIPDatagram for packets arriving to ingress!

    EV << "FEC not resolved, doing regular L3 routing" << endl;

    int gateIndex = ipdatagram->getArrivalGate()->getIndex();

    sendToL2(ipdatagram, gateIndex);
}

virtual int MPLS::numInitStages (  )  const [inline, protected, virtual]

Definition at line 49 of file MPLS.h.

{return 5;}

void MPLS::processMPLSPacketFromL2 ( MPLSPacket mplsPacket  )  [protected, virtual]

Definition at line 222 of file MPLS.cc.

Referenced by processPacketFromL2().

{
    int gateIndex = mplsPacket->getArrivalGate()->getIndex();
    InterfaceEntry *ie = ift->getInterfaceByNetworkLayerGateIndex(gateIndex);
    std::string senderInterface = ie->getName();
    ASSERT(mplsPacket->hasLabel());
    int oldLabel = mplsPacket->getTopLabel();

    EV << "Received " << mplsPacket << " from L2, label=" << oldLabel << " inInterface=" << senderInterface << endl;

    if (oldLabel==-1)
    {
        // This is a IP native packet (RSVP/TED traffic)
        // Decapsulate the message and pass up to L3
        EV << ": decapsulating and sending up\n";

        IPDatagram *ipdatagram = check_and_cast<IPDatagram *>(mplsPacket->decapsulate());
        delete mplsPacket;
        send(ipdatagram, "netwOut", gateIndex);
        return;
    }

    LabelOpVector outLabel;
    std::string outInterface;
    int color;

    bool found = lt->resolveLabel(senderInterface, oldLabel, outLabel, outInterface, color);
    if (!found)
    {
        EV << "discarding packet, incoming label not resolved" << endl;

        delete mplsPacket;
        return;
    }

    int outgoingPort = ift->getInterfaceByName(outInterface.c_str())->getNetworkLayerGateIndex();

    doStackOps(mplsPacket, outLabel);

    if (mplsPacket->hasLabel())
    {
        // forward labeled packet

        EV << "forwarding packet to " << outInterface << endl;

        if (mplsPacket->hasPar("color"))
        {
            mplsPacket->par("color") = color;
        }
        else
        {
            mplsPacket->addPar("color") = color;
        }

        //ASSERT(labelIf[outgoingPort]);

        sendToL2(mplsPacket, outgoingPort);
    }
    else
    {
        // last label popped, decapsulate and send out IP datagram

        EV << "decapsulating IP datagram" << endl;

        IPDatagram *nativeIP = check_and_cast<IPDatagram *>(mplsPacket->decapsulate());
        delete mplsPacket;

        if (outgoingPort != -1)
        {
            sendToL2(nativeIP, outgoingPort);
        }
        else
        {
            send(nativeIP, "netwOut", gateIndex);
        }
    }
}

void MPLS::processPacketFromL2 ( cMessage *  msg  )  [protected, virtual]

Definition at line 196 of file MPLS.cc.

Referenced by handleMessage().

{
    IPDatagram *ipdatagram = dynamic_cast<IPDatagram *>(msg);
    MPLSPacket *mplsPacket = dynamic_cast<MPLSPacket *>(msg);

    if (mplsPacket)
    {
        processMPLSPacketFromL2(mplsPacket);
    }
    else if (ipdatagram)
    {
        // IP datagram arrives at Ingress router. We'll try to classify it
        // and add an MPLS header

        if (!tryLabelAndForwardIPDatagram(ipdatagram))
        {
            int gateIndex = ipdatagram->getArrivalGate()->getIndex();
            send(ipdatagram, "netwOut", gateIndex);
        }
    }
    else
    {
        error("Unknown message received");
    }
}

void MPLS::processPacketFromL3 ( cMessage *  msg  )  [protected, virtual]

Definition at line 86 of file MPLS.cc.

Referenced by handleMessage().

{
    IPDatagram *ipdatagram = check_and_cast<IPDatagram *>(msg);
    //int gateIndex = msg->getArrivalGate()->getIndex();

    // XXX temporary solution, until TCPSocket and IP are extended to support nam tracing
    if (ipdatagram->getTransportProtocol() == IP_PROT_TCP)
    {
        TCPSegment *seg = check_and_cast<TCPSegment*>(ipdatagram->getEncapsulatedMsg());
        if (seg->getDestPort() == LDP_PORT || seg->getSrcPort() == LDP_PORT)
        {
            ASSERT(!ipdatagram->hasPar("color"));
            ipdatagram->addPar("color") = LDP_TRAFFIC;
        }
    }
    else if (ipdatagram->getTransportProtocol() == IP_PROT_ICMP)
    {
        // ASSERT(!ipdatagram->hasPar("color")); XXX this did not hold sometimes...
        if (!ipdatagram->hasPar("color"))
            ipdatagram->addPar("color") = ICMP_TRAFFIC;
    }
    // XXX end of temporary area

    labelAndForwardIPDatagram(ipdatagram);
}

void MPLS::sendToL2 ( cMessage *  msg,
int  gateIndex 
) [protected, virtual]

Definition at line 81 of file MPLS.cc.

Referenced by labelAndForwardIPDatagram(), processMPLSPacketFromL2(), and tryLabelAndForwardIPDatagram().

{
    send(msg, "ifOut", gateIndex);
}

bool MPLS::tryLabelAndForwardIPDatagram ( IPDatagram *  ipdatagram  )  [protected, virtual]

Definition at line 112 of file MPLS.cc.

Referenced by labelAndForwardIPDatagram(), and processPacketFromL2().

{
    LabelOpVector outLabel;
    std::string outInterface;
    int color;

    if (!pct->lookupLabel(ipdatagram, outLabel, outInterface, color))
    {
        EV << "no mapping exists for this packet" << endl;
        return false;
    }

    ASSERT(outLabel.size() > 0);

    int outgoingPort = ift->getInterfaceByName(outInterface.c_str())->getNetworkLayerGateIndex();

    MPLSPacket *mplsPacket = new MPLSPacket(ipdatagram->getName());
    mplsPacket->encapsulate(ipdatagram);
    doStackOps(mplsPacket, outLabel);

    EV << "forwarding packet to " << outInterface << endl;

    mplsPacket->addPar("color") = color;

    if (!mplsPacket->hasLabel())
    {
        // yes, this may happen - if we'are both ingress and egress
        ipdatagram = check_and_cast<IPDatagram*>(mplsPacket->decapsulate()); // XXX FIXME superfluous encaps/decaps
        delete mplsPacket;
        sendToL2(ipdatagram, outgoingPort);
    }
    else
        sendToL2(mplsPacket, outgoingPort);

    return true;
}


Member Data Documentation

simtime_t MPLS::delay1 [protected]

Definition at line 38 of file MPLS.h.

IInterfaceTable* MPLS::ift [protected]

Definition at line 44 of file MPLS.h.

Referenced by initialize(), processMPLSPacketFromL2(), and tryLabelAndForwardIPDatagram().

LIBTable* MPLS::lt [protected]

Definition at line 43 of file MPLS.h.

Referenced by initialize(), and processMPLSPacketFromL2().

IClassifier* MPLS::pct [protected]

Definition at line 45 of file MPLS.h.

Referenced by initialize(), and tryLabelAndForwardIPDatagram().


The documentation for this class was generated from the following files: