?? xrl_mld6igmp_node.cc
字號(hào):
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// 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/contrib/mld6igmp_lite/xrl_mld6igmp_node.cc,v 1.2 2008/07/23 05:09:50 pavlin Exp $"#include "mld6igmp_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxorp/debug.h"#include "libxorp/ipvx.hh"#include "libxorp/status_codes.h"#include "libxorp/utils.hh"#include "mld6igmp_node.hh"#include "mld6igmp_node_cli.hh"#include "mld6igmp_vif.hh"#include "xrl_mld6igmp_node.hh"const TimeVal XrlMld6igmpNode::RETRY_TIMEVAL = TimeVal(1, 0);//// XrlMld6igmpNode front-end interface//XrlMld6igmpNode::XrlMld6igmpNode(int family, xorp_module_id module_id, EventLoop& eventloop, const string& class_name, const string& finder_hostname, uint16_t finder_port, const string& finder_target, const string& fea_target, const string& mfea_target) : Mld6igmpNode(family, module_id, eventloop), XrlStdRouter(eventloop, class_name.c_str(), finder_hostname.c_str(), finder_port), XrlMld6igmpTargetBase(&xrl_router()), Mld6igmpNodeCli(*static_cast<Mld6igmpNode *>(this)), _eventloop(eventloop), _finder_target(finder_target), _fea_target(fea_target), _mfea_target(mfea_target), _ifmgr(eventloop, mfea_target.c_str(), xrl_router().finder_address(), xrl_router().finder_port()), _xrl_fea_client4(&xrl_router()), _xrl_fea_client6(&xrl_router()), _xrl_mld6igmp_client_client(&xrl_router()), _xrl_cli_manager_client(&xrl_router()), _xrl_finder_client(&xrl_router()), _is_finder_alive(false), _is_fea_alive(false), _is_fea_registered(false), _is_mfea_alive(false), _is_mfea_registered(false){ _ifmgr.set_observer(dynamic_cast<Mld6igmpNode*>(this)); _ifmgr.attach_hint_observer(dynamic_cast<Mld6igmpNode*>(this));}XrlMld6igmpNode::~XrlMld6igmpNode(){ shutdown(); _ifmgr.detach_hint_observer(dynamic_cast<Mld6igmpNode*>(this)); _ifmgr.unset_observer(dynamic_cast<Mld6igmpNode*>(this)); delete_pointers_list(_xrl_tasks_queue);}intXrlMld6igmpNode::startup(){ if (start_mld6igmp() != XORP_OK) return (XORP_ERROR); return (XORP_OK);}intXrlMld6igmpNode::shutdown(){ int ret_value = XORP_OK; if (stop_cli() != XORP_OK) ret_value = XORP_ERROR; if (stop_mld6igmp() != XORP_OK) ret_value = XORP_ERROR; return (ret_value);}intXrlMld6igmpNode::enable_cli(){ Mld6igmpNodeCli::enable(); return (XORP_OK);}intXrlMld6igmpNode::disable_cli(){ Mld6igmpNodeCli::disable(); return (XORP_OK);}intXrlMld6igmpNode::start_cli(){ if (Mld6igmpNodeCli::start() != XORP_OK) return (XORP_ERROR); return (XORP_OK);}intXrlMld6igmpNode::stop_cli(){ if (Mld6igmpNodeCli::stop() != XORP_OK) return (XORP_ERROR); return (XORP_OK);}intXrlMld6igmpNode::enable_mld6igmp(){ Mld6igmpNode::enable(); return (XORP_OK);}intXrlMld6igmpNode::disable_mld6igmp(){ Mld6igmpNode::disable(); return (XORP_OK);}intXrlMld6igmpNode::start_mld6igmp(){ if (Mld6igmpNode::start() != XORP_OK) return (XORP_ERROR); return (XORP_OK);}intXrlMld6igmpNode::stop_mld6igmp(){ if (Mld6igmpNode::stop() != XORP_OK) return (XORP_ERROR); return (XORP_OK);}//// Finder-related events///** * Called when Finder connection is established. * * Note that this method overwrites an XrlRouter virtual method. */voidXrlMld6igmpNode::finder_connect_event(){ _is_finder_alive = true;}/** * Called when Finder disconnect occurs. * * Note that this method overwrites an XrlRouter virtual method. */voidXrlMld6igmpNode::finder_disconnect_event(){ XLOG_ERROR("Finder disconnect event. Exiting immediately..."); _is_finder_alive = false; stop_mld6igmp();}//// Task-related methods//voidXrlMld6igmpNode::add_task(XrlTaskBase* xrl_task){ _xrl_tasks_queue.push_back(xrl_task); // If the queue was empty before, start sending the changes if (_xrl_tasks_queue.size() == 1) send_xrl_task();}voidXrlMld6igmpNode::send_xrl_task(){ if (_xrl_tasks_queue.empty()) return; XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front(); XLOG_ASSERT(xrl_task_base != NULL); xrl_task_base->dispatch();}voidXrlMld6igmpNode::pop_xrl_task(){ XLOG_ASSERT(! _xrl_tasks_queue.empty()); XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front(); XLOG_ASSERT(xrl_task_base != NULL); delete xrl_task_base; _xrl_tasks_queue.pop_front();}voidXrlMld6igmpNode::retry_xrl_task(){ if (_xrl_tasks_queue_timer.scheduled()) return; // XXX: already scheduled _xrl_tasks_queue_timer = _eventloop.new_oneoff_after( RETRY_TIMEVAL, callback(this, &XrlMld6igmpNode::send_xrl_task));}//// Register with the FEA//voidXrlMld6igmpNode::fea_register_startup(){ if (! _is_finder_alive) return; // The Finder is dead if (_is_fea_registered) return; // Already registered Mld6igmpNode::incr_startup_requests_n(); // XXX: for FEA registration Mld6igmpNode::incr_startup_requests_n(); // XXX: for FEA birth // // Register interest in the FEA with the Finder // add_task(new RegisterUnregisterInterest(*this, _fea_target, true));}//// Register with the MFEA//voidXrlMld6igmpNode::mfea_register_startup(){ if (! _is_finder_alive) return; // The Finder is dead if (_is_mfea_registered) return; // Already registered Mld6igmpNode::incr_startup_requests_n(); // XXX: for MFEA registration Mld6igmpNode::incr_startup_requests_n(); // XXX: for MFEA birth Mld6igmpNode::incr_startup_requests_n(); // XXX: for the ifmgr // // Register interest in the FEA with the Finder // add_task(new RegisterUnregisterInterest(*this, _mfea_target, true));}//// De-register with the FEA//voidXrlMld6igmpNode::fea_register_shutdown(){ if (! _is_finder_alive) return; // The Finder is dead if (! _is_fea_alive) return; // The FEA is not there anymore if (! _is_fea_registered) return; // Not registered Mld6igmpNode::incr_shutdown_requests_n(); // XXX: for FEA deregistration // // De-register interest in the FEA with the Finder // add_task(new RegisterUnregisterInterest(*this, _fea_target, false));}//// De-register with the MFEA//voidXrlMld6igmpNode::mfea_register_shutdown(){ if (! _is_finder_alive) return; // The Finder is dead if (! _is_mfea_alive) return; // The MFEA is not there anymore if (! _is_mfea_registered) return; // Not registered Mld6igmpNode::incr_shutdown_requests_n(); // XXX: for MFEA deregistration Mld6igmpNode::incr_shutdown_requests_n(); // XXX: for the ifmgr // // De-register interest in the MFEA with the Finder // add_task(new RegisterUnregisterInterest(*this, _mfea_target, false)); // // XXX: when the shutdown is completed, Mld6igmpNode::status_change() // will be called. // _ifmgr.shutdown();}voidXrlMld6igmpNode::send_register_unregister_interest(){ bool success = true; if (! _is_finder_alive) return; // The Finder is dead XLOG_ASSERT(! _xrl_tasks_queue.empty()); XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front(); RegisterUnregisterInterest* entry; entry = dynamic_cast<RegisterUnregisterInterest*>(xrl_task_base); XLOG_ASSERT(entry != NULL); if (entry->is_register()) { // Register interest success = _xrl_finder_client.send_register_class_event_interest( _finder_target.c_str(), xrl_router().instance_name(), entry->target_name(), callback(this, &XrlMld6igmpNode::finder_send_register_unregister_interest_cb)); } else { // Unregister interest success = _xrl_finder_client.send_deregister_class_event_interest( _finder_target.c_str(), xrl_router().instance_name(), entry->target_name(), callback(this, &XrlMld6igmpNode::finder_send_register_unregister_interest_cb)); } if (! success) { // // If an error, then try again // XLOG_ERROR("Failed to %s register interest in %s with the Finder. " "Will try again.", entry->operation_name(), entry->target_name().c_str()); retry_xrl_task(); return; }}voidXrlMld6igmpNode::finder_send_register_unregister_interest_cb(const XrlError& xrl_error){ XLOG_ASSERT(! _xrl_tasks_queue.empty()); XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front(); RegisterUnregisterInterest* entry; entry = dynamic_cast<RegisterUnregisterInterest*>(xrl_task_base); XLOG_ASSERT(entry != NULL); switch (xrl_error.error_code()) { case OKAY: // // If success, then schedule the next task // if (entry->is_register()) { // // Register interest // if (entry->target_name() == _fea_target) { // // If success, then the FEA birth event will startup the FEA // registration. // _is_fea_registered = true; Mld6igmpNode::decr_startup_requests_n(); // XXX: for FEA registration } if (entry->target_name() == _mfea_target) { // // If success, then the MFEA birth event will startup the MFEA // registration and the ifmgr. // _is_mfea_registered = true; Mld6igmpNode::decr_startup_requests_n(); // XXX: for MFEA registration } } else { // // Unregister interest // if (entry->target_name() == _fea_target) { _is_fea_registered = false; Mld6igmpNode::decr_shutdown_requests_n(); // XXX: for the FEA } if (entry->target_name() == _mfea_target) { _is_mfea_registered = false; Mld6igmpNode::decr_shutdown_requests_n(); // XXX: for the MFEA } } pop_xrl_task(); send_xrl_task(); break; case COMMAND_FAILED: // // If a command failed because the other side rejected it, this is // fatal. // XLOG_FATAL("Cannot %s interest in Finder events: %s", entry->operation_name(), xrl_error.str().c_str()); break; case NO_FINDER: case RESOLVE_FAILED: case SEND_FAILED: // // A communication error that should have been caught elsewhere // (e.g., by tracking the status of the Finder and the other targets). // Probably we caught it here because of event reordering. // In some cases we print an error. In other cases our job is done. // if (entry->is_register()) { XLOG_ERROR("XRL communication error: %s", xrl_error.str().c_str()); } else { if (entry->target_name() == _fea_target) { _is_fea_registered = false; } if (entry->target_name() == _mfea_target) { _is_mfea_registered = false; } pop_xrl_task(); send_xrl_task(); } break; case BAD_ARGS: case NO_SUCH_METHOD: case INTERNAL_ERROR: // // An error that should happen only if there is something unusual: // e.g., there is XRL mismatch, no enough internal resources, etc. // We don't try to recover from such errors, hence this is fatal. // XLOG_FATAL("Fatal XRL error: %s", xrl_error.str().c_str()); break; case REPLY_TIMED_OUT: case SEND_FAILED_TRANSIENT: // // If a transient error, then try again // XLOG_ERROR("Failed to %s interest in Finder envents: %s. " "Will try again.", entry->operation_name(), xrl_error.str().c_str()); retry_xrl_task(); break; }}intXrlMld6igmpNode::register_receiver(const string& if_name, const string& vif_name, uint8_t ip_protocol, bool enable_multicast_loopback){ Mld6igmpNode::incr_startup_requests_n(); // XXX: for FEA-receiver add_task(new RegisterUnregisterReceiver(*this, if_name, vif_name, ip_protocol, enable_multicast_loopback,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -