📄 xrl_mld6igmp_node.cc
字号:
membership.vif_index(), membership.source().get_ipv6(), membership.group().get_ipv6(), callback(this, &XrlMld6igmpNode::mld6igmp_client_send_add_delete_membership_cb)); if (success) return; } } else { // Send delete_membership to the client protocol if (Mld6igmpNode::is_ipv4()) { success = _xrl_mld6igmp_client_client.send_delete_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_delete_membership6( membership.dst_module_instance_name().c_str(), xrl_router().class_name(), mld6igmp_vif->name(), membership.vif_index(), membership.source().get_ipv6(), membership.group().get_ipv6(), callback(this, &XrlMld6igmpNode::mld6igmp_client_send_add_delete_membership_cb)); if (success) return; } } if (! success) { // // If an error, then try again // XLOG_ERROR("Failed to send %s for (%s, %s) on vif %s to %s. " "Will try again.", membership.operation_name(), cstring(membership.source()), cstring(membership.group()), mld6igmp_vif->name().c_str(), membership.dst_module_instance_name().c_str()); start_timer_label: _send_add_delete_membership_queue_timer = _eventloop.new_oneoff_after( RETRY_TIMEVAL, callback(this, &XrlMld6igmpNode::send_add_delete_membership)); }}voidXrlMld6igmpNode::mld6igmp_client_send_add_delete_membership_cb( const XrlError& xrl_error){ const SendAddDeleteMembership& membership = _send_add_delete_membership_queue.front(); switch (xrl_error.error_code()) { case OKAY: // // If success, then schedule the next task // _send_add_delete_membership_queue.pop_front(); send_add_delete_membership(); break; case COMMAND_FAILED: // // If a command failed because the other side rejected it, // then print an error and send the next one. // XLOG_ERROR("Cannot %s for a multicast group with a client: %s", membership.operation_name(), xrl_error.str().c_str()); _send_add_delete_membership_queue.pop_front(); send_add_delete_membership(); 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. // XLOG_ERROR("XRL communication error: %s", xrl_error.str().c_str()); 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 // if (! _send_add_delete_membership_queue_timer.scheduled()) { XLOG_ERROR("Failed to %s for a multicast group with a client: %s. " "Will try again.", membership.operation_name(), xrl_error.str().c_str()); _send_add_delete_membership_queue_timer = _eventloop.new_oneoff_after( RETRY_TIMEVAL, callback(this, &XrlMld6igmpNode::send_add_delete_membership)); } break; }}//// Protocol node methods//intXrlMld6igmpNode::proto_send(const string& if_name, const string& vif_name, const IPvX& src_address, const IPvX& dst_address, uint8_t ip_protocol, int32_t ip_ttl, int32_t ip_tos, bool ip_router_alert, bool ip_internet_control, const uint8_t* sndbuf, size_t sndlen, string& error_msg){ add_task(new SendProtocolMessage(*this, if_name, vif_name, src_address, dst_address, ip_protocol, ip_ttl, ip_tos, ip_router_alert, ip_internet_control, sndbuf, sndlen)); error_msg = ""; return (XORP_OK);}/** * Send a protocol message through the FEA. **/voidXrlMld6igmpNode::send_protocol_message(){ 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(); SendProtocolMessage* entry; entry = dynamic_cast<SendProtocolMessage*>(xrl_task_base); XLOG_ASSERT(entry != NULL); // // Check whether we have already registered with the FEA // if (! _is_fea_registered) { retry_xrl_task(); return; } // // Send the protocol message // do { if (Mld6igmpNode::is_ipv4()) { success = _xrl_fea_client4.send_send( _fea_target.c_str(), entry->if_name(), entry->vif_name(), entry->src_address().get_ipv4(), entry->dst_address().get_ipv4(), entry->ip_protocol(), entry->ip_ttl(), entry->ip_tos(), entry->ip_router_alert(), entry->ip_internet_control(), entry->payload(), callback(this, &XrlMld6igmpNode::fea_client_send_protocol_message_cb)); if (success) return; break; } if (Mld6igmpNode::is_ipv6()) { // XXX: no Extention headers XrlAtomList ext_headers_type; XrlAtomList ext_headers_payload; success = _xrl_fea_client6.send_send( _fea_target.c_str(), entry->if_name(), entry->vif_name(), entry->src_address().get_ipv6(), entry->dst_address().get_ipv6(), entry->ip_protocol(), entry->ip_ttl(), entry->ip_tos(), entry->ip_router_alert(), entry->ip_internet_control(), ext_headers_type, ext_headers_payload, entry->payload(), callback(this, &XrlMld6igmpNode::fea_client_send_protocol_message_cb)); if (success) return; break; } XLOG_UNREACHABLE(); break; } while (false); if (! success) { // // If an error, then try again // XLOG_ERROR("Failed to send a protocol message on interface/vif %s/%s. " "Will try again.", entry->if_name().c_str(), entry->vif_name().c_str()); retry_xrl_task(); return; }}voidXrlMld6igmpNode::fea_client_send_protocol_message_cb(const XrlError& xrl_error){ XLOG_ASSERT(! _xrl_tasks_queue.empty()); XrlTaskBase* xrl_task_base = _xrl_tasks_queue.front(); SendProtocolMessage* entry; entry = dynamic_cast<SendProtocolMessage*>(xrl_task_base); XLOG_ASSERT(entry != NULL); switch (xrl_error.error_code()) { case OKAY: // // If success, then schedule the next task // pop_xrl_task(); send_xrl_task(); break; case COMMAND_FAILED: // // If a command failed because the other side rejected it, // then print an error and send the next one. // // XXX: The FEA may fail to send a protocol message, therefore // we don't call XLOG_FATAL() here. For example, the transimssion // by the FEA it may fail if there is no buffer space or if an // unicast destination is not reachable. // Furthermore, all protocol messages are soft-state (i.e., they are // retransmitted periodically by the protocol), // hence we don't retransmit them here if there was an error. // XLOG_ERROR("Cannot send a protocol message: %s", xrl_error.str().c_str()); pop_xrl_task(); send_xrl_task(); 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. // XLOG_ERROR("Cannot send a protocol message: %s", xrl_error.str().c_str()); 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: // // XXX: if a transient error, then don't try again. // All protocol messages are soft-state (i.e., they are // retransmitted periodically by the protocol), // hence we don't retransmit them here if there was an error. // XLOG_ERROR("Failed to send a protocol message: %s", xrl_error.str().c_str()); pop_xrl_task(); send_xrl_task(); break; }}//// Protocol node CLI methods//intXrlMld6igmpNode::add_cli_command_to_cli_manager(const char *command_name, const char *command_help, bool is_command_cd, const char *command_cd_prompt, bool is_command_processor ){ bool success = false; if (! _is_finder_alive) return (XORP_ERROR); // The Finder is dead success = _xrl_cli_manager_client.send_add_cli_command( xorp_module_name(family(), XORP_MODULE_CLI), xrl_router().class_name(), string(command_name), string(command_help), is_command_cd, string(command_cd_prompt), is_command_processor, callback(this, &XrlMld6igmpNode::cli_manager_client_send_add_cli_command_cb)); if (! success) { XLOG_ERROR("Failed to add CLI command '%s' to the CLI manager", command_name); return (XORP_ERROR); } return (XORP_OK);}voidXrlMld6igmpNode::cli_manager_client_send_add_cli_command_cb( const XrlError& xrl_error){ switch (xrl_error.error_code()) { case OKAY: // // If success, then we are done // break; case COMMAND_FAILED: // // If a command failed because the other side rejected it, this is // fatal. // XLOG_FATAL("Cannot add a command to CLI manager: %s", 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. // XLOG_ERROR("Cannot add a command to CLI manager: %s", xrl_error.str().c_str()); 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 // // // TODO: if the command failed, then we should retransmit it // XLOG_ERROR("Failed to add a command to CLI manager: %s", xrl_error.str().c_str()); break; }}intXrlMld6igmpNode::delete_cli_command_from_cli_manager(const char *command_name){ bool success = true; if (! _is_finder_alive) return (XORP_ERROR); // The Finder is dead success = _xrl_cli_manager_client.send_delete_cli_command( xorp_module_name(family(), XORP_MODULE_CLI), xrl_router().class_name(), string(command_name), callback(this, &XrlMld6igmpNode::cli_manager_client_send_delete_cli_command_cb)); if (! success) { XLOG_ERROR("Failed to delete CLI command '%s' with the CLI manager", command_name); return (XORP_ERROR); } return (XORP_OK);}voidXrlMld6igmpNode::cli_manager_client_send_delete_cli_command_cb( const XrlError& xrl_error){ switch (xrl_error.error_code()) { case OKAY: // // If success, then we are done // break; case COMMAND_FAILED: // // If a command failed because the other side rejected it, this is // fatal. // XLOG_FATAL("Cannot delete a command from CLI manager: %s", 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. // XLOG_ERROR("Cannot delete a command from CLI manager: %s", xrl_error.str().c_str()); 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 // // // TODO: if the command failed, then we should retransmit it // XLOG_ERROR("Failed to delete a command from CLI manager: %s", xrl_error.str().c_str()); break; }}//// XRL target methods//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -