// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// Copyright (c) 2001-2007 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.
#ident "$XORP: xorp/rip/peer.cc,v 1.7 2007/02/16 22:47:14 pavlin Exp $"
#include "peer.hh"
#include "port.hh"
#include "system.hh"
template <typename A>
uint32_t
PeerRoutes<A>::expiry_secs() const
{
return _peer.expiry_secs();
}
template <typename A>
uint32_t
PeerRoutes<A>::deletion_secs() const
{
return _peer.deletion_secs();
}
template <typename A>
Peer<A>::Peer(RipPort& p, const Addr& addr)
: RouteEntryOrigin<A>(false), _port(p), _addr(addr),
_peer_routes(*this)
{
RouteDB<A>& rdb = _port.port_manager().system().route_db();
rdb.insert_peer(this);
}
template <typename A>
Peer<A>::~Peer()
{
RouteDB<A>& rdb = _port.port_manager().system().route_db();
rdb.erase_peer(this);
//
// XXX: explicitly remove all peer routes, because we don't use them
// as an indication whether the peer has expired.
//
_peer_routes.clear();
}
template <typename A>
uint32_t
Peer<A>::expiry_secs() const
{
return port().constants().expiry_secs();
}
template <typename A>
uint32_t
Peer<A>::deletion_secs() const
{
return port().constants().deletion_secs();
}
template <typename A>
bool
Peer<A>::update_route(const IPNet<A>& net,
const A& nexthop,
uint32_t cost,
uint32_t tag,
const PolicyTags& policytags)
{
Route* route = _peer_routes.find_route(net);
if (route == NULL) {
RouteEntryOrigin<A>* origin = &_peer_routes;
route = new Route(net, nexthop, cost, origin, tag, policytags);
}
set_expiry_timer(route);
RouteDB<A>& rdb = _port.port_manager().system().route_db();
return (rdb.update_route(net, nexthop, cost, tag, this, policytags,
false));
}
template <typename A>
void
Peer<A>::push_routes()
{
RouteDB<A>& rdb = _port.port_manager().system().route_db();
vector<const RouteEntry<A>*> routes;
if (! port().enabled())
return; // XXX: push routes only for enabled ports
_peer_routes.dump_routes(routes);
typename vector<const RouteEntry<A>*>::const_iterator ri;
for (ri = routes.begin(); ri != routes.end(); ++ri) {
const RouteEntry<A>* r = *ri;
rdb.update_route(r->net(), r->nexthop(), r->cost(), r->tag(),
this, r->policytags(), true);
}
}
template <typename A>
void
Peer<A>::set_expiry_timer(Route* route)
{
XorpTimer t;
uint32_t secs = expiry_secs();
EventLoop& eventloop = _port.port_manager().eventloop();
if (secs) {
t = eventloop.new_oneoff_after_ms(secs * 1000,
callback(this, &Peer<A>::expire_route, route));
}
route->set_timer(t);
}
template <typename A>
void
Peer<A>::expire_route(Route* route)
{
delete route;
}
// ----------------------------------------------------------------------------
// Instantiations
#ifdef INSTANTIATE_IPV4
template class Peer<IPv4>;
#endif
#ifdef INSTANTIATE_IPV6
template class Peer<IPv6>;
#endif
syntax highlighted by Code2HTML, v. 0.9.1