Source: ../../ospf/area_router.hh
|
|
|
|
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// vim:set sts=4 ts=8:
// Copyright (c) 2001-2004 International Computer Science Institute
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software")
// to deal in the Software without restriction, subject to the conditions
// listed in the XORP LICENSE file. These conditions include: you must
// preserve this copyright notice, and you cannot mention the copyright
// holders in advertising related to the Software without their permission.
// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
// notice is a summary of the XORP LICENSE file; the license in that file is
// legally binding.
// $XORP: xorp/ospf/area_router.hh,v 1.101 2006/02/28 00:30:50 atanu Exp $
#ifndef __OSPF_AREA_ROUTER_HH__
#define __OSPF_AREA_ROUTER_HH__
class DataBaseHandle;
/**
* Area Router
*
*/
template <typename A>
class AreaRouter : public ServiceBase {
public:
AreaRouter(Ospf<A>& ospf, OspfTypes::AreaID area,
OspfTypes::AreaType area_type);
/**
* Required by the class Subsystem.
* Called on startup.
*/
bool startup();
/**
* Required by the class Subsystem.
* Called on shutdown.
*/
bool shutdown();
/**
* Add peer
*/
void add_peer(PeerID peer);
/**
* Delete peer
*/
void delete_peer(PeerID peer);
/**
* Peer came up
*/
bool peer_up(PeerID peer);
/**
* Peer went down
*/
bool peer_down(PeerID peer);
/**
* Track border router transitions.
*
* @param up true of the router just became an area border router,
* false if the router was an area border router and is no longer.
*/
void area_border_router_transition(bool up);
/**
* Change the type of this area.
*/
void change_area_router_type(OspfTypes::AreaType area_type);
/**
* Add a virtual link endpoint.
*/
bool add_virtual_link(OspfTypes::RouterID rid);
/**
* Remove a virtual link endpoint.
*/
bool remove_virtual_link(OspfTypes::RouterID rid);
/**
* Start looking through the list of routers for a virtual link endpoint.
*/
void start_virtual_link();
/**
* Check this node to see if its a virtual link endpoint.
*
* @param rc node under consideration.
* @param router this router's Router-LSA.
*/
void check_for_virtual_link(const RouteCmd<Vertex>& rc, Lsa::LsaRef lsar);
/**
* End looking through the list of routers for a virtual link endpoint.
*/
void end_virtual_link();
/**
* Given two LSAs find the interface address of the destination
* LSA. The source LSA can be a Router-LSA or a Network-LSA the
* destination LSA must be a Router-LSA.
*/
bool find_interface_address(Lsa::LsaRef src, Lsa::LsaRef dst,
A& interface)const;
/**
* Add area range.
*/
bool area_range_add(IPNet<A> net, bool advertise);
/**
* Delete area range.
*/
bool area_range_delete(IPNet<A> net);
/**
* Change the advertised state of this area.
*/
bool area_range_change_state(IPNet<A> net, bool advertise);
/**
* Is network covered by an area range and if it is should it be
* advertised.
*/
bool area_range_covered(IPNet<A> net, bool& advertise);
/**
* This network falls in a covered area range, return the covering
* range.
*/
bool area_range_covering(IPNet<A> net, IPNet<A>& sumnet);
/**
* Does this area have any area ranges configured.
*/
bool area_range_configured();
/**
* If this is a "stub" or "nssa" area toggle the sending of a default
* route.
*/
bool originate_default_route(bool enable);
/**
* Set the StubDefaultCost, the default cost sent in a default route in a
* "stub" or "nssa" area.
*/
bool stub_default_cost(uint32_t cost);
/**
* Toggle the sending of summaries into "stub" or "nssa" areas.
*/
bool summaries(bool enable);
/**
* get lsa at index if it exists.
*/
bool get_lsa(const uint32_t index, bool& valid, bool& toohigh, bool& self,
vector<uint8_t>& lsa);
/**
* A new set of router links.
*/
bool new_router_links(PeerID peer, const list<RouterLink>& router_link);
/**
* Refresh Router-LSA.
*
* Cause the generation of a new Router-LSA if necessary.
*
* @param timer true if called by the timer.
*/
void refresh_router_lsa(bool timer = false);
/**
* A new route has been added to the routing table it is being
* presented to this area for possible Summary-LSA generation.
*
* @param area the route came from
* @param net
* @param rt routing entry.
* @param push true if the routes are arriving as a consquence of
* calling summary_push()
*/
void summary_announce(OspfTypes::AreaID area, IPNet<A> net,
RouteEntry<A>& rt, bool push);
/**
* A route has been deleted from the routing table. It may
* previously have caused a Summary-LSA which now needs to be
* withdrawn.
*/
void summary_withdraw(OspfTypes::AreaID area, IPNet<A> net,
RouteEntry<A>& rt);
/**
* @return true if this area should accept an AS-External-LSA or
* a Type-7-LSA.
*/
bool external_area_type() const;
/**
* Copy the net and nexthop information from one AS-External-LSA to
* another.
*
* The first dummy argument A is to allow template specialisation
* by address family.
*/
void external_copy_net_nexthop(A,
ASExternalLsa *dst,
ASExternalLsa *src);
/**
* Given an AS-External-LSA generate a Type-7 LSA.
*
* @param indb if true the Type-7-LSA is already in the database.
*/
Lsa::LsaRef external_generate_type7(Lsa::LsaRef lsar, bool& indb);
/**
* Given a Type-7 LSA generate an AS-External-LSA.
*/
Lsa::LsaRef external_generate_external(Lsa::LsaRef lsar);
/**
* An AS-External-LSA being announced either from another area or
* from the RIB as a redist.
*
* The LSAs should not be scheduled for transmission until the
* external_shove() is seen. In many cases a number of LSAs may
* arrive in a single packet, waiting for the external_shove()
* offers an opportunity for aggregation.
*
* @param lsar the AS-External-LSA
* @param push set to true if the push is a result of an external_push().
* @param redist true if this LSA was locally generated due to a
* redistribution.
*/
void external_announce(Lsa::LsaRef lsar, bool push, bool redist);
/**
* Called to complete a series of calls to external_announce().
*/
void external_shove();
/**
* Refresh this LSA either because a timer has expired or because
* a newer LSA has arrived from another area. In either cause the
* LSA should already be in this area's database.
*/
void external_refresh(Lsa::LsaRef lsar);
/**
* An AS-External-LSA being withdrawn either from another area or
* from the RIB as a redist.
*
* @param lsar the AS-External-LSA
*/
void external_withdraw(Lsa::LsaRef lsar);
/**
* Generate a Network-LSA for this peer.
*/
bool generate_network_lsa(PeerID peer,
OspfTypes::RouterID link_state_id,
list<OspfTypes::RouterID>& attached_routers,
uint32_t network_mask);
/**
* Update the Network-LSA for this peer.
*/
bool update_network_lsa(PeerID peer,
OspfTypes::RouterID link_state_id,
list<OspfTypes::RouterID>& attached_routers,
uint32_t network_mask);
/**
* Withdraw the Network-LSA for this peer by prematurely aging.
*/
bool withdraw_network_lsa(PeerID peer, OspfTypes::RouterID link_state_id);
/**
* Refresh the Network-LSAs.
*
* @param peerid the peer that needs its Network-LSA refreshed.
* @param lsar the Network-LSA itself.
* @param timer is the Network-LSA being refreshed due to the
* timer firing?
*/
void refresh_network_lsa(PeerID peerid, Lsa::LsaRef lsar,
bool timer = false);
/**
* Create an LSA that will be used to announce the default route
* into "stub" and "nssa" areas.
*/
void generate_default_route();
/**
* Find the default route LSA in the database if it exists.
*/
bool find_default_route(size_t& index);
// Temporary storage used by save_default_route() and
// restore_default_route().
Lsa::LsaRef _saved_default_route;
/**
* If the default route LSA is in the database remove it.
* Typically to stop it being purged when the area type changes or
* summarisation is disable.
*/
void save_default_route();
/**
* If the default route LSA should be in the database put it
* back. Either from the previously saved or generate a new one if
* necessary. Typically paired with save_default_route().
*/
void restore_default_route();
/**
* Withdraw the default route LSA if it exists.
* Set the LSA to MaxAge and floods.
*/
void withdraw_default_route();
/**
* Refresh the default route LSA.
* Increments the sequence and floods updates the cost if it has
* changed.
*/
void refresh_default_route();
/**
* Add a network to be announced.
*/
// void add_network(PeerID peer, IPNet<A> network);
/**
* Remove a network to be announced.
*/
// void remove_network(PeerID peer, IPNet<A> network);
/**
* @return the type of this area.
*/
OspfTypes::AreaType get_area_type() const { return _area_type; }
/**
* Get the options that are sent in hello packets, data
* description packets, LSA headers (OSPFv2), Router-LSAs
* (OSPFv3) and Network-LSAs (OSPFv3).
*/
uint32_t get_options() {
return _ospf.get_peer_manager().compute_options(get_area_type());
}
/**
* Receive LSAs
*
* @param peerid that the LSAs arrived on.
* @param nid neighbourID that the LSAs arrived on.
* @param lsas list of recived lsas.
* @param direct_ack list of direct acks to send in response to the LSA
* @param delayed_ack list of delayed acks to send in response to the LSA
* @param backup true if the receiving interface was in state backup.
* @param dr true if the LSA was received from the designated router.
*/
void receive_lsas(PeerID peerid, OspfTypes::NeighbourID nid,
list<Lsa::LsaRef>& lsas,
list<Lsa_header>& direct_ack,
list<Lsa_header>& delayed_ack,
bool backup, bool dr);
/**
* Returned by compare_lsa.
*/
enum LsaSearch {
NOMATCH, // No matching LSA was found.
EQUIVALENT, // The two LSAs are considered equivalent.
NEWER, // The offered LSA is newer than the database copy.
OLDER, // The offered LSA is older than the database copy.
};
/**
* Compare two LSAs.
*
* @param candidate offered LSA
* @param current equivalent to the database copy.
*
* @return LsaSearch that describes the type of match.
*/
LsaSearch compare_lsa(const Lsa_header& candidate,
const Lsa_header& current) const;
/**
* Compare this LSA to
*
* @param Lsa_header that is being sought.
*
* @return LsaSearch that describes the type of match.
*/
LsaSearch compare_lsa(const Lsa_header&) const;
/**
* @return true if this is a newer LSA than we already have.
*/
bool newer_lsa(const Lsa_header&) const;
/**
* Fetch a list of lsas given a list of requests.
*
* The age fields of the returned LSAs will be correctly set.
*
* @param requests list of requests
* @param lsas list of LSAs
*
* @return True if *all* the requests have been satisfied. If an LSA
* can not be found False is returned and the state of the lsas
* list is undefined; hence should not be used.
*
*/
bool get_lsas(const list<Ls_request>& requests,
list<Lsa::LsaRef>& lsas);
/**
* Open database
*
* Used only by the peer to generate the database description packets.
*
* @param empty true if the database is empty.
* @return Database Handle
*/
DataBaseHandle open_database(bool& empty);
/**
* Is this a valid entry to be returned by the database.
*
* This method is for internal use and its use is not recommended.
*
* @return true if this entry is valid.
*/
bool valid_entry_database(size_t index);
/**
* Is there another database entry following this one.
*
* This method is for internal use and its use is not recommended.
*
* @return true if there is a subsequent entry.
*/
bool subsequent(DataBaseHandle& dbh);
/**
* Next database entry
*
* @param last true if this is the last entry.
*
* @return The next LSA in the database.
*/
Lsa::LsaRef get_entry_database(DataBaseHandle& dbh, bool& last);
/**
* Close the database
*
* @param dbd Database descriptor
*/
void close_database(DataBaseHandle& dbh);
/**
* Clear the database.
*/
void clear_database();
/**
* All self originated LSAs of this type MaxAge them.
*/
void maxage_type_database(uint16_t type);
/**
* Is this the backbone area?
*/
bool backbone() const {
return OspfTypes::BACKBONE == _area;
}
bool backbone(OspfTypes::AreaID area) const {
return OspfTypes::BACKBONE == area;
}
/**
* Print link state database.
*/
void testing_print_link_state_database() const;
/**
* Testing entry point to add this router Router-LSA to the
* database replacing the one that is already there.
*/
bool testing_replace_router_lsa(Lsa::LsaRef lsar) {
RouterLsa *rlsa = dynamic_cast<RouterLsa *>(lsar.get());
XLOG_ASSERT(rlsa);
XLOG_ASSERT(rlsa->get_self_originating());
XLOG_ASSERT(_ospf.get_router_id() ==
rlsa->get_header().get_link_state_id());
XLOG_ASSERT(_ospf.get_router_id() ==
rlsa->get_header().get_advertising_router());
size_t index;
if (find_lsa(_router_lsa, index)) {
delete_lsa(_router_lsa, index, true);
}
_router_lsa = lsar;
add_lsa(_router_lsa);
return true;
}
/**
* Testing entry point to add an LSA to the database.
*/
bool testing_add_lsa(Lsa::LsaRef lsar) {
return add_lsa(lsar);
}
/**
* Testing entry point to delete an LSA from the database.
*/
bool testing_delete_lsa(Lsa::LsaRef lsar) {
size_t index;
if (find_lsa(lsar, index)) {
delete_lsa(lsar, index, true);
return true;
}
XLOG_FATAL("Attempt to delete LSA that is not in database \n%s",
cstring(*lsar));
return false;
}
/**
* Testing enty point to force a toal routing computation.
*/
void testing_routing_total_recompute() {
routing_total_recompute();
}
string str() {
return "Area " + pr_id(_area);
}
private:
Ospf<A>& _ospf; // Reference to the controlling class.
OspfTypes::AreaID _area; // Area: That is represented.
OspfTypes::AreaType _area_type; // Type of this area.
map<OspfTypes::RouterID,bool> _vlinks; // Virtual link endpoints.
set<OspfTypes::RouterID> _tmp; // temporary storage for
// virtual links.
bool _summaries; // True if summaries should be
// generated into a stub area.
bool _stub_default_announce; // Announce a default route into
// stub or nssa
uint32_t _stub_default_cost; // The cost of the default
// route that is injected into
// a stub area.
bool _external_flooding; // True if AS-External-LSAs
// are being flooded.
#ifdef UNFINISHED_INCREMENTAL_UPDATE
Spt<Vertex> _spt; // SPT computation unit.
#endif
Lsa::LsaRef _invalid_lsa; // An invalid LSA to overwrite slots
Lsa::LsaRef _router_lsa; // This routers router LSA.
vector<Lsa::LsaRef> _db; // Database of LSAs.
deque<size_t> _empty_slots; // Available slots in the Database.
uint32_t _last_entry; // One past last entry in
// database. A value of 0 is
// an empty database.
uint32_t _allocated_entries; // Number of allocated entries.
uint32_t _readers; // Number of database readers.
DelayQueue<Lsa::LsaRef> _queue; // Router LSA queue.
XorpTimer _reincarnate_timer; // Wait for the LSAs to be purged.
list<Lsa::LsaRef> _reincarnate; // Self-originated LSAs where
// the sequence number has
// reached MaxSequenceNumber.
#ifdef UNFINISHED_INCREMENTAL_UPDATE
uint32_t _TransitCapability; // Used by the spt computation.
// XXX - This needs a better name.
struct Bucket {
Bucket(size_t index, bool known) : _index(index), _known(known)
{}
size_t _index;
bool _known;
};
list<Bucket> _new_lsas; // Indexes of new LSAs that
// have arrived recently.
#else
bool _TransitCapability; // Does this area support
// transit traffic?
void set_transit_capability(bool t) {
_TransitCapability = t;
}
bool get_transit_capability() const {
return _TransitCapability;
}
#endif
/**
* Internal state that is required about each peer.
*/
struct PeerState {
PeerState()
: _up(false)
{}
bool _up; // True if peer is enabled.
list<RouterLink> _router_links; // Router links for this peer
};
typedef ref_ptr<PeerState> PeerStateRef;
typedef map<PeerID, PeerStateRef> PeerMap;
PeerMap _peers; // Peers of this area.
uint32_t _routing_recompute_delay; // How many seconds to wait
// before recompting.
XorpTimer _routing_recompute_timer; // Timer to cause recompute.
// How to handle Type-7 LSAs at the border.
OspfTypes::NSSATranslatorRole _translator_role;
OspfTypes::NSSATranslatorState _translator_state;
bool _type7_propagate; // How to set the propagate bit.
/**
* Range to be summarised or suppressed from other areas.
*/
struct Range {
bool _advertise; // Should this range be advertised.
};
Trie<A, Range> _area_range; // Area range for summary generation.
/**
* Networks with same network number but different prefix lengths
* can generate the same link state ID. When generating a new LSA
* if a collision occurs use:
* RFC 2328 Appendix E. An algorithm for assigning Link State IDs
* to resolve the clash. Summary-LSAs only.
*/
void unique_link_state_id(Lsa::LsaRef lsar);
/**
* Networks with same network number but different prefix lengths
* can generate the same link state ID. When looking for an LSA
* make sure that there the lsar that matches the net is
* found. Summary-LSAs only.
*/
bool unique_find_lsa(Lsa::LsaRef lsar, const IPNet<A>& net, size_t& index);
/**
* Set the network components of the LSA.
*/
void summary_network_lsa_set_net(SummaryNetworkLsa *snlsa, IPNet<A> net);
Lsa::LsaRef summary_network_lsa(IPNet<A> net, RouteEntry<A>& rt);
/**
* Generate a Summary-LSA for an intra area path taking into
* account area ranges. An announcement may not generate an LSA
* and a withdraw may not cause an LSA to be removed.
*/
Lsa::LsaRef summary_network_lsa_intra_area(OspfTypes::AreaID area,
IPNet<A> net,
RouteEntry<A>& rt,
bool& announce);
/**
* Construct a summary LSA if appropriate.
* @param announce true if this in an announce false if its a withdraw.
* @return the LSA can be empty.
*/
Lsa::LsaRef summary_build(OspfTypes::AreaID area, IPNet<A> net,
RouteEntry<A>& rt, bool& announce);
/**
* Announce this Summary-LSA to all neighbours and refresh it as
* appropriate.
*/
void refresh_summary_lsa(Lsa::LsaRef lsar);
/**
* Start aging LSA.
*
* All non self originated LSAs must be aged and when they reach
* MAXAGE flooded and flushed.
*/
bool age_lsa(Lsa::LsaRef lsar);
/**
* This LSA has reached MAXAGE so flood it to all the peers of
* this area. If its an external LSA flood it to all areas.
*/
void maxage_reached(Lsa::LsaRef lsar, size_t index);
/**
* Prematurely age self originated LSAs, remove them from the
* database flood with age set to MAXAGE.
*/
void premature_aging(Lsa::LsaRef lsar, size_t index);
/**
* Increment the sequence number of of this LSA, most importantly
* handle the sequence number reaching MaxSequenceNumber.
*/
void increment_sequence_number(Lsa::LsaRef lsar);
/**
* Update the age and increment the sequence number of of this
* LSA, most importantly handle the sequence number reaching
* MaxSequenceNumber.
*/
void update_age_and_seqno(Lsa::LsaRef lsar, const TimeVal& now);
/**
* Process an LSA where the sequence number has reached MaxSequenceNumber.
*/
void max_sequence_number_reached(Lsa::LsaRef lsar);
/**
* Reincarnate LSAs that have gone through the MaxSequenceNumber
* transition. Called on a periodic timer.
*/
bool reincarnate();
/**
* Add this LSA to the database.
*
* The LSA must have an updated age field.
*
* @param lsar LSA to add.
* @return true on success
*/
bool add_lsa(Lsa::LsaRef lsar);
/**
* Delete this LSA from the database.
*
* @param lsar LSA to delete.
* @param index into database.
* @param invalidate if true as well as removing from the database
* mark the LSA as invalid.
* @return true on success
*/
bool delete_lsa(Lsa::LsaRef lsar, size_t index, bool invalidate);
/**
* Update this LSA in the database.
*
* @param lsar LSA to update.
* @param index into database.
* @return true on success
*/
bool update_lsa(Lsa::LsaRef lsar, size_t index);
/**
* Find LSA matching this request.
*
* @param lsr that is being sought.
* @param index into LSA database if search succeeded.
*
* @return true if an LSA was found.
*/
bool find_lsa(const Ls_request& lsr, size_t& index) const;
/**
* Find LSA matching this request.
*
* @param lsar that is being sought.
* @param index into LSA database if search succeeded.
*
* @return true if an LSA was found.
*/
bool find_lsa(Lsa::LsaRef lsar, size_t& index) const;
/**
* Find Network-LSA.
*
* @param link_state_id
* @param index into LSA database if search succeeded.
*
* @return true if an LSA was found.
*/
bool find_network_lsa(uint32_t link_state_id, size_t& index) const;
/**
* Compare this LSA to
*
* @param Lsa_header that is being sought.
* @param index into LSA database if search succeeded.
*
* @return LsaSearch that describes the type of match.
*/
LsaSearch compare_lsa(const Lsa_header&, size_t& index) const;
/**
* Update router links.
*
* A peer has just changed state, or the refresh timer has fired,
* so update the router lsa and publish.
*
* @return true if something changed.
*/
bool update_router_links();
/*
* Send this LSA to all our peers.
*
* @param peerid The peer this LSA arrived on.
* @param nid The neighbour this LSA arrived on so don't reflect.
* @param lsar The LSA to publish
* @param multicast_on_peer Did this LSA get multicast on this peer.
*/
void publish(const PeerID peerid, const OspfTypes::NeighbourID nid,
Lsa::LsaRef lsar, bool& multicast_on_peer) const;
/*
* Send this LSA to all our peers.
*
* @param lsar The LSA to publish
*/
void publish_all(Lsa::LsaRef lsar);
/**
* Send (push) any queued LSAs.
*/
void push_lsas();
/**
* Return the setting of the propagate bit in a Type-7-LSA.
*/
bool external_propagate_bit(Lsa::LsaRef lsar) const {
XLOG_ASSERT(lsar->type7());
return Options(_ospf.get_version(),lsar->get_header().get_options())
.get_p_bit();
}
/**
* Take a Type-7-LSA that has arrived on the wire and translate if
* required.
*/
void external_type7_translate(Lsa::LsaRef lsar);
/**
* Send this LSA to all area's.
*
* This is an AS-External-LSA being sent to other areas.
*
* @param lsar The LSA to publish
*/
void external_flood_all_areas(Lsa::LsaRef lsar);
/**
* Notify all areas this is the last of the AS-External-LSAs.
*/
void external_push_all_areas();
/**
* @return true if any of the neigbours are in state Exchange or Loading.
*/
bool neighbours_exchange_or_loading() const;
/**
* Is this LSA on this neighbours link state request list.
* @param peerid
* @param nid
*
* @return true if it is.
*/
bool on_link_state_request_list(const PeerID peerid,
const OspfTypes::NeighbourID nid,
Lsa::LsaRef lsar) const;
/**
* Generate a BadLSReq event.
*
* @param peerid
* @param nid
*/
bool event_bad_link_state_request(const PeerID peerid,
const OspfTypes::NeighbourID nid) const;
/**
* Send this LSA directly to the neighbour. Do not place on
* retransmission list.
*
* @param peerid
* @param nid
* @param lsar
*
* @return true on success
*/
bool send_lsa(const PeerID peerid, const OspfTypes::NeighbourID nid,
Lsa::LsaRef lsar) const;
/**
* Check this LSA to see if its link state id matched any of the
* routers interfaces.
*
* @param lsar LSA to check.
* A dummy argument is used to force an IPv4 and an IPv6 instance
* of this method to be generated. Isn't C++ cool?
*/
bool self_originated_by_interface(Lsa::LsaRef lsar, A = A::ZERO()) const;
/**
* If this is a self-originated LSA do the appropriate processing.
* RFC 2328 Section 13.4. Receiving self-originated LSAs
*
* @param lsar received LSA.
* @param match if true this LSA has matched a self-originated LSA
* already in the database.
* @param index if match is true the index into the database for
* the matching LSA.
*
* @return true if this is a self-orignated LSA.
*/
bool self_originated(Lsa::LsaRef lsar, bool match, size_t index);
/**
* Create a vertex for this router.
*/
void RouterVertex(Vertex& v);
/**
* Prepare for routing changes.
*/
void routing_begin();
/**
* Add this LSA to the routing computation.
*
* The calls to this method are bracketed between a call to
* routing begin and routing end.
*
* @param lsar LSA to be added to the database.
* @param known true if this LSA is already in the database.
*/
void routing_add(Lsa::LsaRef lsar, bool known);
/**
* Remove this LSA from the routing computation.
*
* The calls to this method are *NOT* bracketed between a call to
* routing begin and routing end.
*/
void routing_delete(Lsa::LsaRef lsar);
/**
* Routing changes are completed.
* 1) Update the routing table if necessary.
* 2) Possibly generate new summary LSAs.
*/
void routing_end();
/**
* Schedule recomputing the whole table.
*/
void routing_schedule_total_recompute();
/**
* Callback routine that causes route recomputation.
*/
void routing_timer();
/**
* Totally recompute the routing table from the LSA database.
*/
void routing_total_recompute();
void routing_total_recomputeV2();
void routing_total_recomputeV3();
/**
* Compute the discard routes related to area ranges.
*/
void routing_area_ranges(list<RouteCmd<Vertex> >& r);
void routing_area_rangesV2(list<RouteCmd<Vertex> >& r);
void routing_area_rangesV3(list<RouteCmd<Vertex> >& r);
/**
* Compute the inter-area routes.
*/
void routing_inter_area();
void routing_inter_areaV2();
void routing_inter_areaV3();
/**
* Compute the transit area routes.
*/
void routing_transit_area();
void routing_transit_areaV2();
void routing_transit_areaV3();
/**
* Compute the AS external routes.
*/
void routing_as_external();
void routing_as_externalV2();
void routing_as_externalV3();
/**
* RFC 3101 Section 2.5. (6) (e) Calculating Type-7 AS external routes.
*
* Return true if the current LSA should be replaced by the
* candidate LSA.
*/
bool routing_compare_externals(Lsa::LsaRef current,
Lsa::LsaRef candidate) const;
/**
* Does this Router-LSA point back to the router link that points
* at it.
*
* @param rl_type type of link p2p or vlink
* @param link_state_id from RouterLSA that points at rlsa.
* @param rl link from RouterLSA that points at rlsa.
* @param rlsa that is pointed at by previous two arguments.
* @param metric (out argument) from rlsa back to link_state_id if the back
* pointer exists.
* @param interface_address (out argument) if the back pointer exists.
*
* @return true if the back pointer exists also fill in the metric
* and interface address.
* value.
*/
bool bidirectional(RouterLink::Type rl_type,
const uint32_t link_state_id,
const RouterLink& rl,
RouterLsa *rlsa,
uint16_t& metric,
uint32_t& interface_address);
/**
* Does this Network-LSA point back to the router link that points
* at it.
*/
bool bidirectional(const uint32_t link_state_id, const RouterLink& rl,
NetworkLsa *nlsa) const;
/**
* Does the Router-LSA point at the Network-LSA that points at it.
*
* @param interface_address (out argument) if the back pointer exists.
*
* @return true if Router-LSA points at the Network-LSA.
*/
bool bidirectional(RouterLsa *rlsa, NetworkLsa *nlsa,
uint32_t& interface_address);
/**
* Add this newly arrived or changed Router-LSA to the SPT.
*/
void routing_router_lsaV2(Spt<Vertex>& spt, const Vertex& src,
RouterLsa *rlsa);
void routing_router_link_p2p_vlinkV2(Spt<Vertex>& spt, const Vertex& src,
RouterLsa *rlsa, RouterLink rl);
void routing_router_link_transitV2(Spt<Vertex>& spt, const Vertex& src,
RouterLsa *rlsa, RouterLink rl);
void routing_router_link_stubV2(Spt<Vertex>& spt, const Vertex& src,
RouterLsa *rlsa, RouterLink rl);
/**
* Add this newly arrived or changed Router-LSA to the SPT.
*/
void routing_router_lsaV3(Spt<Vertex>& spt, const Vertex& v,
RouterLsa *rlsa);
};
/**
* DataBase Handle
*
* Holds state regarding position in the database
*/
class DataBaseHandle {
public:
DataBaseHandle() : _position(0), _last_entry(0), _valid(false)
{}
DataBaseHandle(bool v, uint32_t last_entry)
: _position(0), _last_entry(last_entry), _valid(v)
{}
uint32_t position() const {
XLOG_ASSERT(valid());
return _position;
}
uint32_t last() const {
XLOG_ASSERT(valid());
return _last_entry;
}
void advance(bool& last) {
XLOG_ASSERT(valid());
XLOG_ASSERT(_last_entry != _position);
_position++;
last = _last_entry == _position;
}
bool valid() const { return _valid; }
void invalidate() { _valid = false; }
private:
uint32_t _position; // Position in database.
uint32_t _last_entry; // One past last entry, for an empty
// database value would be 0.
bool _valid; // True if this handle is valid.
};
#endif // __OSPF_AREA_ROUTER_HH__
Generated by: pavlin on possum.icir.org on Thu Mar 9 04:43:44 2006, using kdoc $.