xorp

ospf.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 __OSPF_OSPF_HH__
00023 #define __OSPF_OSPF_HH__
00024 
00028 struct OspfTypes {
00029 
00033     enum Version {V2 = 2, V3 = 3};
00034     
00038     typedef uint16_t Type;
00039 
00043     typedef uint32_t RouterID;
00044 
00048     typedef uint32_t AreaID;
00049 
00053     enum LinkType {
00054     PointToPoint,
00055     BROADCAST,
00056     NBMA,
00057     PointToMultiPoint,
00058     VirtualLink
00059     };
00060 
00064     typedef uint16_t AuType;
00065     static const AuType NULL_AUTHENTICATION = 0;
00066     static const AuType SIMPLE_PASSWORD = 1;
00067     static const AuType CRYPTOGRAPHIC_AUTHENTICATION = 2;
00068 
00072     enum AreaType {
00073     NORMAL,     // Normal Area
00074     STUB,       // Stub Area
00075     NSSA,       // Not-So-Stubby Area
00076     };
00077 
00081     enum VertexType {
00082     Router,
00083     Network
00084     };
00085 
00089     enum NSSATranslatorRole {
00090     ALWAYS,
00091     CANDIDATE
00092     };
00093 
00097     enum NSSATranslatorState {
00098     ENABLED,
00099     ELECTED,
00100     DISABLED,
00101     };
00102 
00106     static const AreaID BACKBONE = 0;
00107 
00111     typedef uint32_t PeerID;
00112 
00116     typedef uint32_t NeighbourID;
00117 
00121     static const uint16_t IP_PROTOCOL_NUMBER = 89;
00122 
00127     static const PeerID ALLPEERS = 0;
00128 
00133     static const NeighbourID ALLNEIGHBOURS = 0;
00134 
00138     static const uint32_t UNUSED_INTERFACE_ID = 0;
00139 
00149     static const uint32_t LSRefreshTime = 30 * 60;
00150 
00155     static const uint32_t MinLSInterval = 5;
00156 
00163     static const uint32_t MinLSArrival = 1;
00164 
00172     static const uint32_t MaxAge = 60 * 60;
00173 
00180     static const uint32_t CheckAge = 5 * 60;
00181 
00182     /*
00183      * The maximum time dispersion that can occur, as an LSA is flooded
00184      * throughout the AS.  Most of this time is accounted for by the
00185      * LSAs sitting on router output queues (and therefore not aging)
00186      * during the flooding process.  The value of MaxAgeDiff is set to
00187      * 15 minutes.
00188      */
00189     static const int32_t MaxAgeDiff = 15 * 60;
00190 
00191     /*
00192      * The metric value indicating that the destination described by an
00193      * LSA is unreachable. Used in summary-LSAs and AS-external-LSAs as
00194      * an alternative to premature aging. It is
00195      * defined to be the 24-bit binary value of all ones: 0xffffff.
00196      */
00197     static const uint32_t LSInfinity = 0xffffff;
00198 
00199     /*
00200      * The Destination ID that indicates the default route.  This route  
00201      * is used when no other matching routing table entry can be found.  
00202      * The default destination can only be advertised in AS-external-    
00203      * LSAs and in stub areas' type 3 summary-LSAs.  Its value is the    
00204      * IP address 0.0.0.0. Its associated Network Mask is also always    
00205      * 0.0.0.0.                                                          
00206      */
00207     static const uint32_t DefaultDestination = 0;
00208 
00209     /*
00210      * The value used for LS Sequence Number when originating the first
00211      * instance of any LSA.
00212      */
00213     static const int32_t InitialSequenceNumber = 0x80000001;
00214 
00215     /*
00216      * The maximum value that LS Sequence Number can attain.
00217      */
00218     static const int32_t MaxSequenceNumber = 0x7fffffff;
00219 };
00220 
00224 #define VLINK "vlink"
00225 
00229 #define VLINK_MTU 576
00230 
00234 #define TARGET_OSPFv2   "ospfv2"
00235 #define TARGET_OSPFv3   "ospfv3"
00236 
00240 inline
00241 const char *
00242 xrl_target(OspfTypes::Version version)
00243 {
00244     switch (version) {
00245     case OspfTypes::V2:
00246     return TARGET_OSPFv2;
00247     break;
00248     case OspfTypes::V3:
00249     return TARGET_OSPFv3;
00250     break;
00251     }
00252 
00253     XLOG_UNREACHABLE();
00254 }
00255 
00259 inline
00260 string
00261 pr_id(uint32_t id)
00262 {
00263     return IPv4(htonl(id)).str();
00264 }
00265 
00269 inline
00270 uint32_t
00271 set_id(const char *addr)
00272 {
00273     return ntohl(IPv4(addr).addr());
00274 }
00275 
00279 inline
00280 string
00281 pp_link_type(OspfTypes::LinkType link_type)
00282 {
00283     switch(link_type) {
00284     case OspfTypes::PointToPoint:
00285     return "PointToPoint";
00286     case OspfTypes::BROADCAST:
00287     return "BROADCAST";
00288     case OspfTypes::NBMA:
00289     return "NBMA";
00290     case OspfTypes::PointToMultiPoint:
00291     return "PointToMultiPoint";
00292     case OspfTypes::VirtualLink:
00293     return "VirtualLink";
00294     }
00295     XLOG_UNREACHABLE();
00296 }
00297 
00301 inline
00302 OspfTypes::LinkType
00303 from_string_to_link_type(const string& type, bool& status)
00304 {
00305     status = true;
00306     if (type == "p2p")
00307     return OspfTypes::PointToPoint;
00308     else if (type == "broadcast")
00309     return OspfTypes::BROADCAST;
00310     else if (type == "nbma")
00311     return OspfTypes::NBMA;
00312     else if (type == "p2m")
00313     return OspfTypes::PointToMultiPoint;
00314     else if (type == "vlink")
00315     return OspfTypes::VirtualLink;
00316 
00317     XLOG_WARNING("Unable to match %s", type.c_str());
00318     status = false;
00319 
00320     return OspfTypes::BROADCAST;
00321 }
00322 
00326 inline
00327 string
00328 pp_area_type(OspfTypes::AreaType area_type)
00329 {
00330     switch(area_type) {
00331     case OspfTypes::NORMAL:
00332     return "NORMAL";
00333     case OspfTypes::STUB:
00334     return "STUB";
00335     case OspfTypes::NSSA:
00336     return "NSSA";
00337     }
00338     XLOG_UNREACHABLE();
00339 }
00340 
00344 inline
00345 OspfTypes::AreaType
00346 from_string_to_area_type(const string& type, bool& status)
00347 {
00348     status = true;
00349     if (type == "normal")
00350     return OspfTypes::NORMAL;
00351     else if (type == "stub")
00352     return OspfTypes::STUB;
00353     else if (type == "nssa")
00354     return OspfTypes::NSSA;
00355 
00356     XLOG_WARNING("Unable to match %s", type.c_str());
00357     status = false;
00358 
00359     return OspfTypes::NORMAL;
00360 }
00361 
00365 struct RouterInfo {
00366     RouterInfo(OspfTypes::RouterID router_id) 
00367     : _router_id(router_id), _interface_id(0)
00368     {}
00369 
00370     RouterInfo(OspfTypes::RouterID router_id, uint32_t interface_id) 
00371     : _router_id(router_id), _interface_id(interface_id)
00372     {}
00373 
00374     OspfTypes::RouterID _router_id; // Neighbour Router ID. 
00375     uint32_t _interface_id;     // Neighbour interface ID OSPFv3 only.
00376 };
00377 
00381 struct NeighbourInfo {
00382     string _address;        // Address of neighbour.
00383     string _interface;      // Interface name.
00384     string _state;      // The current state.
00385     IPv4 _rid;          // The neighbours router id.
00386     uint32_t _priority;     // The priority in the hello packet.
00387     uint32_t _deadtime;     // Number of seconds before the
00388                 // peering is considered down.
00389     IPv4 _area;         // The area this neighbour belongs to.
00390     uint32_t _opt;      // The options on the hello packet.
00391     IPv4 _dr;           // The designated router.
00392     IPv4 _bdr;          // The backup designated router.
00393     uint32_t _up;       // Time there has been neighbour awareness.
00394     uint32_t _adjacent;     // Time peering has been adjacent.
00395 };
00396 
00400 template <typename A>
00401 struct AddressInfo {
00402     AddressInfo(A address, uint32_t prefix = 0, bool enabled = false)
00403     : _address(address), _prefix(prefix), _enabled(enabled)
00404     {}
00405 
00406     bool operator<(const AddressInfo<A>& other) const {
00407     return _address < other._address;
00408     }
00409 
00410     A _address;     // The address.
00411     uint32_t _prefix;   // Prefix length associated with this address.
00412     bool _enabled;  // True if the address should be used.
00413 };
00414 
00415 #include "policy_varrw.hh"
00416 #include "io.hh"
00417 #include "exceptions.hh"
00418 #include "lsa.hh"
00419 #include "packet.hh"
00420 #include "transmit.hh"
00421 #include "peer_manager.hh"
00422 #include "external.hh"
00423 #include "vlink.hh"
00424 #include "routing_table.hh"
00425 #include "trace.hh"
00426 
00427 template <typename A>
00428 class Ospf {
00429  public:
00430     Ospf(OspfTypes::Version version, EventLoop& eventloop, IO<A>* io);
00431     
00435     OspfTypes::Version version() { return _version; }
00436 
00440     bool running() { return _io->status() != SERVICE_SHUTDOWN; }
00441 
00445     ProcessStatus status(string& reason) {
00446     if (PROC_STARTUP == _process_status) {
00447         if (SERVICE_RUNNING == _io->status()) {
00448         _process_status = PROC_READY;
00449         _reason = "Running";
00450         }
00451     }
00452 
00453     reason = _reason;
00454     return _process_status;
00455     }
00456 
00460     void shutdown() {
00461     _io->shutdown();
00462     _reason = "shutting down";
00463     _process_status = PROC_SHUTDOWN;
00464     }
00465 
00469     bool transmit(const string& interface, const string& vif,
00470           A dst, A src, int ttl, uint8_t* data, uint32_t len);
00471     
00476     void receive(const string& interface, const string& vif,
00477          A dst, A src, uint8_t* data, uint32_t len);
00478 
00482     bool enable_interface_vif(const string& interface, const string& vif);
00483 
00487     bool disable_interface_vif(const string& interface, const string& vif);
00488 
00496     bool enabled(const string& interface, const string& vif);
00497 
00505     bool enabled(const string& interface, const string& vif, A address);
00506 
00516     void register_vif_status(typename IO<A>::VifStatusCb cb) {
00517     _io->register_vif_status(cb);
00518     }
00519 
00529     void register_address_status(typename IO<A>::AddressStatusCb cb) {
00530     _io->register_address_status(cb);
00531     }
00532 
00542     bool get_addresses(const string& interface, const string& vif,
00543                list<A>& addresses) const;
00544 
00555     bool get_link_local_address(const string& interface, const string& vif,
00556                 A& address);
00557 
00562     bool get_interface_id(const string& interface, const string& vif,
00563               uint32_t& interface_id);
00564 
00568     bool get_interface_vif_by_interface_id(uint32_t interface_id,
00569                        string& interface, string& vif);
00570     
00574     bool get_prefix_length(const string& interface, const string& vif,
00575                A address, uint16_t& prefix_length);
00576 
00580     uint32_t get_mtu(const string& interface);
00581 
00585     bool join_multicast_group(const string& interface, const string& vif,
00586                   A mcast);
00587     
00591     bool leave_multicast_group(const string& interface, const string& vif,
00592                    A mcast);
00593 
00597     bool set_hello_interval(const string& interface, const string& vif,
00598                 OspfTypes::AreaID area,
00599                 uint16_t hello_interval);
00600 
00601 #if 0
00602 
00605     bool set_options(const string& interface, const string& vif,
00606              OspfTypes::AreaID area,
00607              uint32_t options);
00608 #endif
00609 
00615     bool create_virtual_link(OspfTypes::RouterID rid);
00616 
00622     bool delete_virtual_link(OspfTypes::RouterID rid);
00623 
00627     bool transit_area_virtual_link(OspfTypes::RouterID rid,
00628                    OspfTypes::AreaID transit_area);
00629     
00630 
00634     bool set_router_priority(const string& interface, const string& vif,
00635                  OspfTypes::AreaID area,
00636                  uint8_t priority);
00637 
00641     bool set_router_dead_interval(const string& interface, const string& vif,
00642                   OspfTypes::AreaID area,
00643                   uint32_t router_dead_interval);
00644 
00648     bool set_interface_cost(const string& interface, const string& vif,
00649                 OspfTypes::AreaID area,
00650                 uint16_t interface_cost);
00651 
00655     bool set_retransmit_interval(const string& interface, const string& vif,
00656                  OspfTypes::AreaID area,
00657                  uint16_t retransmit_interval);
00658 
00662     bool set_inftransdelay(const string& interface, const string& vif,
00663                OspfTypes::AreaID area,
00664                uint16_t inftransdelay);
00665 
00679     bool set_simple_authentication_key(const string& interface,
00680                        const string& vif,
00681                        OspfTypes::AreaID area,
00682                        const string& password,
00683                        string& error_msg);
00684 
00697     bool delete_simple_authentication_key(const string& interface,
00698                       const string& vif,
00699                       OspfTypes::AreaID area,
00700                       string& error_msg);
00701 
00719     bool set_md5_authentication_key(const string& interface, const string& vif,
00720                     OspfTypes::AreaID area, uint8_t key_id,
00721                     const string& password,
00722                     const TimeVal& start_timeval,
00723                     const TimeVal& end_timeval,
00724                     const TimeVal& max_time_drift,
00725                     string& error_msg);
00726 
00741     bool delete_md5_authentication_key(const string& interface,
00742                        const string& vif,
00743                        OspfTypes::AreaID area, uint8_t key_id,
00744                        string& error_msg);
00745 
00749     bool set_passive(const string& interface, const string& vif,
00750              OspfTypes::AreaID area,
00751              bool passive, bool host);
00752 
00757     bool originate_default_route(OspfTypes::AreaID area, bool enable);
00758 
00763     bool stub_default_cost(OspfTypes::AreaID area, uint32_t cost);
00764 
00768     bool summaries(OspfTypes::AreaID area, bool enable);
00769 
00773     bool set_ip_router_alert(bool alert);
00774 
00778     bool area_range_add(OspfTypes::AreaID area, IPNet<A> net, bool advertise);
00779 
00783     bool area_range_delete(OspfTypes::AreaID area, IPNet<A> net);
00784 
00788     bool area_range_change_state(OspfTypes::AreaID area, IPNet<A> net,
00789                  bool advertise);
00790 
00804     bool get_lsa(const OspfTypes::AreaID area, const uint32_t index,
00805          bool& valid, bool& toohigh, bool& self, vector<uint8_t>& lsa);
00806 
00810     bool get_area_list(list<OspfTypes::AreaID>& areas) const;
00811 
00815     bool get_neighbour_list(list<OspfTypes::NeighbourID>& neighbours) const;
00816 
00824     bool get_neighbour_info(OspfTypes::NeighbourID nid,
00825                 NeighbourInfo& ninfo) const;
00826 
00830     bool clear_database();
00831 
00843     bool add_route(IPNet<A> net, A nexthop, uint32_t nexthop_id,
00844            uint32_t metric, bool equal, bool discard,
00845            const PolicyTags& policytags);
00857     bool replace_route(IPNet<A> net, A nexthop, uint32_t nexthop_id,
00858                uint32_t metric, bool equal, bool discard,
00859                const PolicyTags& policytags);
00860 
00864     bool delete_route(IPNet<A> net);
00865 
00872     void configure_filter(const uint32_t& filter, const string& conf);
00873 
00879     void reset_filter(const uint32_t& filter);
00880 
00884     void push_routes();
00885 
00896     bool originate_route(const IPNet<A>& net, const A& nexthop,
00897              const uint32_t& metric,
00898              const PolicyTags& policytags);
00899 
00907     bool withdraw_route(const IPNet<A>& net);
00908 
00912     OspfTypes::Version get_version() const { return _version; }
00913 
00917     EventLoop& get_eventloop() { return _eventloop; }
00918 
00922     void set_testing(bool testing) {_testing = testing; }
00923 
00927     bool get_testing() const { return _testing; }
00928 
00932     PeerManager<A>& get_peer_manager() { return _peer_manager; }
00933 
00937     RoutingTable<A>& get_routing_table() { return _routing_table; }
00938 
00942     LsaDecoder& get_lsa_decoder() { return _lsa_decoder; }
00943 
00947     PolicyFilters& get_policy_filters() { return _policy_filters; }
00948 
00952     uint8_t get_instance_id() const { 
00953     XLOG_ASSERT(OspfTypes::V3 == get_version());
00954     return _instance_id;
00955     }
00956 
00960     void set_instance_id(uint8_t instance_id) { 
00961     XLOG_ASSERT(OspfTypes::V3 == get_version());
00962     _instance_id = instance_id;
00963     }
00964 
00968     OspfTypes::RouterID get_router_id() const { return _router_id; }
00969 
00973     void set_router_id(OspfTypes::RouterID id);
00974 
00978     bool get_rfc1583_compatibility() const { return _rfc1583_compatibility;}
00979 
00983     void set_rfc1583_compatibility(bool compatibility) {
00984     // Don't check for equality we can use this as a hack to force
00985     // routing recomputation.
00986     _rfc1583_compatibility = compatibility;
00987     _peer_manager.routing_recompute_all_areas();
00988     }
00989 
00990     Trace& trace() { return _trace; }
00991 
00992  private:
00993     const OspfTypes::Version _version;  // OSPF version.
00994     EventLoop& _eventloop;
00995 
00996     bool _testing;      // True when testing.
00997 
00998     IO<A>* _io;         // Indirection for sending and
00999                 // receiving packets, as well as
01000                 // adding and deleting routes. 
01001     string _reason;
01002     ProcessStatus _process_status;
01003 
01004     PacketDecoder _packet_decoder;  // Packet decoders.
01005     LsaDecoder _lsa_decoder;        // LSA decoders.
01006     PeerManager<A> _peer_manager;
01007     RoutingTable<A> _routing_table;
01008     PolicyFilters _policy_filters;  // The policy filters.
01009 
01010     uint8_t _instance_id;       // OSPFv3 Only
01011 
01012     OspfTypes::RouterID _router_id; // Router ID.
01013     bool _rfc1583_compatibility;    // Preference rules for route
01014                     // selection. 
01015 
01016     map<string, uint32_t> _iidmap;  // OSPFv3 only mapping of
01017                     // interface/vif to Instance IDs.
01018     
01019     Trace _trace;       // Trace variables.
01020 };
01021 
01022 // The original design did not leave MaxAge LSAs in the database. When
01023 // an LSA reached MaxAge it was removed from the database and existed
01024 // only in retransmission lists. If an LSA was received which seemed
01025 // to be from a previous incarnation of OSPF it had its age set to
01026 // MaxAge and was fired out, also not being added to the database.
01027 // If while a MaxAge LSA is on the retransmission only, either a new
01028 // LSA such as a Network-LSA is generated or an updated LSA arrives a
01029 // second LSA can be created with the same <Type,ID,ADV> tuple. Two LSAs
01030 // can exist on the retransmission list. Leaving the a MaxAge LSA in
01031 // the database solves both problems.
01032 
01033 // #define MAX_AGE_IN_DATABASE
01034 
01035 #define PARANOIA
01036 
01037 #endif // __OSPF_OSPF_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations