⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xrl_rib_notifier.cc

📁 RIP 协议实现
💻 CC
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// vim:set sts=4 ts=8:// Copyright (c) 2001-2008 XORP, Inc.//// 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/xrl_rib_notifier.cc,v 1.19 2008/07/23 05:11:38 pavlin Exp $"// #define DEBUG_LOGGING#include "rip_module.h"#include "libxorp/debug.h"#include "libxorp/xlog.h"#include "libxorp/eventloop.hh"#include "libxipc/xrl_router.hh"#include "xrl/interfaces/rib_xif.hh"#include "constants.hh"#include "xrl_config.hh"#include "xrl_rib_notifier.hh"// ----------------------------------------------------------------------------// Type specific function pointers.//// The following type specific declarations and instantiations hold// function pointers to methods in the XrlRibV0p1Client class.  This// class contains similar methods for adding, updating, removing// routes for IPv4 and IPv6.  The methods have the same forms but have// different names and take different address argument types.  By// specializing just the function pointers, we avoid any// specialization of send related code in the XrlRibNotifier class// later on in this file.template <typename A>struct Send {    typedef bool (XrlRibV0p1Client::*AddIgpTable)	(const char*, const string&, const string&, const string&,	 const bool&, const bool&,	 const XrlRibV0p1Client::AddIgpTable4CB&);    typedef bool (XrlRibV0p1Client::*DeleteIgpTable)	(const char*, const string&, const string&, const string&,	 const bool&, const bool&,	 const XrlRibV0p1Client::DeleteIgpTable4CB&);    typedef bool (XrlRibV0p1Client::*AddRoute)	(const char*, const string&, const bool&, const bool&,	 const IPNet<A>&, const A&, const string&, const string&,	 const uint32_t&, const XrlAtomList&,	 const XrlRibV0p1Client::AddInterfaceRoute4CB&);    typedef bool (XrlRibV0p1Client::*ReplaceRoute)	(const char*, const string&, const bool&, const bool&,	 const IPNet<A>&, const A&, const string&, const string&,	 const uint32_t&, const XrlAtomList&,	 const XrlRibV0p1Client::ReplaceInterfaceRoute4CB&);    typedef bool (XrlRibV0p1Client::*DeleteRoute)	(const char*, const string&, const bool&, const bool&,	 const IPNet<A>&,	 const XrlRibV0p1Client::DeleteRoute4CB&);    static AddIgpTable		add_igp_table;    static DeleteIgpTable	delete_igp_table;    static AddRoute		add_route;    static ReplaceRoute		replace_route;    static DeleteRoute		delete_route;};//// IPv4 Specialized Function pointers//#ifdef INSTANTIATE_IPV4template <>Send<IPv4>::AddIgpTableSend<IPv4>::add_igp_table = &XrlRibV0p1Client::send_add_igp_table4;template <>Send<IPv4>::DeleteIgpTableSend<IPv4>::delete_igp_table = &XrlRibV0p1Client::send_delete_igp_table4;template <>Send<IPv4>::AddRouteSend<IPv4>::add_route = &XrlRibV0p1Client::send_add_interface_route4;template <>Send<IPv4>::ReplaceRouteSend<IPv4>::replace_route = &XrlRibV0p1Client::send_replace_interface_route4;template <>Send<IPv4>::DeleteRouteSend<IPv4>::delete_route = &XrlRibV0p1Client::send_delete_route4;#endif // INSTANTIATE_IPV4//// IPv6 Specialized Function pointers//#ifdef INSTANTIATE_IPV6template <>Send<IPv6>::AddIgpTableSend<IPv6>::add_igp_table = &XrlRibV0p1Client::send_add_igp_table6;template <>Send<IPv6>::DeleteIgpTableSend<IPv6>::delete_igp_table = &XrlRibV0p1Client::send_delete_igp_table6;template <>Send<IPv6>::AddRouteSend<IPv6>::add_route = &XrlRibV0p1Client::send_add_interface_route6;template <>Send<IPv6>::ReplaceRouteSend<IPv6>::replace_route = &XrlRibV0p1Client::send_replace_interface_route6;template <>Send<IPv6>::DeleteRouteSend<IPv6>::delete_route = &XrlRibV0p1Client::send_delete_route6;#endif // INSTANTIATE_IPV6// ----------------------------------------------------------------------------// XrlRibNotifier implementationtemplate <typename A>XrlRibNotifier<A>::XrlRibNotifier(EventLoop&		e,				  UpdateQueue<A>&	uq,				  XrlRouter&		xr,				  uint32_t		mf,				  uint32_t		pms)    : RibNotifierBase<A>(e, uq, pms), ServiceBase("RIB Updater"),      _xs(xr), _cname(xr.class_name()), _iname(xr.instance_name()),      _max_inflight(mf), _inflight(0){    set_status(SERVICE_READY);}template <typename A>XrlRibNotifier<A>::XrlRibNotifier(EventLoop&		e,				  UpdateQueue<A>&	uq,				  XrlSender&		xs,				  const string&		class_name,				  const string&		instance_name,				  uint32_t		mf,				  uint32_t		pms)    : RibNotifierBase<A>(e, uq, pms),      _xs(xs), _cname(class_name), _iname(instance_name),      _max_inflight(mf), _inflight(0){}template <typename A>XrlRibNotifier<A>::~XrlRibNotifier(){}template <typename A>inline voidXrlRibNotifier<A>::incr_inflight(){    _inflight++;    XLOG_ASSERT(_inflight <= _max_inflight);}template <typename A>inline voidXrlRibNotifier<A>::decr_inflight(){    _inflight--;    XLOG_ASSERT(_inflight <= _max_inflight);}template<typename A>intXrlRibNotifier<A>::startup(){    XrlRibV0p1Client c(&_xs);    bool ucast = true;    bool mcast = false;    if ((c.*Send<A>::add_igp_table)	(xrl_rib_name(), "rip", _cname, _iname, ucast, mcast,	 callback(this, &XrlRibNotifier<A>::add_igp_cb)) == false) {	XLOG_ERROR("Failed to send table creation request.");	set_status(SERVICE_FAILED);	return (XORP_ERROR);    }    set_status(SERVICE_STARTING);    incr_inflight();    return (XORP_OK);}template <typename A>voidXrlRibNotifier<A>::add_igp_cb(const XrlError& xe){    decr_inflight();    if (xe != XrlError::OKAY()) {	XLOG_ERROR("add_igp failed: %s\n", xe.str().c_str());	set_status(SERVICE_FAILED);	return;    }    this->start_polling();    set_status(SERVICE_RUNNING);}template<typename A>intXrlRibNotifier<A>::shutdown(){    this->stop_polling();    set_status(SERVICE_SHUTTING_DOWN);    XrlRibV0p1Client c(&_xs);    bool ucast = true;    bool mcast = false;    if ((c.*Send<A>::delete_igp_table)	(xrl_rib_name(), "rip", _cname, _iname, ucast, mcast,	 callback(this, &XrlRibNotifier<A>::delete_igp_cb)) == false) {	XLOG_ERROR("Failed to send table creation request.");	set_status(SERVICE_FAILED);	return (XORP_ERROR);    }    incr_inflight();    return (XORP_OK);}template <typename A>voidXrlRibNotifier<A>::delete_igp_cb(const XrlError& e){    decr_inflight();    if (e != XrlError::OKAY()) {	set_status(SERVICE_FAILED);	return;    }    set_status(SERVICE_SHUTDOWN);}template <typename A>voidXrlRibNotifier<A>::send_add_route(const RouteEntry<A>& re){    XrlRibV0p1Client c(&_xs);    bool ok;    if (_ribnets.find(re.net()) == _ribnets.end()) {	_ribnets.insert(re.net());	ok = (c.*Send<A>::add_route)	      (xrl_rib_name(), "rip", true, false,	       re.net(), re.nexthop(), re.ifname(), re.vifname(), re.cost(),	       re.policytags().xrl_atomlist(),	       callback(this, &XrlRibNotifier<A>::send_route_cb));    } else {	ok = (c.*Send<A>::replace_route)	      (xrl_rib_name(), "rip", true, false,	       re.net(), re.nexthop(), re.ifname(), re.vifname(), re.cost(),	       re.policytags().xrl_atomlist(),	       callback(this, &XrlRibNotifier<A>::send_route_cb));    }    if (ok == false) {	shutdown();	return;    }    incr_inflight();}template <typename A>voidXrlRibNotifier<A>::send_delete_route(const RouteEntry<A>& re){    typename set<IPNet<A> >::iterator i = _ribnets.find(re.net());    if (i == _ribnets.end()) {	debug_msg("Request to delete route to net %s that's not been passed"		  "to rib\n", re.net().str().c_str());	return;    } else {	_ribnets.erase(i);    }    XrlRibV0p1Client c(&_xs);    if ((c.*Send<A>::delete_route)	(xrl_rib_name(), "rip", true, false, re.net(),	 callback(this, &XrlRibNotifier<A>::send_route_cb)) == false) {	shutdown();	return;    }    incr_inflight();}template <typename A>voidXrlRibNotifier<A>::send_route_cb(const XrlError& xe){    decr_inflight();    if (xe != XrlError::OKAY()) {	XLOG_ERROR("Xrl error %s\n", xe.str().c_str());    }}template <typename A>voidXrlRibNotifier<A>::updates_available(){    XLOG_ASSERT(_inflight <= _max_inflight);    for (const RouteEntry<A>* r = this->_uq.get(this->_ri); 	 r != 0; r = this->_uq.next(this->_ri)) {	if (_inflight == _max_inflight) {	    break;	}	if (status() != SERVICE_RUNNING) {	    // If we're not running just skip any available updates.	    continue;	}	if ((r->origin() != NULL) && (r->origin()->is_rib_origin())) {	    // XXX: don't redistribute the RIB routes back to the RIB	    continue;	}	if (r->cost() < RIP_INFINITY) {	    send_add_route(*r);	} else {	    send_delete_route(*r);	}    }}#ifdef INSTANTIATE_IPV4template class XrlRibNotifier<IPv4>;#endif#ifdef INSTANTIATE_IPV6template class XrlRibNotifier<IPv6>;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -