// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- // vim:set sts=4 ts=8: // Copyright (c) 2001-2009 XORP, Inc. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License, Version 2, June // 1991 as published by the Free Software Foundation. Redistribution // and/or modification of this program under the terms of any other // version of the GNU General Public License is not permitted. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details, // see the GNU General Public License, Version 2, a copy of which can be // found in the XORP LICENSE.gpl file. // // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA; // http://xorp.net // $XORP: xorp/rip/xrl_target_common.hh,v 1.40 2009/01/05 18:31:08 jtc 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, System<A>& rip_system); ~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_timeout(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs); XrlCmdError ripx_0_1_route_timeout(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_deletion_delay(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs); XrlCmdError ripx_0_1_deletion_delay(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_request_interval(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs); XrlCmdError ripx_0_1_request_interval(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_update_interval(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs); XrlCmdError ripx_0_1_update_interval(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_update_jitter(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_jitter); XrlCmdError ripx_0_1_update_jitter(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_triggered_update_delay(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs); XrlCmdError ripx_0_1_triggered_update_delay(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_triggered_update_jitter(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs); XrlCmdError ripx_0_1_triggered_update_jitter(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs); XrlCmdError ripx_0_1_set_interpacket_delay(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_msecs); XrlCmdError ripx_0_1_interpacket_delay(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 trace(bool enable); XrlCmdError socketx_user_0_1_recv_event(const string& sockid, const string& if_name, const string& vif_name, const A& src_host, const uint32_t& src_port, const vector<uint8_t>& pdata); XrlCmdError socketx_user_0_1_inbound_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_outgoing_connect_event( const string& sockid); XrlCmdError socketx_user_0_1_error_event(const string& sockid, const string& reason, const bool& fatal); XrlCmdError socketx_user_0_1_disconnect_event(const string& sockid); XrlCmdError policy_backend_0_1_configure(const uint32_t& filter, const string& conf); XrlCmdError policy_backend_0_1_reset(const uint32_t& filter); XrlCmdError policy_backend_0_1_push_routes(); XrlCmdError policy_redistx_0_1_add_routex(const IPNet<A>& net, const bool& unicast, const bool& multicast, const A& nexthop, const uint32_t& metric, const XrlAtomList& policytags); XrlCmdError policy_redistx_0_1_delete_routex(const IPNet<A>& net, const bool& unicast, const bool& multicast); /** * 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; System<A>& _rip_system; }; // ---------------------------------------------------------------------------- // Inline implementation of XrlRipCommonTarget template <typename A> XrlRipCommonTarget<A>::XrlRipCommonTarget(XrlProcessSpy& xps, XrlPortManager<A>& xpm, XrlRedistManager<A>& xrm, bool& should_exit, System<A>& rip_system) : _xps(xps), _xpm(xpm), _xrm(xrm), _should_exit(should_exit), _status(PROC_NULL), _status_note(""), _rip_system(rip_system) { } 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)", XORP_UINT_CAST(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, t, min_val, max_val, method) \ do { \ pair<Port<A>*, XrlCmdError> pp = find_port(ifname, vifname, addr); \ if (pp.first == 0) \ return pp.second; \ Port<A>* p = pp.first; \ \ if (static_cast<int32_t>(t) < min_val) \ return XrlCmdError::COMMAND_FAILED(c_format( \ "value supplied less than permitted minimum (%u < %u)", \ XORP_UINT_CAST(t), XORP_UINT_CAST(min_val))); \ if (t > max_val) \ return XrlCmdError::COMMAND_FAILED(c_format( \ "value supplied greater than permitted maximum (%u > %u)", \ XORP_UINT_CAST(t), XORP_UINT_CAST(max_val))); \ if (p->constants().set_##field (t) == false) \ return XrlCmdError::COMMAND_FAILED( \ "Failed to set value."); \ p->reschedule_##method (); \ return XrlCmdError::OKAY(); \ } while (0) #define PORT_TIMER_GET_HANDLER(field, t) \ do { \ 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(); \ } while (0) template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_route_timeout( const string& ifname, const string& vifname, const A& addr, const uint32_t& t ) { PORT_TIMER_SET_HANDLER(expiry_secs, t, 10, 10000, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_route_timeout( const string& ifname, const string& vifname, const A& addr, uint32_t& t ) { PORT_TIMER_GET_HANDLER(expiry_secs, t); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_deletion_delay( const string& ifname, const string& vifname, const A& addr, const uint32_t& t ) { PORT_TIMER_SET_HANDLER(deletion_secs, t, 10, 10000, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_deletion_delay( const string& ifname, const string& vifname, const A& addr, uint32_t& t ) { PORT_TIMER_GET_HANDLER(deletion_secs, t); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_request_interval( const string& ifname, const string& vifname, const A& addr, const uint32_t& t ) { PORT_TIMER_SET_HANDLER(table_request_period_secs, t, 0, 10000, request_table_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_request_interval( const string& ifname, const string& vifname, const A& addr, uint32_t& t ) { PORT_TIMER_GET_HANDLER(table_request_period_secs, t); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_update_interval( const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs ) { PORT_TIMER_SET_HANDLER(update_interval, t_secs, 1, 600, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_update_interval(const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs) { PORT_TIMER_GET_HANDLER(update_interval, t_secs); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_update_jitter(const string& ifname, const string& vifname, const A& addr, const uint32_t& t_jitter) { PORT_TIMER_SET_HANDLER(update_jitter, t_jitter, 0, 100, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_update_jitter(const string& ifname, const string& vifname, const A& addr, uint32_t& t_jitter) { PORT_TIMER_GET_HANDLER(update_jitter, t_jitter); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_triggered_update_delay( const string& ifname, const string& vifname, const A& addr, const uint32_t& t_secs) { PORT_TIMER_SET_HANDLER(triggered_update_delay, t_secs, 1, 10000, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_triggered_update_delay( const string& ifname, const string& vifname, const A& addr, uint32_t& t_secs) { PORT_TIMER_GET_HANDLER(triggered_update_delay, t_secs); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_triggered_update_jitter( const string& ifname, const string& vifname, const A& addr, const uint32_t& t_jitter) { PORT_TIMER_SET_HANDLER(triggered_update_jitter, t_jitter, 0, 100, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_triggered_update_jitter( const string& ifname, const string& vifname, const A& addr, uint32_t& t_jitter) { PORT_TIMER_GET_HANDLER(triggered_update_jitter, t_jitter); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_set_interpacket_delay( const string& ifname, const string& vifname, const A& addr, const uint32_t& t_msecs ) { PORT_TIMER_SET_HANDLER(interpacket_delay_ms, t_msecs, 10, 10000, dummy_timer); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::ripx_0_1_interpacket_delay( const string& ifname, const string& vifname, const A& addr, uint32_t& t_msecs ) { PORT_TIMER_GET_HANDLER(interpacket_delay_ms, t_msecs); } 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().sec(); return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::trace(bool enable) { _rip_system.route_trace().all(enable); _xpm.packet_trace().all(enable); return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::socketx_user_0_1_recv_event( const string& sockid, const string& if_name, const string& vif_name, const A& src_host, const uint32_t& src_port, const vector<uint8_t>& pdata ) { _xpm.deliver_packet(sockid, if_name, vif_name, src_host, src_port, pdata); return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::socketx_user_0_1_inbound_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_inbound_connect_event %s %s/%u %s\n", sockid.c_str(), src_host.str().c_str(), XORP_UINT_CAST(src_port), new_sockid.c_str()); UNUSED(sockid); UNUSED(src_host); UNUSED(src_port); UNUSED(new_sockid); accept = false; return XrlCmdError::COMMAND_FAILED("Inbound connect not requested."); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::socketx_user_0_1_outgoing_connect_event( const string& sockid ) { debug_msg("socketx_user_0_1_outgoing_connect_event %s\n", sockid.c_str()); UNUSED(sockid); return XrlCmdError::COMMAND_FAILED("Outgoing 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_disconnect_event( const string& sockid ) { debug_msg("socketx_user_0_1_disconnect_event %s\n", sockid.c_str()); UNUSED(sockid); return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::policy_backend_0_1_configure(const uint32_t& filter, const string& conf) { try { _rip_system.configure_filter(filter, conf); } catch(const PolicyException& e) { return XrlCmdError::COMMAND_FAILED("Filter configure failed: " + e.str()); } return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::policy_backend_0_1_reset(const uint32_t& filter) { try { _rip_system.reset_filter(filter); } catch(const PolicyException& e) { return XrlCmdError::COMMAND_FAILED("Filter reset failed: " + e.str()); } return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::policy_backend_0_1_push_routes() { _rip_system.push_routes(); return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::policy_redistx_0_1_add_routex(const IPNet<A>& net, const bool& unicast, const bool& multicast, const A& nexthop, const uint32_t& metric, const XrlAtomList& policytags) { string ifname, vifname; UNUSED(multicast); if (! unicast) return XrlCmdError::OKAY(); // // XXX: The interface and vif name are empty, because the policy // mechanism doesn't support setting them (yet). // _xrm.add_route(net, nexthop, ifname, vifname, metric, 0, policytags); return XrlCmdError::OKAY(); } template <typename A> XrlCmdError XrlRipCommonTarget<A>::policy_redistx_0_1_delete_routex(const IPNet<A>& net, const bool& unicast, const bool& multicast) { UNUSED(multicast); if (! unicast) return XrlCmdError::OKAY(); _xrm.delete_route(net); return XrlCmdError::OKAY(); } #endif // __RIPX_XRL_TARGET_COMMON_HH__