Source: ../../rip/xrl_target_common.hh


 
LOGO
 Annotated List  Files  Globals  Hierarchy  Index  Top
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-

// 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/rip/xrl_target_common.hh,v 1.15 2004/06/21 18:06:04 hodson Exp $

#ifndef __RIP_XRL_TARGET_COMMON_HH__
#define __RIP_XRL_TARGET_COMMON_HH__

#include "libxorp/status_codes.h"

#include "peer.hh"

class XrlProcessSpy;
template <typename A> class XrlPortManager;
template <typename A> class System;
template <typename A> class XrlRedistManager;

/**
 * @short Common handler for Xrl Requests.
 *
 * This class implements Xrl Target code that is common to both RIP
 * and RIP NG.
 */
template <typename A>
class XrlRipCommonTarget {
public:
    XrlRipCommonTarget(XrlProcessSpy& 		xps,
		       XrlPortManager<A>&	xpm,
		       XrlRedistManager<A>&	xrm,
		       bool& 			should_exit);

    ~XrlRipCommonTarget();

    void set_status(ProcessStatus ps, const string& annotation = "");

    XrlCmdError common_0_1_get_status(uint32_t& status, string& reason);

    XrlCmdError common_0_1_shutdown();

    XrlCmdError
    finder_event_observer_0_1_xrl_target_birth(const string& class_name,
					       const string& instance_name);

    XrlCmdError
    finder_event_observer_0_1_xrl_target_death(const string& class_name,
					       const string& instance_name);

    XrlCmdError
    ripx_0_1_add_rip_address(const string&	ifname,
			     const string&	vifname,
			     const A&		addr);

    XrlCmdError
    ripx_0_1_remove_rip_address(const string&	ifname,
				const string&	vifname,
				const A&	addr);

    XrlCmdError
    ripx_0_1_set_rip_address_enabled(const string&	ifname,
				     const string&	vifname,
				     const A&		addr,
				     const bool&	enabled);

    XrlCmdError
    ripx_0_1_rip_address_enabled(const string&	ifname,
				 const string&	vifname,
				 const A&	addr,
				 bool&		enabled);

    XrlCmdError ripx_0_1_set_cost(const string&		ifname,
				  const string&		vifname,
				  const A&		addr,
				  const uint32_t&	cost);

    XrlCmdError ripx_0_1_cost(const string&	ifname,
			      const string&	vifname,
			      const A&		addr,
			      uint32_t&		cost);

    XrlCmdError ripx_0_1_set_horizon(const string&	ifname,
				     const string&	vifname,
				     const A&		addr,
				     const string&	horizon);

    XrlCmdError ripx_0_1_horizon(const string&	ifname,
				 const string&	vifname,
				 const A&	addr,
				 string&	horizon);

    XrlCmdError ripx_0_1_set_passive(const string&	ifname,
				     const string&	vifname,
				     const A&		addr,
				     const bool&	passive);

    XrlCmdError ripx_0_1_passive(const string&	ifname,
				 const string&	vifname,
				 const A&	addr,
				 bool&		passive);

    XrlCmdError
    ripx_0_1_set_accept_non_rip_requests(const string&	ifname,
					 const string&	vifname,
					 const A&	addr,
					 const bool&	accept);

    XrlCmdError ripx_0_1_accept_non_rip_requests(const string&	ifname,
						 const string&	vifname,
						 const A&	addr,
						 bool&		accept);

    XrlCmdError ripx_0_1_set_accept_default_route(const string&	ifname,
						  const string&	vifname,
						  const A&	addr,
						  const bool&	accept);

    XrlCmdError ripx_0_1_accept_default_route(const string&	ifname,
					      const string&	vifname,
					      const A&		addr,
					      bool&		accept);

    XrlCmdError
    ripx_0_1_set_advertise_default_route(const string&	ifname,
					 const string&	vifname,
					 const A&	addr,
					 const bool&	advertise);

    XrlCmdError ripx_0_1_advertise_default_route(const string&	ifname,
						 const string&	vifname,
						 const A&	addr,
						 bool&		advertise);

