Source: ../../rib/rt_tab_redist.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2009 XORP, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, Version 2, June
// 1991 as published by the Free Software Foundation. Redistribution
// and/or modification of this program under the terms of any other
// version of the GNU General Public License is not permitted.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU General Public License, Version 2, a copy of which can be
// found in the XORP LICENSE.gpl file.
//
// XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
// $XORP: xorp/rib/rt_tab_redist.hh,v 1.20 2009/01/05 18:31:07 jtc Exp $
#ifndef __RIB_RT_TAB_REDIST_HH__
#define __RIB_RT_TAB_REDIST_HH__
#include "rt_tab_base.hh"
template <typename A>
class Redistributor;
template <typename A>
class RedistOutput;
template <typename A>
class RedistPolicy;
/**
* Comparitor to allow nets to be stored in a sorted container.
*/
template <typename A>
struct RedistNetCmp {
bool operator() (const IPNet<A>& l, const IPNet<A>& r) const;
};
/**
* @short RouteTable used to redistribute routes.
*
* The RedistTable is used to redistribute routes from a routing table
* back out to a routing protocol. For example, when you want to
* redistribute BGP routes into OSPF.
*
* For most operations the RedistTable is essentially a passthrough.
* It keeps track of nets it hears add and deletes for so when route
* @ref Redistributor objects are added to the RedistTable they can
* announce the existing routes at startup.
*
* Design note: RedistTable uses a set of IPNet's to cache routes - this
* should be route entry pointers with an appropriate comparitor (not pointer
* value based).
*/
template<class A>
class RedistTable : public RouteTable<A> {
public:
typedef set<IPNet<A>,RedistNetCmp<A> > RouteIndex;
public:
/**
* Constructor.
*
* Plumbs RedistTable in RIB graph after from_table.
*
* @param from_table table to redistribute routes from.
*/
RedistTable(const string& tablename,
RouteTable<A>* from_table);
/**
* Destructor.
*
* Unplumbs table and deletes Redistributor object instances previously
* added with add_redistributor and not previously removed with
* remove_redistributor.
*/
~RedistTable();
/**
* Add a redistributor to announce existing routes and future updates
* to.
*/
void add_redistributor(Redistributor<A>* r);
/**
* Remove a redistributor.
*/
void remove_redistributor(Redistributor<A>* r);
/**
* Find redistributor with given name attribute.
*/
Redistributor<A>* redistributor(const string& name);
//
// Standard RouteTable methods
//
int add_route(const IPRouteEntry<A>& route, RouteTable<A>* caller);
int delete_route(const IPRouteEntry<A>* route, RouteTable<A>* caller);
const IPRouteEntry<A>* lookup_route(const IPNet<A>& net) const;
const IPRouteEntry<A>* lookup_route(const A& addr) const;
RouteRange<A>* lookup_route_range(const A& addr) const;
TableType type() const { return REDIST_TABLE; }
RouteTable<A>* parent() { return _parent; }
void replumb(RouteTable<A>* old_parent, RouteTable<A>* new_parent);
string str() const;
/**
* Get nets of live routes seen by RedistTable since it was
* instantiated.
*/
const RouteIndex& route_index() const { return _rt_index; }
protected:
RouteTable<A>* _parent; // Immediately upstream table. May
// differ from _from_table if a
// Deletion table or another redist
// table has been plumbed in.
RouteIndex _rt_index;
list<Redistributor<A>*> _outputs;
};
/**
* Controller class that takes routes from RedistTable and passes them
* on via RedistOutput.
*
* Instances of this class are constructed when one routing protocol
* requests route distribution from another. Instances walk the
* routes available in the RedistTable route index, resolve them, and
* announce them via the RedistOutput. Future updates received
* from the RedistTable are propagated via the Redistributor instances
* associated with it.
*/
template <typename A>
class Redistributor
{
public:
class RedistEventInterface {
// Methods only available to RedistTable.
void did_add(const IPRouteEntry<A>& ipr);
void will_delete(const IPRouteEntry<A>& ipr);
void did_delete(const IPRouteEntry<A>& ipr);
friend class RedistTable<A>;
friend class Redistributor<A>;
public:
RedistEventInterface(Redistributor<A>* r) : _r(r) {}
private:
Redistributor<A>* _r;
};
class OutputEventInterface {
// Methods only available to RedistOutput. These are
// events it can tell us about.
void low_water();
void high_water();
void fatal_error();
friend class RedistOutput<A>;
friend class Redistributor<A>;
public:
OutputEventInterface(Redistributor<A>* r) : _r(r) {}
private:
Redistributor<A>* _r;
};
public:
Redistributor(EventLoop& e, const string& name);
virtual ~Redistributor();
const string& name() const;
void set_redist_table(RedistTable<A>* rt);
/**
* Bind RedistOutput to Redistributor instance. The output
* should be dynamically allocated with new. When a new
* redistributor output is set, the existing output is removed via
* delete. The RedistOutput is deleted by the
* Redistributor when the Redistributor is destructed.
*/
void set_output(RedistOutput<A>* output);
/**
* Bind policy object to Redistributor instance. The policy
* should be dynamically allocated with new. When a new policy is
* set, the existing policy is removed via delete. The policy is
* deleted by the Redistributor when the Redistributor is
* destructed.
*/
void set_policy(RedistPolicy<A>* policy);
/**
* Determine if policy accepts updates to route.
*
* @return true if associated property accepts update to route or
* if no policy is enforced, false otherwise.
*/
bool policy_accepts(const IPRouteEntry<A>& ipr) const;
/**
* Method available to instances of RedistTable to announce events
* to the Redistributor instance.
*/
RedistEventInterface& redist_event() { return _rei; }
/**
* Method available to instances of RedistOutput to
* announce transport events to the Redistributor instance.
*/
OutputEventInterface& output_event() { return _oei; }
/**
* Indicate dump status. When Redistributor is first connected it dumps
* existing routes to it's RedistOutput.
*
* @return true if route dump is in process, false if route dump is
* either not started or finished.
*/
bool dumping() const { return _dumping; }
private:
/**
* Start initial route dump when a RedistTable is associated with instance
* through set_redist_table().
*/
void start_dump();
void finish_dump();
void schedule_dump_timer();
void unschedule_dump_timer();
void dump_a_route();
const IPNet<A>& last_dumped_net() const { return _last_net; }
RedistTable<A>* redist_table() { return _table; }
RedistOutput<A>* output() { return _output; }
private:
// The following are not implemented
Redistributor(const Redistributor<A>&);
Redistributor<A>& operator=(const Redistributor<A>&);
// These are nested classes and need to be friends to invoke methods in
// enclosing class.
friend class RedistEventInterface;
friend class OutputEventInterface;
private:
EventLoop& _e;
string _name;
RedistTable<A>* _table;
RedistOutput<A>* _output;
RedistPolicy<A>* _policy;
RedistEventInterface _rei;
OutputEventInterface _oei;
bool _dumping; // Announcing existing routes
bool _blocked; // Output above high water
IPNet<A> _last_net; // Last net announced
XorpTimer _dtimer;
static const IPNet<A> NO_LAST_NET; // Indicator for last net inval
};
/**
* Base class for propagaing output of route add and delete messages.
*/
template <typename A>
class RedistOutput
{
public:
RedistOutput(Redistributor<A>* r);
virtual ~RedistOutput();
virtual void add_route(const IPRouteEntry<A>& ipr) = 0;
virtual void delete_route(const IPRouteEntry<A>& ipr) = 0;
/**
* Method called by Redistributor to indicate start of initial
* route dump. This occurs when an output is first attached to
* the redistributor to announce the existing routes.
*/
virtual void starting_route_dump() = 0;
/**
* Method called by Redistributor to indicate end of initial
* route dump. This occurs when an output is first attached to
* the redistributor to announce the existing routes.
*/
virtual void finishing_route_dump() = 0;
protected:
void announce_low_water() { _r->output_event().low_water(); }
void announce_high_water() { _r->output_event().high_water(); }
void announce_fatal_error() { _r->output_event().fatal_error(); }
private:
// The following are not implemented
RedistOutput(const RedistOutput<A>&);
RedistOutput<A>& operator=(const RedistOutput<A>&);
private:
Redistributor<A>* _r;
};
// ----------------------------------------------------------------------------
// Inline RedistTable methods
template <typename A>
inline bool
RedistNetCmp<A>::operator() (const IPNet<A>& l, const IPNet<A>& r) const
{
if (l.prefix_len() != r.prefix_len())
return l.prefix_len() < r.prefix_len();
return l.masked_addr() < r.masked_addr();
}
#endif // __RIB_RT_TAB_REDIST_HH__
Generated by: pavlin on kobe.xorp.net on Wed Jan 7 19:11:09 2009, using kdoc 2.0a54+XORP.