xorp

route_table_cache.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 // $XORP: xorp/bgp/route_table_cache.hh,v 1.32 2008/11/08 06:14:38 mjh Exp $
00021 
00022 #ifndef __BGP_ROUTE_TABLE_CACHE_HH__
00023 #define __BGP_ROUTE_TABLE_CACHE_HH__
00024 
00025 
00026 #include "libxorp/timer.hh"
00027 #include "route_table_base.hh"
00028 #include "crash_dump.hh"
00029 #include "libxorp/ref_trie.hh"
00030 #include "peer_handler.hh"
00031 
00037 template<class A>
00038 class CacheRoute {
00039 public:
00040     CacheRoute(const SubnetRoute<A>* route, uint32_t genid) 
00041     : _routeref(route), _genid(genid) {}
00042     const SubnetRoute<A>* route() const { return _routeref.route(); }
00043     uint32_t genid() const { return _genid; }
00044 private:
00045     SubnetRouteConstRef<A> _routeref;
00046     uint32_t _genid;
00047 };
00048 
00049 
00050 class EventLoop;
00051 
00084 template<class A>
00085 class CacheTable : public BGPRouteTable<A>, CrashDumper {
00086 public:
00087     CacheTable(string tablename, Safi safi, BGPRouteTable<A> *parent,
00088            const PeerHandler *peer);
00089     ~CacheTable();
00090     int add_route(InternalMessage<A> &rtmsg,
00091           BGPRouteTable<A> *caller);
00092     int replace_route(InternalMessage<A> &old_rtmsg,
00093               InternalMessage<A> &new_rtmsg,
00094               BGPRouteTable<A> *caller);
00095     int delete_route(InternalMessage<A> &rtmsg, 
00096              BGPRouteTable<A> *caller);
00097     int push(BGPRouteTable<A> *caller);
00098     int route_dump(InternalMessage<A> &rtmsg,
00099            BGPRouteTable<A> *caller,
00100            const PeerHandler *dump_peer);
00101 
00102     void flush_cache();
00103     const SubnetRoute<A> *lookup_route(const IPNet<A> &net,
00104                        uint32_t& genid,
00105                        FPAListRef& pa_list) const;
00106     void route_used(const SubnetRoute<A>* route, bool in_use);
00107 
00108     RouteTableType type() const {return CACHE_TABLE;}
00109     string str() const;
00110 
00111     /* mechanisms to implement flow control in the output plumbing */
00112     bool get_next_message(BGPRouteTable<A> *next_table);
00113 
00114     int route_count() const {
00115     return _route_table->route_count();
00116     }
00117 
00118     string dump_state() const;
00119 
00120     EventLoop& eventloop() const;
00121 
00122 private:
00123     RefTrie<A, const CacheRoute<A> > *_route_table;
00124     const PeerHandler *_peer;
00125 
00126     // stats to help debugging
00127     int _unchanged_added, _unchanged_deleted, _changed_added, _changed_deleted;
00128 };
00129 
00135 template<class A>
00136 class DeleteAllNodes {
00137 public:
00138     typedef RefTrie<A, const CacheRoute<A> > RouteTable;
00139     typedef queue<RouteTable *> RouteTables;
00140 
00141     DeleteAllNodes(const PeerHandler *peer, RouteTable *route_table)
00142     : _peer(peer) {
00143 
00144         bool empty = _route_tables.empty();
00145         _route_tables.push(route_table);
00146 
00147         if (empty) {
00148         _deleter_task = 
00149             _peer->eventloop().new_task(
00150             callback(this, &DeleteAllNodes<A>::delete_some_nodes),
00151             XorpTask::PRIORITY_BACKGROUND,
00152             XorpTask::WEIGHT_DEFAULT);
00153         } else {
00154         delete this;
00155         }
00156     }
00157     
00163     bool delete_some_nodes() {
00164     RouteTable *route_table = _route_tables.front();
00165     typename RouteTable::iterator current = route_table->begin();
00166     for(int i = 0; i < _deletions_per_call; i++) {
00167         // In theory if current is invalid then it will move to a
00168         // valid entry. Unlike the STL, which this isn't.
00169         PAListRef<A> old_pa_list = current.payload().route()->attributes();
00170         old_pa_list.deregister_with_attmgr();
00171         route_table->erase(current);
00172         if (current == route_table->end()) {
00173         _route_tables.pop();
00174         route_table->delete_self();
00175         break;
00176         }
00177     }
00178 
00179     if (_route_tables.empty()) {
00180         delete this;
00181         return false;
00182     }
00183 
00184     return true;
00185     }
00186 
00190     static bool running() {
00191     return !_route_tables.empty();
00192     }
00193 private:
00194     static RouteTables _route_tables;   // Queue of route tables to delete.
00195     XorpTask _deleter_task;         // 
00196     const PeerHandler *_peer;       // Handle to the EventLoop.
00197     static int _deletions_per_call; // Number of nodes deleted per call.
00198 };
00199 
00200 #endif // __BGP_ROUTE_TABLE_CACHE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations