xorp

rt_tab_redist.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/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__
 All Classes Namespaces Functions Variables Typedefs Enumerations