INET Framework for OMNeT++/OMNEST
stpi.h
Go to the documentation of this file.
00001 /*
00002  * stpInstance.h
00003  *
00004  *  Created on: 16.5.2011
00005  *      Author: aranel
00006  */
00007 
00008 #ifndef STPI_H_
00009 #define STPI_H_
00010 
00011 #include "MACAddress.h"
00012 #include "macTable.h"
00013 #include "STPBPDU_m.h"
00014 #include "STPTCN_m.h"
00015 
00016 
00017 class stpi {
00018 public:
00019         stpi(unsigned int _vlan, unsigned int portCount, MACAddress _bridgeAddress, MACTable * _addrTable);
00020         virtual ~stpi();
00021 
00022         /* WARNING SEND HACK */
00023 
00024         typedef struct {
00025                 unsigned int port;
00026                 cMessage * msg;
00027         } tMsg;
00028 
00029         void send(cMessage *, unsigned int);
00030         std::vector<tMsg> msgList;
00031 
00032         /* END OF SEND HACK */
00033 
00034         /* According to IEEE802.1D 9.2.9 Encoding of Port Role values */
00035         typedef enum {
00036                 RUNKNOWN = 0,
00037                 RALTERNATE = 1,
00038                 RDESIGNATED = 2,
00039                 RROOT = 3,
00040         } tPortRole;
00041 
00042         /* According to IEEE802.1D-1998 8.4 Port States */
00043         typedef enum {
00044                 SDISABLED = 0, // accept nothing, dispatch nothing
00045                 SDISCARDING = 1, // accept BPDU
00046                 SLEARNING = 3, // learning enabled
00047                 SFORWARDING = 4, // accept all, dispatch all
00048         } tPortState;
00049 
00050         typedef struct {
00051                 bool Learning;
00052                 bool Forwarding;
00053         } tPortFlags;
00054 
00055         typedef struct {
00056                 bool enabled;
00057                 tPortState state;
00058                 tPortRole role;
00059 
00060                 unsigned int priority; // TODO own vector for RW
00061 
00062                 /* FLAGS */
00063                 tPortFlags flags;
00064 
00065                 /* discovered values */
00066                 unsigned int rootPathCost;
00067                 unsigned int rootPriority;
00068                 MACAddress rootID;
00069 
00070                 unsigned int bridgePriority;
00071                 MACAddress bridgeID;
00072 
00073                 unsigned int portPriority; // of designated bridge
00074                 unsigned int portID;
00075 
00076                 /* TODO from bandwidth */
00077                 unsigned int linkCost;
00078 
00079                 unsigned int age; // age of this information
00080                 unsigned int fdWhile; // forward timer
00081 
00082                 /* discovered */
00083                 unsigned int maxAge;
00084                 unsigned int fwdDelay;
00085                 unsigned int helloTime;
00086         } tPort;
00087 
00088         bool learning(unsigned int);
00089         bool forwarding(unsigned int);
00090 
00091 
00092     void handleBPDU(STPBPDU * bpdu);
00093     void handleTCN(STPTCN * tcn);
00094 
00095 //  protected:
00096     virtual void handleMessage(cMessage * msg);
00097 
00098 
00099     void handleSelfMessage(cMessage * msg);
00100     void generateHelloBPDU(int port);
00101     void generateTCN();
00102 
00103     bool superiorBPDU(int port, STPBPDU * bpdu);
00104     void setSuperiorBPDU(int port, STPBPDU * bpdu);
00105 
00106     /* Generate BPDUs to all interfaces (for Root), isRoot Check commencing */
00107     void generator();
00108     void handleTick();
00109     void checkTimers();
00110     void checkParametersChange();
00111 
00112     void resetAge(int p);
00113     void resetFDWhile(int p);
00114     void initPortTable();
00115     void setPortState(unsigned int, tPortState);
00116 
00117     /* check if this bridge is root eligible, true is the root */
00118     bool checkRootEligibility();
00119     /* try become root and make all designated ports, or
00120      * will be designated and select root port ...
00121      */
00122     void tryRoot();
00123     /* compare two BridgeIDs (resp. PortID), positive -- first is the superior, zero -- same ID,
00124      * and negative -- first is inferior */
00125     int superiorID(unsigned int, MACAddress, unsigned int, MACAddress);
00126     int superiorPort(unsigned int, unsigned int, unsigned int, unsigned int);
00127     /* comparsion of all IDs in tPort structure */
00128     int superiorTPort(tPort, tPort);
00129     /* select root port */
00130     void selectRootPort();
00131 
00132     /* select designated ports */
00133     void selectDesignatedPorts();
00134     /* set all ports to Designated (for root bridge) */
00135     void allDesignated();
00136 
00137 
00138     /* neighbor lost handling */
00139     void lostRoot();
00140     void lostAlternate(int port);
00141 
00142     void reset();
00143 
00144 
00145         unsigned int vlan;
00146 
00147         bool isRoot;
00148         int rootPort;
00149         std::vector<unsigned int> desPorts; // designated ports
00150 
00151         unsigned int portCount;
00152 
00153         MACAddress bridgeAddress;
00154         unsigned int bridgePriority;
00155 
00156         /* discovered values */
00157         unsigned int rootPathCost;
00158         unsigned int rootPriority;
00159         MACAddress rootID;
00160 
00161         /* SET BY MGMT */
00162         unsigned int maxAge;
00163         unsigned int fwdDelay;
00164         unsigned int helloTime;
00165         unsigned int userPriority;
00166 
00167         /* parameter change detection */
00168         unsigned int ubridgePriority;
00169 
00170         /* SET BY ROOT BRIDGE */
00171         unsigned int cMaxAge;
00172         unsigned int cFwdDelay;
00173         unsigned int cHelloTime; // c stands for current
00174 
00175         /* BRIDGE TIMERS */
00176         unsigned int helloTimer;
00177 
00178         /* topology change commencing */
00179         int topologyChange;
00180         bool topologyChangeNotification;
00181         bool topologyChangeRecvd;
00182 
00183         std::vector<tPort> portTable;
00184         tPort defaultPort;
00185 
00186 
00187         MACTable * addrTable;
00188 
00189 
00190 };
00191 
00192 inline std::ostream& operator<<(std::ostream& os, const stpi::tPortRole r) {
00193 
00194         switch (r){
00195         case stpi::RUNKNOWN:
00196                 os << "Unkn";
00197                 break;
00198         case stpi::RALTERNATE:
00199                 os << "Altr";
00200                 break;
00201         case stpi::RDESIGNATED:
00202                 os << "Desg";
00203                 break;
00204         case stpi::RROOT:
00205                 os << "Root";
00206                 break;
00207         default:
00208                 os << "<?>";
00209                 break;
00210         }
00211 
00212         return os;
00213 }
00214 
00215 inline std::ostream& operator<<(std::ostream& os, const stpi::tPortState s) {
00216 
00217         switch (s){
00218         case stpi::SDISABLED:
00219                 os << "---";
00220                 break;
00221         case stpi::SDISCARDING:
00222                 os << "DIS";
00223                 break;
00224         case stpi::SLEARNING:
00225                 os << "LRN";
00226                 break;
00227         case stpi::SFORWARDING:
00228                 os << "FWD";
00229                 break;
00230         default:
00231                 os << "<?>";
00232                 break;
00233         }
00234 
00235         return os;
00236 }
00237 
00238 inline std::ostream& operator<<(std::ostream& os, const stpi::tPortFlags f) {
00239         os << "[";
00240         if (f.Learning) {
00241                 os << "L";
00242         } else {
00243                 os << "_";
00244         }
00245         if (f.Forwarding) {
00246                 os << "F";
00247         } else {
00248                 os << "_";
00249         }
00250         os << "]";
00251         return os;
00252 }
00253 
00254 inline std::ostream& operator<<(std::ostream& os, const stpi::tPort p) {
00255         /*
00256         if (p.enabled) {
00257                 os << " + ";
00258         } else {
00259                 os << " - ";
00260         }
00261         */
00262 
00263 
00264 
00265         os << p.flags  << " " << p.role << " " << p.state << " ";
00266         os << p.linkCost << " ";
00267         os <<  p.priority  << " ";
00268 /*
00269         os << p.age << " ";
00270         os << p.fdWhile << " ";
00271 */
00272         /* DEBUG
00273           os << " "
00274            << p.rootPathCost << " " << p.priority << " :: ";
00275 
00276         os << p.rootPriority << "/" << p.rootID << ";"
00277            << p.bridgePriority << "/" << p.bridgeID << ";"
00278            << p.portPriority << "/" << p.portID ;
00279    */
00280         return os;
00281 }
00282 
00283 inline std::ostream& operator<<(std::ostream& os, const stpi i) {
00284         os << "VLAN " << i.vlan << " \n";
00285 
00286         //os << "TC:" << i.topologyChange << " TCN:" << i.topologyChangeNotification <<
00287         //      " TCR:" << i.topologyChangeRecvd << " \n";
00288 
00289 
00290         os << "RootID Priority: " << i.rootPriority << " \n";
00291         os << "  Address: " << i.rootID << " \n";
00292         if (i.isRoot) {
00293                 os << "  This bridge is the Root. \n";
00294         } else {
00295                 os << "  Cost: " << i.rootPathCost << " \n";
00296                 os << "  Port: " << i.rootPort << " \n";
00297         }
00298         os << "  Hello Time: " << i.cHelloTime << " \n";
00299         os << "  Max Age: " << i.cMaxAge << " \n";
00300         os << "  Forward Delay: " << i.cFwdDelay << " \n";
00301 
00302         os << "BridgeID Priority: " << i.bridgePriority << "\n";
00303         os << "  Address: " << i.bridgeAddress << " \n";
00304         //os << "\n";
00305         os << "  Hello Time: " << i.helloTime << " \n";
00306         os << "  Max Age: " << i.maxAge << " \n";
00307         os << "  Forward Delay: " << i.fwdDelay << " \n";
00308         os << "Port Flag Role State Cost Priority \n";
00309         os << "-----------------------------------------\n";
00310 
00311         for (unsigned int x = 0; x < i.portCount; x++) {
00312                 os << x << "  " << i.portTable.at(x) << " \n";
00313         }
00314 
00315 
00316         return os;
00317 }
00318 
00319 
00320 #endif /* STPINSTANCE_H_ */