// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
// vim:set sts=4 ts=8:
// 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/redist.cc,v 1.12 2007/02/16 22:47:15 pavlin Exp $"
#include "rip_module.h"
#include "libxorp/xlog.h"
#include "libxorp/eventloop.hh"
#include "libxorp/ipv4.hh"
#include "libxorp/ipv6.hh"
#include "libxorp/ipv4net.hh"
#include "libxorp/ipv6net.hh"
#include "constants.hh"
#include "route_db.hh"
#include "route_entry.hh"
#include "redist.hh"
// ----------------------------------------------------------------------------
// RedistRouteOrigin
template <typename A>
uint32_t
RedistRouteOrigin<A>::expiry_secs() const
{
return 0;
}
template <typename A>
uint32_t
RedistRouteOrigin<A>::deletion_secs() const
{
return DEFAULT_DELETION_SECS;
}
// ----------------------------------------------------------------------------
// RouteRedistributor
template <typename A>
RouteRedistributor<A>::RouteRedistributor(RouteDB<A>& rdb,
const string& protocol,
uint16_t cost,
uint16_t tag)
: _route_db(rdb), _protocol(protocol), _cost(cost), _tag(tag), _wdrawer(0)
{
_rt_origin = new RedistRouteOrigin<A>();
}
template <typename A>
RouteRedistributor<A>::~RouteRedistributor()
{
delete _rt_origin;
delete _wdrawer;
}
template <typename A>
bool
RouteRedistributor<A>::add_route(const Net& net, const Addr& nexthop,
const PolicyTags& policytags)
{
_route_db.add_rib_route(net, nexthop, _cost, _tag, _rt_origin, policytags);
return _route_db.update_route(net, nexthop, _cost, _tag, _rt_origin,
policytags, false);
}
template <typename A>
bool
RouteRedistributor<A>::add_route(const Net& net,
const Addr& nexthop,
uint16_t cost,
uint16_t tag,
const PolicyTags& policytags)
{
_route_db.add_rib_route(net, nexthop, cost, tag, _rt_origin, policytags);
return _route_db.update_route(net, nexthop, cost, tag, _rt_origin,
policytags, false);
}
template <typename A>
bool
RouteRedistributor<A>::expire_route(const Net& net)
{
_route_db.delete_rib_route(net);
return _route_db.update_route(net, A::ZERO(), RIP_INFINITY,
_tag, _rt_origin, PolicyTags(), false);
}
template <typename A>
const string&
RouteRedistributor<A>::protocol() const
{
return _protocol;
}
template <typename A>
uint16_t
RouteRedistributor<A>::tag() const
{
return _tag;
}
template <typename A>
uint16_t
RouteRedistributor<A>::cost() const
{
return _cost;
}
template <typename A>
uint32_t
RouteRedistributor<A>::route_count() const
{
return _rt_origin->route_count();
}
template <typename A>
void
RouteRedistributor<A>::withdraw_routes()
{
if (_wtimer.scheduled() == false) {
EventLoop& e = _route_db.eventloop();
_wtimer = e.new_periodic_ms(5,
callback(this, &RouteRedistributor::withdraw_batch));
}
}
template <typename A>
bool
RouteRedistributor<A>::withdrawing_routes() const
{
return _wtimer.scheduled();
}
template <typename A>
bool
RouteRedistributor<A>::withdraw_batch()
{
if (_wdrawer == 0) {
_wdrawer = new RouteWalker<A>(_route_db);
_wdrawer->reset();
}
XLOG_ASSERT(_wdrawer->state() == RouteWalker<A>::STATE_RUNNING);
uint32_t visited = 0;
const RouteEntry<A>* r = _wdrawer->current_route();
while (r != 0) {
if (r->origin() == _rt_origin) {
_route_db.update_route(r->net(), r->nexthop(),
RIP_INFINITY, r->tag(),
_rt_origin, r->policytags(), false);
}
r = _wdrawer->next_route();
if (++visited == 5) {
return true; // we're not finished - reschedule timer
}
}
delete _wdrawer;
_wdrawer = 0;
return false; // we're finished - cancel timer
}
// ----------------------------------------------------------------------------
// Instantiations
#ifdef INSTANTIATE_IPV4
template class RedistRouteOrigin<IPv4>;
template class RouteRedistributor<IPv4>;
#endif
#ifdef INSTANTIATE_IPV6
template class RouteRedistributor<IPv6>;
template class RedistRouteOrigin<IPv6>;
#endif
syntax highlighted by Code2HTML, v. 0.9.1