xorp

xrl_io.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/ospf/xrl_io.hh,v 1.35 2008/11/14 12:44:19 bms Exp $
00022 
00023 #ifndef __OSPF_XRL_IO_HH__
00024 #define __OSPF_XRL_IO_HH__
00025 
00026 #include "libxipc/xrl_router.hh"
00027 
00028 #include "libfeaclient/ifmgr_xrl_mirror.hh"
00029 #include "policy/backend/policytags.hh"
00030 
00031 #include "io.hh"
00032 
00033 class EventLoop;
00034 template <typename A> class XrlIO;
00035 
00041 template <class A>
00042 class XrlQueue {
00043 public:
00044     XrlQueue(EventLoop& eventloop, XrlRouter& xrl_router);
00045 
00046     void set_io(XrlIO<A> *io) {
00047     _io = io;
00048     }
00049 
00050     void queue_add_route(string ribname, const IPNet<A>& net,
00051              const A& nexthop, uint32_t nexthop_id, 
00052              uint32_t metric, const PolicyTags& policytags);
00053 
00054     void queue_delete_route(string ribname, const IPNet<A>& net);
00055 
00056     bool busy();
00057 private:
00058     static const size_t WINDOW = 100;   // Maximum number of XRLs
00059                     // allowed in flight.
00060 
00061     XrlIO<A>    *_io;
00062     EventLoop& _eventloop;
00063     XrlRouter& _xrl_router;
00064 
00065     struct Queued {
00066     bool add;
00067     string ribname;
00068     IPNet<A> net;
00069     A nexthop;
00070     uint32_t nexthop_id;
00071     uint32_t metric;
00072     string comment;
00073     PolicyTags policytags;
00074     };
00075 
00076     deque <Queued> _xrl_queue;
00077     size_t _flying; //XRLs currently in flight
00078 
00082     bool maximum_number_inflight() const { return _flying >= WINDOW; }
00083 
00087     void start();
00088 
00096     bool sendit_spec(Queued& q, const char *protocol);
00097 
00098     EventLoop& eventloop() const;
00099 
00100     void route_command_done(const XrlError& error, const string comment);
00101 };
00102 
00106 template <typename A>
00107 class XrlIO : public IO<A>,
00108           public IfMgrHintObserver,
00109           public ServiceChangeObserverBase {
00110  public:
00111     XrlIO(EventLoop& eventloop, XrlRouter& xrl_router, const string& feaname,
00112       const string& ribname)
00113     : _eventloop(eventloop),
00114       _xrl_router(xrl_router),
00115       _feaname(feaname),
00116       _ribname(ribname),
00117       _component_count(0),
00118       _ifmgr(eventloop, feaname.c_str(), _xrl_router.finder_address(),
00119          _xrl_router.finder_port()),
00120       _rib_queue(eventloop, xrl_router)
00121 
00122     {
00123     _ifmgr.set_observer(this);
00124     _ifmgr.attach_hint_observer(this);
00125     _rib_queue.set_io(this);
00126     //
00127     // TODO: for now startup inside the constructor. Ideally, we want
00128     // to startup after the FEA birth event.
00129     //
00130 //  startup();
00131     }
00132 
00133     ~XrlIO() {
00134     //
00135     // TODO: for now shutdown inside the destructor. Ideally, we want
00136     // to shutdown gracefully before we call the destructor.
00137     //
00138 //  shutdown();
00139 
00140     _ifmgr.detach_hint_observer(this);
00141     _ifmgr.unset_observer(this);
00142     }
00143 
00149     int startup() {
00150     //
00151     // XXX: when the startup is completed,
00152     // IfMgrHintObserver::tree_complete() will be called.
00153     //
00154     if (_ifmgr.startup() != XORP_OK) {
00155         ServiceBase::set_status(SERVICE_FAILED);
00156         return (XORP_ERROR);
00157     }
00158 
00159     register_rib();
00160     component_up("startup");
00161 
00162     return (XORP_OK);
00163     }
00164 
00165 
00171     int shutdown() {
00172     //
00173     // XXX: when the shutdown is completed, XrlIO::status_change()
00174     // will be called.
00175     //
00176 
00177     unregister_rib();
00178     component_down("shutdown");
00179 
00180     return (_ifmgr.shutdown());
00181     }
00182 
00186     void component_up(string /*name*/) {
00187 //      fprintf(stderr, "Component: %s count %d\n", name.c_str(),
00188 //      _component_count + 1);
00189     _component_count++;
00190     // XXX - Should really get every component to register at
00191     // initialisation time and track the individual
00192     // status. Simpler to uncomment the printfs and track the count.
00193 #ifdef HAVE_IPV6
00194     if (4 == _component_count)
00195         ServiceBase::set_status(SERVICE_RUNNING);
00196 #else
00197     if (3 == _component_count)
00198         ServiceBase::set_status(SERVICE_RUNNING);
00199 #endif
00200     }
00201 
00205     void component_down(string /*name*/) {
00206 //      fprintf(stderr, "Component: %s count %d\n", name.c_str(),
00207 //      _component_count - 1);
00208     _component_count--;
00209     if (0 == _component_count)
00210         ServiceBase::set_status(SERVICE_SHUTDOWN);
00211     else
00212         ServiceBase::set_status(SERVICE_SHUTTING_DOWN);
00213     }
00214 
00218     void recv(const string& interface,
00219           const string& vif,
00220           A src,
00221           A dst,
00222           uint8_t ip_protocol,
00223           int32_t ip_ttl,
00224           int32_t ip_tos,
00225           bool ip_router_alert,
00226           bool ip_internet_control,
00227           const vector<uint8_t>& payload);
00228 
00232     bool send(const string& interface, const string& vif, 
00233           A dst, A src,
00234           int ttl, uint8_t* data, uint32_t len);
00235 
00239     bool enable_interface_vif(const string& interface, const string& vif);
00240 
00244     bool disable_interface_vif(const string& interface, const string& vif);
00245 
00252     bool is_interface_enabled(const string& interface) const;
00253 
00261     bool is_vif_enabled(const string& interface, const string& vif) const;
00262 
00271     bool is_address_enabled(const string& interface, const string& vif,
00272                 const A& address) const;
00273 
00283     bool get_addresses(const string& interface, const string& vif,
00284                list<A>& addresses) const;
00285 
00295     bool get_link_local_address(const string& interface, const string& vif,
00296                 A& address);
00297 
00305     bool get_interface_id(const string& interface, uint32_t& interface_id);
00306 
00315     uint32_t get_prefix_length(const string& interface, const string& vif,
00316                    A address);
00317 
00324     uint32_t get_mtu(const string& interface);
00325 
00329     bool join_multicast_group(const string& interface, const string& vif,
00330                   A mcast);
00331 
00335     bool leave_multicast_group(const string& interface, const string& vif,
00336                    A mcast);
00337 
00341     void register_rib();
00342 
00346     void unregister_rib();
00347 
00348     void rib_command_done(const XrlError& error, bool up, const char *comment);
00349 
00361     bool add_route(IPNet<A> net,
00362            A nexthop,
00363            uint32_t nexthop_id,
00364            uint32_t metric,
00365            bool equal,
00366            bool discard,
00367            const PolicyTags& policytags);
00368 
00380     bool replace_route(IPNet<A> net,
00381                A nexthop,
00382                uint32_t nexthop_id,
00383                uint32_t metric,
00384                bool equal,
00385                bool discard,
00386                const PolicyTags& policytags);
00387 
00391     bool delete_route(IPNet<A> net);
00392 
00393  private:
00401     void status_change(ServiceBase* service,
00402                ServiceStatus    old_status,
00403                ServiceStatus    new_status) {
00404     if (old_status == new_status)
00405         return;
00406     if (SERVICE_RUNNING == new_status)
00407         component_up(service->service_name());
00408     if (SERVICE_SHUTDOWN == new_status)
00409         component_down(service->service_name());
00410 
00411     }
00412 
00418     const ServiceBase* ifmgr_mirror_service_base() const {
00419     return dynamic_cast<const ServiceBase*>(&_ifmgr);
00420     }
00421 
00427     const IfMgrIfTree& ifmgr_iftree() const { return _ifmgr.iftree(); }
00428 
00433     void tree_complete();
00434 
00439     void updates_made();
00440 
00441     //
00442     // XRL callbacks
00443     //
00444     void send_cb(const XrlError& xrl_error, string interface, string vif);
00445     void enable_interface_vif_cb(const XrlError& xrl_error, string interface,
00446                  string vif);
00447     void disable_interface_vif_cb(const XrlError& xrl_error, string interface,
00448                   string vif);
00449     void join_multicast_group_cb(const XrlError& xrl_error, string interface,
00450                  string vif);
00451     void leave_multicast_group_cb(const XrlError& xrl_error, string interface,
00452                   string vif);
00453 
00454     EventLoop&      _eventloop;
00455     XrlRouter&      _xrl_router;
00456     string      _feaname;
00457     string      _ribname;
00458     uint32_t        _component_count;
00459 
00460     IfMgrXrlMirror  _ifmgr;
00461     XrlQueue<A>     _rib_queue;
00462 
00463     //
00464     // A local copy with the interface state information
00465     //
00466     IfMgrIfTree     _iftree;
00467 };
00468 #endif // __OSPF_XRL_IO_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations