xorp

rib.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-2011 XORP, Inc and Others
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 
00022 #ifndef __RIB_RIB_HH__
00023 #define __RIB_RIB_HH__
00024 
00025 
00026 
00027 
00028 
00029 #include "libxorp/xorp.h"
00030 #include "libxorp/ipv4.hh"
00031 #include "libxorp/ipv6.hh"
00032 #include "libxorp/ipnet.hh"
00033 #include "libxorp/nexthop.hh"
00034 #include "libxorp/vif.hh"
00035 
00036 #include "route.hh"
00037 #include "rt_tab_base.hh"
00038 #include "rt_tab_origin.hh"
00039 #include "rt_tab_merged.hh"
00040 #include "rt_tab_extint.hh"
00041 #include "rt_tab_redist.hh"
00042 #include "rt_tab_pol_redist.hh"
00043 #include "rt_tab_register.hh"
00044 #include "rt_tab_pol_conn.hh"
00045 
00046 #include "policy/backend/policytags.hh"
00047 #include "policy/backend/policy_redist_map.hh"
00048 
00049 class RegisterServer;
00050 class RibManager;
00051 class RibVif;
00052 
00053 enum RibTransportType {
00054     UNICAST = 1,
00055     MULTICAST   = 2
00056 };
00057 
00058 enum RibVerifyType {
00059     MISS    = 0,    // No route to destination
00060     DISCARD = 1,    // Discard route for destination
00061     UNREACHABLE = 2,    // Unreachable route for destination
00062     IP      = 3 // Protocol route to destination
00063 };
00064 
00076 template<class A>
00077 class RIB :
00078     public NONCOPYABLE
00079 {
00080 public:
00091     RIB(RibTransportType rib_type, RibManager& rib_manager,
00092     EventLoop& eventloop);
00093 
00097     virtual ~RIB();
00098 
00102     void set_errors_are_fatal() { _errors_are_fatal = true; }
00103 
00109     list<string> registered_protocol_names() const;
00110 
00118     void initialize(RegisterServer& register_server);
00119 
00131     int initialize_redist_all(const string& all);
00132 
00141     int initialize_policy_redist();
00142 
00153     int initialize_register(RegisterServer& register_server);
00154 
00170     int new_origin_table(const string&  tablename,
00171              const string&  target_class,
00172              const string&  target_instance,
00173              uint32_t   admin_distance,
00174              ProtocolType   protocol_type);
00175 
00185     virtual int new_vif(const string& vifname, const Vif& vif);
00186 
00193     virtual int delete_vif(const string& vifname);
00194 
00200     virtual void destroy_deleted_vif(RibVif* rib_vif);
00201 
00215     virtual int set_vif_flags(const string& vifname,
00216                   bool is_p2p,
00217                   bool is_loopback,
00218                   bool is_multicast,
00219                   bool is_broadcast,
00220                   bool is_up,
00221                   uint32_t mtu);
00222 
00237     virtual int add_vif_address(const string&   vifname,
00238                 const A&    addr,
00239                 const IPNet<A>& subnet,
00240                 const A&    broadcast_addr,
00241                 const A&    peer_addr);
00242 
00250     virtual int delete_vif_address(const string& vifname, const A& addr);
00251 
00262     int add_connected_route(const RibVif&   vif,
00263                 const IPNet<A>& net,
00264                 const A&        nexthop_addr,
00265                 const A&        peer_addr);
00266 
00276     int delete_connected_route(const RibVif&    vif,
00277                    const IPNet<A>&  net,
00278                    const A&     peer_addr);
00279 
00296     virtual int add_route(const string&     tablename,
00297               const IPNet<A>&   net,
00298               const A&      nexthop_addr,
00299               const string&     ifname,
00300               const string&     vifname,
00301               uint32_t      metric,
00302               const PolicyTags& policytags);
00303 
00321     virtual int replace_route(const string& tablename,
00322                   const IPNet<A>&   net,
00323                   const A&      nexthop_addr,
00324                   const string& ifname,
00325                   const string& vifname,
00326                   uint32_t      metric,
00327                   const PolicyTags& policytags);
00328 
00341     virtual int verify_route(const A&       lookupaddr,
00342                  const string&  ifname,
00343                  const A&       nexthop_addr,
00344                  uint32_t       metric,
00345                  RibVerifyType  matchtype);
00346 
00356     virtual int delete_route(const string&   tablename,
00357                  const IPNet<A>& subnet);
00358 
00367     virtual const A& lookup_route(const A& lookupaddr);
00368 
00372     virtual RouteRange<A>* route_range_lookup(const A& lookupaddr);
00373 
00383     virtual RouteRegister<A>* route_register(const A&      lookupaddr,
00384                          const string& module);
00385 
00397     virtual int route_deregister(const IPNet<A>& subnet, const string& module);
00398 
00405     Protocol* find_protocol(const string& protocol);
00406 
00410     RedistTable<A>* protocol_redist_table(const string& protocol);
00411 
00426     virtual int add_igp_table(const string& tablename,
00427                   const string& target_class,
00428                   const string& target_instance);
00429 
00443     virtual int delete_igp_table(const string& tablename,
00444                  const string& target_class,
00445                  const string& target_instance);
00446 
00462     virtual int add_egp_table(const string& tablename,
00463                   const string& target_class,
00464                   const string& target_instance);
00465 
00479     virtual int delete_egp_table(const string& tablename,
00480                  const string& target_class,
00481                  const string& target_instance);
00482 
00490     void target_death(const string& target_class,
00491               const string& target_instance);
00492 
00496     void print_rib() const;
00497 
00501     string name() const;
00502 
00506     void push_routes();
00507 
00516     int set_protocol_admin_distance(const string& protocol_name,
00517                     const uint32_t& admin_distance);
00518 
00524     map<string, uint32_t>& get_protocol_admin_distances() {
00525     return _admin_distances;
00526     }
00527 
00535     uint32_t get_protocol_admin_distance(const string& protocol_name);
00536 
00537 private:
00549     int add_origin_table(const string& tablename,
00550              const string& target_class,
00551              const string& target_instance,
00552              ProtocolType  protocol_type);
00553 
00564     int delete_origin_table(const string& tablename,
00565                 const string& target_class,
00566                 const string& target_instance);
00567 
00576     int add_policy_connected_table(const string& origin_tablename);
00577 
00585     int add_redist_table(const string& origin_tablename);
00586 
00599     RouteTable<A>* track_back(RouteTable<A>* rt, int typemask) const;
00600 
00612     RouteTable<A>* track_forward(RouteTable<A>* rt, int typemask) const;
00613 
00620     RouteTable<A>* find_table(const string& tablename);
00621 
00631     OriginTable<A>* find_table_by_instance(const string& tablename,
00632                        const string& target_class,
00633                        const string& target_instance);
00634 
00645     int add_table(RouteTable<A>* table);
00646 
00654     int remove_table(const string& tablename);
00655 
00663     RibVif* find_vif(const A& addr);
00664 
00672     IPExternalNextHop<A>* find_external_nexthop(const A& addr);
00673 
00681     IPPeerNextHop<A>* find_peer_nexthop(const A& addr);
00682 
00690     IPExternalNextHop<A>* find_or_create_external_nexthop(const A& addr);
00691 
00699     IPPeerNextHop<A>* find_or_create_peer_nexthop(const A& addr);
00700 
00704     void flush();
00705 
00706 protected:
00707     RibManager&     _rib_manager;
00708     EventLoop&      _eventloop;
00709     RouteTable<A>*  _final_table;
00710     RegisterTable<A>*   _register_table;
00711 
00712     bool        _multicast;
00713     bool        _errors_are_fatal;
00714 
00715     PolicyRedistTable<A>*       _policy_redist_table;
00716 
00717     list<RouteTable<A>* >       _tables;
00718     map<string, Protocol* >     _protocols;
00719     map<string, OriginTable<A>* >   _routing_protocol_instances;
00720     map<string, RibVif*>        _vifs;
00721     map<string, RibVif*>        _deleted_vifs;
00722     map<string, uint32_t>       _admin_distances;
00723     map<A, IPExternalNextHop<A> >   _external_nexthops;
00724     map<A, IPPeerNextHop<A> >       _peer_nexthops;
00725 };
00726 
00727 typedef RIB<IPv4> IPv4RIB;
00728 #ifdef HAVE_IPV6
00729 typedef RIB<IPv6> IPv6RIB;
00730 #endif
00731 
00732 class RibVif : public Vif {
00733 public:
00734     RibVif(RIB<IPv4>* rib, const Vif& vif)
00735     : Vif(vif), _rib4(rib),
00736 #ifdef HAVE_IPV6
00737       _rib6(NULL),
00738 #endif
00739       _usage_counter(0),
00740       _is_deleted(false)
00741     {}
00742 #ifdef HAVE_IPV6
00743     RibVif(RIB<IPv6>* rib, const Vif& vif)
00744     : Vif(vif), _rib4(NULL), _rib6(rib), _usage_counter(0),
00745       _is_deleted(false)
00746     {}
00747 #endif
00748 
00749     ~RibVif() {}
00750 
00751     size_t copy_in(const Vif& from_vif) {
00752     Vif* to_vif = this;
00753     *to_vif = from_vif;
00754     return (sizeof(from_vif));
00755     }
00756 
00757     void set_deleted(bool v) { _is_deleted = v; }
00758 
00759     uint32_t usage_counter() const { return (_usage_counter); }
00760     void incr_usage_counter() { _usage_counter++; }
00761     void decr_usage_counter() {
00762     _usage_counter--;
00763     if (_is_deleted && (_usage_counter == 0)) {
00764         if (_rib4 != NULL) {
00765         _rib4->destroy_deleted_vif(this);
00766         return;
00767         }
00768 #ifdef HAVE_IPV6
00769         if (_rib6 != NULL) {
00770         _rib6->destroy_deleted_vif(this);
00771         return;
00772         }
00773 #endif
00774     }
00775     }
00776 
00777 private:
00778     //
00779     // XXX: This is a hack that we have two RIB pointers, when one should
00780     // be sufficient. It is to avoid templatization of this class, otherwise
00781     // the generic RouteEntry also needs to become a template.
00782     //
00783     RIB<IPv4>*  _rib4;
00784 #ifdef HAVE_IPV6
00785     RIB<IPv6>*  _rib6;
00786 #endif
00787     uint32_t    _usage_counter;
00788     bool    _is_deleted;
00789 };
00790 
00791 #endif // __RIB_RIB_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations