INET Framework for OMNeT++/OMNEST
ANSASwitchCore Class Reference

#include <ansaSwitchCore.h>

List of all members.

Classes

struct  s_frame_descriptor

Public Types

typedef struct
ANSASwitchCore::s_frame_descriptor 
tFrameDescriptor

Public Member Functions

MACAddress getBridgeAddress ()

Protected Member Functions

virtual void initialize (int stage)
virtual int numInitStages () const
virtual void handleMessage (cMessage *msg)
virtual void finish ()
bool reception (tFrameDescriptor &frame, cMessage *msg)
void relay (tFrameDescriptor &frame)
void dispatch (tFrameDescriptor &frame)
bool ingress (tFrameDescriptor &tmp, EthernetIIFrame *frame, int rPort)
bool ingress (tFrameDescriptor &tmp, AnsaEtherFrame *frame, int rPort)
void egress (tFrameDescriptor &frame)
void learn (tFrameDescriptor &frame)
void processFrame (cMessage *msg)
void handleIncomingFrame (EthernetIIFrame *frame)
void handleAndDispatchFrame (EthernetIIFrame *frame, int inputport)
void broadcastFrame (EthernetIIFrame *frame, int inputport)
void sinkMsg (cMessage *msg)
void sinkDupMsg (cMessage *msg)
void dispatchBPDU (cMessage *msg, int port)
void deliverBPDU (tFrameDescriptor &frame)
AnsaEtherFrametagMsg (EthernetIIFrame *_frame, int _vlan)
EthernetIIFrameuntagMsg (AnsaEtherFrame *_frame)

Protected Attributes

MACAddress bridgeGroupAddress
MACAddress bridgeAddress
MACTableaddrTable
VLANTablevlanTable
StpspanningTree
cMessage * currentMsg
int portCount

Detailed Description

Definition at line 30 of file ansaSwitchCore.h.


Member Typedef Documentation


Member Function Documentation

void ANSASwitchCore::broadcastFrame ( EthernetIIFrame frame,
int  inputport 
) [protected]

Definition at line 306 of file ansaSwitchCore.cc.

Referenced by handleAndDispatchFrame().

                                                                         {
        for (int i = 0; i < this->portCount; ++i) {
                if (i != inputport) {
                        send((EthernetIIFrame*) frame->dup(), "ifOut", i);
                }
        }
        delete frame;

        return;
}

Definition at line 350 of file ansaSwitchCore.cc.

Referenced by relay().

                                                                      {
        send(frame.payload->dup(), "stpOut", frame.rPort);
}

Definition at line 195 of file ansaSwitchCore.cc.

Referenced by relay().

                                                                   {

        EthernetIIFrame * untaggedFrame = new EthernetIIFrame(frame.name.c_str());
        AnsaEtherFrame * taggedFrame = new AnsaEtherFrame(frame.name.c_str());

        taggedFrame->setKind(frame.payload->getKind());
        taggedFrame->setSrc(frame.src);
        taggedFrame->setDest(frame.dest);
        taggedFrame->setByteLength(ETHER_MAC_FRAME_BYTES);
        taggedFrame->setVlan(frame.VID);
        taggedFrame->setEtherType(frame.etherType);

        taggedFrame->encapsulate(frame.payload->dup());
        if (taggedFrame->getByteLength() < MIN_ETHERNET_FRAME) {
                taggedFrame->setByteLength(MIN_ETHERNET_FRAME); // "padding"
        }

        untaggedFrame->setKind(frame.payload->getKind());
        untaggedFrame->setSrc(frame.src);
        untaggedFrame->setDest(frame.dest);
        untaggedFrame->setByteLength(ETHER_MAC_FRAME_BYTES);
        untaggedFrame->setEtherType(frame.etherType);

        untaggedFrame->encapsulate(frame.payload->dup());
        if (untaggedFrame->getByteLength() < MIN_ETHERNET_FRAME) {
                untaggedFrame->setByteLength(MIN_ETHERNET_FRAME); // "padding"
        }
        VLANTable::tVIDPortList::iterator it;
        for (it = frame.portList.begin(); it != frame.portList.end(); it++) {
                if (it->port >= portCount) {
                        continue;
                }
                if (spanningTree->forwarding(it->port, frame.VID) == false) {
                        continue;
                }
                if (it->action == VLANTable::INCLUDE) {
                        send(taggedFrame->dup(), "ifOut", it->port);
                } else {
                        send(untaggedFrame->dup(), "ifOut", it->port);
                }
        }

        delete taggedFrame;
        delete untaggedFrame;
        return;
}
void ANSASwitchCore::dispatchBPDU ( cMessage *  msg,
int  port 
) [protected]

Definition at line 328 of file ansaSwitchCore.cc.

Referenced by handleMessage().

                                                         {
        if (port >= this->portCount || port < 0) {
                return;
        }

        EthernetIIFrame * untaggedFrame = new EthernetIIFrame(msg->getName());

        untaggedFrame->setKind(msg->getKind());
        untaggedFrame->setSrc(bridgeAddress);
        untaggedFrame->setDest(bridgeGroupAddress);
        untaggedFrame->setByteLength(ETHER_MAC_FRAME_BYTES);
        untaggedFrame->setEtherType(-1);

        untaggedFrame->encapsulate((cPacket *)msg);
        if (untaggedFrame->getByteLength() < MIN_ETHERNET_FRAME) {
                untaggedFrame->setByteLength(MIN_ETHERNET_FRAME); // "padding"
        }


        send((EthernetIIFrame*) untaggedFrame, "ifOut", port);
}

Definition at line 180 of file ansaSwitchCore.cc.

Referenced by relay().

                                                                 {
  // MINIMIZE OUT PORTS
  // SET TAG ACTIONS

        VLANTable::tVIDPortList tmp = frame.portList;
        frame.portList.clear();

        for (unsigned int i = 0; i < tmp.size(); i++) {
                if (vlanTable->isAllowed(frame.VID, tmp.at(i).port) == true && tmp.at(i).port != frame.rPort) {
                        frame.portList.push_back(tmp.at(i));
                }
        }

}
void ANSASwitchCore::finish ( ) [protected, virtual]

Definition at line 354 of file ansaSwitchCore.cc.

                            {
        cancelAndDelete(this->currentMsg);
        return;
}

Definition at line 6 of file ansaSwitchCore.cc.

Referenced by Stp::initialize().

                                            {
        Enter_Method_Silent();
        return bridgeAddress;
}
void ANSASwitchCore::handleAndDispatchFrame ( EthernetIIFrame frame,
int  inputport 
) [protected]

Definition at line 270 of file ansaSwitchCore.cc.

Referenced by processFrame().

                                                                                 {
        this->addrTable->update(frame->getSrc(), inputport);

        /*
         AnsaEtherFrame * tmp;
         tmp = this->tagMsg(frame, 1);
         newframe = this->untagMsg(tmp);
         */

        // handle broadcast frames first
        if (frame->getDest().isBroadcast()) {
                EV<< "Broadcasting broadcast frame " << frame << endl;
                broadcastFrame(frame, inputport);
                return;
        }

        // Finds output port of destination address and sends to output port
        // if not found then broadcasts to all other ports instead
        MACTable::tPortList portList = addrTable->getPorts(frame->getDest());

        if (portList.size() == 0) {
                EV << "Dest address " << frame->getDest() << " unknown, broadcasting frame " << frame << endl;
                broadcastFrame(frame, inputport);
        } else {
                for (unsigned int i = 0; i < portList.size(); i++) {
                        if (inputport != portList.at(i)) {
                                EV << "Sending frame " << frame << " with dest address " << frame->getDest() << " to port " << portList.at(i) << endl;
                                send(frame->dup(), "ifOut", portList.at(i));
                        }
                }
                delete frame;
        }

        return;
}

Definition at line 251 of file ansaSwitchCore.cc.

                                                               {
        // If buffer not full, insert payload frame into buffer and process the frame in parallel.
        cMessage *msg = this->currentMsg;
        ASSERT(msg->getContextPointer()==NULL);
        msg->setContextPointer(frame);
        scheduleAt(simTime(), msg);
        return;
}
void ANSASwitchCore::handleMessage ( cMessage *  msg) [protected, virtual]

Definition at line 39 of file ansaSwitchCore.cc.

                                                {

        if (!msg->isSelfMessage()) {
                tFrameDescriptor frame;

                if (strcmp(msg->getArrivalGate()->getName(), "stpIn") == 0) {
                        /* Messages from STP process */
                        dispatchBPDU(msg, msg->getArrivalGate()->getIndex());
                        return;

                } else if (strcmp(msg->getArrivalGate()->getName(), "ifIn") == 0) {
                        /* Messages from network */
                        if (reception(frame, msg) == true) {
                                //EV << frame;
                                //error("BLE BLE");
                                relay(frame);
                        }
                        delete frame.payload;
                }
        } else {
                // Self message signal used to indicate a frame has finished processing
                processFrame(msg);
        }
        delete msg;
}
bool ANSASwitchCore::ingress ( ANSASwitchCore::tFrameDescriptor tmp,
EthernetIIFrame frame,
int  rPort 
) [protected]

Definition at line 142 of file ansaSwitchCore.cc.

Referenced by reception().

                                                                                                   {
        // Info from recepted frame
        tmp.payload = frame->decapsulate();
        tmp.name.insert(0, frame->getName());
        tmp.rPort = rPort;
        tmp.src = frame->getSrc();
        tmp.dest = frame->getDest();
        tmp.etherType = frame->getEtherType();

        // VLAN Assign
        tmp.VID = vlanTable->getVID(rPort);

        if (tmp.VID == 0) {
                return false;
        }


        return true;
}
bool ANSASwitchCore::ingress ( ANSASwitchCore::tFrameDescriptor tmp,
AnsaEtherFrame frame,
int  rPort 
) [protected]

Definition at line 162 of file ansaSwitchCore.cc.

                                                                                                  {
        // Info from recepted frame
        tmp.payload = frame->decapsulate();
        tmp.name.insert(0, frame->getName());
        tmp.rPort = rPort;
        tmp.VID = frame->getVlan();
        tmp.src = frame->getSrc();
        tmp.dest = frame->getDest();
        tmp.etherType = frame->getEtherType();

        // VLAN Allowed
        if (vlanTable->isAllowed(frame->getVlan(), rPort) == false) {
                return false;
        }

        return true;
}
void ANSASwitchCore::initialize ( int  stage) [protected, virtual]

Definition at line 12 of file ansaSwitchCore.cc.

                                         {

        if (stage == 0) {
                portCount = gateSize("ifOut");

                /* because ASSERT in handleIncomingFrame() */
                int i = 0;
                char msgname[16];
                sprintf(msgname, "switchMsg %d", i);
                currentMsg = new cMessage(msgname, i);

                cModule * tmp_macTable = getParentModule()->getSubmodule("MACTable");
                addrTable = check_and_cast<MACTable *>(tmp_macTable);

                cModule * tmp_vlanTable = getParentModule()->getSubmodule("VLANTable");
                vlanTable = check_and_cast<VLANTable *>(tmp_vlanTable);

                cModule * tmp_stp = getParentModule()->getSubmodule("stp");
                spanningTree = check_and_cast<Stp *>(tmp_stp);

                bridgeGroupAddress = MACAddress("01-80-C2-00-00-00");
                bridgeAddress = MACAddress::generateAutoAddress();

                WATCH(bridgeAddress);
        }
}

Definition at line 243 of file ansaSwitchCore.cc.

Referenced by relay().

                                                                {
        if (spanningTree->learning(frame.rPort, frame.VID) == true) {
          addrTable->update(frame.src, frame.rPort);
        }
}
virtual int ANSASwitchCore::numInitStages ( ) const [inline, protected, virtual]

Definition at line 64 of file ansaSwitchCore.h.

{return 1;}
void ANSASwitchCore::processFrame ( cMessage *  msg) [protected]

Definition at line 260 of file ansaSwitchCore.cc.

Referenced by handleMessage().

                                               {
        EthernetIIFrame *frame = (EthernetIIFrame *) msg->getContextPointer();
        ASSERT(frame);
        msg->setContextPointer(NULL);
        int inputport = frame->getArrivalGate()->getIndex();

        handleAndDispatchFrame(frame, inputport);
        return;
}
bool ANSASwitchCore::reception ( ANSASwitchCore::tFrameDescriptor frame,
cMessage *  msg 
) [protected]

Definition at line 65 of file ansaSwitchCore.cc.

Referenced by handleMessage().

                                                                                   {
 /* ACTIVE TOPOLOGY ENFORCEMENT AFTER CLASSIFICATION AND INGRESS
  * because of learning state operation, MAC record can be learned
  * after classification and ingress, if learning is enabled on
  * that port.
  */
  //CLASSIFICATION & INGRESS CALL
        int rPort = msg->getArrivalGate()->getIndex();

        cMessage * tmp = msg;
        ASSERT(tmp);

        // Classify frame, and unpack to frame descriptor
        if (dynamic_cast<AnsaEtherFrame *>(tmp)){
                AnsaEtherFrame * taggedFrame = (AnsaEtherFrame *) tmp;
                if (ingress(frame, taggedFrame, rPort) == false) {
                        return false;
                }
        } else if (dynamic_cast<EthernetIIFrame *>(tmp)) {
                EthernetIIFrame * untaggedFrame = (EthernetIIFrame *) tmp;
                ingress(frame, untaggedFrame, rPort); // discarding forbidden PortVID is in relay
        }

        return true;
}

Definition at line 91 of file ansaSwitchCore.cc.

Referenced by handleMessage().

                                                                {

        // BPDU Handling
        if (frame.dest == bridgeGroupAddress) {
                deliverBPDU(frame);
                return;
        }

        /* Dropping forbidden PortVID*/
        if (frame.VID == 0) {
                return;
        }

        // BROADCAST ??
        if (frame.dest.isBroadcast()) {
                frame.portList = vlanTable->getPorts(frame.VID);
                if (frame.portList.size() == 0) {
                        return;
                }

        } else {
                VLANTable::tVIDPort tmpPort;
                tmpPort.action = VLANTable::REMOVE;

                MACTable::tPortList tmpPortList = addrTable->getPorts(frame.dest);

                if (tmpPortList.size() == 0) { // not known -> bcast
                        frame.portList = vlanTable->getPorts(frame.VID);
                } else {
                        for (unsigned int i = 0; i < tmpPortList.size(); i++) {
                                tmpPort.port = tmpPortList.at(i);
                                frame.portList.push_back(tmpPort);
                        }
                }
        }

        //EV << frame;
        //error("BLE BLE");


        // LEARNING (explained in reception())
        learn(frame);
        // ACTIVE TOPOLOGY ENFORCEMENT (explained in reception())
        if (spanningTree->forwarding(frame.rPort, frame.VID) == true) {
                // EGRESS
                egress(frame);
                // SEND
                dispatch(frame);
        }
}
void ANSASwitchCore::sinkDupMsg ( cMessage *  msg) [protected]

Definition at line 323 of file ansaSwitchCore.cc.

                                             {
        send(msg->dup(), "toSink");
        return;
}
void ANSASwitchCore::sinkMsg ( cMessage *  msg) [protected]

Definition at line 317 of file ansaSwitchCore.cc.

                                          {
        send(msg, "toSink");
        return;
}
AnsaEtherFrame * ANSASwitchCore::tagMsg ( EthernetIIFrame _frame,
int  _vlan 
) [protected]

Definition at line 381 of file ansaSwitchCore.cc.

                                                                           {

        EthernetIIFrame * tmp = _frame;

        cPacket * payload = tmp->decapsulate();
        AnsaEtherFrame * frame = new AnsaEtherFrame(payload->getName());

        frame->setSrc(tmp->getSrc());
        frame->setDest(tmp->getDest());
        frame->setByteLength(ETHER_MAC_FRAME_BYTES);
        frame->setVlan(_vlan);
        frame->setEtherType(tmp->getEtherType());

        frame->encapsulate(payload);
        if (frame->getByteLength() < MIN_ETHERNET_FRAME) {
                frame->setByteLength(MIN_ETHERNET_FRAME); // "padding"
        }

        return frame;
}

Definition at line 402 of file ansaSwitchCore.cc.

                                                                  {

        AnsaEtherFrame * tmp = _frame;

        cPacket * payload = tmp->decapsulate();
        EthernetIIFrame * frame = new EthernetIIFrame(payload->getName());

        frame->setSrc(tmp->getSrc()); // if blank, will be filled in by MAC
        frame->setDest(tmp->getDest());
        frame->setByteLength(ETHER_MAC_FRAME_BYTES);
        frame->setEtherType(tmp->getEtherType());

        frame->encapsulate(payload);
        if (frame->getByteLength() < MIN_ETHERNET_FRAME) {
                frame->setByteLength(MIN_ETHERNET_FRAME); // "padding"
        }
        return frame;
}

Member Data Documentation

Definition at line 55 of file ansaSwitchCore.h.

Referenced by handleAndDispatchFrame(), initialize(), learn(), and relay().

Definition at line 53 of file ansaSwitchCore.h.

Referenced by dispatchBPDU(), getBridgeAddress(), and initialize().

Definition at line 52 of file ansaSwitchCore.h.

Referenced by dispatchBPDU(), initialize(), and relay().

cMessage* ANSASwitchCore::currentMsg [protected]

Definition at line 59 of file ansaSwitchCore.h.

Referenced by finish(), handleIncomingFrame(), and initialize().

int ANSASwitchCore::portCount [protected]

Definition at line 61 of file ansaSwitchCore.h.

Referenced by broadcastFrame(), dispatch(), dispatchBPDU(), and initialize().

Definition at line 57 of file ansaSwitchCore.h.

Referenced by dispatch(), initialize(), learn(), and relay().

Definition at line 56 of file ansaSwitchCore.h.

Referenced by egress(), ingress(), initialize(), and relay().


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