xorp

rt_tab_base.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2009 XORP, Inc.
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License, Version 2, June
00008 // 1991 as published by the Free Software Foundation. Redistribution
00009 // and/or modification of this program under the terms of any other
00010 // version of the GNU General Public License is not permitted.
00011 // 
00012 // This program is distributed in the hope that it will be useful, but
00013 // WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00015 // see the GNU General Public License, Version 2, a copy of which can be
00016 // found in the XORP LICENSE.gpl file.
00017 // 
00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00019 // http://xorp.net
00020 
00021 // $XORP: xorp/rib/rt_tab_base.hh,v 1.25 2008/10/02 21:58:12 bms Exp $
00022 
00023 #ifndef __RIB_RT_TAB_BASE_HH__
00024 #define __RIB_RT_TAB_BASE_HH__
00025 
00026 #include "libxorp/xorp.h"
00027 
00028 #include "route.hh"
00029 #include "protocol.hh"
00030 #include "libxorp/trie.hh"
00031 
00032 enum TableType {
00033     ORIGIN_TABLE        = 1 << 0,
00034     MERGED_TABLE        = 1 << 1,
00035     EXTINT_TABLE        = 1 << 2,
00036     REDIST_TABLE        = 1 << 3,
00037     REGISTER_TABLE      = 1 << 4,
00038     DELETION_TABLE      = 1 << 5,
00039     EXPECT_TABLE        = 1 << 6,
00040     LOG_TABLE           = 1 << 7,
00041     POLICY_REDIST_TABLE     = 1 << 8,
00042     POLICY_CONNECTED_TABLE  = 1 << 9,
00043     MAX_TABLE_TYPE      = 1 << 9
00044 };
00045 
00069 template<class A>
00070 class RouteRange {
00071 public:
00072     RouteRange(const A& req_addr, const IPRouteEntry<A>* route,
00073            const A& top, const A& bottom)
00074     : _req_addr(req_addr), _route(route), _top(top), _bottom(bottom) {}
00075 
00076     const A& top() const            { return _top;      }
00077     const A& bottom() const         { return _bottom;   }
00078     const IPRouteEntry<A>* route() const    { return _route;    }
00079     const IPNet<A>& net() const         { return _route->net(); }
00080 
00089     void merge(const RouteRange* his_rr)    {
00090         const IPRouteEntry<A>* rrr = his_rr->route();
00091 
00092         if (_route == NULL)
00093         _route = rrr;
00094         else if (rrr != NULL) {
00095         int my_prefix_len = net().prefix_len();
00096         int his_prefix_len = his_rr->net().prefix_len();
00097         if (his_prefix_len > my_prefix_len) // his route beats mine
00098             _route = rrr;
00099         else if (his_prefix_len == my_prefix_len) {
00100             // routes are equivalent, compare distance
00101             if (_route->admin_distance() >
00102                 rrr->admin_distance()) // his is better
00103             _route = rrr;
00104             // note: if routes have same admin distance, mine wins.
00105         }
00106         }
00107 
00108         if (_top > his_rr->top())   // he wins, shrink _top
00109         _top = his_rr->top();
00110         if (_bottom < his_rr->bottom()) // he wins, shrink _bottom
00111         _bottom = his_rr->bottom();
00112     }
00113 
00114     // Return the largest subnet contained in the range.
00115     IPNet<A> minimal_subnet() const {
00116         for (size_t bits = 0; bits <= A::addr_bitlen(); bits++) {
00117         IPNet<A> net(_req_addr, bits);
00118         if (net.masked_addr() >= _bottom && net.top_addr() <= _top)
00119             return net; // we got it.
00120         }
00121         XLOG_UNREACHABLE();
00122     }
00123 
00124 private:
00125     A   _req_addr;
00126     const IPRouteEntry<A>* _route;
00127     A   _top;
00128     A   _bottom;
00129 };
00130 
00154 template<class A>
00155 class RouteTable {
00156 public:
00157     RouteTable(const string& name) : _tablename(name), _next_table(NULL) {}
00158     virtual ~RouteTable();
00159 
00160     virtual int add_route(const IPRouteEntry<A>& route,
00161               RouteTable*        caller) = 0;
00162 
00163     virtual int delete_route(const IPRouteEntry<A>* route,
00164                  RouteTable*        caller) = 0;
00165 
00166     virtual const IPRouteEntry<A>* lookup_route(const IPNet<A>& net) const = 0;
00167 
00168     virtual const IPRouteEntry<A>* lookup_route(const A& addr) const = 0;
00169 
00170     virtual RouteRange<A>* lookup_route_range(const A& addr) const = 0;
00171 
00172     virtual void set_next_table(RouteTable* next_table);
00173 
00174     // parent is only supposed to be called on single-parent tables
00175     virtual RouteTable* parent() { XLOG_UNREACHABLE(); return NULL; }
00176 
00177     virtual TableType type() const = 0;
00178     virtual void replumb(RouteTable* old_parent, RouteTable* new_parent) = 0;
00179     virtual string str() const = 0;
00180     virtual void flush() {}
00181 
00182     const string& tablename() const     { return _tablename; }
00183     RouteTable* next_table()            { return _next_table; }
00184     const RouteTable* next_table() const    { return _next_table; }
00185 
00186     // this call should be received and dealt with by the PolicyRedistTable. 
00187     virtual void replace_policytags(const IPRouteEntry<A>& route,
00188                     const PolicyTags& prevtags,
00189                     RouteTable* caller);
00190 
00191 protected:
00192     void set_tablename(const string& s) { _tablename = s; }
00193 
00194 private:
00195     string  _tablename;
00196     RouteTable* _next_table;
00197 };
00198 
00199 #endif // __RIB_RT_TAB_BASE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations