?? xrl_mld6igmp_node.cc
字號:
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 + -