Source: ../../bgp/route_table_aggregation.hh


 
LOGO
 Annotated List  Files  Globals  Hierarchy  Index  Top
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-

// Copyright (c) 2001-2006 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.

// $XORP: xorp/bgp/route_table_aggregation.hh,v 1.11 2006/03/16 00:03:32 pavlin Exp $

#ifndef __BGP_ROUTE_TABLE_AGGREGATION_HH__
#define __BGP_ROUTE_TABLE_AGGREGATION_HH__

#include "peer_handler.hh"
#include "route_table_base.hh"
#include "libxorp/ref_trie.hh"


/**
 * @short classes used for BGP prefix aggregation.
 *
 * The main aggregation processing occurs and all the state is kept
 * in an AggregationTable stage that is plumbed between the decission
 * and fanout tables.  Additionally, static filters immediately following
 * the fanout table may filter out certain routes marked by the
 * AggregationTable, depending on whether the outbound branch is of IBGP
 * or EBGP type.
 *                                              +---------+
 *                                            ->| Filters |->IBGP...
 *  \                                        /  +---------+
 *   ->+-----------+  +--------+  +--------+/   +---------+
 *  -->| Decission |->| Aggreg.|->| Fanout |--->| Filters |->IBGP...
 *   ->+-----------+  +--------+  +--------+\   +---------+
 *  /                                        \  +---------+
 *                    Processing,             ->| Filters |->EBGP...
 *                     state,                   +---------+
 *                     marking                 Static filters
 * 
 * Routes can be marked as candidates for aggregation using the generic
 * policy framework before they enter the Aggregation stage.  Routes not
 * marked for aggregation, or those improperly marked, will be
 * propagated through both the aggregation and static filtering stages
 * without any processing whatsoever, regardless on the downstream
 * peering type (IBGP or EBGP). 
 *
 * Routes that can trigger instantiation of an aggregate route (those
 * that have been properly marked) will be copied and copies stored in
 * the AggregationTable for further processing.  Regardless of the
 * outcome of the aggregation processing, every original route will be
 * marked as IBGP_ONLY and propagated downstream.  Filtering stages
 * residing on IBGP paths will propagate such routes further downstream,
 * while on EBGP paths all routes marked as IBGP_ONLY will be discarded.
 *
 * In addition to original routes marked as described in the previous
 * paragraph, the AggregationStage can emit both the aggregate and
 * copies of the original routes.  Any such routes will be marked with
 * an appropriate EBGP_ONLY_* marker, instructing the filtering stages
 * on IBGP branches to unconditionally drop them.  On EBGP branches...
 *
 *
 * Open issues:
 *
 * - return values for add/delete/replace routes
 *
 * - aggregate route tagging / dumping when a new EBGP peering comes up
 *
 * - {de|re}aggragetion of large aggregates -> timer based vs. atomic
 */

class XrlStdRouter;

template<class A>
class DumpIterator;

template<class A>
class AggregationTable;

template<class A>
class ComponentRoute {
public:
    ComponentRoute(const SubnetRoute<A>* route,
		   const PeerHandler *origin,
		   uint32_t genid,
		   bool from_previous_peering) : _routeref(route) {
	_origin_peer = origin;
	_genid = genid;
	_from_previous_peering = from_previous_peering;
    }
    const SubnetRoute<A>* route() const { return _routeref.route(); }
    const PeerHandler* origin_peer() const { return _origin_peer; }
    uint32_t genid() const { return _genid; }
    bool from_previous_peering() const { return _from_previous_peering; }
private:
    SubnetRouteConstRef<A> _routeref;
    const PeerHandler *_origin_peer;
    uint32_t _genid;
    bool _from_previous_peering;
};


template<class A>
class AggregateRoute {
public:
    AggregateRoute(IPNet<A> net,
		   bool brief_mode,
		   IPv4 bgp_id,
		   AsNum asnum)
        : _net(net), _brief_mode(brief_mode),
	  _was_announced(0), _is_suppressed(0) {
	    NextHopAttribute<A> nhatt(A::ZERO());
	    AsPath aspath;
	    OriginAttribute igp_origin_att(IGP);
	_pa_list = new PathAttributeList<A>(nhatt, aspath, igp_origin_att);
	_pa_list->rehash();
	_aggregator_attribute = new AggregatorAttribute(bgp_id, asnum);
    }
    ~AggregateRoute() {
	if (_components_table.begin() != _components_table.end())
	    XLOG_WARNING("ComponentsTable trie was not empty on deletion\n");
	delete _pa_list;
	delete _aggregator_attribute;
    }
    inline const PathAttributeList<A> *pa_list() const { return _pa_list; }
    inline const IPNet<A> net() const { return _net; }
    inline const bool was_announced() const { return _was_announced; }
    inline const bool is_suppressed() const { return _is_suppressed; }
    inline const bool brief_mode() const { return _brief_mode; }
    inline void was_announced(bool value) { _was_announced = value; }
    inline void is_suppressed(bool value) { _is_suppressed = value; }
    inline void brief_mode(bool value) { _brief_mode = value; }
    void reevaluate(AggregationTable<A> *parent);
    RefTrie<A, const ComponentRoute<A> > *components_table() {
	return &_components_table;
    }

private:
    const IPNet<A> _net;
    bool _brief_mode;
    AggregatorAttribute *_aggregator_attribute;

    RefTrie<A, const ComponentRoute<A> > _components_table;
    PathAttributeList<A> *_pa_list;
    bool _was_announced;
    bool _is_suppressed;
};


template<class A>
class AggregationTable : public BGPRouteTable<A>  {
public:
    AggregationTable(string tablename,
		     BGPPlumbing& master,
		     BGPRouteTable<A> *parent);
    ~AggregationTable();
    int add_route(const InternalMessage<A> &rtmsg,
                  BGPRouteTable<A> *caller);
    int replace_route(const InternalMessage<A> &old_rtmsg,
                      const InternalMessage<A> &new_rtmsg,
                      BGPRouteTable<A> *caller);
    int delete_route(const InternalMessage<A> &rtmsg,
                     BGPRouteTable<A> *caller);
    int push(BGPRouteTable<A> *caller);

    bool dump_next_route(DumpIterator<A>& dump_iter);
    int route_dump(const InternalMessage<A> &rtmsg,
		   BGPRouteTable<A> *caller,
		   const PeerHandler *dump_peer);

    const SubnetRoute<A> *lookup_route(const IPNet<A> &net,
                                       uint32_t& genid) const;
    void route_used(const SubnetRoute<A>* route, bool in_use);

    RouteTableType type() const {return AGGREGATION_TABLE;}
    string str() const;

    /* mechanisms to implement flow control in the output plumbing */
    bool get_next_message(BGPRouteTable<A> *next_table);

    int route_count() const {
        return _aggregates_table.route_count(); // XXX is this OK?
    }

    void peering_went_down(const PeerHandler *peer, uint32_t genid,
                           BGPRouteTable<A> *caller);
    void peering_down_complete(const PeerHandler *peer, uint32_t genid,
                               BGPRouteTable<A> *caller);
    void peering_came_up(const PeerHandler *peer, uint32_t genid,
                         BGPRouteTable<A> *caller);

private:
    friend class AggregateRoute<A>;

    RefTrie<A, const AggregateRoute<A> > _aggregates_table;
    BGPPlumbing& _master_plumbing;
};


class AggregationHandler : public PeerHandler {
public:
    AggregationHandler();

    virtual PeerType get_peer_type() const {
	return PEER_TYPE_INTERNAL;
    }                                                                           

    const uint32_t get_unique_id() const { return _fake_unique_id; }
    virtual bool originate_route_handler() const { return true; }
    const uint32_t _fake_unique_id;
};


#endif // __BGP_ROUTE_TABLE_AGGREGATION_HH__

Generated by: pavlin on possum.icir.org on Wed Aug 2 15:36:33 2006, using kdoc $.