|
INET Framework for OMNeT++/OMNEST
|
00001 00002 #include "macTable.h" 00003 00004 Define_Module(MACTable); 00005 00006 00007 /* --- PUBLIC --- */ 00008 00009 MACTable::MACTable() { 00010 this->initDefaults(); 00011 return; 00012 } 00013 00014 MACTable::MACTable(int _tableSize) { 00015 this->initDefaults(); 00016 if (_tableSize < 0) { 00017 this->addressTableSize = 0; 00018 } else { 00019 this->addressTableSize = _tableSize; 00020 } 00021 return; 00022 } 00023 00024 MACTable::~MACTable() { 00025 return; 00026 } 00027 00028 const MACTable::AddressTable * MACTable::getTable() { 00029 return &(this->table); 00030 } 00031 00032 00033 00034 void MACTable::update(MACAddress& addr, int port) { 00035 Enter_Method_Silent(); 00036 00037 flushAged(); 00038 00039 AddressTable::iterator iter; 00040 00041 iter = this->table.find(addr); 00042 if (iter == this->table.end()) { 00043 // Observe finite table size 00044 if (this->addressTableSize != 0 && this->table.size() == (unsigned int)addressTableSize) { 00045 EV << "Making room in Address Table by throwing out aged entries.\n"; 00046 00047 if (this->table.size() == (unsigned int)addressTableSize) { 00048 removeOldest(); 00049 } 00050 } 00051 // Add entry to table 00052 EV << "Adding entry to Address Table: "<< addr << " --> port" << port << "\n"; 00053 00054 tRecord entry; 00055 entry.addr = addr; 00056 entry.insert_time = simTime(); 00057 entry.portList.push_back(port); 00058 entry.type = DYNAMIC; 00059 entry.spec = NONE; 00060 00061 this->table[addr] = entry; 00062 } else { 00063 // Update existing entry 00064 EV << "Updating entry in Address Table: "<< addr << " --> port" << port << "\n"; 00065 00066 tRecord& entry = iter->second; 00067 00068 if (entry.type == DYNAMIC) { 00069 entry.insert_time = simTime(); 00070 if (entry.portList.at(0) != port) { 00071 entry.portList.clear(); 00072 entry.portList.push_back(port); 00073 } 00074 } 00075 } 00076 00077 return; 00078 } 00079 00080 MACTable::tSpec MACTable::getSpec(MACAddress& addr) { 00081 Enter_Method_Silent(); 00082 00083 AddressTable::iterator iter = table.find(addr); 00084 if (iter == table.end()) { 00085 // not found 00086 return NONE; 00087 } 00088 if ((iter->second.type != STATIC) && 00089 (iter->second.insert_time + agingTime) <= simTime()) { 00090 // don't use (and throw out) aged entries 00091 EV << "Ignoring and deleting aged entry: "<< iter->first << "\n"; 00092 00093 table.erase(iter); 00094 00095 return NONE; 00096 } 00097 00098 return iter->second.spec; 00099 } 00100 00101 00102 MACTable::tPortList& MACTable::getPorts(MACAddress& addr) { 00103 00104 Enter_Method_Silent(); 00105 00106 AddressTable::iterator iter = table.find(addr); 00107 if (iter == table.end()) { 00108 // not found 00109 return empty; 00110 } 00111 if ((iter->second.type != STATIC) && 00112 (iter->second.insert_time + agingTime) <= simTime()) { 00113 // don't use (and throw out) aged entries 00114 EV << "Ignoring and deleting aged entry: "<< iter->first << "\n"; 00115 00116 table.erase(iter); 00117 00118 return empty; 00119 } 00120 00121 return iter->second.portList; 00122 } 00123 00124 void MACTable::flush() { 00125 00126 Enter_Method_Silent(); 00127 00128 AddressTable::iterator iter; 00129 for (iter = table.begin(); iter != table.end();) { 00130 AddressTable::iterator cur = iter++; 00131 tRecord entry = cur->second; 00132 if (entry.type == DYNAMIC) { //TODO GROUP adresses too ? 00133 table.erase(cur); 00134 } 00135 } 00136 00137 return; 00138 } 00139 00140 void MACTable::enableFasterAging() { 00141 Enter_Method_Silent(); 00142 agingTime = fasterAging; 00143 } 00144 00145 void MACTable::resetAging() { 00146 Enter_Method_Silent(); 00147 agingTime = uAgingTime; 00148 } 00149 00150 00151 /* --- PRIVATE --- */ 00152 00153 00154 void MACTable::initDefaults() { 00155 addressTableSize = 1024; // TODO 00156 00157 /* by IEEE 802.1D-1998 00158 * " The Bridges then use a short value 00159 * to age out dynamic entries 00160 * in the Fitering Database for a period." 00161 * */ 00162 fasterAging = 5; // short value to age out ... (5s < 5xHelloTime = 10s) 00163 uAgingTime = 300; // recommended value by IEEE 802.1D-1998 (and later)... 00164 agingTime = uAgingTime; // renew of user defined value, is triggered by STP process and receiving bpdu 00165 return; 00166 } 00167 00168 /* MGMT */ 00169 00170 void MACTable::flushAged() { 00171 00172 Enter_Method_Silent(); 00173 00174 AddressTable::iterator iter; 00175 for (iter = this->table.begin(); iter != this->table.end();) { 00176 AddressTable::iterator cur = iter++; // iter will get invalidated after erase() 00177 tRecord entry = cur->second; 00178 if (entry.type == DYNAMIC && entry.insert_time + agingTime <= simTime()) { 00179 EV << "Removing aged entry from Address Table: " << cur->first << "\n"; 00180 this->table.erase(cur); 00181 } 00182 } 00183 return; 00184 } 00185 00186 void MACTable::removeOldest() { 00187 00188 Enter_Method_Silent(); 00189 00190 AddressTable::iterator oldest = this->table.end(); 00191 simtime_t oldestInsertTime = simTime()+1; 00192 for (AddressTable::iterator iter = this->table.begin(); iter != this->table.end(); iter++) { 00193 if (iter->second.type != DYNAMIC && iter->second.insert_time < oldestInsertTime) { 00194 oldest = iter; 00195 oldestInsertTime = iter->second.insert_time; 00196 } 00197 } 00198 if (oldest != this->table.end()) { 00199 EV << "Table full, removing oldest entry: " << 00200 oldest->first << "\n"; 00201 this->table.erase(oldest); 00202 } 00203 return; 00204 } 00205 00206 00207 void MACTable::add(MACAddress addr, int port, tType type, tSpec spec) { 00208 AddressTable::iterator iter; 00209 00210 iter = this->table.find(addr); 00211 if (iter == this->table.end()) { // record not found 00212 // Observe finite table size 00213 if (this->addressTableSize != 0 && this->table.size() == (unsigned int)addressTableSize) { 00214 EV << "Making room in Address Table by throwing out aged entries.\n"; 00215 00216 if (this->table.size() == (unsigned int)addressTableSize) { 00217 removeOldest(); 00218 } 00219 } 00220 // Add entry to table 00221 EV << "Adding entry to Address Table: "<< addr << " --> port" << port << "\n"; 00222 00223 tRecord entry; // create new entry, with given port & type 00224 entry.addr = addr; 00225 entry.insert_time = simTime(); 00226 entry.portList.push_back(port); 00227 entry.type = type; 00228 entry.spec = spec; 00229 00230 this->table[addr] = entry; 00231 } else { 00232 // Update existing entry 00233 EV << "Updating entry in Address Table: "<< addr << " --> port" << port << "\n"; 00234 00235 tRecord& entry = iter->second; 00236 00237 entry.insert_time = simTime(); 00238 unsigned int i; 00239 for (i = 0; i < entry.portList.size(); i++) { // search through portList for given port 00240 if (entry.portList.at(i) == port) { 00241 break; 00242 } 00243 } 00244 if (i < entry.portList.size()) { 00245 entry.portList.clear(); 00246 entry.portList.push_back(port); 00247 } 00248 } 00249 00250 return; 00251 } 00252 00253 void MACTable::remove(MACAddress addr) { 00254 AddressTable::iterator iter; 00255 00256 iter = this->table.find(addr); 00257 if (iter == this->table.end()) { // record not found 00258 return; 00259 } else { 00260 this->table.erase(iter); 00261 } 00262 return; 00263 } 00264 00265 void MACTable::removePort(MACAddress addr, int port) { 00266 AddressTable::iterator iter; 00267 00268 iter = this->table.find(addr); 00269 if (iter == this->table.end()) { // record not found 00270 return; 00271 } else { 00272 tRecord& entry = iter->second; 00273 tPortList::iterator pIter; 00274 for (pIter = entry.portList.begin(); pIter < entry.portList.end(); pIter++) { // search through portList for given port 00275 if (*pIter == port) { 00276 entry.portList.erase(pIter); 00277 break; 00278 } 00279 } 00280 } 00281 return; 00282 } 00283 00284 void MACTable::addStatic(MACAddress addr, tPortList ports) { 00285 AddressTable::iterator iter; 00286 00287 iter = this->table.find(addr); 00288 if (iter == this->table.end()) { // record not found 00289 // Observe finite table size 00290 if (this->addressTableSize != 0 && this->table.size() == (unsigned int)addressTableSize) { 00291 EV << "Making room in Address Table by throwing out aged entries.\n"; 00292 00293 if (this->table.size() == (unsigned int)addressTableSize) { 00294 removeOldest(); 00295 } 00296 } 00297 // Add entry to table 00298 EV << "Adding static entry to Address Table: "<< addr << " " << ports << std::endl; 00299 00300 tRecord entry; // create new entry, with given port & type 00301 entry.addr = addr; 00302 entry.insert_time = simTime(); 00303 entry.portList = ports; 00304 entry.type = STATIC; 00305 entry.spec = NONE; 00306 00307 this->table[addr] = entry; 00308 } else { 00309 // Update existing entry 00310 EV << "Updating entry in Address Table: "<< addr << " " << ports << std::endl; 00311 00312 tRecord& entry = iter->second; 00313 00314 entry.insert_time = simTime(); 00315 unsigned int i; 00316 unsigned int c; 00317 for(i = 0; i < ports.size(); i++) { // for all input port number 00318 for(c = 0; c < entry.portList.size(); c++) { // search through whole port vector 00319 if (entry.portList.at(c) == ports.at(i)) { // if port number match 00320 break; 00321 } 00322 00323 } 00324 if (c == entry.portList.size()) { // if port record not found 00325 entry.portList.push_back(ports.at(i)); // insert new 00326 } 00327 00328 } 00329 } 00330 00331 00332 return; 00333 } 00334 00335 00336 /* --- PROTECTED --- */ 00337 00338 void MACTable::initialize() { 00339 this->initDefaults(); 00340 00341 /* TEST */ 00342 /* 00343 tPortList tmp0, tmp1; 00344 tmp0.push_back(0); 00345 tmp0.push_back(1); 00346 tmp0.push_back(2); 00347 tmp0.push_back(3); 00348 00349 tmp1.push_back(2); 00350 tmp1.push_back(3); 00351 tmp1.push_back(4); 00352 tmp1.push_back(5); 00353 00354 addStatic(MACAddress("01:00:00:00:00:01"), tmp0); 00355 addStatic(MACAddress("01:00:00:00:00:02"), tmp1); 00356 removePort(MACAddress("01:00:00:00:00:01"), 2); 00357 remove(MACAddress("01:00:00:00:00:02")); 00358 add(MACAddress("01:00:00:00:00:03"), 16, GROUP, NONE); 00359 */ 00360 /* END TEST */ 00361 00362 00363 /* IEEE802.1D Table 7-10 Reserved addresses */ 00364 // Bridge Group Address -> go to STP 00365 add(MACAddress("01-80-C2-00-00-00"), 0, STATIC, STP); 00366 /* end of table */ 00367 00368 00369 WATCH_MAP(this->table); 00370 WATCH(this->addressTableSize); 00371 WATCH(this->agingTime); 00372 WATCH_RW(uAgingTime); 00373 return; 00374 } 00375 00376 void MACTable::finish() { 00377 EV << "ANSA Switch, end of transmission." << std::endl; 00378 return; 00379 } 00380 00381 00382