xorp

static_routes_node.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 // $XORP: xorp/static_routes/static_routes_node.hh,v 1.32 2008/10/02 21:58:29 bms Exp $
00022 
00023 #ifndef __STATIC_ROUTES_STATIC_ROUTES_NODE_HH__
00024 #define __STATIC_ROUTES_STATIC_ROUTES_NODE_HH__
00025 
00026 
00027 //
00028 // StaticRoutes node definition.
00029 //
00030 
00031 
00032 
00033 #include "libxorp/service.hh"
00034 #include "libxorp/status_codes.h"
00035 
00036 #include "libfeaclient/ifmgr_xrl_mirror.hh"
00037 
00038 #include "policy/backend/policytags.hh"
00039 #include "policy/backend/policy_filters.hh"
00040 
00041 class EventLoop;
00042 
00048 class StaticRoute {
00049 public:
00067     StaticRoute(bool unicast, bool multicast,
00068         const IPv4Net& network, const IPv4& nexthop,
00069         const string& ifname, const string& vifname,
00070         uint32_t metric, bool is_backup_route)
00071     : _unicast(unicast), _multicast(multicast),
00072       _network(network), _nexthop(nexthop),
00073       _ifname(ifname), _vifname(vifname),
00074       _metric(metric), _is_backup_route(is_backup_route),
00075       _route_type(IDLE_ROUTE), _is_ignored(false),
00076       _is_filtered(false), _is_accepted_by_nexthop(false) {}
00077 
00078 #ifdef XORP_USE_USTL
00079     StaticRoute() { }
00080 #endif
00081 
00099     StaticRoute(bool unicast, bool multicast,
00100         const IPv6Net& network, const IPv6& nexthop,
00101         const string& ifname, const string& vifname,
00102         uint32_t metric, bool is_backup_route)
00103     : _unicast(unicast), _multicast(multicast),
00104       _network(network), _nexthop(nexthop),
00105       _ifname(ifname), _vifname(vifname),
00106       _metric(metric), _is_backup_route(is_backup_route),
00107       _route_type(IDLE_ROUTE), _is_ignored(false),
00108       _is_filtered(false), _is_accepted_by_nexthop(false) {}
00109 
00117     bool operator==(const StaticRoute& other) const {
00118     return (is_same_route(other)
00119         && (_route_type == other._route_type)
00120         && (_policytags == other._policytags));
00121     }
00122 
00130     bool is_same_route(const StaticRoute& other) const {
00131     return ((_unicast == other.unicast())
00132         && (_multicast == other.multicast())
00133         && (_network == other.network())
00134         && (_nexthop == other.nexthop())
00135         && (_ifname == other.ifname())
00136         && (_vifname == other.vifname())
00137         && (_metric == other.metric()));
00138     }
00139 
00145     bool is_ipv4() const { return _network.is_ipv4(); }
00146 
00152     bool is_ipv6() const { return _network.is_ipv6(); }
00153 
00160     bool unicast() const { return _unicast; }
00161 
00168     bool multicast() const { return _multicast; }
00169 
00175     const IPvXNet& network() const { return _network; }
00176 
00182     const IPvX& nexthop() const { return _nexthop; }
00183 
00189     void set_nexthop(const IPvX& v) { _nexthop = v; }
00190 
00196     const string& ifname() const { return _ifname; }
00197 
00203     void set_ifname(const string& v) { _ifname = v; }
00204 
00210     const string& vifname() const { return _vifname; }
00211 
00217     void set_vifname(const string& v) { _vifname = v; }
00218 
00224     uint32_t metric() const { return _metric; }
00225 
00231     bool is_backup_route() const { return _is_backup_route; }
00232 
00238     bool is_add_route() const { return (_route_type == ADD_ROUTE); }
00239 
00245     bool is_replace_route() const { return (_route_type == REPLACE_ROUTE); }
00246 
00252     bool is_delete_route() const { return (_route_type == DELETE_ROUTE); }
00253 
00257     void set_add_route() { _route_type = ADD_ROUTE; }
00258 
00262     void set_replace_route() { _route_type = REPLACE_ROUTE; }
00263 
00267     void set_delete_route() { _route_type = DELETE_ROUTE; }
00268 
00275     bool is_interface_route() const { return ! (_ifname.empty()
00276                         && _vifname.empty()); }
00277 
00284     bool is_valid_entry(string& error_msg) const;
00285 
00294     bool is_ignored() const { return _is_ignored; }
00295 
00304     void set_ignored(bool v) { _is_ignored = v; }
00305 
00309     PolicyTags& policytags() { return _policytags; }
00310 
00317     bool is_filtered() const { return _is_filtered; }
00318 
00326     void set_filtered(bool v) { _is_filtered = v; }
00327 
00334     bool is_accepted_by_nexthop() const { return _is_accepted_by_nexthop; }
00335 
00343     void set_accepted_by_nexthop(bool v) { _is_accepted_by_nexthop = v; }
00344 
00351     bool is_accepted_by_rib() const;
00352 
00353 private:
00354     bool    _unicast;
00355     bool    _multicast;
00356     IPvXNet _network;
00357     IPvX    _nexthop;
00358     string  _ifname;
00359     string  _vifname;
00360     uint32_t    _metric;
00361     bool    _is_backup_route;
00362     enum RouteType { IDLE_ROUTE, ADD_ROUTE, REPLACE_ROUTE, DELETE_ROUTE };
00363     RouteType   _route_type;
00364     bool    _is_ignored;    // True if the route is to be ignored
00365     bool    _is_filtered;   // True if rejected by a policy filter
00366     bool    _is_accepted_by_nexthop; // True if the route is accepted based on its next-hop information
00367     PolicyTags  _policytags;
00368 };
00369 
00370 
00376 class StaticRoutesNode : public IfMgrHintObserver,
00377              public ServiceBase,
00378              public ServiceChangeObserverBase {
00379 public:
00380     typedef multimap<IPvXNet, StaticRoute> Table;
00381 
00387     StaticRoutesNode(EventLoop& eventloop);
00388 
00392     virtual ~StaticRoutesNode();
00393 
00399     EventLoop&  eventloop() { return _eventloop; }
00400 
00406     const string& protocol_name() const { return _protocol_name; }
00407 
00413     int startup();
00414 
00420     int shutdown();
00421 
00429     ProcessStatus   node_status(string& reason_msg);
00430 
00436     bool    is_done() const { return (_node_status == PROC_DONE); }
00437 
00443     bool    is_enabled() const { return _is_enabled; }
00444 
00454     void    set_enabled(bool enable);
00455     
00475     int add_route4(bool unicast, bool multicast,
00476            const IPv4Net& network, const IPv4& nexthop,
00477            const string& ifname, const string& vifname,
00478            uint32_t metric, bool is_backup_route, string& error_msg);
00479 
00499     int add_route6(bool unicast, bool multicast,
00500            const IPv6Net& network, const IPv6& nexthop,
00501            const string& ifname, const string& vifname,
00502            uint32_t metric, bool is_backup_route, string& error_msg);
00503 
00523     int replace_route4(bool unicast, bool multicast,
00524                const IPv4Net& network, const IPv4& nexthop,
00525                const string& ifname, const string& vifname,
00526                uint32_t metric, bool is_backup_route,
00527                string& error_msg);
00528 
00548     int replace_route6(bool unicast, bool multicast,
00549                const IPv6Net& network, const IPv6& nexthop,
00550                const string& ifname, const string& vifname,
00551                uint32_t metric, bool is_backup_route,
00552                string& error_msg);
00553 
00572     int delete_route4(bool unicast, bool multicast, const IPv4Net& network,
00573               const IPv4& nexthop, const string& ifname,
00574               const string& vifname, bool is_backup_route,
00575               string& error_msg);
00576 
00595     int delete_route6(bool unicast, bool multicast, const IPv6Net& network,
00596               const IPv6& nexthop, const string& ifname,
00597               const string& vifname, bool is_backup_route,
00598               string& error_msg);
00599 
00608     StaticRoutesNode::Table::iterator find_route(
00609     StaticRoutesNode::Table& table,
00610     const StaticRoute& key_route);
00611 
00620     StaticRoutesNode::Table::iterator find_best_accepted_route(
00621     StaticRoutesNode::Table& table,
00622     const StaticRoute& key_route);
00623 
00624     //
00625     // Debug-related methods
00626     //
00627     
00635     bool    is_log_trace() const { return (_is_log_trace); }
00636     
00644     void    set_log_trace(bool is_enabled) { _is_log_trace = is_enabled; }
00645 
00656     void configure_filter(const uint32_t& filter, const string& conf);
00657 
00663     void reset_filter(const uint32_t& filter);
00664 
00668     void push_routes();
00669 
00675     void push_pull_rib_routes(bool is_push);
00676 
00677 
00678 protected:
00679     //
00680     // IfMgrHintObserver methods
00681     //
00682     void tree_complete();
00683     void updates_made();
00684 
00685     void incr_startup_requests_n();
00686     void decr_startup_requests_n();
00687     void incr_shutdown_requests_n();
00688     void decr_shutdown_requests_n();
00689     void update_status();
00690 
00691 private:
00699     void status_change(ServiceBase*  service,
00700                ServiceStatus old_status,
00701                ServiceStatus new_status);
00702 
00711     virtual const ServiceBase* ifmgr_mirror_service_base() const = 0;
00712 
00721     virtual const IfMgrIfTree&  ifmgr_iftree() const = 0;
00722 
00729     virtual void fea_register_startup() = 0;
00730 
00737     virtual void fea_register_shutdown() = 0;
00738 
00745     virtual void rib_register_startup() = 0;
00746 
00753     virtual void rib_register_shutdown() = 0;
00754 
00763     int add_route(const StaticRoute& static_route, string& error_msg);
00764 
00773     int replace_route(const StaticRoute& static_route, string& error_msg);
00774 
00783     int delete_route(const StaticRoute& static_route, string& error_msg);
00784 
00794     void prepare_route_for_transmission(StaticRoute& orig_route,
00795                     StaticRoute& copy_route);
00796 
00805     virtual void inform_rib_route_change(const StaticRoute& static_route) = 0;
00806 
00815     virtual void cancel_rib_route_change(const StaticRoute& static_route) = 0;
00816 
00826     bool update_route(const IfMgrIfTree& iftree, StaticRoute& route);
00827 
00834     bool do_filtering(StaticRoute& route);
00835 
00843     bool is_accepted_by_nexthop(const StaticRoute& route) const;
00844 
00850     void inform_rib(const StaticRoute& r);
00851 
00857     void set_node_status(ProcessStatus v) { _node_status = v; }
00858 
00859     EventLoop&      _eventloop;     // The event loop
00860     ProcessStatus   _node_status;       // The node/process status
00861     const string    _protocol_name;     // The protocol name
00862     bool        _is_enabled;        // Flag whether node is enabled
00863 
00864     //
00865     // The routes are stored in a multimap, because we allow more than one
00866     // route for the same subnet destination. We need this to support
00867     // floating static routes: routes to same destination but different
00868     // next-hop router and metric.
00869     //
00870     StaticRoutesNode::Table _static_routes;     // The routes
00871 
00872     // The winning routes
00873     map<IPvXNet, StaticRoute>   _winning_routes_unicast;
00874     map<IPvXNet, StaticRoute>   _winning_routes_multicast;
00875 
00876     //
00877     // Status-related state
00878     //
00879     size_t      _startup_requests_n;
00880     size_t      _shutdown_requests_n;
00881 
00882     //
00883     // A local copy with the interface state information
00884     //
00885     IfMgrIfTree     _iftree;
00886 
00887     //
00888     // Debug and test-related state
00889     //
00890     bool        _is_log_trace;      // If true, enable XLOG_TRACE()
00891 
00892     PolicyFilters   _policy_filters;    // Only one instance of this!
00893 };
00894 
00895 #endif // __STATIC_ROUTES_STATIC_ROUTES_NODE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations