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

📄 xrl_mld6igmp_node.cc

📁 MLDv2 support igmpv3 lite
💻 CC
📖 第 1 页 / 共 5 页
字号:
					    true));    return (XORP_OK);}intXrlMld6igmpNode::unregister_receiver(const string& if_name,				     const string& vif_name,				     uint8_t ip_protocol){    Mld6igmpNode::incr_shutdown_requests_n();	// XXX: for FEA-non-receiver    add_task(new RegisterUnregisterReceiver(*this, if_name, vif_name,					    ip_protocol,					    false,	// XXX: ignored					    false));    return (XORP_OK);}voidXrlMld6igmpNode::send_register_unregister_receiver(){    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();    RegisterUnregisterReceiver* entry;    entry = dynamic_cast<RegisterUnregisterReceiver*>(xrl_task_base);    XLOG_ASSERT(entry != NULL);    //    // Check whether we have already registered with the FEA    //    if (! _is_fea_registered) {	retry_xrl_task();	return;    }    if (entry->is_register()) {	// Register a receiver with the FEA	if (Mld6igmpNode::is_ipv4()) {	    success = _xrl_fea_client4.send_register_receiver(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		entry->enable_multicast_loopback(),		callback(this, &XrlMld6igmpNode::fea_client_send_register_unregister_receiver_cb));	    if (success)		return;	}	if (Mld6igmpNode::is_ipv6()) {	    success = _xrl_fea_client6.send_register_receiver(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		entry->enable_multicast_loopback(),		callback(this, &XrlMld6igmpNode::fea_client_send_register_unregister_receiver_cb));	    if (success)		return;	}    } else {	// Unregister a receiver with the FEA	if (Mld6igmpNode::is_ipv4()) {	    success = _xrl_fea_client4.send_unregister_receiver(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		callback(this, &XrlMld6igmpNode::fea_client_send_register_unregister_receiver_cb));	    if (success)		return;	}	if (Mld6igmpNode::is_ipv6()) {	    success = _xrl_fea_client6.send_unregister_receiver(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		callback(this, &XrlMld6igmpNode::fea_client_send_register_unregister_receiver_cb));	    if (success)		return;	}    }    if (! success) {	//	// If an error, then try again	//	XLOG_ERROR("Failed to %s register receiver on interface %s vif %s "		   "IP protocol %u with the FEA. "		   "Will try again.",		   entry->operation_name(),		   entry->if_name().c_str(),		   entry->vif_name().c_str(),		   entry->ip_protocol());	retry_xrl_task();	return;    }}voidXrlMld6igmpNode::fea_client_send_register_unregister_receiver_cb(    const XrlError& xrl_error){    XLOG_ASSERT(! _xrl_tasks_queue.empty());    XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front();    RegisterUnregisterReceiver* entry;    entry = dynamic_cast<RegisterUnregisterReceiver*>(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())	    Mld6igmpNode::decr_startup_requests_n();  // XXX: for FEA-receiver	else	    Mld6igmpNode::decr_shutdown_requests_n(); // XXX: for FEA-non-receiver	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 receiver with the FEA: %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 {	    Mld6igmpNode::decr_shutdown_requests_n();  // XXX: for FEA-non-receiver	    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 receiver with the FEA: %s. "		   "Will try again.",		   entry->operation_name(), xrl_error.str().c_str());	retry_xrl_task();	break;    }}intXrlMld6igmpNode::join_multicast_group(const string& if_name,				      const string& vif_name,				      uint8_t ip_protocol,				      const IPvX& group_address){    Mld6igmpNode::incr_startup_requests_n();		// XXX: for FEA-join    add_task(new JoinLeaveMulticastGroup(*this, if_name, vif_name, ip_protocol,					 group_address, true));    return (XORP_OK);}intXrlMld6igmpNode::leave_multicast_group(const string& if_name,				       const string& vif_name,				       uint8_t ip_protocol,				       const IPvX& group_address){    Mld6igmpNode::incr_shutdown_requests_n();		// XXX: for FEA-leave    add_task(new JoinLeaveMulticastGroup(*this, if_name, vif_name, ip_protocol,					 group_address, false));    return (XORP_OK);}voidXrlMld6igmpNode::send_join_leave_multicast_group(){    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();    JoinLeaveMulticastGroup* entry;    entry = dynamic_cast<JoinLeaveMulticastGroup*>(xrl_task_base);    XLOG_ASSERT(entry != NULL);    //    // Check whether we have already registered with the FEA    //    if (! _is_fea_registered) {	retry_xrl_task();	return;    }    if (entry->is_join()) {	// Join a multicast group with the FEA	if (Mld6igmpNode::is_ipv4()) {	    success = _xrl_fea_client4.send_join_multicast_group(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		entry->group_address().get_ipv4(),		callback(this, &XrlMld6igmpNode::fea_client_send_join_leave_multicast_group_cb));	    if (success)		return;	}	if (Mld6igmpNode::is_ipv6()) {	    success = _xrl_fea_client6.send_join_multicast_group(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		entry->group_address().get_ipv6(),		callback(this, &XrlMld6igmpNode::fea_client_send_join_leave_multicast_group_cb));	    if (success)		return;	}    } else {	// Leave a multicast group with the FEA	if (Mld6igmpNode::is_ipv4()) {	    success = _xrl_fea_client4.send_leave_multicast_group(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		entry->group_address().get_ipv4(),		callback(this, &XrlMld6igmpNode::fea_client_send_join_leave_multicast_group_cb));	    if (success)		return;	}	if (Mld6igmpNode::is_ipv6()) {	    success = _xrl_fea_client6.send_leave_multicast_group(		_fea_target.c_str(),		xrl_router().instance_name(),		entry->if_name(),		entry->vif_name(),		entry->ip_protocol(),		entry->group_address().get_ipv6(),		callback(this, &XrlMld6igmpNode::fea_client_send_join_leave_multicast_group_cb));	    if (success)		return;	}    }    if (! success) {	//	// If an error, then try again	//	XLOG_ERROR("Failed to %s group %s on interface/vif %s/%s with the FEA. "		   "Will try again.",		   entry->operation_name(),		   entry->group_address().str().c_str(),		   entry->if_name().c_str(),		   entry->vif_name().c_str());	retry_xrl_task();	return;    }}voidXrlMld6igmpNode::fea_client_send_join_leave_multicast_group_cb(    const XrlError& xrl_error){    XLOG_ASSERT(! _xrl_tasks_queue.empty());    XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front();    JoinLeaveMulticastGroup* entry;    entry = dynamic_cast<JoinLeaveMulticastGroup*>(xrl_task_base);    XLOG_ASSERT(entry != NULL);    switch (xrl_error.error_code()) {    case OKAY:	//	// If success, then schedule the next task	//	if (entry->is_join())	    Mld6igmpNode::decr_startup_requests_n();	// XXX: for FEA-join	else	    Mld6igmpNode::decr_shutdown_requests_n();	// XXX: for FEA-leave	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 a multicast group with the FEA: %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_join()) {	    XLOG_ERROR("XRL communication error: %s", xrl_error.str().c_str());	} else {	    Mld6igmpNode::decr_shutdown_requests_n();	// XXX: for FEA-leave	    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 group %s on interface/vif %s/%s "		   "with the FEA: %s. "		   "Will try again.",		   entry->operation_name(),		   entry->group_address().str().c_str(),		   entry->if_name().c_str(),		   entry->vif_name().c_str(),		   xrl_error.str().c_str());	retry_xrl_task();	break;    }}intXrlMld6igmpNode::send_add_membership(const string& dst_module_instance_name,				     xorp_module_id dst_module_id,				     uint32_t vif_index,				     const IPvX& source,				     const IPvX& group){    Mld6igmpVif *mld6igmp_vif = Mld6igmpNode::vif_find_by_vif_index(vif_index);        if (mld6igmp_vif == NULL) {	XLOG_ERROR("Cannot send add_membership to %s for (%s, %s) on vif "		   "with vif_index %d: no such vif",		   dst_module_instance_name.c_str(),		   cstring(source),		   cstring(group),		   vif_index);	return (XORP_ERROR);    }    _send_add_delete_membership_queue.push_back(SendAddDeleteMembership(						    dst_module_instance_name,						    dst_module_id,						    vif_index,						    source,						    group,						    true));    // If the queue was empty before, start sending the changes    if (_send_add_delete_membership_queue.size() == 1) {	send_add_delete_membership();    }    return (XORP_OK);}intXrlMld6igmpNode::send_delete_membership(const string& dst_module_instance_name,					xorp_module_id dst_module_id,					uint32_t vif_index,					const IPvX& source,					const IPvX& group){    Mld6igmpVif *mld6igmp_vif = Mld6igmpNode::vif_find_by_vif_index(vif_index);        if (mld6igmp_vif == NULL) {	XLOG_ERROR("Cannot send delete_membership to %s for (%s, %s) on vif "		   "with vif_index %d: no such vif",		   dst_module_instance_name.c_str(),		   cstring(source),		   cstring(group),		   vif_index);	return (XORP_ERROR);    }    _send_add_delete_membership_queue.push_back(SendAddDeleteMembership(						    dst_module_instance_name,						    dst_module_id,						    vif_index,						    source,						    group,						    false));    // If the queue was empty before, start sending the changes    if (_send_add_delete_membership_queue.size() == 1) {	send_add_delete_membership();    }    return (XORP_OK);}voidXrlMld6igmpNode::send_add_delete_membership(){    bool success = true;    Mld6igmpVif *mld6igmp_vif = NULL;    if (! _is_finder_alive)	return;		// The Finder is dead    if (_send_add_delete_membership_queue.empty())	return;			// No more changes    const SendAddDeleteMembership& membership = _send_add_delete_membership_queue.front();    mld6igmp_vif = Mld6igmpNode::vif_find_by_vif_index(membership.vif_index());    if (mld6igmp_vif == NULL) {	XLOG_ERROR("Cannot send %s for (%s, %s) on vif "		   "with vif_index %d to %s: no such vif",		   membership.operation_name(),		   cstring(membership.source()),		   cstring(membership.group()),		   membership.vif_index(),		   membership.dst_module_instance_name().c_str());	_send_add_delete_membership_queue.pop_front();	goto start_timer_label;    }    if (membership.is_add()) {	// Send add_membership to the client protocol	if (Mld6igmpNode::is_ipv4()) {	    success = _xrl_mld6igmp_client_client.send_add_membership4(		membership.dst_module_instance_name().c_str(),		xrl_router().class_name(),		mld6igmp_vif->name(),		membership.vif_index(),		membership.source().get_ipv4(),		membership.group().get_ipv4(),		callback(this, &XrlMld6igmpNode::mld6igmp_client_send_add_delete_membership_cb));	    if (success)		return;	}	if (Mld6igmpNode::is_ipv6()) {	    success = _xrl_mld6igmp_client_client.send_add_membership6(		membership.dst_module_instance_name().c_str(),		xrl_router().class_name(),		mld6igmp_vif->name(),

⌨️ 快捷键说明

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