#include <MACRelayUnitBase.h>
Protected Types | |
typedef std::map< MACAddress, AddressEntry, MAC_compare > | AddressTable |
Protected Member Functions | |
virtual void | initialize () |
virtual void | handleAndDispatchFrame (EtherFrame *frame, int inputport) |
virtual void | broadcastFrame (EtherFrame *frame, int inputport) |
virtual void | readAddressTable (const char *fileName) |
virtual void | updateTableWithAddress (MACAddress &address, int portno) |
virtual int | getPortForAddress (MACAddress &address) |
virtual void | printAddressTable () |
virtual void | removeAgedEntriesFromTable () |
virtual void | removeOldestTableEntry () |
virtual 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 |
typedef std::map<MACAddress, AddressEntry, MAC_compare> MACRelayUnitBase::AddressTable [protected] |
void MACRelayUnitBase::initialize | ( | ) | [protected, virtual] |
Read parameters parameters.
Reimplemented in MACRelayUnitNP, and MACRelayUnitPP.
Referenced by MACRelayUnitPP::initialize(), and MACRelayUnitNP::initialize().
00065 { 00066 // number of ports 00067 numPorts = gate("lowerLayerOut",0)->size(); 00068 if (gate("lowerLayerIn",0)->size()!=numPorts) 00069 error("the sizes of the lowerLayerIn[] and lowerLayerOut[] gate vectors must be the same"); 00070 00071 // other parameters 00072 addressTableSize = par("addressTableSize"); 00073 addressTableSize = addressTableSize >= 0 ? addressTableSize : 0; 00074 00075 agingTime = par("agingTime"); 00076 agingTime = agingTime > 0 ? agingTime : 10; 00077 00078 // Option to pre-read in Address Table. To turn ot off, set addressTableFile to empty string 00079 const char *addressTableFile = par("addressTableFile"); 00080 if (addressTableFile && *addressTableFile) 00081 readAddressTable(addressTableFile); 00082 00083 seqNum = 0; 00084 00085 WATCH_MAP(addresstable); 00086 }
void MACRelayUnitBase::handleAndDispatchFrame | ( | EtherFrame * | frame, | |
int | inputport | |||
) | [protected, virtual] |
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.
Referenced by MACRelayUnitPP::processFrame(), and MACRelayUnitNP::processFrame().
00089 { 00090 // update address table 00091 updateTableWithAddress(frame->getSrc(), inputport); 00092 00093 // handle broadcast frames first 00094 if (frame->getDest().isBroadcast()) 00095 { 00096 EV << "Broadcasting broadcast frame " << frame << endl; 00097 broadcastFrame(frame, inputport); 00098 return; 00099 } 00100 00101 // Finds output port of destination address and sends to output port 00102 // if not found then broadcasts to all other ports instead 00103 int outputport = getPortForAddress(frame->getDest()); 00104 if (inputport==outputport) 00105 { 00106 EV << "Output port is same as input port, " << frame->getFullName() << 00107 " dest " << frame->getDest() << ", discarding frame\n"; 00108 delete frame; 00109 return; 00110 } 00111 if (outputport>=0) 00112 { 00113 EV << "Sending frame " << frame << " with dest address " << frame->getDest() << " to port " << outputport << endl; 00114 send(frame, "lowerLayerOut", outputport); 00115 } 00116 else 00117 { 00118 EV << "Dest address " << frame->getDest() << " unknown, broadcasting frame " << frame << endl; 00119 broadcastFrame(frame, inputport); 00120 } 00121 }
void MACRelayUnitBase::broadcastFrame | ( | EtherFrame * | frame, | |
int | inputport | |||
) | [protected, virtual] |
Utility function: sends the frame on all ports except inputport. The message pointer should not be referenced any more after this call.
Referenced by handleAndDispatchFrame().
00124 { 00125 for (int i=0; i<numPorts; ++i) 00126 if (i!=inputport) 00127 send((EtherFrame*)frame->dup(), "lowerLayerOut", i); 00128 delete frame; 00129 }
void MACRelayUnitBase::readAddressTable | ( | const char * | fileName | ) | [protected, virtual] |
Pre-reads in entries for Address Table during initialization.
Referenced by initialize().
00232 { 00233 FILE *fp = fopen(fileName, "r"); 00234 if (fp == NULL) 00235 error("cannot open address table file `%s'", fileName); 00236 00237 // Syntax of the file goes as: 00238 // Address in hexadecimal representation, Portno 00239 // ffffffff 1 00240 // ffffeed1 2 00241 // aabcdeff 3 00242 // 00243 // etc... 00244 // 00245 // Each iteration of the loop reads in an entire line i.e. up to '\n' or EOF characters 00246 // and uses strtok to extract tokens from the resulting string 00247 char *line; 00248 int lineno = 0; 00249 while ((line = fgetline(fp)) != NULL) 00250 { 00251 lineno++; 00252 00253 // lines beginning with '#' are treated as comments 00254 if (line[0]=='#') 00255 continue; 00256 00257 // scan in hexaddress 00258 char *hexaddress = strtok(line, " \t"); 00259 // scan in port number 00260 char *portno = strtok(NULL, " \t"); 00261 00262 // empty line? 00263 if (!hexaddress) 00264 continue; 00265 00266 // broken line? 00267 if (!portno) 00268 error("line %d invalid in address table file `%s'", lineno, fileName); 00269 00270 // Create an entry with address and portno and insert into table 00271 AddressEntry entry; 00272 entry.insertionTime = 0; 00273 entry.portno = atoi(portno); 00274 addresstable[MACAddress(hexaddress)] = entry; 00275 00276 // Garbage collection before next iteration 00277 delete [] line; 00278 } 00279 fclose(fp); 00280 }
void MACRelayUnitBase::updateTableWithAddress | ( | MACAddress & | address, | |
int | portno | |||
) | [protected, virtual] |
Enters address into table.
Referenced by handleAndDispatchFrame().
00178 { 00179 AddressTable::iterator iter; 00180 00181 iter = addresstable.find(address); 00182 if (iter == addresstable.end()) 00183 { 00184 // Observe finite table size 00185 if (addressTableSize!=0 && addresstable.size() == (unsigned int)addressTableSize) 00186 { 00187 // lazy removal of aged entries: only if table gets full (this step is not strictly needed) 00188 EV << "Making room in Address Table by throwing out aged entries.\n"; 00189 removeAgedEntriesFromTable(); 00190 00191 if (addresstable.size() == (unsigned int)addressTableSize) 00192 removeOldestTableEntry(); 00193 } 00194 00195 // Add entry to table 00196 EV << "Adding entry to Address Table: "<< address << " --> port" << portno << "\n"; 00197 AddressEntry entry; 00198 entry.portno = portno; 00199 entry.insertionTime = simTime(); 00200 addresstable[address] = entry; 00201 } 00202 else 00203 { 00204 // Update existing entry 00205 EV << "Updating entry in Address Table: "<< address << " --> port" << portno << "\n"; 00206 AddressEntry& entry = iter->second; 00207 entry.insertionTime = simTime(); 00208 entry.portno = portno; 00209 } 00210 }
int MACRelayUnitBase::getPortForAddress | ( | MACAddress & | address | ) | [protected, virtual] |
Returns output port for address, or -1 if unknown.
Referenced by handleAndDispatchFrame().
00213 { 00214 AddressTable::iterator iter = addresstable.find(address); 00215 if (iter == addresstable.end()) 00216 { 00217 // not found 00218 return -1; 00219 } 00220 if (iter->second.insertionTime + agingTime <= simTime()) 00221 { 00222 // don't use (and throw out) aged entries 00223 EV << "Ignoring and deleting aged entry: "<< iter->first << " --> port" << iter->second.portno << "\n"; 00224 addresstable.erase(iter); 00225 return -1; 00226 } 00227 return iter->second.portno; 00228 }
void MACRelayUnitBase::printAddressTable | ( | ) | [protected, virtual] |
Prints contents of address table on ev.
Referenced by MACRelayUnitPP::processFrame(), and MACRelayUnitNP::processFrame().
00132 { 00133 AddressTable::iterator iter; 00134 EV << "Address Table (" << addresstable.size() << " entries):\n"; 00135 for (iter = addresstable.begin(); iter!=addresstable.end(); ++iter) 00136 { 00137 EV << " " << iter->first << " --> port" << iter->second.portno << 00138 (iter->second.insertionTime+agingTime <= simTime() ? " (aged)" : "") << endl; 00139 } 00140 }
void MACRelayUnitBase::removeAgedEntriesFromTable | ( | ) | [protected, virtual] |
Utility function: throws out all aged entries from table.
Referenced by updateTableWithAddress().
00143 { 00144 for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end();) 00145 { 00146 AddressTable::iterator cur = iter++; // iter will get invalidated after erase() 00147 AddressEntry& entry = cur->second; 00148 if (entry.insertionTime + agingTime <= simTime()) 00149 { 00150 EV << "Removing aged entry from Address Table: " << 00151 cur->first << " --> port" << cur->second.portno << "\n"; 00152 addresstable.erase(cur); 00153 } 00154 } 00155 }
void MACRelayUnitBase::removeOldestTableEntry | ( | ) | [protected, virtual] |
Utility function: throws out oldest (not necessarily aged) entry from table.
Referenced by updateTableWithAddress().
00158 { 00159 AddressTable::iterator oldest = addresstable.end(); 00160 simtime_t oldestInsertTime = simTime()+1; 00161 for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end(); iter++) 00162 { 00163 if (iter->second.insertionTime < oldestInsertTime) 00164 { 00165 oldest = iter; 00166 oldestInsertTime = iter->second.insertionTime; 00167 } 00168 } 00169 if (oldest != addresstable.end()) 00170 { 00171 EV << "Table full, removing oldest entry: " << 00172 oldest->first << " --> port" << oldest->second.portno << "\n"; 00173 addresstable.erase(oldest); 00174 } 00175 }
void MACRelayUnitBase::sendPauseFrame | ( | int | portno, | |
int | pauseUnits | |||
) | [protected, virtual] |
Utility function (for use by subclasses) to send a flow control PAUSE frame on the given port.
Referenced by MACRelayUnitPP::handleIncomingFrame(), and MACRelayUnitNP::handleIncomingFrame().
00284 { 00285 EV << "Creating and sending PAUSE frame on port " << portno << " with duration=" << pauseUnits << " units\n"; 00286 00287 // create Ethernet frame 00288 char framename[40]; 00289 sprintf(framename, "pause-%d-%d", getId(), seqNum++); 00290 EtherPauseFrame *frame = new EtherPauseFrame(framename); 00291 frame->setPauseTime(pauseUnits); 00292 00293 frame->setByteLength(ETHER_MAC_FRAME_BYTES+ETHER_PAUSE_COMMAND_BYTES); 00294 if (frame->getByteLength() < MIN_ETHERNET_FRAME) 00295 frame->setByteLength(MIN_ETHERNET_FRAME); 00296 00297 send(frame, "lowerLayerOut", portno); 00298 }
int MACRelayUnitBase::numPorts [protected] |
int MACRelayUnitBase::addressTableSize [protected] |
Referenced by MACRelayUnitPP::initialize(), MACRelayUnitNP::initialize(), initialize(), and updateTableWithAddress().
simtime_t MACRelayUnitBase::agingTime [protected] |
AddressTable MACRelayUnitBase::addresstable [protected] |
int MACRelayUnitBase::seqNum [protected] |
Referenced by initialize(), and sendPauseFrame().