    XrlCmdError
    ripx_0_1_set_route_expiry_seconds(const string&	ifname,
				      const string&	vifname,
				      const A&		addr,
				      const uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_route_expiry_seconds(const string&	ifname,
				  const string&	vifname,
				  const A&	addr,
				  uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_set_route_deletion_seconds(const string&	ifname,
					const string&	vifname,
					const A&	addr,
					const uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_route_deletion_seconds(const string&	ifname,
				    const string&	vifname,
				    const A&		addr,
				    uint32_t&		t_secs);

    XrlCmdError
    ripx_0_1_set_table_request_seconds(const string&	ifname,
				       const string&	vifname,
				       const A&		addr,
				       const uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_table_request_seconds(const string&	ifname,
				   const string&	vifname,
				   const A&		addr,
				   uint32_t&		t_secs);

    XrlCmdError
    ripx_0_1_set_unsolicited_response_min_seconds(const string&	ifname,
						  const string&	vifname,
						  const A&	addr,
						  const uint32_t& t_secs);

    XrlCmdError
    ripx_0_1_unsolicited_response_min_seconds(const string&	ifname,
					      const string&	vifname,
					      const A&		addr,
					      uint32_t&		t_secs);

    XrlCmdError
    ripx_0_1_set_unsolicited_response_max_seconds(
					const string&	ifname,
					const string&	vifname,
					const A&	addr,
					const uint32_t&	t_secs
					);

    XrlCmdError
    ripx_0_1_unsolicited_response_max_seconds(const string&	ifname,
					      const string&	vifname,
					      const A&		addr,
					      uint32_t&		t_secs);

    XrlCmdError
    ripx_0_1_set_triggered_update_min_seconds(const string&	ifname,
					      const string&	vifname,
					      const A&		addr,
					      const uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_triggered_update_min_seconds(const string&	ifname,
					  const string&	vifname,
					  const A&	addr,
					  uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_set_triggered_update_max_seconds(const string&	ifname,
					      const string&	vifname,
					      const A&		addr,
					      const uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_triggered_update_max_seconds(const string&	ifname,
					  const string&	vifname,
					  const A&	addr,
					  uint32_t&	t_secs);

    XrlCmdError
    ripx_0_1_set_interpacket_delay_milliseconds(const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t_msecs);

    XrlCmdError
    ripx_0_1_interpacket_delay_milliseconds(const string&	ifname,
					    const string&	vifname,
					    const A&		addr,
					    uint32_t&		t_msecs);

    XrlCmdError ripx_0_1_rip_address_status(const string&	ifname,
					    const string&	vifname,
					    const A&		addr,
					    string&		status);

    XrlCmdError ripx_0_1_get_all_addresses(XrlAtomList&	ifnames,
					   XrlAtomList&	vifnames,
					   XrlAtomList&	addrs);

    XrlCmdError ripx_0_1_get_peers(const string& ifname,
				   const string& vifname,
				   const A&	 addr,
				   XrlAtomList&	 peers);

    XrlCmdError ripx_0_1_get_all_peers(XrlAtomList& peers,
				       XrlAtomList& ifnames,
				       XrlAtomList& vifnames,
				       XrlAtomList& addrs);

    XrlCmdError ripx_0_1_get_counters(const string&	ifname,
				      const string&	vifname,
				      const A&		addr,
				      XrlAtomList&	descriptions,
				      XrlAtomList&	values);

    XrlCmdError ripx_0_1_get_peer_counters(const string&	ifname,
					   const string&	vifname,
					   const A&		addr,
					   const A&		peer,
					   XrlAtomList&		descriptions,
					   XrlAtomList&		values,
					   uint32_t&		peer_last_pkt);

    XrlCmdError ripx_0_1_redist_protocol_routes(const string&	protocol,
						const uint32_t& cost,
						const uint32_t& tag);

    XrlCmdError ripx_0_1_no_redist_protocol_routes(const string& protocol);

    XrlCmdError redistx_0_1_add_route(const IPNet<A>&		net,
				      const A&			nexthop,
				      const string&		ifname,
				      const string&		vifname,
				      const uint32_t&		metric,
				      const uint32_t&		ad,
				      const string&		cookie);

    XrlCmdError redistx_0_1_delete_route(const IPNet<A>&	net,
					 const string&		cookie);

    XrlCmdError socketx_user_0_1_recv_event(const string&	sockid,
					    const A&		src_host,
					    const uint32_t&	src_port,
					    const vector<uint8_t>& pdata);

    XrlCmdError socketx_user_0_1_connect_event(const string&	sockid,
					       const A&		src_host,
					       const uint32_t&	src_port,
					       const string&	new_sockid,
					       bool&		accept);

    XrlCmdError socketx_user_0_1_error_event(const string&	sockid,
					     const string& 	reason,
					     const bool&	fatal);

    XrlCmdError socketx_user_0_1_close_event(const string&	sockid,
					     const string&	reason);

    /**
     * Find Port associated with ifname, vifname, addr.
     *
     * @return on success the first item in the pair will be a
     * non-null pointer to the port and the second item with be
     * XrlCmdError::OKAY().  On failyre the first item in the pair
     * will be null and the XrlCmdError will signify the reason for
     * the failure.
     */
    pair<Port<A>*,XrlCmdError> find_port(const string&	ifname,
					 const string&	vifname,
					 const A&	addr);

protected:
    XrlProcessSpy&		_xps;
    XrlPortManager<A>&		_xpm;
    XrlRedistManager<A>&	_xrm;

    bool&			_should_exit;

    ProcessStatus		_status;
    string			_status_note;
};


// ----------------------------------------------------------------------------
// Inline implementation of XrlRipCommonTarget

template <typename A>
XrlRipCommonTarget<A>::XrlRipCommonTarget(XrlProcessSpy&	xps,
					  XrlPortManager<A>& 	xpm,
					  XrlRedistManager<A>&	xrm,
					  bool&			should_exit)
    : _xps(xps), _xpm(xpm), _xrm(xrm),
      _should_exit(should_exit), _status(PROC_NULL), _status_note("")
{
}

template <typename A>
XrlRipCommonTarget<A>::~XrlRipCommonTarget()
{
}

template <typename A>
void
XrlRipCommonTarget<A>::set_status(ProcessStatus status, const string& note)
{
    debug_msg("Status Update %d -> %d: %s\n", _status, status, note.c_str());
    _status 	 = status;
    _status_note = note;
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::common_0_1_get_status(uint32_t& status,
					     string&   reason)
{
    status = _status;
    reason = _status_note;
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::common_0_1_shutdown()
{
    debug_msg("Shutdown requested.\n");
    _should_exit = true;
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::finder_event_observer_0_1_xrl_target_birth(
							const string& cname,
							const string& iname
							)
{
    _xps.birth_event(cname, iname);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::finder_event_observer_0_1_xrl_target_death(
							const string& cname,
							const string& iname
							)
{
    _xps.death_event(cname, iname);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_add_rip_address(const string&	ifname,
					       const string&	vifname,
					       const A&		addr)
{
    debug_msg("rip_x_1_add_rip_address %s/%s/%s\n",
	      ifname.c_str(), vifname.c_str(), addr.str().c_str());
    if (_xpm.add_rip_address(ifname, vifname, addr) == false) {
	return XrlCmdError::COMMAND_FAILED();
    }
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_remove_rip_address(const string& ifname,
					 const string&		 vifname,
					 const A&   		 addr)
{
    debug_msg("ripx_0_1_remove_rip_address %s/%s/%s\n",
	      ifname.c_str(), vifname.c_str(), addr.str().c_str());
    if (_xpm.remove_rip_address(ifname, vifname, addr) == false) {
	return XrlCmdError::COMMAND_FAILED();
    }
    return XrlCmdError::OKAY();
}


// ----------------------------------------------------------------------------
// Utility methods

template <typename A>
pair<Port<A>*, XrlCmdError>
XrlRipCommonTarget<A>::find_port(const string&	ifn,
				 const string&	vifn,
				 const A&	addr)
{
    Port<A>* p = _xpm.find_port(ifn, vifn, addr);
    if (p == 0) {
	string e = c_format("RIP not running on %s/%s/%s",
			    ifn.c_str(), vifn.c_str(), addr.str().c_str());
	return make_pair(p, XrlCmdError::COMMAND_FAILED(e));
    }
    return make_pair(p, XrlCmdError::OKAY());
}


// ----------------------------------------------------------------------------
// Port configuration accessors and modifiers

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_rip_address_enabled(const string&	ifn,
							const string&	vifn,
							const A&	addr,
							const bool&	en)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifn, vifn, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    p->set_enabled(en);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_rip_address_enabled(const string& ifn,
						    const string& vifn,
						    const A&	  addr,
						    bool&	  en)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifn, vifn, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    en = p->enabled();

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_cost(const string&	ifname,
			       const string&		vifname,
			       const A&			addr,
			       const uint32_t&		cost)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;

    if (cost > RIP_INFINITY) {
	string e = c_format("Cost must be less that RIP infinity (%u)",
			    RIP_INFINITY);
	return XrlCmdError::COMMAND_FAILED(e);
    }

    p->set_cost(cost);

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_cost(const string&	ifname,
				     const string&	vifname,
				     const A&		addr,
				     uint32_t&		cost)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    cost = p->cost();

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_horizon(const string&	ifname,
					    const string&	vifname,
					    const A&		addr,
					    const string&	horizon)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;

    RipHorizon rh[3] = { NONE, SPLIT, SPLIT_POISON_REVERSE };
    for (uint32_t i = 0; i < 3; ++i) {
	if (string(rip_horizon_name(rh[i])) == horizon) {
	    p->set_horizon(rh[i]);
	    return XrlCmdError::OKAY();
	}
    }
    return XrlCmdError::COMMAND_FAILED(
			c_format("Horizon type \"%s\" not recognized.",
				 horizon.c_str()));
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_horizon(const string&	ifname,
					const string&	vifname,
					const A&	addr,
					string&		horizon)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    horizon = rip_horizon_name(p->horizon());
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_passive(const string&	ifname,
					    const string&	vifname,
					    const A&		addr,
					    const bool&		passive)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    p->set_passive(passive);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_passive(const string&	ifname,
					const string&	vifname,
					const A&	addr,
					bool&		passive)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    passive = p->passive();
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_accept_non_rip_requests(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const bool&	accept
						)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    p->set_accept_non_rip_requests(accept);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_accept_non_rip_requests(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						bool&		accept
						)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    accept = p->accept_non_rip_requests();
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_accept_default_route(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const bool&	accept
						)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    p->set_accept_default_route(accept);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_accept_default_route(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						bool&		accept
						)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    accept = p->accept_default_route();
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_advertise_default_route(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const bool&	advertise
						)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    p->set_advertise_default_route(advertise);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_advertise_default_route(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						bool&		advertise
						)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    advertise = p->advertise_default_route();
    return XrlCmdError::OKAY();
}


// ----------------------------------------------------------------------------
// The following pair of macros are used in setting timer constants on
// RIP ports.

#define PORT_TIMER_SET_HANDLER(field, min_val, max_val)			\
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);	\
    if (pp.first == 0)							\
	return pp.second;						\
    Port<A>* p = pp.first;						\
									\
    if (t < min_val) 							\
	return XrlCmdError::COMMAND_FAILED(c_format(			\
	    "value supplied less than permitted minimum (%u < %u)", 	\
	    t, min_val));						\
    if (t > max_val) 							\
	return XrlCmdError::COMMAND_FAILED(c_format(			\
	    "value supplied greater than permitted maximum (%u > %u)", 	\
	    t, max_val));						\
    if (p->constants().set_##field (t) == false)			\
	return XrlCmdError::COMMAND_FAILED(				\
	    "Failed to set value.");					\
    return XrlCmdError::OKAY();

#define PORT_TIMER_GET_HANDLER(field)					\
    pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr);	\
    if (pp.first == 0)							\
	return pp.second;						\
    Port<A>* p = pp.first;						\
    t = p->constants(). field ();					\
    return XrlCmdError::OKAY();


template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_route_expiry_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t
						)
{
    PORT_TIMER_SET_HANDLER(expiry_secs, 10, 10000);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_route_expiry_seconds(
					     const string&	ifname,
					     const string&	vifname,
					     const A&		addr,
					     uint32_t&		t
					     )
{
    PORT_TIMER_GET_HANDLER(expiry_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_route_deletion_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t
						)
{
    PORT_TIMER_SET_HANDLER(deletion_secs, 10, 10000);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_route_deletion_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(deletion_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_table_request_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t
						)
{
    PORT_TIMER_SET_HANDLER(table_request_period_secs, 1, 10000);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_table_request_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(table_request_period_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_unsolicited_response_min_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t& t
						)
{
    PORT_TIMER_SET_HANDLER(unsolicited_response_min_secs, 1, 300);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_unsolicited_response_min_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(unsolicited_response_min_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_unsolicited_response_max_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t& t
						)
{
    PORT_TIMER_SET_HANDLER(unsolicited_response_max_secs, 1, 600);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_unsolicited_response_max_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(unsolicited_response_max_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_triggered_update_min_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t
						)
{
    PORT_TIMER_SET_HANDLER(triggered_update_min_wait_secs, 1, 10000);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_triggered_update_min_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(triggered_update_min_wait_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_triggered_update_max_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t
						)
{
    PORT_TIMER_SET_HANDLER(triggered_update_max_wait_secs, 1, 10000);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_triggered_update_max_seconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(triggered_update_max_wait_secs);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_set_interpacket_delay_milliseconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						const uint32_t&	t
						)
{
    PORT_TIMER_SET_HANDLER(interpacket_delay_ms, 10, 10000);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_interpacket_delay_milliseconds(
						const string&	ifname,
						const string&	vifname,
						const A&	addr,
						uint32_t&	t
						)
{
    PORT_TIMER_GET_HANDLER(interpacket_delay_ms);
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_rip_address_status(const string&	ifn,
						  const string&		vifn,
						  const A&		addr,
						  string&		status)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifn, vifn, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    status = p->enabled() ? "enabled" : "disabled";

    if (p->enabled()
	&& _xpm.underlying_rip_address_up(ifn, vifn, addr) == false) {
	if (_xpm.underlying_rip_address_exists(ifn, vifn, addr)) {
	    status += " [gated by disabled FEA interface/vif/address]";
	} else {
	    status += " [gated by non-existant FEA interface/vif/address]";
	}
    }

    debug_msg("ripx_0_1_rip_address_status %s/%s/%s -> %s\n",
	      ifn.c_str(), vifn.c_str(), addr.str().c_str(),
	      status.c_str());

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_get_all_addresses(XrlAtomList&	ifnames,
						  XrlAtomList&	vifnames,
						  XrlAtomList&	addrs)
{
    const typename PortManagerBase<A>::PortList & ports = _xpm.const_ports();
    typename PortManagerBase<A>::PortList::const_iterator pci;

    for (pci = ports.begin(); pci != ports.end(); ++pci) {
	const Port<A>*	     	port = *pci;
	const PortIOBase<A>* 	pio  = port->io_handler();
	if (pio == 0) {
	    continue;
	}
	ifnames.append  ( XrlAtom(pio->ifname())   );
	vifnames.append ( XrlAtom(pio->vifname())  );
	addrs.append    ( XrlAtom(pio->address())  );
    }
    return XrlCmdError::OKAY();
}


template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_get_peers(const string&	ifn,
					  const string&	vifn,
					  const A&	addr,
					  XrlAtomList&	peers)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifn, vifn, addr);
    if (pp.first == 0)
	return pp.second;

    Port<A>* p = pp.first;
    typename Port<A>::PeerList::const_iterator pi = p->peers().begin();
    while (pi != p->peers().end()) {
	const Peer<A>* peer = *pi;
	peers.append(XrlAtom(peer->address()));
	++pi;
    }
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_get_all_peers(XrlAtomList&	peers,
					      XrlAtomList&	ifnames,
					      XrlAtomList&	vifnames,
					      XrlAtomList&	addrs)
{
    const typename PortManagerBase<A>::PortList & ports = _xpm.const_ports();
    typename PortManagerBase<A>::PortList::const_iterator pci;

    for (pci = ports.begin(); pci != ports.end(); ++pci) {
	const Port<A>* port = *pci;
	const PortIOBase<A>* pio = port->io_handler();
	if (pio == 0) {
	    continue;
	}

	typename Port<A>::PeerList::const_iterator pi;
	for (pi = port->peers().begin(); pi != port->peers().end(); ++pi) {
	    const Peer<A>* peer = *pi;
	    peers.append    ( XrlAtom(peer->address()) );
	    ifnames.append  ( XrlAtom(pio->ifname())   );
	    vifnames.append ( XrlAtom(pio->vifname())  );
	    addrs.append    ( XrlAtom(pio->address())  );
	}
    }
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_get_counters(const string&	ifn,
					     const string&	vifn,
					     const A&		addr,
					     XrlAtomList&	descriptions,
					     XrlAtomList&	values)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifn, vifn, addr);
    if (pp.first == 0)
	return pp.second;

    const Port<A>* p = pp.first;
    descriptions.append(XrlAtom("", string("Requests Sent")));
    values.append(XrlAtom(p->counters().table_requests_sent()));

    descriptions.append(XrlAtom("", string("Updates Sent")));
    values.append(XrlAtom(p->counters().unsolicited_updates()));

    descriptions.append(XrlAtom("", string("Triggered Updates Sent")));
    values.append(XrlAtom(p->counters().triggered_updates()));

    descriptions.append(XrlAtom("", string("Non-RIP Updates Sent")));
    values.append(XrlAtom(p->counters().non_rip_updates_sent()));

    descriptions.append(XrlAtom("", string("Total Packets Received")));
    values.append(XrlAtom(p->counters().packets_recv()));

    descriptions.append(XrlAtom("", string("Request Packets Received")));
    values.append(XrlAtom(p->counters().table_requests_recv()));

    descriptions.append(XrlAtom("", string("Update Packets Received")));
    values.append(XrlAtom(p->counters().update_packets_recv()));

    descriptions.append(XrlAtom("", string("Bad Packets Received")));
    values.append(XrlAtom(p->counters().bad_packets()));

    if (A::ip_version() == 4) {
	descriptions.append(XrlAtom("", string("Authentication Failures")));
	values.append(XrlAtom(p->counters().bad_auth_packets()));
    }

    descriptions.append(XrlAtom("", string("Bad Routes Received")));
    values.append(XrlAtom(p->counters().bad_routes()));

    descriptions.append(XrlAtom("", string("Non-RIP Requests Received")));
    values.append(XrlAtom(p->counters().non_rip_requests_recv()));

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_get_peer_counters(
					const string&	ifn,
					const string&	vifn,
					const A&	addr,
					const A&	peer_addr,
					XrlAtomList&	descriptions,
					XrlAtomList&	values,
					uint32_t&	peer_last_active)
{
    pair<Port<A>*, XrlCmdError> pp = find_port(ifn, vifn, addr);
    if (pp.first == 0)
	return pp.second;

    const Port<A>* port = pp.first;

    typename Port<A>::PeerList::const_iterator pi;
    pi = find_if(port->peers().begin(), port->peers().end(),
		 peer_has_address<A>(peer_addr));

    if (pi == port->peers().end()) {
	return XrlCmdError::COMMAND_FAILED(
		c_format("Peer %s not found on %s/%s/%s",
			 peer_addr.str().c_str(), ifn.c_str(), vifn.c_str(),
			 addr.str().c_str())
		);
    }

    const Peer<A>* const peer = *pi;

    descriptions.append(  XrlAtom("", string("Total Packets Received")) );
    values.append( XrlAtom(peer->counters().packets_recv()) );

    descriptions.append(XrlAtom("", string("Request Packets Received")));
    values.append(XrlAtom(peer->counters().table_requests_recv()));

    descriptions.append(XrlAtom("", string("Update Packets Received")));
    values.append(XrlAtom(peer->counters().update_packets_recv()));

    descriptions.append(XrlAtom("", string("Bad Packets Received")));
    values.append(XrlAtom(peer->counters().bad_packets()));

    if (A::ip_version() == 4) {
	descriptions.append(XrlAtom("", string("Authentication Failures")));
	values.append(XrlAtom(peer->counters().bad_auth_packets()));
    }

    descriptions.append(XrlAtom("", string("Bad Routes Received")));
    values.append(XrlAtom(peer->counters().bad_routes()));

    descriptions.append(XrlAtom("", string("Routes Active")));
    values.append(XrlAtom(peer->route_count()));

    peer_last_active = peer->last_active().secs();

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_redist_protocol_routes(const string&	protocol,
						       const uint32_t&	cost,
						       const uint32_t& 	tag)
{
    _xrm.request_redist_for(protocol, cost, tag);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::ripx_0_1_no_redist_protocol_routes(const string& protocol)
{
    _xrm.request_no_redist_for(protocol);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::redistx_0_1_add_route(const IPNet<A>&	net,
					     const A&		nexthop,
					     const string&	/* ifname */,
					     const string&	/* vifname */,
					     const uint32_t&	/* metric */,
					     const uint32_t&	/* admin_d */,
					     const string&	cookie)
{
    // We use cookie of the protocol name to make find the relevant redist table simple.
    _xrm.add_route(cookie, net, nexthop);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::redistx_0_1_delete_route(const IPNet<A>&	net,
						const string&	cookie)
{
    _xrm.delete_route(cookie, net);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::socketx_user_0_1_recv_event(
					const string&		sockid,
					const A&		src_host,
					const uint32_t&		src_port,
					const vector<uint8_t>&	pdata
					)
{
    _xpm.deliver_packet(sockid, src_host, src_port, pdata);
    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::socketx_user_0_1_connect_event(
					const string&	sockid,
					const A&	src_host,
					const uint32_t&	src_port,
					const string&	new_sockid,
					bool&		accept
					)
{
    debug_msg("socketx_user_0_1_connect_event %s %s/%u %s\n",
	      sockid.c_str(), src_host.str().c_str(), src_port,
	      new_sockid.c_str());

    UNUSED(sockid);
    UNUSED(src_host);
    UNUSED(src_port);
    UNUSED(new_sockid);

    accept = false;
    return XrlCmdError::COMMAND_FAILED("Connect not requested.");
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::socketx_user_0_1_error_event(
					const string&	sockid,
					const string& 	reason,
					const bool&	fatal
					)
{
    debug_msg("socketx_user_0_1_error_event %s %s %s \n",
	      sockid.c_str(), reason.c_str(),
	      fatal ? "fatal" : "non-fatal");

    UNUSED(sockid);
    UNUSED(reason);
    UNUSED(fatal);

    return XrlCmdError::OKAY();
}

template <typename A>
XrlCmdError
XrlRipCommonTarget<A>::socketx_user_0_1_close_event(
					const string&	sockid,
					const string&	reason
					)
{
    debug_msg("socketx_user_0_1_close_event %s %s\n",
	      sockid.c_str(), reason.c_str());

    UNUSED(sockid);
    UNUSED(reason);

    return XrlCmdError::OKAY();
}

#endif // __RIPX_XRL_TARGET_COMMON_HH__

Generated by: pavlin on possum.icir.org on Thu Jul 8 23:48:39 2004, using kdoc $.