|
xorp
|
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/rib/rt_tab_redist.hh,v 1.19 2008/10/02 21:58:13 bms Exp $ 00021 00022 #ifndef __RIB_RT_TAB_REDIST_HH__ 00023 #define __RIB_RT_TAB_REDIST_HH__ 00024 00025 00026 00027 #include "rt_tab_base.hh" 00028 00029 template <typename A> 00030 class Redistributor; 00031 00032 template <typename A> 00033 class RedistOutput; 00034 00035 template <typename A> 00036 class RedistPolicy; 00037 00038 #ifndef XORP_USE_USTL 00039 00042 template <typename A> 00043 struct RedistNetCmp { 00044 bool operator() (const IPNet<A>& l, const IPNet<A>& r) const; 00045 }; 00046 #endif 00047 00048 00065 template<class A> 00066 class RedistTable : public RouteTable<A> { 00067 public: 00068 #ifdef XORP_USE_USTL 00069 typedef set<IPNet<A> > RouteIndex; 00070 #else 00071 typedef set<IPNet<A>,RedistNetCmp<A> > RouteIndex; 00072 #endif 00073 00074 public: 00082 RedistTable(const string& tablename, 00083 RouteTable<A>* from_table); 00084 00092 ~RedistTable(); 00093 00098 void add_redistributor(Redistributor<A>* r); 00099 00103 void remove_redistributor(Redistributor<A>* r); 00104 00108 Redistributor<A>* redistributor(const string& name); 00109 00110 // 00111 // Standard RouteTable methods 00112 // 00113 int add_route(const IPRouteEntry<A>& route, RouteTable<A>* caller); 00114 int delete_route(const IPRouteEntry<A>* route, RouteTable<A>* caller); 00115 const IPRouteEntry<A>* lookup_route(const IPNet<A>& net) const; 00116 const IPRouteEntry<A>* lookup_route(const A& addr) const; 00117 RouteRange<A>* lookup_route_range(const A& addr) const; 00118 TableType type() const { return REDIST_TABLE; } 00119 RouteTable<A>* parent() { return _parent; } 00120 void replumb(RouteTable<A>* old_parent, RouteTable<A>* new_parent); 00121 string str() const; 00122 00127 const RouteIndex& route_index() const { return _rt_index; } 00128 00129 protected: 00130 RouteTable<A>* _parent; // Immediately upstream table. May 00131 // differ from _from_table if a 00132 // Deletion table or another redist 00133 // table has been plumbed in. 00134 RouteIndex _rt_index; 00135 list<Redistributor<A>*> _outputs; 00136 }; 00137 00138 00139 00151 template <typename A> 00152 class Redistributor : 00153 public NONCOPYABLE 00154 { 00155 public: 00156 class RedistEventInterface { 00157 // Methods only available to RedistTable. 00158 void did_add(const IPRouteEntry<A>& ipr); 00159 void will_delete(const IPRouteEntry<A>& ipr); 00160 void did_delete(const IPRouteEntry<A>& ipr); 00161 00162 friend class RedistTable<A>; 00163 friend class Redistributor<A>; 00164 00165 public: 00166 RedistEventInterface(Redistributor<A>* r) : _r(r) {} 00167 00168 private: 00169 Redistributor<A>* _r; 00170 }; 00171 00172 class OutputEventInterface { 00173 // Methods only available to RedistOutput. These are 00174 // events it can tell us about. 00175 void low_water(); 00176 void high_water(); 00177 void fatal_error(); 00178 00179 friend class RedistOutput<A>; 00180 friend class Redistributor<A>; 00181 00182 public: 00183 OutputEventInterface(Redistributor<A>* r) : _r(r) {} 00184 00185 private: 00186 Redistributor<A>* _r; 00187 }; 00188 00189 public: 00190 Redistributor(EventLoop& e, const string& name); 00191 virtual ~Redistributor(); 00192 00193 const string& name() const; 00194 00195 void set_redist_table(RedistTable<A>* rt); 00196 00204 void set_output(RedistOutput<A>* output); 00205 00213 void set_policy(RedistPolicy<A>* policy); 00214 00221 bool policy_accepts(const IPRouteEntry<A>& ipr) const; 00222 00227 RedistEventInterface& redist_event() { return _rei; } 00228 00233 OutputEventInterface& output_event() { return _oei; } 00234 00242 bool dumping() const { return _dumping; } 00243 00244 private: 00249 void start_dump(); 00250 void finish_dump(); 00251 00252 void schedule_dump_timer(); 00253 void unschedule_dump_timer(); 00254 void dump_a_route(); 00255 00256 const IPNet<A>& last_dumped_net() const { return _last_net; } 00257 RedistTable<A>* redist_table() { return _table; } 00258 RedistOutput<A>* output() { return _output; } 00259 00260 private: 00261 // These are nested classes and need to be friends to invoke methods in 00262 // enclosing class. 00263 friend class RedistEventInterface; 00264 friend class OutputEventInterface; 00265 00266 private: 00267 EventLoop& _e; 00268 string _name; 00269 RedistTable<A>* _table; 00270 RedistOutput<A>* _output; 00271 RedistPolicy<A>* _policy; 00272 00273 RedistEventInterface _rei; 00274 OutputEventInterface _oei; 00275 00276 bool _dumping; // Announcing existing routes 00277 bool _blocked; // Output above high water 00278 IPNet<A> _last_net; // Last net announced 00279 XorpTimer _dtimer; 00280 00281 static const IPNet<A> NO_LAST_NET; // Indicator for last net inval 00282 }; 00283 00284 00285 00289 template <typename A> 00290 class RedistOutput : 00291 public NONCOPYABLE 00292 { 00293 public: 00294 RedistOutput(Redistributor<A>* r); 00295 virtual ~RedistOutput(); 00296 00297 virtual void add_route(const IPRouteEntry<A>& ipr) = 0; 00298 virtual void delete_route(const IPRouteEntry<A>& ipr) = 0; 00299 00305 virtual void starting_route_dump() = 0; 00306 00312 virtual void finishing_route_dump() = 0; 00313 00314 protected: 00315 void announce_low_water() { _r->output_event().low_water(); } 00316 void announce_high_water() { _r->output_event().high_water(); } 00317 void announce_fatal_error() { _r->output_event().fatal_error(); } 00318 00319 private: 00320 Redistributor<A>* _r; 00321 }; 00322 00323 00324 // ---------------------------------------------------------------------------- 00325 // Inline RedistTable methods 00326 00327 #ifndef XORP_USE_USTL 00328 template <typename A> 00329 inline bool 00330 RedistNetCmp<A>::operator() (const IPNet<A>& l, const IPNet<A>& r) const 00331 { 00332 if (l.prefix_len() != r.prefix_len()) 00333 return l.prefix_len() < r.prefix_len(); 00334 return l.masked_addr() < r.masked_addr(); 00335 } 00336 #endif 00337 00338 #endif // __RIB_RT_TAB_REDIST_HH__