VLANs(802.1Q)forOMNet++
0.5Beta
|
This class is taken from INET FrameWork switches and changed a bit to support logical links. More...
#include <MACVlanRelayUnitBase.h>
Protected Types | |
typedef std::map< mac_llid, AddressEntry, macllidCmp > | AddressTable |
The mac-address table as a map of mac_llid and extra information. | |
Protected Member Functions | |
virtual void | initialize () |
Read parameters parameters. | |
virtual void | readAddressTable (const char *fileName) |
Pre-reads in entries for Address Table during initialization. | |
virtual void | updateTableWithAddress (mac_llid MacLLid, std::string portName) |
Enters address into table. | |
virtual void | updateTableFromFrame (EtherFrame *frame) |
Enters address and vlan (if any) into table. | |
virtual std::string | getPortForAddress (mac_llid MacLLid) |
Returns output port for address, or "" if unknown. | |
virtual std::vector< port_llid > | getLLIDsForAddress (MACAddress mac) |
Returns LLIDs for address. | |
virtual void | printAddressTable () |
Prints contents of address table on ev. | |
virtual void | removeAgedEntriesFromTable () |
Utility function: throws out all aged entries from table. | |
virtual void | removeOldestTableEntry () |
Utility function: throws out oldest (not necessarily aged) entry from table. | |
Protected Attributes | |
int | numPorts |
int | addressTableSize |
simtime_t | agingTime |
AddressTable | addresstable |
int | seqNum |
This class is taken from INET FrameWork switches and changed a bit to support logical links.
The basic struct used here is the mac_llid which bonds a MAC address with a logical entity. The same struct could be used to support VLANs in the switches.
From the INET documentation:
"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."
typedef std::map<mac_llid, AddressEntry, macllidCmp> MACVlanRelayUnitBase::AddressTable [protected] |
The mac-address table as a map of mac_llid and extra information.
std::vector< port_llid > MACVlanRelayUnitBase::getLLIDsForAddress | ( | MACAddress | mac | ) | [protected, virtual] |
Returns LLIDs for address.
{ std::vector<port_llid> res; for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end(); iter++) { // Check for aged if (iter->second.insertionTime + agingTime <= simTime()) { // don't use (and throw out) aged entries EV << "Ignoring and deleting aged entry: "<< iter->first.mac << " --> port " << iter->second.portName << " llid " << iter->first.llid << "\n"; addresstable.erase(iter); continue; } if (iter->first.mac == mac){ port_llid pl; pl.llid = iter->first.llid; pl.port = iter->second.portName; res.push_back(pl); } } return res; }
string MACVlanRelayUnitBase::getPortForAddress | ( | mac_llid | MacLLid | ) | [protected, virtual] |
Returns output port for address, or "" if unknown.
{ AddressTable::iterator iter = addresstable.find(ml); if (iter == addresstable.end()) { // not found return ""; } if (iter->second.insertionTime + agingTime <= simTime()) { // don't use (and throw out) aged entries EV << "Ignoring and deleting aged entry: "<< iter->first.mac << " --> port " << iter->second.portName << " llid " << iter->first.llid << "\n"; addresstable.erase(iter); return ""; } return iter->second.portName; }
void MACVlanRelayUnitBase::initialize | ( | ) | [protected, virtual] |
Read parameters parameters.
{ // number of ports numPorts = 2; // other parameters addressTableSize = par("addressTableSize"); addressTableSize = addressTableSize >= 0 ? addressTableSize : 0; agingTime = par("agingTime"); agingTime = agingTime > 0 ? agingTime : 10; // Option to pre-read in Address Table. To turn ot off, set addressTableFile to empty string const char *addressTableFile = par("addressTableFile"); if (addressTableFile && *addressTableFile) readAddressTable(addressTableFile); seqNum = 0; WATCH_MAP(addresstable); }
void MACVlanRelayUnitBase::printAddressTable | ( | ) | [protected, virtual] |
Prints contents of address table on ev.
{ AddressTable::iterator iter; EV << "Address Table (" << addresstable.size() << " entries):\n"; for (iter = addresstable.begin(); iter!=addresstable.end(); ++iter) { EV << " " << iter->first << " --> port " << iter->second.portName << " --> llid " << iter->first.llid << (iter->second.insertionTime+agingTime <= simTime() ? " (aged)" : "") << endl; } }
void MACVlanRelayUnitBase::readAddressTable | ( | const char * | fileName | ) | [protected, virtual] |
Pre-reads in entries for Address Table during initialization.
{ FILE *fp = fopen(fileName, "r"); if (fp == NULL) error("cannot open address table file `%s'", fileName); // Syntax of the file goes as: // Address in hexadecimal representation, portName // ffffffff Xout 1000 // ffffeed1 Yout 901 // aabcdeff Zout 3 // // etc... // // Each iteration of the loop reads in an entire line i.e. up to '\n' or EOF characters // and uses strtok to extract tokens from the resulting string char *line; int lineno = 0; while ((line = fgetline(fp)) != NULL) { lineno++; // lines beginning with '#' are treated as comments if (line[0]=='#') continue; // scan in hexaddress char *hexaddress = strtok(line, " \t"); // scan in port number string portName; portName = strtok(NULL, " \t"); // scan in logical number char *llid = strtok(NULL, " \t"); // empty line? if (!hexaddress) continue; // broken line? if (portName!="" || !llid) error("line %d invalid in address table file `%s'", lineno, fileName); // Create an entry with address and portName and insert into table AddressEntry entry; entry.insertionTime = 0; entry.portName = portName; mac_llid ml; ml.mac=MACAddress(hexaddress); ml.llid = atoi(llid); addresstable[ml] = entry; // Garbage collection before next iteration delete [] line; } fclose(fp); }
void MACVlanRelayUnitBase::removeAgedEntriesFromTable | ( | ) | [protected, virtual] |
Utility function: throws out all aged entries from table.
{ for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end();) { AddressTable::iterator cur = iter++; // iter will get invalidated after erase() AddressEntry& entry = cur->second; if (entry.insertionTime + agingTime <= simTime()) { EV << "Removing aged entry from Address Table: " << cur->first << " --> port" << cur->second.portName << "\n"; addresstable.erase(cur); } } }
void MACVlanRelayUnitBase::removeOldestTableEntry | ( | ) | [protected, virtual] |
Utility function: throws out oldest (not necessarily aged) entry from table.
{ AddressTable::iterator oldest = addresstable.end(); simtime_t oldestInsertTime = simTime()+1; for (AddressTable::iterator iter = addresstable.begin(); iter != addresstable.end(); iter++) { if (iter->second.insertionTime < oldestInsertTime) { oldest = iter; oldestInsertTime = iter->second.insertionTime; } } if (oldest != addresstable.end()) { EV << "Table full, removing oldest entry: " << oldest->first << " --> port" << oldest->second.portName <<"\n"; addresstable.erase(oldest); } }
void MACVlanRelayUnitBase::updateTableFromFrame | ( | EtherFrame * | frame | ) | [protected, virtual] |
Enters address and vlan (if any) into table.
{ mac_llid ml; ml.llid=-1; if (dynamic_cast<EthernetDot1QFrame *>(frame)!=NULL) ml.llid=dynamic_cast<EthernetDot1QFrame *>(frame)->getVlanID(); ml.mac = frame->getSrc(); updateTableWithAddress(ml, "ethOut"); }
void MACVlanRelayUnitBase::updateTableWithAddress | ( | mac_llid | MacLLid, |
std::string | portName | ||
) | [protected, virtual] |
Enters address into table.
{ AddressTable::iterator iter; iter = addresstable.find(MacLLid); if (iter == addresstable.end()) { // Observe finite table size if (addressTableSize!=0 && addresstable.size() == (unsigned int)addressTableSize) { // lazy removal of aged entries: only if table gets full (this step is not strictly needed) EV << "Making room in Address Table by throwing out aged entries.\n"; removeAgedEntriesFromTable(); if (addresstable.size() == (unsigned int)addressTableSize) removeOldestTableEntry(); } // Add entry to table EV << "Adding entry to Address Table: "<< MacLLid.mac << " --> port " << portName << " --> llid " << MacLLid.llid << "\n"; AddressEntry entry; entry.portName = portName; entry.insertionTime = simTime(); addresstable[MacLLid] = entry; } else { // Update existing entry EV << "Updating entry in Address Table: "<< MacLLid.mac << " --> port " << portName << " --> llid " << MacLLid.llid << "\n"; AddressEntry& entry = iter->second; entry.insertionTime = simTime(); entry.portName = portName; } }
AddressTable MACVlanRelayUnitBase::addresstable [protected] |
int MACVlanRelayUnitBase::addressTableSize [protected] |
simtime_t MACVlanRelayUnitBase::agingTime [protected] |
int MACVlanRelayUnitBase::numPorts [protected] |
int MACVlanRelayUnitBase::seqNum [protected] |