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

📄 mld6igmp_node.cc

📁 MLDv2 support igmpv3 lite
💻 CC
📖 第 1 页 / 共 3 页
字号:
// -*- 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/mld6igmp_node.cc,v 1.2 2008/07/23 05:09:49 pavlin Exp $"//// Multicast Listener Discovery and Internet Group Management Protocol// node implementation (common part).// IGMPv1 and IGMPv2 (RFC 2236), IGMPv3 (RFC 3376),// MLDv1 (RFC 2710), and MLDv2 (RFC 3810).//#include "mld6igmp_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxorp/debug.h"#include "libxorp/ipvx.hh"#include "mld6igmp_node.hh"#include "mld6igmp_vif.hh"//// Exported variables////// Local constants definitions////// Local structures/classes, typedefs and macros////// Local variables////// Local functions prototypes///** * Mld6igmpNode::Mld6igmpNode: * @family: The address family (%AF_INET or %AF_INET6 * for IPv4 and IPv6 respectively). * @module_id: The module ID (must be %XORP_MODULE_MLD6IGMP). * @eventloop: The event loop. *  * MLD6IGMP node constructor. **/Mld6igmpNode::Mld6igmpNode(int family, xorp_module_id module_id,			   EventLoop& eventloop)    : ProtoNode<Mld6igmpVif>(family, module_id, eventloop),      _is_log_trace(false){    XLOG_ASSERT(module_id == XORP_MODULE_MLD6IGMP);    if (module_id != XORP_MODULE_MLD6IGMP) {	XLOG_FATAL("Invalid module ID = %d (must be 'XORP_MODULE_MLD6IGMP' = %d)",		   module_id, XORP_MODULE_MLD6IGMP);    }        _buffer_recv = BUFFER_MALLOC(BUF_SIZE_DEFAULT);    //    // Set the node status    //    ProtoNode<Mld6igmpVif>::set_node_status(PROC_STARTUP);    //    // Set myself as an observer when the node status changes    //    set_observer(this);}/** * Mld6igmpNode::~Mld6igmpNode: * @:  *  * MLD6IGMP node destructor. *  **/Mld6igmpNode::~Mld6igmpNode(){    //    // Unset myself as an observer when the node status changes    //    unset_observer(this);    stop();    ProtoNode<Mld6igmpVif>::set_node_status(PROC_NULL);    delete_all_vifs();        BUFFER_FREE(_buffer_recv);}/** * Mld6igmpNode::start: * @:  *  * Start the MLD or IGMP protocol. * TODO: This function should not start the protocol operation on the * interfaces. The interfaces must be activated separately. * After the startup operations are completed, * Mld6igmpNode::final_start() is called to complete the job. *  * Return value: %XORP_OK on success, otherwize %XORP_ERROR. **/intMld6igmpNode::start(){    if (! is_enabled())	return (XORP_OK);    //    // Test the service status    //    if ((ServiceBase::status() == SERVICE_STARTING)	|| (ServiceBase::status() == SERVICE_RUNNING)) {	return (XORP_OK);    }    if (ServiceBase::status() != SERVICE_READY) {	return (XORP_ERROR);    }    if (ProtoNode<Mld6igmpVif>::pending_start() != XORP_OK)	return (XORP_ERROR);    //    // Register with the FEA and MFEA    //    fea_register_startup();    mfea_register_startup();    //    // Set the node status    //    ProtoNode<Mld6igmpVif>::set_node_status(PROC_STARTUP);    //    // Update the node status    //    update_status();    return (XORP_OK);}/** * Mld6igmpNode::final_start: * @:  *  * Complete the start-up of the MLD/IGMP protocol. *  * Return value: %XORP_OK on success, otherwise %XORP_ERROR. **/intMld6igmpNode::final_start(){#if 0	// TODO: XXX: PAVPAVPAV    if (! is_pending_up())	return (XORP_ERROR);#endif    if (ProtoNode<Mld6igmpVif>::start() != XORP_OK) {	ProtoNode<Mld6igmpVif>::stop();	return (XORP_ERROR);    }    // Start the mld6igmp_vifs    start_all_vifs();    XLOG_INFO("Protocol started");    return (XORP_OK);}/** * Mld6igmpNode::stop: * @:  *  * Gracefully stop the MLD or IGMP protocol. * XXX: After the cleanup is completed, * Mld6igmpNode::final_stop() is called to complete the job. * XXX: This function, unlike start(), will stop the protocol * operation on all interfaces. *  * Return value: %XORP_OK on success, otherwise %XORP_ERROR. **/intMld6igmpNode::stop(){    //    // Test the service status    //    if ((ServiceBase::status() == SERVICE_SHUTDOWN)	|| (ServiceBase::status() == SERVICE_SHUTTING_DOWN)	|| (ServiceBase::status() == SERVICE_FAILED)) {	return (XORP_OK);    }    if ((ServiceBase::status() != SERVICE_RUNNING)	&& (ServiceBase::status() != SERVICE_STARTING)	&& (ServiceBase::status() != SERVICE_PAUSING)	&& (ServiceBase::status() != SERVICE_PAUSED)	&& (ServiceBase::status() != SERVICE_RESUMING)) {	return (XORP_ERROR);    }    if (ProtoNode<Mld6igmpVif>::pending_stop() != XORP_OK)	return (XORP_ERROR);    //    // Perform misc. MLD6IGMP-specific stop operations    //    // XXX: nothing to do        // Stop the vifs    stop_all_vifs();        //    // Set the node status    //    ProtoNode<Mld6igmpVif>::set_node_status(PROC_SHUTDOWN);    //    // Update the node status    //    update_status();    return (XORP_OK);}/** * Mld6igmpNode::final_stop: * @:  *  * Completely stop the MLD/IGMP protocol. *  * Return value: %XORP_OK on success, otherwise %XORP_ERROR. **/intMld6igmpNode::final_stop(){    if (! (is_up() || is_pending_up() || is_pending_down()))	return (XORP_ERROR);    if (ProtoNode<Mld6igmpVif>::stop() != XORP_OK)	return (XORP_ERROR);    XLOG_INFO("Protocol stopped");    return (XORP_OK);}/** * Enable the node operation. *  * If an unit is not enabled, it cannot be start, or pending-start. */voidMld6igmpNode::enable(){    ProtoUnit::enable();    XLOG_INFO("Protocol enabled");}/** * Disable the node operation. *  * If an unit is disabled, it cannot be start or pending-start. * If the unit was runnning, it will be stop first. */voidMld6igmpNode::disable(){    stop();    ProtoUnit::disable();    XLOG_INFO("Protocol disabled");}/** * Get the IP protocol number. * * @return the IP protocol number. */uint8_tMld6igmpNode::ip_protocol_number() const{    if (proto_is_igmp())	return (IPPROTO_IGMP);    if (proto_is_mld6())	return (IPPROTO_ICMPV6);    XLOG_UNREACHABLE();    return (0);}voidMld6igmpNode::status_change(ServiceBase*  service,			    ServiceStatus old_status,			    ServiceStatus new_status){    if (service == this) {	if ((old_status == SERVICE_STARTING)	    && (new_status == SERVICE_RUNNING)) {	    // The startup process has completed	    if (final_start() != XORP_OK) {		XLOG_ERROR("Cannot complete the startup process; "			   "current state is %s",			   ProtoNode<Mld6igmpVif>::state_str().c_str());		return;	    }	    ProtoNode<Mld6igmpVif>::set_node_status(PROC_READY);	    return;	}	if ((old_status == SERVICE_SHUTTING_DOWN)	    && (new_status == SERVICE_SHUTDOWN)) {	    // The shutdown process has completed	    final_stop();	    // Set the node status	    ProtoNode<Mld6igmpVif>::set_node_status(PROC_DONE);	    return;	}	//	// TODO: check if there was an error	//	return;    }    if (service == ifmgr_mirror_service_base()) {	if ((old_status == SERVICE_SHUTTING_DOWN)	    && (new_status == SERVICE_SHUTDOWN)) {	    decr_shutdown_requests_n();			// XXX: for the ifmgr	}    }}voidMld6igmpNode::tree_complete(){    decr_startup_requests_n();				// XXX: for the ifmgr    //    // XXX: we use same actions when the tree is completed or updates are made    //    updates_made();}voidMld6igmpNode::updates_made(){    map<string, Vif>::iterator mld6igmp_vif_iter;    string error_msg;    //    // Update the local copy of the interface tree    //    _iftree = ifmgr_iftree();    //    // Add new vifs and update existing ones    //    IfMgrIfTree::IfMap::const_iterator ifmgr_iface_iter;    for (ifmgr_iface_iter = _iftree.interfaces().begin();	 ifmgr_iface_iter != _iftree.interfaces().end();	 ++ifmgr_iface_iter) {	const IfMgrIfAtom& ifmgr_iface = ifmgr_iface_iter->second;	IfMgrIfAtom::VifMap::const_iterator ifmgr_vif_iter;	for (ifmgr_vif_iter = ifmgr_iface.vifs().begin();	     ifmgr_vif_iter != ifmgr_iface.vifs().end();	     ++ifmgr_vif_iter) {	    const IfMgrVifAtom& ifmgr_vif = ifmgr_vif_iter->second;	    const string& ifmgr_vif_name = ifmgr_vif.name();	    Vif* node_vif = NULL;		    mld6igmp_vif_iter = configured_vifs().find(ifmgr_vif_name);	    if (mld6igmp_vif_iter != configured_vifs().end()) {		node_vif = &(mld6igmp_vif_iter->second);	    }	    //	    // Add a new vif	    //	    if (node_vif == NULL) {		uint32_t vif_index = ifmgr_vif.vif_index();		XLOG_ASSERT(vif_index != Vif::VIF_INDEX_INVALID);		if (add_config_vif(ifmgr_vif_name, vif_index, error_msg)		    != XORP_OK) {		    XLOG_ERROR("Cannot add vif %s to the set of configured "			       "vifs: %s",			       ifmgr_vif_name.c_str(), error_msg.c_str());		    continue;		}		mld6igmp_vif_iter = configured_vifs().find(ifmgr_vif_name);		XLOG_ASSERT(mld6igmp_vif_iter != configured_vifs().end());		node_vif = &(mld6igmp_vif_iter->second);		// FALLTHROUGH	    }	    //	    // Update the pif_index	    //	    set_config_pif_index(ifmgr_vif_name,				 ifmgr_vif.pif_index(),				 error_msg);		    //	    // Update the vif flags	    //	    bool is_up = ifmgr_iface.enabled();	    is_up &= (! ifmgr_iface.no_carrier());	    is_up &= ifmgr_vif.enabled();	    set_config_vif_flags(ifmgr_vif_name,				 ifmgr_vif.pim_register(),				 ifmgr_vif.p2p_capable(),				 ifmgr_vif.loopback(),				 ifmgr_vif.multicast_capable(),				 ifmgr_vif.broadcast_capable(),				 is_up,				 ifmgr_iface.mtu(),				 error_msg);		}    }    //    // Add new vif addresses, update existing ones, and remove old addresses    //    for (ifmgr_iface_iter = _iftree.interfaces().begin();	 ifmgr_iface_iter != _iftree.interfaces().end();	 ++ifmgr_iface_iter) {	const IfMgrIfAtom& ifmgr_iface = ifmgr_iface_iter->second;	const string& ifmgr_iface_name = ifmgr_iface.name();	IfMgrIfAtom::VifMap::const_iterator ifmgr_vif_iter;	for (ifmgr_vif_iter = ifmgr_iface.vifs().begin();	     ifmgr_vif_iter != ifmgr_iface.vifs().end();	     ++ifmgr_vif_iter) {	    const IfMgrVifAtom& ifmgr_vif = ifmgr_vif_iter->second;	    const string& ifmgr_vif_name = ifmgr_vif.name();	    Vif* node_vif = NULL;	    //	    // Add new vif addresses and update existing ones	    //	    mld6igmp_vif_iter = configured_vifs().find(ifmgr_vif_name);	    if (mld6igmp_vif_iter != configured_vifs().end()) {		node_vif = &(mld6igmp_vif_iter->second);	    }	    if (is_ipv4()) {		IfMgrVifAtom::IPv4Map::const_iterator a4_iter;		for (a4_iter = ifmgr_vif.ipv4addrs().begin();		     a4_iter != ifmgr_vif.ipv4addrs().end();		     ++a4_iter) {		    const IfMgrIPv4Atom& a4 = a4_iter->second;		    VifAddr* node_vif_addr = node_vif->find_address(IPvX(a4.addr()));		    IPvX addr(a4.addr());		    IPvXNet subnet_addr(addr, a4.prefix_len());		    IPvX broadcast_addr(IPvX::ZERO(family()));		    IPvX peer_addr(IPvX::ZERO(family()));		    if (a4.has_broadcast())			broadcast_addr = IPvX(a4.broadcast_addr());		    if (a4.has_endpoint())			peer_addr = IPvX(a4.endpoint_addr());		    if (node_vif_addr == NULL) {			if (add_config_vif_addr(				ifmgr_vif_name,				addr,				subnet_addr,				broadcast_addr,				peer_addr,				error_msg)			    != XORP_OK) {			    XLOG_ERROR("Cannot add address %s to vif %s from "				       "the set of configured vifs: %s",				       cstring(addr), ifmgr_vif_name.c_str(),				       error_msg.c_str());			}			continue;		    }		    if ((addr == node_vif_addr->addr())			&& (subnet_addr == node_vif_addr->subnet_addr())			&& (broadcast_addr == node_vif_addr->broadcast_addr())			&& (peer_addr == node_vif_addr->peer_addr())) {			continue;	// Nothing changed		    }		    // Update the address		    if (delete_config_vif_addr(ifmgr_vif_name,					       addr,					       error_msg)

⌨️ 快捷键说明

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