Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MACRelayUnitBase Class Reference

#include <MACRelayUnitBase.h>

Inheritance diagram for MACRelayUnitBase:

MACRelayUnitNP MACRelayUnitPP List of all members.

Detailed Description

Implements base switching functionality of Ethernet switches. Note that neither activity() nor handleMessage() is redefined here -- active behavior (incl. queueing and performance aspects) must be addressed in subclasses.


Protected Types

typedef std::map< MACAddress,
AddressEntry, MAC_compare
AddressTable

Protected Member Functions

void initialize ()
void handleAndDispatchFrame (EtherFrame *frame, int inputport)
void broadcastFrame (EtherFrame *frame, int inputport)
void readAddressTable (const char *fileName)
void updateTableWithAddress (MACAddress &address, int portno)
int getPortForAddress (MACAddress &address)
void printAddressTable ()
void removeAgedEntriesFromTable ()
void removeOldestTableEntry ()
void sendPauseFrame (int portno, int pauseUnits)

Protected Attributes

int numPorts
int addressTableSize
simtime_t agingTime
AddressTable addresstable
int seqNum

Classes

struct  AddressEntry
struct  MAC_compare


Member Typedef Documentation

typedef std::map<MACAddress, AddressEntry, MAC_compare> MACRelayUnitBase::AddressTable [protected]
 


Member Function Documentation

void MACRelayUnitBase::broadcastFrame EtherFrame frame,
int  inputport
[protected]
 

Utility function: sends the frame on all ports except inputport. The message pointer should not be referenced any more after this call.

00108 {
00109     for (int i=0; i<numPorts; ++i)
00110         if (i!=inputport)
00111             send((EtherFrame*)frame->dup(), "lowerLayerOut", i);
00112     delete frame;
00113 }

int MACRelayUnitBase::getPortForAddress MACAddress address  )  [protected]
 

Returns output port for address, or -1 if unknown.

00197 {
00198     AddressTable::iterator iter = addresstable.find(address);
00199     if (iter == addresstable.end())
00200     {
00201         // not found
00202         return -1;
00203     }
00204     if (iter->second.insertionTime + agingTime <= simTime())
00205     {
00206         // don't use (and throw out) aged entries
00207         EV << "Ignoring and deleting aged entry: "<< iter->first << " --> port" << iter->second.portno << "\n";
00208         addresstable.erase(iter);
00209         return -1;
00210     }
00211     return iter->second.portno;
00212 }

void MACRelayUnitBase::handleAndDispatchFrame EtherFrame frame,
int  inputport
[protected]
 

Updates address table with source address, determines output port and sends out (or broadcasts) frame on ports. Includes calls to updateTableWithAddress() and getPortForAddress().

The message pointer should not be referenced any more after this call.

00073 {
00074     // update address table
00075     updateTableWithAddress(frame->getSrc(), inputport);
00076 
00077     // handle broadcast frames first
00078     if (frame->getDest().isBroadcast())
00079     {
00080         EV << "Broadcasting broadcast frame " << frame << endl;
00081         broadcastFrame(frame, inputport);
00082         return;
00083     }
00084 
00085     // Finds output port of destination address and sends to output port
00086     // if not found then broadcasts to all other ports instead
00087     int outputport = getPortForAddress(frame->getDest());
00088     if (inputport==outputport)
00089     {
00090         EV << "Output port is same as input port, " << frame->fullName() <<
00091               " dest " << frame->getDest() << ", discarding frame\n";
00092         delete frame;
00093         return;
00094     }
00095     if (outputport>=0)
00096     {
00097         EV << "Sending frame " << frame << " with dest address " << frame->getDest() << " to port " << outputport << endl;
00098         send(frame, "lowerLayerOut", outputport);
00099     }
00100     else
00101     {
00102         EV << "Dest address " << frame->getDest() << " unknown, broadcasting frame " << frame << endl;
00103         broadcastFrame(frame, inputport);
00104     }
00105 }

void MACRelayUnitBase::initialize  )  [protected]
 

Read parameters parameters.

Reimplemented in MACRelayUnitNP, and MACRelayUnitPP.

00049 {
00050     // number of ports
00051     numPorts = gate("lowerLayerOut",0)->size();
00052     if (gate("lowerLayerIn",0)->size()!=numPorts)
00053         error("the sizes of the lowerLayerIn[] and lowerLayerOut[] gate vectors must be the same");
00054 
00055     // other parameters
00056     addressTableSize = par("addressTableSize");
00057     addressTableSize = addressTableSize >= 0 ? addressTableSize : 0;
00058 
00059     agingTime = par("agingTime");
00060     agingTime = agingTime > 0 ? agingTime : 10;
00061 
00062     // Option to pre-read in Address Table. To turn ot off, set addressTableFile to empty string
00063     const char *addressTableFile = par("addressTableFile");
00064     if (addressTableFile && *addressTableFile)
00065         readAddressTable(addressTableFile);
00066 
00067     seqNum = 0;
00068 
00069     WATCH_MAP(addresstable);
00070 }

void MACRelayUnitBase::printAddressTable  )  [protected]
 

Prints contents of address table on ev.

00116 {
00117     AddressTable::iterator iter;
00118     EV << "Address Table (" << addresstable.size() << " entries):\n";
00119     for (iter = addresstable.begin(); iter!=addresstable.end(); ++iter)
00120     {
00121         EV << "  " << iter->first << " --> port" << iter->second.portno <<
00122               (iter->second.insertionTime+agingTime <= simTime() ? " (aged)" : "") << endl;
00123     }
00124 }

void MACRelayUnitBase::readAddressTable const char *  fileName  )  [protected]
 

Pre-reads in entries for Address Table during initialization.

00216 {
00217     FILE *fp = fopen(fileName, "r");
00218     if (fp == NULL)
00219         error("cannot open address table file `%s'", fileName);
00220 
00221     //  Syntax of the file goes as:
00222     //  Address in hexadecimal representation, Portno
00223     //  ffffffff    1
00224     //  ffffeed1    2
00225     //  aabcdeff    3
00226     //
00227     //  etc...
00228     //
00229     //  Each iteration of the loop reads in an entire line i.e. up to '\n' or EOF characters
00230     //  and uses strtok to extract tokens from the resulting string
00231     char *line;
00232     int lineno = 0;
00233     while ((line = fgetline(fp)) != NULL)
00234     {
00235         lineno++;
00236 
00237         // lines beginning with '#' are treated as comments
00238         if (line[0]=='#')
00239             continue;
00240 
00241         // scan in hexaddress
00242         char *hexaddress = strtok(line, " \t");
00243         // scan in port number
00244         char *portno = strtok(NULL, " \t");
00245 
00246         // empty line?
00247         if (!hexaddress)
00248             continue;
00249 
00250         // broken line?
00251         if (!portno)
00252             error("line %d invalid in address table file `%s'", lineno, fileName);
00253 
00254         // Create an entry with address and portno and insert into table
00255         AddressEntry entry;
00256         entry.insertionTime = 0;
00257         entry.portno = atoi(portno);
00258         addresstable[MACAddress(hexaddress)] = entry;
00259 
00260         // Garbage collection before next iteration
00261         delete [] line;
00262     }
00263     fclose(fp);
00264 }

void MACRelayUnitBase::removeAgedEntriesFromTable  )  [protected]
 

Utility function: throws out all aged entries from table.

00127 {
00128     for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end();)
00129     {
00130         AddressTable::iterator cur = iter++; // iter will get invalidated after erase()
00131         AddressEntry& entry = cur->second;
00132         if (entry.insertionTime + agingTime <= simTime())
00133         {
00134             EV << "Removing aged entry from Address Table: " <<
00135                   cur->first << " --> port" << cur->second.portno << "\n";
00136             addresstable.erase(cur);
00137         }
00138     }
00139 }

void MACRelayUnitBase::removeOldestTableEntry  )  [protected]
 

Utility function: throws out oldest (not necessarily aged) entry from table.

00142 {
00143     AddressTable::iterator oldest = addresstable.end();
00144     simtime_t oldestInsertTime = simTime()+1;
00145     for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end(); iter++)
00146     {
00147         if (iter->second.insertionTime < oldestInsertTime)
00148         {
00149             oldest = iter;
00150             oldestInsertTime = iter->second.insertionTime;
00151         }
00152     }
00153     if (oldest != addresstable.end())
00154     {
00155         EV << "Table full, removing oldest entry: " <<
00156               oldest->first << " --> port" << oldest->second.portno << "\n";
00157         addresstable.erase(oldest);
00158     }
00159 }

void MACRelayUnitBase::sendPauseFrame int  portno,
int  pauseUnits
[protected]
 

Utility function (for use by subclasses) to send a flow control PAUSE frame on the given port.

00268 {
00269     EV << "Creating and sending PAUSE frame on port " << portno << " with duration=" << pauseUnits << " units\n";
00270 
00271     // create Ethernet frame
00272     char framename[40];
00273     sprintf(framename, "pause-%d-%d", id(), seqNum++);
00274     EtherPauseFrame *frame = new EtherPauseFrame(framename, ETH_PAUSE);
00275     frame->setPauseTime(pauseUnits);
00276 
00277     frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_PAUSE_COMMAND_BYTES);
00278     if (frame->byteLength() < MIN_ETHERNET_FRAME)
00279         frame->setByteLength(MIN_ETHERNET_FRAME);
00280 
00281     send(frame, "lowerLayerOut", portno);
00282 }

void MACRelayUnitBase::updateTableWithAddress MACAddress address,
int  portno
[protected]
 

Enters address into table.

00162 {
00163     AddressTable::iterator iter;
00164 
00165     iter = addresstable.find(address);
00166     if (iter == addresstable.end())
00167     {
00168         // Observe finite table size
00169         if (addressTableSize!=0 && addresstable.size() == (unsigned int)addressTableSize)
00170         {
00171             // lazy removal of aged entries: only if table gets full (this step is not strictly needed)
00172             EV << "Making room in Address Table by throwing out aged entries.\n";
00173             removeAgedEntriesFromTable();
00174 
00175             if (addresstable.size() == (unsigned int)addressTableSize)
00176                 removeOldestTableEntry();
00177         }
00178 
00179         // Add entry to table
00180         EV << "Adding entry to Address Table: "<< address << " --> port" << portno << "\n";
00181         AddressEntry entry;
00182         entry.portno = portno;
00183         entry.insertionTime = simTime();
00184         addresstable[address] = entry;
00185     }
00186     else
00187     {
00188         // Update existing entry
00189         EV << "Updating entry in Address Table: "<< address << " --> port" << portno << "\n";
00190         AddressEntry& entry = iter->second;
00191         entry.insertionTime = simTime();
00192         entry.portno = portno;
00193     }
00194 }


Member Data Documentation

AddressTable MACRelayUnitBase::addresstable [protected]
 

int MACRelayUnitBase::addressTableSize [protected]
 

simtime_t MACRelayUnitBase::agingTime [protected]
 

int MACRelayUnitBase::numPorts [protected]
 

int MACRelayUnitBase::seqNum [protected]
 


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:26 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0