433
437
template <typename A>
439
PeerManager<A>::enabled(const string& interface, const string& vif, A address)
441
debug_msg("Interface %s Vif %s Address %s\n", interface.c_str(),
442
vif.c_str(), cstring(address));
444
switch (_ospf.get_version()) {
448
// If the address is set to zero then try and get the
449
// link-local address.
450
if (A::ZERO() == address) {
451
if (!_ospf.get_link_local_address(interface, vif, address))
452
if (_ospf.enabled(interface, vif))
453
XLOG_WARNING("link-local address must be configured "
454
"on %s/%s", interface.c_str(), vif.c_str());
458
return _ospf.enabled(interface, vif, address);
461
template <typename A>
434
462
OspfTypes::PeerID
435
463
PeerManager<A>::create_peer(const string& interface, const string& vif,
452
480
OspfTypes::PeerID peerid = create_peerid(interface, vif);
454
switch (_ospf.get_version()) {
458
if (OspfTypes::VirtualLink != linktype) {
459
// Note that the source address is going to be replaced with
460
// the link local address, unless this is a virtual link.
461
if (!_ospf.get_link_local_address(interface, vif, source)) {
462
destroy_peerid(interface, vif);
464
c_format("Unable to get link local address for "
466
interface.c_str(), vif.c_str()));
472
// Get the prefix length.
473
uint16_t interface_prefix_length;
474
if (!_ospf.get_prefix_length(interface, vif, source,
475
interface_prefix_length)) {
476
destroy_peerid(interface, vif);
478
c_format("Unable to get prefix length for %s/%s/%s",
479
interface.c_str(), vif.c_str(), cstring(source)));
483
uint16_t interface_mtu = _ospf.get_mtu(interface);
484
if (0 == interface_mtu) {
485
destroy_peerid(interface, vif);
487
c_format("Unable to get MTU for %s", interface.c_str()));
490
482
// If we got this far create_peerid did not throw an exception so
491
483
// this interface/vif is unique.
493
485
_peers[peerid] = new PeerOut<A>(_ospf, interface, vif, peerid,
494
source, interface_prefix_length,
495
interface_mtu, linktype,
496
area, area_router->get_area_type());
498
switch (_ospf.get_version()) {
501
case OspfTypes::V3: {
502
uint32_t interface_id;
503
if (!_ospf.get_interface_id(interface, vif, interface_id)) {
506
c_format("Unable to get interface ID for %s",
509
_peers[peerid]->set_interface_id(interface_id);
486
source, linktype, area,
487
area_router->get_area_type());
514
489
// Pass in the option to be sent by the hello packet.
515
490
_peers[peerid]->set_options(area,
516
491
compute_options(area_router->get_area_type()));
518
switch (_ospf.get_version()) {
520
_peers[peerid]->set_link_status(_ospf.enabled(interface, vif, source));
524
// If this is a virtual link bring it up now, otherwise
525
// wait for the call to activate.
526
if (OspfTypes::VirtualLink == linktype) {
527
_peers[peerid]->set_link_status(_ospf.enabled(interface, vif,
531
// This call needs to be made only once per invocation of OSPF
532
// but at this point we know that the interface mirror is up
534
_ospf.register_address_status(callback(this,
536
address_status_change));
540
// This call needs to be made only once per invocation of OSPF
541
// but at this point we know that the interface mirror is up
493
// These two registrations need to be made only once per
494
// invocation of OSPF, however, at this point we know that the interface
495
// mirror is up and running.
543
496
_ospf.register_vif_status(callback(this,
544
497
&PeerManager<A>::
545
498
vif_status_change));
499
_ospf.register_address_status(callback(this, &PeerManager<A>::
500
address_status_change));
547
502
area_router->add_peer(peerid);
549
// The peer has now been fully configured so initialise it.
550
_peers[peerid]->go(area);
504
// If the interface, vif and source are up the peer will start running.
505
_peers[peerid]->set_link_status(enabled(interface, vif, source));
929
893
template <typename A>
895
PeerManager<A>::clear_database()
897
// Drop all adjacencies.
898
typename map<OspfTypes::PeerID, PeerOut<A> *>::const_iterator p;
899
for(p = _peers.begin(); p != _peers.end(); p++) {
900
// If this peer is up then taking it down and bringing it up
901
// should drop all adjacencies.
902
if( (*p).second->get_state()) {
903
(*p).second->set_state(false);
904
(*p).second->set_state(true);
908
// Clear the AS-External-LSA database.
909
_external.clear_database();
911
// Clear the area databases.
912
typename map<OspfTypes::AreaID, AreaRouter<A> *>::const_iterator a;
913
for (a = _areas.begin(); a != _areas.end(); a++) {
914
// Changing the area type of the router will delete the
915
// Router-LSA generated by this router and revive it.
916
(*a).second->change_area_router_type((*a).second->get_area_type());
919
// Recompute the routes in all areas to withdraw the routes and
920
// remove virtual links. This will also cause the summary routes
921
// to be withdrawn. Should not be required as dropping the
922
// adjacencies should prompt a route recomputation.
923
routing_recompute_all_areas();
925
typename map<IPNet<A>, Summary>::iterator i;
926
for(i = _summaries.begin(); i != _summaries.end(); i++)
927
XLOG_WARNING("Summary not removed %s %s", cstring(i->first),
928
cstring(i->second._rtentry));
933
template <typename A>
931
935
PeerManager<A>::queue_lsa(const OspfTypes::PeerID peerid,
932
936
const OspfTypes::PeerID peer,
933
937
OspfTypes::NeighbourID nid, Lsa::LsaRef lsar,
1963
1981
template <typename A>
1983
PeerManager<A>::summary_replace(OspfTypes::AreaID area, IPNet<A> net,
1985
RouteEntry<A>& previous_rt,
1986
OspfTypes::AreaID previous_area)
1988
debug_msg("Area %s net %s rentry %s\n", pr_id(area).c_str(),
1989
cstring(net), cstring(rt));
1991
bool previous = summary_candidate(previous_area, net, previous_rt);
1992
bool current = summary_candidate(area, net, rt);
1994
if (current != previous) {
1996
summary_withdraw(previous_area, net, previous_rt);
1998
summary_announce(area, net, rt);
2002
XLOG_ASSERT(current == previous);
2004
// Don't need to check for !previous as it is the same as current.
2008
XLOG_ASSERT(current);
2009
XLOG_ASSERT(previous);
2011
_external.suppress_route_withdraw(previous_area, net, previous_rt);
2012
_external.suppress_route_announce(area, net, rt);
2014
XLOG_ASSERT(1 == _summaries.count(net));
2015
_summaries.erase(_summaries.find(net));
2016
Summary s(area, rt);
2017
_summaries.insert(make_pair(net, s));
2019
typename map<OspfTypes::AreaID, AreaRouter<A> *>::const_iterator i;
2020
for (i = _areas.begin(); i != _areas.end(); i++) {
2021
if ((*i).first == area) {
2022
if (area != previous_area)
2023
(*i).second->summary_withdraw(previous_area, net,
2027
if ((*i).first == previous_area) {
2028
if (area != previous_area)
2029
(*i).second->summary_announce(area, net, rt, false);
2032
(*i).second->summary_replace(area, net, rt, previous_rt,previous_area);
2036
template <typename A>
1965
2038
PeerManager<A>::summary_push(OspfTypes::AreaID area)
1967
2040
debug_msg("Area %s\n", pr_id(area).c_str());