libTFO
|
00001 00030 #ifndef __FIBENTRY_HH__ 00031 #define __FIBENTRY_HH__ 00032 00033 #include <stdint.h> 00034 00035 enum FibEntryState 00036 { 00037 FIB_ENTRY_STATE_INACTIVE, 00038 FIB_ENTRY_STATE_ACTIVE, 00039 FIB_ENTRY_STATE_MOD_ADD, 00040 FIB_ENTRY_STATE_MOD_MOVE, 00041 FIB_ENTRY_STATE_MOD_ACTION, 00042 FIB_ENTRY_STATE_MOD_REMOVE, 00043 }; 00044 00045 enum FibEntryTable 00046 { 00047 FIB_ENTRY_TABLE_FAST, 00048 FIB_ENTRY_TABLE_SLOW 00049 }; 00050 00051 enum FibEntryHitsUpdateType 00052 { 00053 FIB_ENTRY_HITS_ADD, 00054 FIB_ENTRY_HITS_UPDATE_BIN, 00055 FIB_ENTRY_HITS_UPDATE_TOTAL, 00056 FIB_ENTRY_HITS_REPLACE 00057 }; 00058 00066 template <typename M, typename A, typename U> 00067 class FibEntry 00068 { 00069 public: 00070 typedef M match_type; 00071 typedef A action_type; 00072 typedef U user_type; 00073 00082 inline FibEntry (uint32_t size_b2, uint32_t size_b3, const M& m, const A& a) 00083 : _match(m), _action(a), _old_action(a), 00084 _state(FIB_ENTRY_STATE_INACTIVE), _table(FIB_ENTRY_TABLE_SLOW), _ttl(0), 00085 _size_b2(size_b2), _size_b3(size_b3), 00086 _hits_current(0), _hits_total(0), _hits_b1(0), _hits_b2(0), _hits_b3(0), 00087 _hits_ring_size(0), _hits_ring_pos(0) 00088 { 00089 _hits_ring = new uint64_t[size_b3]; 00090 } 00091 00095 inline ~FibEntry (void) 00096 { 00097 delete [] _hits_ring; 00098 } 00099 00103 inline const M& match (void) const 00104 { return _match; } 00105 00109 inline const A& action (void) const 00110 { return _action; } 00111 00119 inline const A& action (const A& a) 00120 { return (_action = a); } 00121 00125 inline const A& old_action (void) const 00126 { return _old_action; } 00127 00135 inline const A& old_action (const A& a) 00136 { return (_old_action = a); } 00137 00141 inline U& user_data (void) 00142 { return _user_data; } 00143 00147 inline const enum FibEntryState& state (void) const 00148 { return _state; } 00149 00157 inline const enum FibEntryState& state (enum FibEntryState s) 00158 { return (_state = s); } 00159 00163 inline const enum FibEntryTable& table (void) const 00164 { return _table; } 00165 00173 inline const enum FibEntryTable& table (enum FibEntryTable t) 00174 { return (_table = t); } 00175 00179 inline const uint32_t ttl (void) const 00180 { return _ttl; } 00181 00189 inline const uint32_t ttl (uint32_t t) 00190 { return (_ttl = t); } 00191 00197 inline const uint32_t ttl_decrement (void) 00198 { return (_ttl ? --_ttl : 0); } 00199 00203 inline const uint64_t& hits_total (void) const 00204 { return _hits_total; } 00205 00209 inline const uint64_t& hits_b1 (void) const 00210 { return _hits_b1; } 00211 00215 inline const uint64_t& hits_b2 (void) const 00216 { return _hits_b2; } 00217 00221 inline const uint64_t& hits_b3 (void) const 00222 { return _hits_b3; } 00223 00230 inline void update_hits (const uint64_t& hits, const enum FibEntryHitsUpdateType type) 00231 { 00232 switch (type) 00233 { 00234 case FIB_ENTRY_HITS_ADD: 00235 _hits_current += hits; 00236 break; 00237 case FIB_ENTRY_HITS_UPDATE_BIN: 00238 _hits_current = hits; 00239 break; 00240 case FIB_ENTRY_HITS_UPDATE_TOTAL: 00241 if (hits >= _hits_total) 00242 { 00243 _hits_current = hits - _hits_total; 00244 break; 00245 } 00246 /* if (hits < _hits_total), we assume a counter wrap-around or reset 00247 has happened, i.e., we proceed similar to FIB_ENTRY_HITS_REPLACE. */ 00248 case FIB_ENTRY_HITS_REPLACE: 00249 _hits_current = hits; 00250 _hits_total = 0; 00251 break; 00252 } 00253 } 00254 00258 inline void bin_complete (void) 00259 { 00261 #define FIB_ENTRY_RING_POS(curr, dist, size) \ 00262 (((curr) >= (dist)) ? \ 00263 ((curr) - (dist)) : \ 00264 ((size) - ((dist) - (curr)))) 00265 00267 _hits_total += _hits_current; 00268 00269 _hits_b1 = _hits_current; 00270 00271 _hits_b2 += _hits_current; 00272 if (_hits_ring_size >= _size_b2) 00273 _hits_b2 -= _hits_ring[FIB_ENTRY_RING_POS(_hits_ring_pos, _size_b2 - 1, _hits_ring_size)]; 00274 00275 _hits_b3 += _hits_current; 00276 if (_hits_ring_size >= _size_b3) 00277 _hits_b3 -= _hits_ring[FIB_ENTRY_RING_POS(_hits_ring_pos, _size_b3 - 1, _hits_ring_size)]; 00278 00279 _hits_ring_pos = (_hits_ring_pos + 1) % _size_b3; 00280 _hits_ring[_hits_ring_pos] = _hits_current; 00281 if (_hits_ring_size < _size_b3) 00282 _hits_ring_size++; 00283 00284 _hits_current = 0; 00285 } 00286 00287 private: 00288 /* forwarding information */ 00289 const M _match; 00290 A _action; 00291 A _old_action; 00292 U _user_data; 00293 00294 /* installation status */ 00295 enum FibEntryState _state; 00296 enum FibEntryTable _table; 00297 int _ttl; 00298 00299 /* bin sizes */ 00300 uint32_t _size_b2; 00301 uint32_t _size_b3; 00302 00303 /* traffic statistics */ 00304 uint64_t _hits_current; 00305 uint64_t _hits_total; 00306 uint64_t _hits_b1; 00307 uint64_t _hits_b2; 00308 uint64_t _hits_b3; 00309 uint64_t* _hits_ring; 00310 uint32_t _hits_ring_size; 00311 uint32_t _hits_ring_pos; 00312 }; 00313 00314 #endif