diff --git a/src/comm/aca_grpc.cpp b/src/comm/aca_grpc.cpp index d6bfa435..98150ef0 100644 --- a/src/comm/aca_grpc.cpp +++ b/src/comm/aca_grpc.cpp @@ -41,7 +41,7 @@ HostRequestReply GoalStateProvisionerImpl::RequestGoalStates(HostRequest *reques { grpc::ClientContext ctx; alcor::schema::HostRequestReply reply; - + if (chan_->GetState(false) != grpc_connectivity_state::GRPC_CHANNEL_READY) { ACA_LOG_INFO("%s, it is: [%d]\n", "Channel state is not READY", chan_->GetState(false)); reply.mutable_operation_statuses()->Add(); diff --git a/src/dhcp/aca_dhcp_state_handler.cpp b/src/dhcp/aca_dhcp_state_handler.cpp index 14b80086..9f89e5d4 100644 --- a/src/dhcp/aca_dhcp_state_handler.cpp +++ b/src/dhcp/aca_dhcp_state_handler.cpp @@ -53,20 +53,16 @@ int Aca_Dhcp_State_Handler::update_dhcp_state_workitem(const DHCPState current_D int overall_rc = EXIT_SUCCESS; ulong culminative_dataplane_programming_time = 0; ulong culminative_network_configuration_time = 0; - auto operation_start = chrono::steady_clock::now(); - DHCPConfiguration current_DhcpConfiguration = current_DhcpState.configuration(); stDhcpCfg.mac_address = current_DhcpConfiguration.mac_address(); stDhcpCfg.ipv4_address = current_DhcpConfiguration.ipv4_address(); stDhcpCfg.ipv6_address = current_DhcpConfiguration.ipv6_address(); stDhcpCfg.port_host_name = current_DhcpConfiguration.port_host_name(); - string subnet_id = current_DhcpConfiguration.subnet_id(); for (int i = 0; i < parsed_struct.subnet_states_size(); i++) { SubnetState current_SubnetState = parsed_struct.subnet_states(i); SubnetConfiguration current_SubnetConfiguration = current_SubnetState.configuration(); - if (subnet_id == current_SubnetConfiguration.id()) { stDhcpCfg.gateway_address = current_SubnetConfiguration.gateway().ip_address(); stDhcpCfg.subnet_mask = @@ -80,8 +76,34 @@ int Aca_Dhcp_State_Handler::update_dhcp_state_workitem(const DHCPState current_D break; } } - - switch (current_DhcpState.operation_type()) { + alcor::schema::OperationType current_operation_type = + current_DhcpState.operation_type(); + ACA_LOG_INFO("%s, port_states size: %d\n", "Searching in port states\n", + parsed_struct.port_states().size()); + + if (current_operation_type == alcor::schema::OperationType::UPDATE) { + for (int i = 0; i < parsed_struct.port_states().size(); i++) { + ACA_LOG_INFO( + "Port %d MAC: %s, device_ID: %s, device_owner: %s\n", i, + (parsed_struct.port_states(i).configuration().mac_address()).c_str(), + (parsed_struct.port_states(i).configuration().device_id()).c_str(), + (parsed_struct.port_states(i).configuration().device_owner()).c_str()); + if (parsed_struct.port_states(i).configuration().mac_address() == + current_DhcpConfiguration.mac_address() && + !parsed_struct.port_states(i).configuration().device_id().empty() && + !parsed_struct.port_states(i).configuration().device_owner().empty()) { + current_operation_type = alcor::schema::OperationType::CREATE; + break; + } + } + } + /* + In the current test environment, Nova may send DHCP UPDATE, when it tries to + CREATE a new port, we are now adding this logic to the ACA as a temporary + fix, if this logic is proved to be successful, this logic may be moved to the + Port Manger/Dataplane Manager. + */ + switch (current_operation_type) { case OperationType::CREATE: overall_rc = this->dhcp_programming_if->add_dhcp_entry(&stDhcpCfg); break; @@ -96,17 +118,13 @@ int Aca_Dhcp_State_Handler::update_dhcp_state_workitem(const DHCPState current_D overall_rc = EXIT_FAILURE; break; } - auto operation_end = chrono::steady_clock::now(); - auto operation_total_time = cast_to_microseconds(operation_end - operation_start).count(); - aca_goal_state_handler::Aca_Goal_State_Handler::get_instance().add_goal_state_operation_status( gsOperationReply, current_DhcpConfiguration.id(), DHCP, current_DhcpState.operation_type(), overall_rc, culminative_dataplane_programming_time, culminative_network_configuration_time, operation_total_time); - return overall_rc; } @@ -144,23 +162,17 @@ int Aca_Dhcp_State_Handler::update_dhcp_state_workitem_v2(const DHCPState curren int overall_rc = EXIT_SUCCESS; ulong culminative_dataplane_programming_time = 0; ulong culminative_network_configuration_time = 0; - auto operation_start = chrono::steady_clock::now(); - DHCPConfiguration current_DhcpConfiguration = current_DhcpState.configuration(); stDhcpCfg.mac_address = current_DhcpConfiguration.mac_address(); stDhcpCfg.ipv4_address = current_DhcpConfiguration.ipv4_address(); stDhcpCfg.ipv6_address = current_DhcpConfiguration.ipv6_address(); stDhcpCfg.port_host_name = current_DhcpConfiguration.port_host_name(); - string subnet_id = current_DhcpConfiguration.subnet_id(); - auto subnetStateFound = parsed_struct.subnet_states().find(subnet_id); - if (subnetStateFound != parsed_struct.subnet_states().end()) { SubnetState current_SubnetState = subnetStateFound->second; SubnetConfiguration current_SubnetConfiguration = current_SubnetState.configuration(); - stDhcpCfg.gateway_address = current_SubnetConfiguration.gateway().ip_address(); stDhcpCfg.subnet_mask = aca_convert_cidr_to_netmask(current_SubnetConfiguration.cidr()); @@ -174,9 +186,27 @@ int Aca_Dhcp_State_Handler::update_dhcp_state_workitem_v2(const DHCPState curren subnet_id.c_str()); overall_rc = EXIT_FAILURE; } - + alcor::schema::OperationType current_operation_type = + current_DhcpState.operation_type(); + /* + In the current test environment, Nova may send DHCP UPDATE, when it tries to + CREATE a new port, we are now adding this logic to the ACA as a temporary + fix, if this logic is proved to be successful, this logic may be moved to the + Port Manger/Dataplane Manager. + */ + if (current_operation_type == alcor::schema::OperationType::UPDATE) { + auto target_port_state = + parsed_struct.port_states().find(current_DhcpConfiguration.mac_address()); + // target_port_state.first is the key (resource_id) + // target_port_state.second is the value (PortState) + if (target_port_state != parsed_struct.port_states().end() && + !target_port_state->second.configuration().device_id().empty() && + !target_port_state->second.configuration().device_owner().empty()) { + current_operation_type = alcor::schema::OperationType::CREATE; + } + } if (overall_rc == EXIT_SUCCESS) { - switch (current_DhcpState.operation_type()) { + switch (current_operation_type) { case OperationType::CREATE: overall_rc = this->dhcp_programming_if->add_dhcp_entry(&stDhcpCfg); break; @@ -191,17 +221,13 @@ int Aca_Dhcp_State_Handler::update_dhcp_state_workitem_v2(const DHCPState curren overall_rc = EXIT_FAILURE; } } - auto operation_end = chrono::steady_clock::now(); - auto operation_total_time = cast_to_microseconds(operation_end - operation_start).count(); - aca_goal_state_handler::Aca_Goal_State_Handler::get_instance().add_goal_state_operation_status( gsOperationReply, current_DhcpConfiguration.id(), DHCP, current_DhcpState.operation_type(), overall_rc, culminative_dataplane_programming_time, culminative_network_configuration_time, operation_total_time); - return overall_rc; } diff --git a/src/dp_abstraction/aca_dataplane_ovs.cpp b/src/dp_abstraction/aca_dataplane_ovs.cpp index 14160d4c..87656687 100644 --- a/src/dp_abstraction/aca_dataplane_ovs.cpp +++ b/src/dp_abstraction/aca_dataplane_ovs.cpp @@ -216,6 +216,12 @@ int ACA_Dataplane_OVS::update_port_state_workitem(const PortState current_PortSt } alcor::schema::OperationType current_operation_type = current_PortState.operation_type(); + /* + In the current test environment, Nova may send PORT UPDATE, when it tries to + CREATE a new port, when the device_id and device_owner are not empty, we are + now adding this logic to the ACA as a temporary fix, if this logic is proved + to be successful, this logic may be moved to the Port Manger/Dataplane Manager. + */ if (current_PortState.operation_type() == OperationType::UPDATE) { if (!current_PortConfiguration.device_id().empty() && !current_PortConfiguration.device_owner().empty()) {