diff --git a/include/aca_vlan_manager.h b/include/aca_vlan_manager.h index 8ca5223b..545c997c 100644 --- a/include/aca_vlan_manager.h +++ b/include/aca_vlan_manager.h @@ -38,7 +38,7 @@ struct vpc_table_entry { // CTSL::HashMap CTSL::HashMap ovs_ports; - string auxGateway_id; + string zeta_gateway_id; }; class ACA_Vlan_Manager { @@ -59,15 +59,13 @@ class ACA_Vlan_Manager { int delete_l2_neighbor(string virtual_ip, string virtual_mac, uint tunnel_id, ulong &culminative_time); - // create a neighbor port without specifying vpc_id and neighbor ID - int create_neighbor_outport(alcor::schema::NetworkType network_type, string remote_host_ip, - uint tunnel_id, ulong &culminative_time); + void set_zeta_gateway(uint tunnel_id, const string auxGateway_id); - void set_aux_gateway(uint tunnel_id, const string auxGateway_id); + int remove_zeta_gateway(uint tunnel_id); - string get_aux_gateway_id(uint tunnel_id); + string get_zeta_gateway_id(uint tunnel_id); - bool is_exist_aux_gateway(const string auxGateway_id); + bool is_exist_zeta_gateway(const string auxGateway_id); // compiler will flag error when below is called ACA_Vlan_Manager(ACA_Vlan_Manager const &) = delete; diff --git a/include/aca_zeta_oam_server.h b/include/aca_zeta_oam_server.h new file mode 100644 index 00000000..d42ee92a --- /dev/null +++ b/include/aca_zeta_oam_server.h @@ -0,0 +1,120 @@ +// Copyright 2019 The Alcor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ACA_ZETA_OAM_SERVER_H +#define ACA_ZETA_OAM_SERVER_H + +#include +#include +#include +#include +#include + +#include "goalstateprovisioner.grpc.pb.h" + +using namespace std; +namespace aca_zeta_oam_server +{ +//OAM Message Type +#define OAM_MSG_FLOW_INJECTION (0) +#define OAM_MSG_FLOW_DELETION (1) +#define OAM_MSG_NONE (2) +#define OAM_MSG_MAX (3) + +struct oam_match { + string sip; + string dip; + string sport; + string dport; + string proto; + uint vni; +}; + +struct oam_action { + string inst_nw_dst; + string node_nw_dst; + string inst_dl_dst; + string node_dl_dst; + string idle_timeout; +}; + +struct flow_inject_msg { + struct in_addr inner_src_ip; // Inner Packet SIP + struct in_addr inner_dst_ip; // Inner Packet DIP + uint16_t src_port; // Inner Packet SPort + uint16_t dst_port; // Inner Packet DPort + uint8_t proto; // Inner Packet Protocol + uint8_t vni[3]; // tunnel_id, 3bytes + struct in_addr inst_dst_ip; // Destination Inst IP + struct in_addr node_dst_ip; // Destination Node IP + uint8_t inst_dst_mac[6]; // Destination Inst MAC + uint8_t node_dst_mac[6]; // Destination Node MAC + uint16_t idle_timeout; // 0 - 65536s +}; + +struct flow_del_msg { + struct in_addr inner_src_ip; + struct in_addr inner_dst_ip; + uint16_t src_port; + uint16_t dst_port; + uint8_t proto; + uint8_t vni[3]; +}; + +struct oam_message { + uint32_t op_code; + union op_data { + struct flow_inject_msg msg_inject_flow; + struct flow_del_msg msg_del_flow; + } data; +}; + +class ACA_Zeta_Oam_Server { + public: + ACA_Zeta_Oam_Server(); + ~ACA_Zeta_Oam_Server(); + + static ACA_Zeta_Oam_Server &get_instance(); + void oams_recv(uint32_t udp_dport, void *message); + bool lookup_oam_port_in_cache(uint port_number); + void add_oam_port_cache(uint port_number); + + private: + uint8_t _get_message_type(oam_message *oammsg); + string _get_mac_addr(uint8_t *mac); + uint _get_tunnel_id(uint8_t *vni); + bool _validate_oam_message(oam_message *oammsg); + bool _check_oam_server_port(uint32_t udp_dport, oam_match match); + oam_match _get_oam_match_field(oam_message *oammsg); + oam_action _get_oam_action_field(oam_message *oammsg); + + int _add_direct_path(oam_match match, oam_action action); + int _del_direct_path(oam_match match); + + void _init_oam_msg_ops(); + void _parse_oam_flow_injection(uint32_t udp_dport, oam_message *oammsg); + void _parse_oam_flow_deletion(uint32_t udp_dport, oam_message *oammsg); + void _parse_oam_none(uint32_t /* in_port */, oam_message *oammsg); + + void (aca_zeta_oam_server::ACA_Zeta_Oam_Server ::*_parse_oam_msg_ops[OAM_MSG_MAX])( + uint32_t udp_dpost, oam_message *oammsg); + + // unordered_set + unordered_set _oam_ports_cache; + + // mutex for reading and writing to _oam_ports_cache + mutex _oam_ports_cache_mutex; +}; +} // namespace aca_zeta_oam_server +#endif // #ifndef ACA_Zeta_OAM_SERVER_H \ No newline at end of file diff --git a/include/aca_zeta_programming.h b/include/aca_zeta_programming.h index 2a4522c3..b690fa60 100644 --- a/include/aca_zeta_programming.h +++ b/include/aca_zeta_programming.h @@ -19,56 +19,55 @@ #include #include #include "goalstateprovisioner.grpc.pb.h" +#include "hashmap/HashMap.h" using namespace std; + static atomic_uint current_available_group_id(1); namespace aca_zeta_programming { struct zeta_config { - string group_id; - // - list zeta_buckets; - uint32_t port_inband_operation; -}; - -struct aux_gateway_entry { - uint oam_port; uint group_id; + uint oam_port; + // set + unordered_set zeta_buckets; }; class ACA_Zeta_Programming { public: + ACA_Zeta_Programming(); + ~ACA_Zeta_Programming(); static ACA_Zeta_Programming &get_instance(); - uint get_or_create_group_id(string auxGateway_id); + void create_entry(string zeta_gateway_id, uint oam_port); - int create_or_update_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, - const string vpc_id, uint32_t tunnel_id); + void clear_all_data(); - int delete_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, - const string vpc_id, uint32_t tunnel_id); + int create_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, uint tunnel_id); - bool is_exist_group_rule(uint group_id); + int delete_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, uint tunnel_id); - uint get_oam_server_port(string auxGateway_id); + bool oam_port_rule_exists(uint port_number); - void set_oam_server_port(string auxGateway_id, uint port_number); + bool group_rule_exists(uint group_id); - bool is_exist_oam_port(uint port_number); + uint get_oam_port(string zeta_gateway_id); - private: - int _create_or_update_zeta_group_entry(zeta_config *zeta_config_in); - - int _delete_zeta_group_entry(zeta_config *zeta_config_in); + uint get_group_id(string zeta_gateway_id); private: - // unordered_map - unordered_map _zeta_gateways_table; + int _create_oam_ofp(uint port_number); + int _delete_oam_ofp(uint port_number); - mutex _zeta_gateways_table_mutex; + int _create_group_punt_rule(uint tunnel_id, uint group_id); + int _delete_group_punt_rule(uint tunnel_id); + + int _create_zeta_group_entry(zeta_config *zeta_config_in); + int _delete_zeta_group_entry(zeta_config *zeta_config_in); - void create_entry_unsafe(string auxGateway_id); + // hashtable + CTSL::HashMap _zeta_config_table; }; } // namespace aca_zeta_programming #endif // #ifndef ACA_ZETA_PROGRAMMING_H \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8065fefa..26d20d3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,9 +17,8 @@ set(SOURCES ./ovs/aca_ovs_control.cpp ./dhcp/aca_dhcp_state_handler.cpp ./dhcp/aca_dhcp_server.cpp - ./zeta/aca_oam_server.cpp + ./zeta/aca_zeta_oam_server.cpp ./zeta/aca_zeta_programming.cpp - ./zeta/aca_oam_port_manager.cpp ) FIND_LIBRARY(RDKAFKA rdkafka /usr/lib/x86_64-linux-gnu NO_DEFAULT_PATH) FIND_LIBRARY(CPPKAFKA cppkafka /usr/local/lib NO_DEFAULT_PATH) diff --git a/src/dp_abstraction/aca_dataplane_ovs.cpp b/src/dp_abstraction/aca_dataplane_ovs.cpp index 9e2de39a..6a5a4063 100644 --- a/src/dp_abstraction/aca_dataplane_ovs.cpp +++ b/src/dp_abstraction/aca_dataplane_ovs.cpp @@ -243,8 +243,8 @@ int ACA_Dataplane_OVS::update_port_state_workitem(const PortState current_PortSt if (found_auxgateway.aux_gateway_type() == ZETA) { ACA_LOG_INFO("%s", "AuxGateway_type is zeta!\n"); // Update the zeta settings of vpc - overall_rc = ACA_Zeta_Programming::get_instance().create_or_update_zeta_config( - found_auxgateway, current_PortConfiguration.vpc_id(), found_tunnel_id); + overall_rc = ACA_Zeta_Programming::get_instance().create_zeta_config( + found_auxgateway, found_tunnel_id); } break; @@ -277,7 +277,7 @@ int ACA_Dataplane_OVS::update_port_state_workitem(const PortState current_PortSt ACA_LOG_INFO("%s", "AuxGateway_type is zeta!\n"); // Delete the zeta settings of vpc overall_rc = ACA_Zeta_Programming::get_instance().delete_zeta_config( - found_auxgateway, current_PortConfiguration.vpc_id(), found_tunnel_id); + found_auxgateway, found_tunnel_id); } break; diff --git a/src/ovs/aca_ovs_control.cpp b/src/ovs/aca_ovs_control.cpp index 075f694f..1e740822 100644 --- a/src/ovs/aca_ovs_control.cpp +++ b/src/ovs/aca_ovs_control.cpp @@ -33,8 +33,7 @@ #include #include #include "aca_dhcp_server.h" -#include "aca_oam_server.h" -#include "aca_oam_port_manager.h" +#include "aca_zeta_oam_server.h" using namespace std; using namespace ovs_control; @@ -267,10 +266,9 @@ void ACA_OVS_Control::parse_packet(uint32_t in_port, void *packet) } /* oam message procedure */ - if (aca_oam_port_manager::Aca_Oam_Port_Manager::get_instance().is_oam_server_port( - (uint32_t)udp_dport)) { + if (aca_zeta_oam_server::ACA_Zeta_Oam_Server::get_instance().lookup_oam_port_in_cache((uint)udp_dport)) { ACA_LOG_INFO("%s", " Message Type: OAM\n"); - aca_oam_server::ACA_Oam_Server::get_instance().oams_recv( + aca_zeta_oam_server::ACA_Zeta_Oam_Server::get_instance().oams_recv( (uint32_t)udp_dport, const_cast(payload)); } } diff --git a/src/ovs/aca_vlan_manager.cpp b/src/ovs/aca_vlan_manager.cpp index 2dfdcf9e..ae1614e5 100644 --- a/src/ovs/aca_vlan_manager.cpp +++ b/src/ovs/aca_vlan_manager.cpp @@ -256,42 +256,26 @@ int ACA_Vlan_Manager::delete_l2_neighbor(string virtual_ip, string virtual_mac, return overall_rc; } -// create a neighbor port without specifying vpc_id and neighbor ID -int ACA_Vlan_Manager::create_neighbor_outport(alcor::schema::NetworkType network_type, - string remote_host_ip, uint /*tunnel_id*/, - ulong &culminative_time) +string ACA_Vlan_Manager::get_zeta_gateway_id(uint tunnel_id) { - int overall_rc = EXIT_SUCCESS; - - ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::create_neighbor_outport ---> Entering\n"); - - string outport_name = aca_get_outport_name(network_type, remote_host_ip); - - // since this is a new outport, configure OVS and openflow rule - string cmd_string = - "--may-exist add-port br-tun " + outport_name + " -- set interface " + - outport_name + " type=" + aca_get_network_type_string(network_type) + - " options:df_default=true options:egress_pkt_mark=0 options:in_key=flow options:out_key=flow options:remote_ip=" + - remote_host_ip; - - ACA_OVS_L2_Programmer::get_instance().execute_ovsdb_command( - cmd_string, culminative_time, overall_rc); + ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::get_zeta_gateway_id ---> Entering\n"); - // incoming from neighbor through vxlan port (based on remote IP) - cmd_string = "add-flow br-tun \"table=0,priority=25,in_port=\"" + - outport_name + "\" actions=resubmit(,4)\""; - - ACA_OVS_L2_Programmer::get_instance().execute_openflow_command( - cmd_string, culminative_time, overall_rc); + vpc_table_entry *current_vpc_table_entry; + string zeta_gateway_id; - ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::create_neighbor_outport <--- Exiting\n"); + if (!_vpcs_table.find(tunnel_id, current_vpc_table_entry)) { + ACA_LOG_ERROR("tunnel_id %u not found in vpc_table\n", tunnel_id); + } else { + zeta_gateway_id = current_vpc_table_entry->zeta_gateway_id; + } - return overall_rc; + ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::get_zeta_gateway_id <--- Entering\n"); + return zeta_gateway_id; } -void ACA_Vlan_Manager::set_aux_gateway(uint tunnel_id, const string auxGateway_id) +void ACA_Vlan_Manager::set_zeta_gateway(uint tunnel_id, const string auxGateway_id) { - ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::set_aux_gateway ---> Entering\n"); + ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::set_zeta_gateway ---> Entering\n"); vpc_table_entry *new_vpc_table_entry = nullptr; @@ -300,34 +284,34 @@ void ACA_Vlan_Manager::set_aux_gateway(uint tunnel_id, const string auxGateway_i _vpcs_table.find(tunnel_id, new_vpc_table_entry); } - new_vpc_table_entry->auxGateway_id = auxGateway_id; + new_vpc_table_entry->zeta_gateway_id = auxGateway_id; - ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::set_aux_gateway <--- Exiting\n"); + ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::set_zeta_gateway <--- Exiting\n"); } -string ACA_Vlan_Manager::get_aux_gateway_id(uint tunnel_id) +int ACA_Vlan_Manager::remove_zeta_gateway(uint tunnel_id) { - ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::get_aux_gateway_id ---> Entering\n"); + ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::remove_zeta_gateway ---> Entering\n"); + int overall_rc = EXIT_SUCCESS; + string zeta_gateway_id; vpc_table_entry *current_vpc_table_entry; - string auxGateway_id; if (!_vpcs_table.find(tunnel_id, current_vpc_table_entry)) { ACA_LOG_ERROR("tunnel_id %u not found in vpc_table\n", tunnel_id); } else { - auxGateway_id = current_vpc_table_entry->auxGateway_id; + current_vpc_table_entry->zeta_gateway_id = ""; } - ACA_LOG_DEBUG("ACA_Vlan_Manager::get_aux_gateway_id <--- Exiting, auxGateway_id =%s\n", - auxGateway_id.c_str()); - - return auxGateway_id; + ACA_LOG_DEBUG("ACA_Vlan_Manager::remove_zeta_gateway <--- Exiting, overall_rc = %d\n", + overall_rc); + return overall_rc; } -bool ACA_Vlan_Manager::is_exist_aux_gateway(string auxGateway_id) +bool ACA_Vlan_Manager::is_exist_zeta_gateway(string zeta_gateway_id) { ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::get_aux_gateway_id ---> Entering\n"); - bool auxGateway_id_found = false; + bool zeta_gateway_id_found = false; for (size_t i = 0; i < _vpcs_table.hashSize; i++) { auto hash_node = (_vpcs_table.hashTable[i]).head; @@ -341,15 +325,15 @@ bool ACA_Vlan_Manager::is_exist_aux_gateway(string auxGateway_id) (_vpcs_table.hashTable[i]).mutex_); while (hash_node != nullptr) { - if (hash_node->getValue()->auxGateway_id == auxGateway_id) { - auxGateway_id_found = true; + if (hash_node->getValue()->zeta_gateway_id == zeta_gateway_id) { + zeta_gateway_id_found = true; break; } - if (auxGateway_id_found) { + if (zeta_gateway_id_found) { break; // break out of for loop on _vpcs_table } else { - // aux_Gateway_id not found yet, look at the next hash_node + // zeta_gateway_id not found yet, look at the next hash_node hash_node = hash_node->next; } } @@ -359,9 +343,9 @@ bool ACA_Vlan_Manager::is_exist_aux_gateway(string auxGateway_id) } } - ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::get_aux_gateway_id ---> Entering\n"); + ACA_LOG_DEBUG("%s", "ACA_Vlan_Manager::get_aux_gateway_id <--- Entering\n"); - return auxGateway_id_found; + return zeta_gateway_id_found; } } // namespace aca_vlan_manager diff --git a/src/zeta/aca_oam_port_manager.cpp b/src/zeta/aca_oam_port_manager.cpp deleted file mode 100644 index 889e4b47..00000000 --- a/src/zeta/aca_oam_port_manager.cpp +++ /dev/null @@ -1,201 +0,0 @@ - -// Copyright 2019 The Alcor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "aca_oam_port_manager.h" -#include "aca_log.h" -#include -#include "aca_ovs_control.h" - -using namespace aca_ovs_control; - -namespace aca_oam_port_manager -{ -Aca_Oam_Port_Manager::Aca_Oam_Port_Manager() -{ -} - -Aca_Oam_Port_Manager::~Aca_Oam_Port_Manager() -{ - //clear all oam punt rules - for (auto port_number : _oam_ports_cache) { - _delete_oam_ofp(port_number); - } - _clear_all_data(); -} - -Aca_Oam_Port_Manager &Aca_Oam_Port_Manager::get_instance() -{ - // Instance is destroyed when program exits. - // It is instantiated on first use. - static Aca_Oam_Port_Manager instance; - return instance; -} - -// add the OAM punt rule -int Aca_Oam_Port_Manager::_create_oam_ofp(uint port_number) -{ - int overall_rc; - - string opt = "table=0,priority=25,udp,udp_dst=" + to_string(port_number) + ",actions=CONTROLLER"; - - overall_rc = ACA_OVS_Control::get_instance().add_flow("br-int", opt.c_str()); - - if (overall_rc == EXIT_SUCCESS) { - ACA_LOG_INFO("%s", "creat_oam_ofp succeeded!\n"); - } else { - ACA_LOG_ERROR("creat_oam_ofp failed!!! overrall_rc: %d\n", overall_rc); - } - - return overall_rc; -} - -// delete the OAM punt rule -int Aca_Oam_Port_Manager::_delete_oam_ofp(uint port_number) -{ - int overall_rc; - - string opt = "udp,udp_dst=" + to_string(port_number); - - overall_rc = ACA_OVS_Control::get_instance().del_flows("br-int", opt.c_str()); - - if (overall_rc == EXIT_SUCCESS) { - ACA_LOG_INFO("%s", "delete_oam_ofp succeeded!\n"); - } else { - ACA_LOG_ERROR("delete_oam_ofp failed!!! overrall_rc: %d\n", overall_rc); - } - return overall_rc; -} - -void Aca_Oam_Port_Manager::_clear_all_data() -{ - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::clear_all_data ---> Entering\n"); - - // -----critical section starts----- - _oam_ports_cache_mutex.lock(); - // All the elements in the unordered_set container are dropped: - // their destructors are called, and they are removed from the container, - // leaving _oam_ports_cache with a size of 0. - _oam_ports_cache.clear(); - _oam_ports_cache_mutex.unlock(); - // -----critical section ends----- - - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::clear_all_data <--- Exiting\n"); -} - -// unsafe function, needs to be called inside oam_ports_table_mutex lock -// this function assumes there is no existing entry for port_number -void Aca_Oam_Port_Manager::create_entry_unsafe(uint port_number) -{ - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::create_entry_unsafe ---> Entering\n"); - - _oam_ports_cache.emplace(port_number); - - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::create_entry_unsafe <--- Exiting\n"); -} - -// update oam_ports_table and add the OAM punt rule also if this is the first port in the VPC -void Aca_Oam_Port_Manager::add_oam_port_rule(uint port_number) -{ - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::add_oam_port_rule ---> Entering\n"); - // -----critical section starts----- - _oam_ports_cache_mutex.lock(); - if (_oam_ports_cache.find(port_number) == _oam_ports_cache.end()) { - create_entry_unsafe(port_number); - _create_oam_ofp(port_number); - } - _oam_ports_cache_mutex.unlock(); - // -----critical section ends----- - - ACA_LOG_DEBUG("%s", "ACA_OVS_Programmer::add_oam_port_rule <--- Exiting\n"); -} - -// update oam_ports_table and delete the OAM punt rule if the last port in the VPC has been deleted -int Aca_Oam_Port_Manager::remove_oam_port_rule(uint port_number) -{ - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::remove_oam_port_rule ---> Entering\n"); - - int overall_rc; - - // -----critical section starts----- - _oam_ports_cache_mutex.lock(); - if (_oam_ports_cache.find(port_number) == _oam_ports_cache.end()) { - ACA_LOG_ERROR("port_number %u not find in oam_ports_table\n", port_number); - overall_rc = ENOENT; - } else { - // clean up the oam_ports_cache entry - int rc = _oam_ports_cache.erase(port_number); - if (rc == 1) { - ACA_LOG_INFO("Successfuly cleaned up entry for port_number %u\n", port_number); - - } else { - ACA_LOG_ERROR("Failed to clean up entry for port_number %u\n", port_number); - } - - // clean oam port rule - overall_rc = _delete_oam_ofp(port_number); - - if (rc != 1 || overall_rc != EXIT_SUCCESS) { - overall_rc = EXIT_FAILURE; - } - } - _oam_ports_cache_mutex.unlock(); - // -----critical section ends----- - - ACA_LOG_DEBUG("Aca_Oam_Port_Manager::remove_oam_port_rule <--- Exiting, overall_rc = %d\n", - overall_rc); - - return overall_rc; -} - -// Determine whether the port is oam server port -bool Aca_Oam_Port_Manager::is_oam_server_port(uint port_number) -{ - ACA_LOG_DEBUG("%s", "Aca_Oam_Port_Manager::is_oam_server_port ---> Entering\n"); - - bool overall_rc; - - // -----critical section starts----- - _oam_ports_cache_mutex.lock(); - if (_oam_ports_cache.find(port_number) == _oam_ports_cache.end()) { - ACA_LOG_ERROR("port_number %u not find in oam_ports_table\n", port_number); - overall_rc = false; - } else { - overall_rc = true; - } - _oam_ports_cache_mutex.unlock(); - // -----critical section ends----- - ACA_LOG_DEBUG("Aca_Oam_Port_Manager::is_oam_server_port <--- Exiting, overall_rc = %d\n", - overall_rc); - - return overall_rc; -} - -bool Aca_Oam_Port_Manager::is_exist_oam_port_rule(uint port_number) -{ - int overall_rc = EXIT_FAILURE; - - string opt = "table=0,udp,udp_dst=" + to_string(port_number); - - // overall_rc = ACA_OVS_Control::get_instance().flow_exists("br_tun", opt.c_str()); - if (overall_rc == EXIT_SUCCESS) { - ACA_LOG_INFO("%s", "Oam port rule is exist!\n"); - return true; - } else { - ACA_LOG_INFO("%s", "Oam port rule is not exist!\n"); - return false; - } -} - -} // namespace aca_oam_port_manager \ No newline at end of file diff --git a/src/zeta/aca_oam_server.cpp b/src/zeta/aca_zeta_oam_server.cpp similarity index 64% rename from src/zeta/aca_oam_server.cpp rename to src/zeta/aca_zeta_oam_server.cpp index 4511640b..d0e0fa70 100644 --- a/src/zeta/aca_oam_server.cpp +++ b/src/zeta/aca_zeta_oam_server.cpp @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "aca_oam_server.h" +#include "aca_zeta_oam_server.h" #include "aca_log.h" #include "goalstateprovisioner.grpc.pb.h" #include @@ -23,49 +23,45 @@ #include "aca_ovs_control.h" #include "aca_vlan_manager.h" #include "aca_zeta_programming.h" +#include using namespace std; using namespace aca_ovs_control; -namespace aca_oam_server +namespace aca_zeta_oam_server { -ACA_Oam_Server::ACA_Oam_Server() +ACA_Zeta_Oam_Server::ACA_Zeta_Oam_Server() { _init_oam_msg_ops(); } -ACA_Oam_Server::~ACA_Oam_Server() +ACA_Zeta_Oam_Server::~ACA_Zeta_Oam_Server() { } -ACA_Oam_Server &ACA_Oam_Server::get_instance() +ACA_Zeta_Oam_Server &ACA_Zeta_Oam_Server::get_instance() { - static ACA_Oam_Server instance; + static ACA_Zeta_Oam_Server instance; return instance; } -bool ACA_Oam_Server::_validate_oam_message(oam_message *oammsg) +bool ACA_Zeta_Oam_Server::_validate_oam_message(oam_message *oammsg) { - int retcode = 0; - if (!oammsg) { ACA_LOG_ERROR("%s", "OAM message is null!\n"); return false; } - if (OAM_MSG_FLOW_INJECTION != oammsg->op_code && OAM_MSG_FLOW_DELETION != oammsg->op_code) { - retcode = -1; + uint op_code = ntohl(oammsg->op_code); + if (op_code != OAM_MSG_FLOW_INJECTION && op_code != OAM_MSG_FLOW_DELETION) { ACA_LOG_ERROR("%s", "Invalid 'op_code' field for OAM message!\n"); - } - - if (0 != retcode) { return false; } return true; } -void ACA_Oam_Server::oams_recv(uint udp_dport, void *message) +void ACA_Zeta_Oam_Server::oams_recv(uint udp_dport, void *message) { oam_message *oammsg = nullptr; @@ -76,7 +72,7 @@ void ACA_Oam_Server::oams_recv(uint udp_dport, void *message) oammsg = (oam_message *)message; - if (_validate_oam_message(oammsg)) { + if (!_validate_oam_message(oammsg)) { ACA_LOG_ERROR("%s", "Invalid OAM message!\n"); return; } @@ -88,38 +84,40 @@ void ACA_Oam_Server::oams_recv(uint udp_dport, void *message) return; } -void ACA_Oam_Server::_init_oam_msg_ops() +void ACA_Zeta_Oam_Server::_init_oam_msg_ops() { _parse_oam_msg_ops[OAM_MSG_FLOW_INJECTION] = - &aca_oam_server::ACA_Oam_Server::_parse_oam_flow_injection; + &aca_zeta_oam_server::ACA_Zeta_Oam_Server::_parse_oam_flow_injection; _parse_oam_msg_ops[OAM_MSG_FLOW_DELETION] = - &aca_oam_server::ACA_Oam_Server::_parse_oam_flow_deletion; + &aca_zeta_oam_server::ACA_Zeta_Oam_Server::_parse_oam_flow_deletion; // error: array subscript is above array bounds [-Werror=array-bounds] // because _parse_oam_msg_ops and defined to have three element so // doing _parse_oam_msg_ops[OAM_MSG_NONE(3)] in invalid - // _parse_oam_msg_ops[OAM_MSG_NONE] = &aca_oam_server::ACA_Oam_Server::_parse_oam_none; + // _parse_oam_msg_ops[OAM_MSG_NONE] = &aca_zeta_oam_server::ACA_Zeta_Oam_Server::_parse_oam_none; } -uint8_t ACA_Oam_Server::_get_message_type(oam_message *oammsg) +uint8_t ACA_Zeta_Oam_Server::_get_message_type(oam_message *oammsg) { if (!oammsg) { ACA_LOG_ERROR("%s", "OAM message is null!\n"); return OAM_MSG_NONE; } - if (oammsg->op_code != OAM_MSG_FLOW_INJECTION && oammsg->op_code != OAM_MSG_FLOW_DELETION) { + uint8_t op_code = (uint8_t)(ntohl(oammsg->op_code)); + + if (op_code != OAM_MSG_FLOW_INJECTION && op_code != OAM_MSG_FLOW_DELETION) { return OAM_MSG_NONE; } - return (uint8_t)(ntohl(oammsg->op_code)); + return op_code; } -string ACA_Oam_Server::_get_mac_addr(uint8_t *mac) +string ACA_Zeta_Oam_Server::_get_mac_addr(uint8_t *mac) { string mac_string; stringstream ss; - //Convert mac address to string + // Convert mac address to string // from uint8[6] to string for (int i = 0; i < 6; i++) { ss << std::hex << std::setw(2) << std::setfill('0') @@ -132,24 +130,19 @@ string ACA_Oam_Server::_get_mac_addr(uint8_t *mac) return mac_string; } -string ACA_Oam_Server::_get_vpc_id(uint8_t *vni) +uint ACA_Zeta_Oam_Server::_get_tunnel_id(uint8_t *vni) { - string vpc_id; - stringstream ss; + uint tunnel_id; - for (int i = 0; i < 3; i++) { - ss << std::hex << std::setw(2) << std::setfill('0') - << static_cast(vni[i]); - } - - ss >> vpc_id; - vpc_id.pop_back(); + // Convert tunnel_id to uint + // from uint8[3] to uint + tunnel_id = ((uint)vni[0]) | ((uint)vni[1]) << 8 | ((uint) vni[2]) << 16; - return vpc_id; + return tunnel_id; } //extract data for flow table matching from the oam message -oam_match ACA_Oam_Server::_get_oam_match_field(oam_message *oammsg) +oam_match ACA_Zeta_Oam_Server::_get_oam_match_field(oam_message *oammsg) { oam_match match; @@ -160,15 +153,14 @@ oam_match ACA_Oam_Server::_get_oam_match_field(oam_message *oammsg) match.sport = to_string(ntohs(msg_data.src_port)); match.dport = to_string(ntohs(msg_data.dst_port)); match.proto = to_string(msg_data.proto); - // TODO: figure out the conversion from 4 bytes VNI to tunnel_id string - // why don't we make match.vni as uint? - // match.vni = _get_vpc_id(msg_data.vni); + // TODO: figure out the conversion from 3 bytes VNI to tunnel_id + match.vni = _get_tunnel_id(msg_data.vni); return match; } //extract the data used for the flow table action from the oam message -oam_action ACA_Oam_Server::_get_oam_action_field(oam_message *oammsg) +oam_action ACA_Zeta_Oam_Server::_get_oam_action_field(oam_message *oammsg) { oam_action action; @@ -184,12 +176,14 @@ oam_action ACA_Oam_Server::_get_oam_action_field(oam_message *oammsg) } //check whether the udp_dport is the oam server port of the vpc -bool ACA_Oam_Server::_check_oam_server_port(uint udp_dport, oam_match match) +bool ACA_Zeta_Oam_Server::_check_oam_server_port(uint udp_dport, oam_match match) { - string auxGateway_id = aca_vlan_manager::ACA_Vlan_Manager::get_instance().get_aux_gateway_id( - std::stoul(match.vni)); - uint32_t oam_port = aca_zeta_programming::ACA_Zeta_Programming::get_instance().get_oam_server_port( - auxGateway_id); + uint tunnel_id = match.vni; + string zeta_gateway_id = + aca_vlan_manager::ACA_Vlan_Manager::get_instance().get_zeta_gateway_id(tunnel_id); + + uint oam_port = aca_zeta_programming::ACA_Zeta_Programming::get_instance().get_oam_port( + zeta_gateway_id); if (udp_dport == oam_port) { ACA_LOG_INFO("%s", "oam port is correct!\n"); @@ -200,9 +194,8 @@ bool ACA_Oam_Server::_check_oam_server_port(uint udp_dport, oam_match match) } } -void ACA_Oam_Server::_parse_oam_flow_injection(uint udp_dport, oam_message *oammsg) +void ACA_Zeta_Oam_Server::_parse_oam_flow_injection(uint udp_dport, oam_message *oammsg) { - unsigned long not_care_culminative_time; int overall_rc; oam_match match = _get_oam_match_field(oammsg); @@ -214,16 +207,6 @@ void ACA_Oam_Server::_parse_oam_flow_injection(uint udp_dport, oam_message *oamm oam_action action = _get_oam_action_field(oammsg); - string remote_host_ip = action.node_nw_dst; - uint tunnel_id = strtoul(match.vni.c_str(), NULL, 10); - alcor::schema::NetworkType network_type = alcor::schema::NetworkType::VXLAN; - - if (!aca_is_port_on_same_host(remote_host_ip)) { - ACA_LOG_INFO("%s", "port_neighbor not exist!\n"); - //crate neighbor_port - aca_vlan_manager::ACA_Vlan_Manager::get_instance().create_neighbor_outport( - network_type, remote_host_ip, tunnel_id, not_care_culminative_time); - } overall_rc = _add_direct_path(match, action); if (overall_rc == EXIT_SUCCESS) { @@ -235,7 +218,7 @@ void ACA_Oam_Server::_parse_oam_flow_injection(uint udp_dport, oam_message *oamm return; } -void ACA_Oam_Server::_parse_oam_flow_deletion(uint udp_dport, oam_message *oammsg) +void ACA_Zeta_Oam_Server::_parse_oam_flow_deletion(uint udp_dport, oam_message *oammsg) { int overall_rc; oam_match match = _get_oam_match_field(oammsg); @@ -255,30 +238,27 @@ void ACA_Oam_Server::_parse_oam_flow_deletion(uint udp_dport, oam_message *oamms return; } -void ACA_Oam_Server::_parse_oam_none(uint /* in_port */, oam_message *oammsg) +void ACA_Zeta_Oam_Server::_parse_oam_none(uint /* in_port */, oam_message *oammsg) { ACA_LOG_ERROR("Wrong OAM message type! (Message type = %d)\n", _get_message_type(oammsg)); return; } -int ACA_Oam_Server::_add_direct_path(oam_match match, oam_action action) +int ACA_Zeta_Oam_Server::_add_direct_path(oam_match match, oam_action action) { unsigned long not_care_culminative_time; int overall_rc = EXIT_SUCCESS; - // string vlan_id = to_string(aca_vlan_manager::ACA_Vlan_Manager::get_instance().get_or_create_vlan_id( - std::stoul(match.vni))); - string outport_name = - aca_get_outport_name(alcor::schema::NetworkType::VXLAN, action.node_nw_dst); + match.vni)); string cmd_match = "ip,nw_proto=" + match.proto + ",nw_src=" + match.sip + ",nw_dst=" + match.dip + ",tp_src=" + match.sport + ",tp_dst=" + match.dport + ",dl_vlan=" + vlan_id; - string cmd_action = ",actions=\"strip_vlan,load:" + match.vni + - "->NXM_NX_TUN_ID[],mod_dl_dst=" + action.inst_dl_dst + - ",mod_nw_dst=" + action.inst_nw_dst + - ",output:" + outport_name + "\""; + string cmd_action = ",actions=\"strip_vlan,load:" + to_string(match.vni) + + "->NXM_NX_TUN_ID[],set_field:" + action.node_nw_dst + + "->tun_dst,mod_dl_dst=" + action.inst_dl_dst + + ",mod_nw_dst=" + action.inst_nw_dst + ",output:vxlan-generic\""; // Adding unicast rules in table20 string opt = "add-flow br-tun table=20,priority=50,idle_timeout=" + action.idle_timeout + @@ -295,11 +275,11 @@ int ACA_Oam_Server::_add_direct_path(oam_match match, oam_action action) return overall_rc; } -int ACA_Oam_Server::_del_direct_path(oam_match match) +int ACA_Zeta_Oam_Server::_del_direct_path(oam_match match) { int overall_rc; string vlan_id = to_string(aca_vlan_manager::ACA_Vlan_Manager::get_instance().get_or_create_vlan_id( - std::stoul(match.vni))); + match.vni)); string opt = "table=20,priority=50,ip,nw_proto=" + match.proto + ",nw_src=" + match.sip + ",nw_dst=" + match.dip + @@ -317,4 +297,21 @@ int ACA_Oam_Server::_del_direct_path(oam_match match) return overall_rc; } -} // namespace aca_oam_server +// add oam port number to cache +void ACA_Zeta_Oam_Server::add_oam_port_cache(uint port_number) +{ + if (_oam_ports_cache.find(port_number) == _oam_ports_cache.end()) { + _oam_ports_cache.emplace(port_number); + } +} + +// find the oam port number in the cache +bool ACA_Zeta_Oam_Server::lookup_oam_port_in_cache(uint port_number) +{ + if (_oam_ports_cache.find(port_number) != _oam_ports_cache.end()) { + return true; + } else { + return false; + } +} +} // namespace aca_zeta_oam_server diff --git a/src/zeta/aca_zeta_programming.cpp b/src/zeta/aca_zeta_programming.cpp index 1ffecabf..35633a0f 100644 --- a/src/zeta/aca_zeta_programming.cpp +++ b/src/zeta/aca_zeta_programming.cpp @@ -16,143 +16,272 @@ #include "aca_ovs_l2_programmer.h" #include "aca_util.h" #include "aca_log.h" -#include "aca_oam_port_manager.h" #include "aca_vlan_manager.h" #include "aca_ovs_control.h" +#include "aca_zeta_oam_server.h" -using namespace aca_oam_port_manager; using namespace alcor::schema; using namespace aca_ovs_control; using namespace aca_vlan_manager; +using namespace aca_ovs_l2_programmer; namespace aca_zeta_programming { +ACA_Zeta_Programming::ACA_Zeta_Programming() +{ +} + +ACA_Zeta_Programming::~ACA_Zeta_Programming() +{ + clear_all_data(); +} + ACA_Zeta_Programming &ACA_Zeta_Programming::get_instance() { static ACA_Zeta_Programming instance; return instance; } -void ACA_Zeta_Programming::create_entry_unsafe(string auxGateway_id) +void ACA_Zeta_Programming::create_entry(string zeta_gateway_id, uint oam_port) { - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::create_entry_unsafe ---> Entering\n"); - aux_gateway_entry new_table_entry; - new_table_entry.group_id = current_available_group_id.load(); - _zeta_gateways_table.emplace(auxGateway_id, new_table_entry); - current_available_group_id++; + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::create_entry ---> Entering\n"); - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::create_entry_unsafe <--- Exiting\n"); + zeta_config *new_zeta_cfg = new zeta_config; + // fetch the value first to used for new_zeta_cfg->group_id + // then add 1 after, doing both atomically + // std::memory_order_relaxed option won't help much for x86 but other + // CPU architecture can take advantage of it + new_zeta_cfg->group_id = + current_available_group_id.fetch_add(1, std::memory_order_relaxed); + + new_zeta_cfg->oam_port = oam_port; + _zeta_config_table.insert(zeta_gateway_id, new_zeta_cfg); + + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::create_entry <--- Exiting\n"); } -uint ACA_Zeta_Programming::get_or_create_group_id(string auxGateway_id) +void ACA_Zeta_Programming::clear_all_data() { - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::get_or_create_group_id ---> Entering\n"); + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::clear_all_data ---> Entering\n"); - // -----critical section starts----- - _zeta_gateways_table_mutex.lock(); - if (_zeta_gateways_table.find(auxGateway_id) == _zeta_gateways_table.end()) { - create_entry_unsafe(auxGateway_id); - } - uint acquired_group_id = _zeta_gateways_table[auxGateway_id].group_id; - _zeta_gateways_table_mutex.unlock(); - // -----critical section ends----- + // All the elements in the container are deleted: + // their destructors are called, and they are removed from the container, + // leaving an empty _zeta_config_table table. + _zeta_config_table.clear(); - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::get_or_create_group_id <--- Exiting\n"); - - return acquired_group_id; + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::clear_all_data <--- Exiting\n"); } -int ACA_Zeta_Programming::create_or_update_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, - const string /*vpc_id*/, uint tunnel_id) +int ACA_Zeta_Programming::_create_group_punt_rule(uint tunnel_id, uint group_id) { + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::_create_group_punt_rule ---> Entering\n"); + unsigned long not_care_culminative_time; int overall_rc = EXIT_SUCCESS; - zeta_config stZetaCfg; - uint group_id = get_or_create_group_id(current_AuxGateway.id()); + uint vlan_id = ACA_Vlan_Manager::get_instance().get_or_create_vlan_id(tunnel_id); - stZetaCfg.group_id = to_string(group_id); - for (auto destination : current_AuxGateway.destinations()) { - stZetaCfg.zeta_buckets.push_back(destination.ip_address()); - string remote_host_ip = destination.ip_address(); - if (!aca_is_port_on_same_host(remote_host_ip)) { - ACA_LOG_INFO("%s", "port_neighbor not exist!\n"); - //crate neighbor_port - ACA_Vlan_Manager::get_instance().create_neighbor_outport( - alcor::schema::NetworkType::VXLAN, remote_host_ip, tunnel_id, - not_care_culminative_time); - } + string opt = "add-flow br-tun table=22,priority=50,dl_vlan=" + to_string(vlan_id) + + ",actions=\"strip_vlan,load:" + to_string(tunnel_id) + + "->NXM_NX_TUN_ID[],group:" + to_string(group_id) + "\""; + + ACA_OVS_L2_Programmer::get_instance().execute_openflow_command( + opt, not_care_culminative_time, overall_rc); + + if (overall_rc == EXIT_SUCCESS) { + ACA_LOG_INFO("%s", "_create_group_punt_rule succeeded!\n"); + } else { + ACA_LOG_ERROR("_create_group_punt_rule failed!!! overrall_rc: %d\n", overall_rc); } - uint oam_server_port = current_AuxGateway.zeta_info().port_inband_operation(); - string auxGateway_id = ACA_Vlan_Manager::get_instance().get_aux_gateway_id(tunnel_id); + ACA_LOG_DEBUG("ACA_Zeta_Programming::_create_group_punt_rule <--- Exiting, overall_rc = %d\n", + overall_rc); + return overall_rc; +} + +int ACA_Zeta_Programming::_delete_group_punt_rule(uint tunnel_id) +{ + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::_delete_group_punt_rule ---> Entering\n"); + int overall_rc; - // auxGateway is not set - if (auxGateway_id.empty()) { - ACA_LOG_INFO("%s", "auxGateway_id is empty!\n"); + uint vlan_id = ACA_Vlan_Manager::get_instance().get_or_create_vlan_id(tunnel_id); + string opt = "table=22,priority=50,dl_vlan=" + to_string(vlan_id); - if (!is_exist_group_rule(group_id)) { - // add the group bucket rule - overall_rc = _create_or_update_zeta_group_entry(&stZetaCfg); - } + overall_rc = ACA_OVS_Control::get_instance().del_flows("br-tun", opt.c_str()); - if (!Aca_Oam_Port_Manager::get_instance().is_exist_oam_port_rule(oam_server_port)) { - //update oam_ports_cache and add the OAM punt rule also - Aca_Oam_Port_Manager::get_instance().add_oam_port_rule(oam_server_port); - } + if (overall_rc == EXIT_SUCCESS) { + ACA_LOG_INFO("%s", "_delete_group_punt_rule succeeded!\n"); + } else { + ACA_LOG_ERROR("_delete_group_punt_rule failed!!! overrall_rc: %d\n", overall_rc); + } - ACA_Vlan_Manager::get_instance().set_aux_gateway(tunnel_id, auxGateway_id); + ACA_LOG_DEBUG("ACA_Zeta_Programming::_delete_group_punt_rule <--- Exiting, overall_rc = %d\n", + overall_rc); + return overall_rc; +} - ACA_Zeta_Programming::get_instance().set_oam_server_port(auxGateway_id, oam_server_port); +// add the OAM punt rule +int ACA_Zeta_Programming::_create_oam_ofp(uint port_number) +{ + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::_create_oam_ofp ---> Entering\n"); + int overall_rc; + string opt = "table=0,priority=25,udp,udp_dst=" + to_string(port_number) + ",actions=CONTROLLER"; + overall_rc = ACA_OVS_Control::get_instance().add_flow("br-int", opt.c_str()); + + if (overall_rc == EXIT_SUCCESS) { + ACA_LOG_INFO("%s", "creat_oam_ofp succeeded!\n"); } else { - ACA_LOG_INFO("%s", "auxGateway_id is not empty!\n"); + ACA_LOG_ERROR("creat_oam_ofp failed!!! overrall_rc: %d\n", overall_rc); } + ACA_LOG_DEBUG("ACA_Zeta_Programming::_create_oam_ofp <--- Exiting, overall_rc = %d\n", + overall_rc); return overall_rc; } -int ACA_Zeta_Programming::delete_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, - const string /*vpc_id*/, uint tunnel_id) + +// delete the OAM punt rule +int ACA_Zeta_Programming::_delete_oam_ofp(uint port_number) { - zeta_config stZetaCfg; + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::_delete_oam_ofp ---> Entering\n"); + int overall_rc; + + string opt = "udp,udp_dst=" + to_string(port_number); + + overall_rc = ACA_OVS_Control::get_instance().del_flows("br-int", opt.c_str()); + + if (overall_rc == EXIT_SUCCESS) { + ACA_LOG_INFO("%s", "delete_oam_ofp succeeded!\n"); + } else { + ACA_LOG_ERROR("delete_oam_ofp failed!!! overrall_rc: %d\n", overall_rc); + } + + ACA_LOG_DEBUG("ACA_Zeta_Programming::_delete_oam_ofp <--- Exiting, overall_rc = %d\n", + overall_rc); + return overall_rc; +} + +uint ACA_Zeta_Programming::get_oam_port(string zeta_gateway_id) +{ + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::get_oam_port ---> Entering\n"); + zeta_config *current_zeta_cfg; + uint oam_port = 0; + if (_zeta_config_table.find(zeta_gateway_id, current_zeta_cfg)) { + oam_port = current_zeta_cfg->oam_port; + } else { + ACA_LOG_ERROR("zeta_gateway_id %s not found in zeta_config_table\n", + zeta_gateway_id.c_str()); + } + + ACA_LOG_DEBUG("ACA_Zeta_Programming::get_oam_port <--- Exiting, oam_port = %d\n", oam_port); + return oam_port; +} + +int ACA_Zeta_Programming::create_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, + uint tunnel_id) +{ + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::create_zeta_config ---> Entering\n"); int overall_rc = EXIT_SUCCESS; + zeta_config *new_zeta_cfg; + bool bucket_not_found = false; + unordered_set new_zeta_buckets; - uint group_id = get_or_create_group_id(current_AuxGateway.id()); - stZetaCfg.group_id = to_string(group_id); + uint oam_port = current_AuxGateway.zeta_info().port_inband_operation(); - string auxGateway_id = current_AuxGateway.id(); + if (!_zeta_config_table.find(current_AuxGateway.id(), new_zeta_cfg)) { + create_entry(current_AuxGateway.id(), oam_port); + _create_oam_ofp(oam_port); + // add oam port number to cache + aca_zeta_oam_server::ACA_Zeta_Oam_Server::get_instance().add_oam_port_cache(oam_port); + + _zeta_config_table.find(current_AuxGateway.id(), new_zeta_cfg); + } for (auto destination : current_AuxGateway.destinations()) { - stZetaCfg.zeta_buckets.push_back(destination.ip_address()); + if (new_zeta_cfg->zeta_buckets.find(destination.ip_address()) == + new_zeta_cfg->zeta_buckets.end()) { + bucket_not_found |= true; + } + new_zeta_buckets.insert(destination.ip_address()); } - uint oam_port = current_AuxGateway.zeta_info().port_inband_operation(); - // Reset auxGateway_id to empty - ACA_Vlan_Manager::get_instance().set_aux_gateway(tunnel_id, ""); + // If the buckets have changed, update the buckets and group table rules. + if (new_zeta_cfg->zeta_buckets.size() != new_zeta_buckets.size() || + bucket_not_found == true) { + new_zeta_cfg->zeta_buckets = new_zeta_buckets; + overall_rc = _create_zeta_group_entry(new_zeta_cfg); + } + + // get the current auxgateway_id of vpc + string current_zeta_id = ACA_Vlan_Manager::get_instance().get_zeta_gateway_id(tunnel_id); + if (current_zeta_id.empty()) { + ACA_LOG_INFO("%s", "The vpc currently has not auxgateway set!\n"); + ACA_Vlan_Manager::get_instance().set_zeta_gateway(tunnel_id, + current_AuxGateway.id()); + _create_group_punt_rule(tunnel_id, new_zeta_cfg->group_id); + } else { + ACA_LOG_INFO("%s", "The vpc currently has an auxgateway set!\n"); + } + + ACA_LOG_DEBUG("ACA_Zeta_Programming::create_zeta_config <--- Exiting, overall_rc = %d\n", + overall_rc); + return overall_rc; +} + +int ACA_Zeta_Programming::delete_zeta_config(const alcor::schema::AuxGateway current_AuxGateway, + uint tunnel_id) +{ + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::delete_zeta_config ---> Entering\n"); + zeta_config stZetaCfg; + int overall_rc = EXIT_SUCCESS; - if (!ACA_Vlan_Manager::get_instance().is_exist_aux_gateway(auxGateway_id)) { - // update oam_ports_cache and delete the OAM punt rule - Aca_Oam_Port_Manager::get_instance().remove_oam_port_rule(oam_port); - // delete the group bucket rule - overall_rc = _delete_zeta_group_entry(&stZetaCfg); + zeta_config *current_zeta_cfg; + + if (!_zeta_config_table.find(current_AuxGateway.id(), current_zeta_cfg)) { + ACA_LOG_ERROR("zeta_gateway_id %s not found in zeta_config_table\n", + current_AuxGateway.id().c_str()); + } else { + string current_zeta_gateway_id = + ACA_Vlan_Manager::get_instance().get_zeta_gateway_id(tunnel_id); + + if (current_zeta_gateway_id.empty()) { + ACA_LOG_INFO("%s", "No auxgateway is currently set for this vpc!\n"); + } else { + if (current_zeta_gateway_id != current_AuxGateway.id()) { + ACA_LOG_ERROR("%s", "The auxgateway_id is inconsistent with the auxgateway_id currently set by the vpc!\n"); + } else { + ACA_LOG_INFO("%s", "Reset auxGateway to empty!\n"); + _delete_group_punt_rule(tunnel_id); + overall_rc = ACA_Vlan_Manager::get_instance().remove_zeta_gateway(tunnel_id); + } + } + + if (!ACA_Vlan_Manager::get_instance().is_exist_zeta_gateway( + current_AuxGateway.id())) { + _delete_oam_ofp(current_zeta_cfg->oam_port); + _zeta_config_table.erase(current_AuxGateway.id()); + } } + ACA_LOG_DEBUG("ACA_Zeta_Programming::delete_zeta_config <--- Exiting, overall_rc = %d\n", + overall_rc); return overall_rc; } -int ACA_Zeta_Programming::_create_or_update_zeta_group_entry(zeta_config *zeta_cfg) +int ACA_Zeta_Programming::_create_zeta_group_entry(zeta_config *zeta_cfg) { + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::_create_zeta_group_entry ---> Entering\n"); unsigned long not_care_culminative_time; int overall_rc = EXIT_SUCCESS; - //adding group table rule - string cmd = "-O OpenFlow13 add-group br-tun group_id=" + zeta_cfg->group_id + ",type=select"; - list::iterator it; + // adding group table rule + string cmd = "-O OpenFlow13 add-group br-tun group_id=" + to_string(zeta_cfg->group_id) + + ",type=select"; + unordered_set::iterator it; for (it = zeta_cfg->zeta_buckets.begin(); it != zeta_cfg->zeta_buckets.end(); it++) { - string outport_name = aca_get_outport_name(alcor::schema::NetworkType::VXLAN, *it); - cmd += ",bucket=output:" + outport_name; + cmd += ",bucket=\"set_field:" + *it + "->tun_dst,output:vxlan-generic\""; } - //add group table rule + // add group table rule aca_ovs_l2_programmer::ACA_OVS_L2_Programmer::get_instance().execute_openflow_command( cmd, not_care_culminative_time, overall_rc); @@ -162,16 +291,19 @@ int ACA_Zeta_Programming::_create_or_update_zeta_group_entry(zeta_config *zeta_c ACA_LOG_ERROR("update_zeta_group_entry failed!!! overrall_rc: %d\n", overall_rc); } + ACA_LOG_DEBUG("ACA_Zeta_Programming::_create_zeta_group_entry <--- Exiting, overall_rc = %d\n", + overall_rc); return overall_rc; } int ACA_Zeta_Programming::_delete_zeta_group_entry(zeta_config *zeta_cfg) { + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::_delete_zeta_group_entry ---> Entering\n"); unsigned long not_care_culminative_time; int overall_rc = EXIT_SUCCESS; - //delete group table rule - string cmd = "-O OpenFlow13 del-groups br-tun group_id=" + zeta_cfg->group_id; + // delete group table rule + string cmd = "-O OpenFlow13 del-groups br-tun group_id=" + to_string(zeta_cfg->group_id); aca_ovs_l2_programmer::ACA_OVS_L2_Programmer::get_instance().execute_openflow_command( cmd, not_care_culminative_time, overall_rc); @@ -181,10 +313,13 @@ int ACA_Zeta_Programming::_delete_zeta_group_entry(zeta_config *zeta_cfg) ACA_LOG_ERROR("delete_zeta_group_entry failed!!! overrall_rc: %d\n", overall_rc); } + ACA_LOG_DEBUG("ACA_Zeta_Programming::_delete_zeta_group_entry <--- Exiting, overall_rc = %d\n", + overall_rc); return overall_rc; } -bool ACA_Zeta_Programming::is_exist_group_rule(uint group_id) +// Determine whether the group table rule already exists? +bool ACA_Zeta_Programming::group_rule_exists(uint group_id) { bool overall_rc; @@ -195,73 +330,46 @@ bool ACA_Zeta_Programming::is_exist_group_rule(uint group_id) overall_rc = aca_net_config::Aca_Net_Config::get_instance().execute_system_command(cmd_string); if (overall_rc == EXIT_SUCCESS) { + ACA_LOG_INFO("%s", "group rule is exist!\n"); return true; } else { + ACA_LOG_INFO("%s", "group rule is not exist!\n"); return false; } } -// query oam_port with auxGateway_id -uint ACA_Zeta_Programming::get_oam_server_port(string auxGateway_id) +bool ACA_Zeta_Programming::oam_port_rule_exists(uint port_number) { - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::get_oam_server_port ---> Entering\n"); + int overall_rc = EXIT_FAILURE; - uint port_number; + string opt = "table=0,udp,udp_dst=" + to_string(port_number); - // -----critical section starts----- - _zeta_gateways_table_mutex.lock(); - if (_zeta_gateways_table.find(auxGateway_id) == _zeta_gateways_table.end()) { - ACA_LOG_ERROR("auxGateway_id %s not find in _zeta_gateways_table\n", - auxGateway_id.c_str()); - // If the tunnel_id cannot be found, set the port number to 0. - port_number = 0; + overall_rc = ACA_OVS_Control::get_instance().flow_exists("br_tun", opt.c_str()); + if (overall_rc == EXIT_SUCCESS) { + ACA_LOG_INFO("%s", "Oam port rule is exist!\n"); + return true; } else { - port_number = _zeta_gateways_table[auxGateway_id].oam_port; + ACA_LOG_INFO("%s", "Oam port rule is not exist!\n"); + return false; } - _zeta_gateways_table_mutex.unlock(); - // -----critical section ends----- - - ACA_LOG_DEBUG("ACA_Zeta_Programming::get_oam_server_port <--- Exiting, port_number=%u\n", - port_number); - - return port_number; } -// Bind oam_server_port to auxGateway -void ACA_Zeta_Programming::set_oam_server_port(string auxGateway_id, uint port_number) +uint ACA_Zeta_Programming::get_group_id(string zeta_gateway_id) { - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::set_oam_server_port ---> Entering\n"); + ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::get_group_id ---> Entering\n"); + uint group_id = 0; + zeta_config *current_zeta_cfg; - // -----critical section starts----- - _zeta_gateways_table_mutex.lock(); - if (_zeta_gateways_table.find(auxGateway_id) == _zeta_gateways_table.end()) { - create_entry_unsafe(auxGateway_id); + if (!_zeta_config_table.find(zeta_gateway_id, current_zeta_cfg)) { + group_id = current_zeta_cfg->group_id; + } else { + ACA_LOG_ERROR("zeta_gateway_id %s not found in zeta_config_table\n", + zeta_gateway_id.c_str()); } - _zeta_gateways_table[auxGateway_id].oam_port = port_number; - _zeta_gateways_table_mutex.unlock(); - // -----critical section ends----- - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::set_oam_server_port <--- Exiting\n"); -} + return group_id; -bool ACA_Zeta_Programming::is_exist_oam_port(uint port_number) -{ - bool rc = false; - - ACA_LOG_DEBUG("%s", "ACA_Zeta_Programming::is_exist_oam_port ---> Entering\n"); - // -----critical section starts----- - _zeta_gateways_table_mutex.lock(); - for (auto entry : _zeta_gateways_table) { - aux_gateway_entry vpc_entry = entry.second; - if (vpc_entry.oam_port == port_number) { - rc = true; - break; - } - } - _zeta_gateways_table_mutex.unlock(); - // -----critical section ends----- - ACA_LOG_DEBUG("ACA_Zeta_Programming::is_exist_oam_port <--- Exiting, rc = %d\n", rc); - return rc; + ACA_LOG_DEBUG("ACA_Zeta_Programming::get_group_id <--- Exiting, overall_rc = %u\n", group_id); } } // namespace aca_zeta_programming \ No newline at end of file diff --git a/test/gtest/aca_test_oam.cpp b/test/gtest/aca_test_oam.cpp index 28773bcd..c63526a2 100644 --- a/test/gtest/aca_test_oam.cpp +++ b/test/gtest/aca_test_oam.cpp @@ -14,14 +14,18 @@ #include "gtest/gtest.h" #define private public -#include "aca_oam_server.h" +#include "aca_zeta_oam_server.h" #include "aca_util.h" -#include "goalstateprovisioner.grpc.pb.h" #include #include "aca_ovs_control.h" #include "aca_vlan_manager.h" +#include "aca_zeta_programming.h" +#include "aca_ovs_l2_programmer.h" -using namespace aca_oam_server; +using namespace aca_zeta_oam_server; +using namespace aca_ovs_control; +using namespace aca_zeta_programming; +using namespace aca_ovs_l2_programmer; extern string vmac_address_1; extern string vmac_address_2; @@ -34,27 +38,42 @@ extern string vip_address_4; extern string remote_ip_1; extern string remote_ip_2; -alcor::schema::NetworkType network_type = alcor::schema::NetworkType::VXLAN; - +extern string auxGateway_id_1; +extern string auxGateway_id_2; - -using namespace aca_ovs_control; +extern uint tunnel_id_1; +extern uint tunnel_id_2; +extern uint oam_port_1; +extern uint oam_port_2; TEST(oam_message_test_cases, oams_recv_valid) { int retcode = 0; - oam_message stOamMsg; + ulong not_care_culminative_time = 0; + int overall_rc; - stOamMsg.op_code = 0; + // delete and add br-int and br-tun bridges to clear everything + ACA_OVS_L2_Programmer::get_instance().execute_ovsdb_command( + "del-br br-int", not_care_culminative_time, overall_rc); + + ACA_OVS_L2_Programmer::get_instance().execute_ovsdb_command( + "del-br br-tun", not_care_culminative_time, overall_rc); + + // create and setup br-int and br-tun bridges, and their patch ports + overall_rc = ACA_OVS_L2_Programmer::get_instance().setup_ovs_bridges_if_need(); + ASSERT_EQ(overall_rc, EXIT_SUCCESS); + + oam_message stOamMsg; - stOamMsg.data.msg_inject_flow.inner_src_ip.s_addr = 55; - stOamMsg.data.msg_inject_flow.inner_dst_ip.s_addr = 66; - stOamMsg.data.msg_inject_flow.src_port = 500; - stOamMsg.data.msg_inject_flow.dst_port = 500; + stOamMsg.data.msg_inject_flow.inner_src_ip.s_addr = 55; // 55.0.0.0 + stOamMsg.data.msg_inject_flow.inner_dst_ip.s_addr = 66; // 66.0.0.0 + stOamMsg.data.msg_inject_flow.src_port = 500; // 62465 + stOamMsg.data.msg_inject_flow.dst_port = 500; // 62455 stOamMsg.data.msg_inject_flow.proto = 0; + // fill VNI: 197295 stOamMsg.data.msg_inject_flow.vni[0] = 0xaf; stOamMsg.data.msg_inject_flow.vni[1] = 0x02; - stOamMsg.data.msg_inject_flow.vni[2] = 0xee; + stOamMsg.data.msg_inject_flow.vni[2] = 0x03; stOamMsg.data.msg_inject_flow.node_dst_ip.s_addr = 77; stOamMsg.data.msg_inject_flow.inst_dst_ip.s_addr = 88; stOamMsg.data.msg_inject_flow.inst_dst_mac[0] = 0x3c; @@ -65,20 +84,37 @@ TEST(oam_message_test_cases, oams_recv_valid) stOamMsg.data.msg_inject_flow.inst_dst_mac[5] = 0x65; stOamMsg.data.msg_inject_flow.idle_timeout = 120; - ACA_Oam_Server::get_instance().oams_recv(55, &stOamMsg); + oam_match match = ACA_Zeta_Oam_Server::get_instance()._get_oam_match_field(&stOamMsg); - retcode = ACA_Oam_Server::get_instance()._validate_oam_message(&stOamMsg); - EXPECT_EQ(retcode, true); + // fill vpc_tables + aca_vlan_manager::ACA_Vlan_Manager::get_instance().create_entry(match.vni); + aca_vlan_manager::ACA_Vlan_Manager::get_instance().set_zeta_gateway(match.vni, auxGateway_id_1); + + // fill zeta_config_table + ACA_Zeta_Programming::get_instance().create_entry(auxGateway_id_1, oam_port_1); - retcode = ACA_Oam_Server::get_instance()._get_message_type(&stOamMsg); + // flow injection + stOamMsg.op_code = htonl(0); + ACA_Zeta_Oam_Server::get_instance().oams_recv(oam_port_1, &stOamMsg); + retcode = ACA_Zeta_Oam_Server::get_instance()._get_message_type(&stOamMsg); EXPECT_EQ(retcode, OAM_MSG_FLOW_INJECTION); + // flwo deletion + stOamMsg.op_code = htonl(1); + ACA_Zeta_Oam_Server::get_instance().oams_recv(oam_port_1, &stOamMsg); + retcode = ACA_Zeta_Oam_Server::get_instance()._get_message_type(&stOamMsg); + EXPECT_EQ(retcode, OAM_MSG_FLOW_DELETION); + + retcode = ACA_Zeta_Oam_Server::get_instance()._validate_oam_message(&stOamMsg); + EXPECT_EQ(retcode, true); + + ACA_Zeta_Programming::get_instance().clear_all_data(); + aca_vlan_manager::ACA_Vlan_Manager::get_instance().clear_all_data(); } TEST(oam_message_test_cases, add_direct_path_valid) { int retcode = 0; - unsigned long not_care_culminative_time; oam_match match; oam_action action; @@ -86,7 +122,7 @@ TEST(oam_message_test_cases, add_direct_path_valid) match.dip = vip_address_2; match.sport = "55"; match.dport = "77"; - match.vni = "300"; + match.vni = 300; match.proto = "6"; action.inst_nw_dst = vip_address_3; @@ -95,18 +131,11 @@ TEST(oam_message_test_cases, add_direct_path_valid) action.node_dl_dst = vmac_address_2; action.idle_timeout = "120"; - if (!aca_is_port_on_same_host(action.node_nw_dst)) { - ACA_LOG_INFO("%s", "port_neighbor not exist!\n"); - //crate neighbor_port - aca_vlan_manager::ACA_Vlan_Manager::get_instance().create_neighbor_outport( - network_type, action.node_nw_dst, 300, not_care_culminative_time); - } - string vlan_id = to_string(aca_vlan_manager::ACA_Vlan_Manager::get_instance().get_or_create_vlan_id( - strtoul(match.vni.c_str(), NULL, 10))); + match.vni)); // add unicast rule - aca_oam_server::ACA_Oam_Server::get_instance()._add_direct_path(match, action); + ACA_Zeta_Oam_Server::get_instance()._add_direct_path(match, action); string cmd = "table=20,ip,nw_proto=" + match.proto + ",nw_src=" + match.sip + ",nw_dst=" + match.dip + ",tp_src=" + match.sport + @@ -119,7 +148,6 @@ TEST(oam_message_test_cases, add_direct_path_valid) TEST(oam_message_test_cases, del_direct_path_valid) { int retcode = 0; - unsigned long not_care_culminative_time; oam_match match; oam_action action; @@ -128,7 +156,7 @@ TEST(oam_message_test_cases, del_direct_path_valid) match.dip = vip_address_2; match.sport = "55"; match.dport = "77"; - match.vni = "400"; + match.vni = 400; match.proto = "6"; action.inst_nw_dst = vip_address_3; @@ -137,20 +165,13 @@ TEST(oam_message_test_cases, del_direct_path_valid) action.node_dl_dst = vmac_address_2; action.idle_timeout = "120"; - if (!aca_is_port_on_same_host(action.node_nw_dst)) { - ACA_LOG_INFO("%s", "port_neighbor not exist!\n"); - //crate neighbor_port - aca_vlan_manager::ACA_Vlan_Manager::get_instance().create_neighbor_outport( - network_type, action.node_nw_dst, 300, not_care_culminative_time); - } - string vlan_id = to_string(aca_vlan_manager::ACA_Vlan_Manager::get_instance().get_or_create_vlan_id( - strtoul(match.vni.c_str(), NULL, 10))); + match.vni)); // add unicast rule - aca_oam_server::ACA_Oam_Server::get_instance()._add_direct_path(match, action); + ACA_Zeta_Oam_Server::get_instance()._add_direct_path(match, action); - aca_oam_server::ACA_Oam_Server::get_instance()._del_direct_path(match); + ACA_Zeta_Oam_Server::get_instance()._del_direct_path(match); string cmd = "table=20,ip,nw_proto=" + match.proto + ",nw_src=" + match.sip + ",nw_dst=" + match.dip + ",tp_src=" + match.sport + @@ -159,4 +180,3 @@ TEST(oam_message_test_cases, del_direct_path_valid) retcode = ACA_OVS_Control::get_instance().flow_exists("br-tun", cmd.c_str()); EXPECT_EQ(retcode, EXIT_FAILURE); } - diff --git a/test/gtest/aca_test_ovs_util.cpp b/test/gtest/aca_test_ovs_util.cpp index aa0882d2..cac2946e 100644 --- a/test/gtest/aca_test_ovs_util.cpp +++ b/test/gtest/aca_test_ovs_util.cpp @@ -65,6 +65,12 @@ string subnet1_gw_ip = "10.10.0.1"; string subnet2_gw_ip = "10.10.1.1"; string subnet1_gw_mac = "fa:16:3e:d7:f2:11"; string subnet2_gw_mac = "fa:16:3e:d7:f2:21"; +string auxGateway_id_1 = "11"; +string auxGateway_id_2 = "22"; +uint tunnel_id_1 = 555; +uint tunnel_id_2 = 666; +uint oam_port_1 = 6799; +uint oam_port_2 = 6800; extern bool g_demo_mode; // total time for execute_system_command in microseconds diff --git a/test/gtest/aca_test_zeta_programming.cpp b/test/gtest/aca_test_zeta_programming.cpp index b83c0472..45c2a598 100644 --- a/test/gtest/aca_test_zeta_programming.cpp +++ b/test/gtest/aca_test_zeta_programming.cpp @@ -26,6 +26,7 @@ #include #include +using namespace std; using namespace aca_comm_manager; using namespace alcor::schema; using namespace aca_zeta_programming; @@ -59,13 +60,13 @@ extern bool g_demo_mode; extern void aca_test_create_default_port_state(PortState *new_port_states); extern void aca_test_create_default_subnet_state(SubnetState *new_subnet_states); -string auxGateway_id_1 = "11"; -string auxGateway_id_2 = "22"; +extern string auxGateway_id_1; +extern string auxGateway_id_2; -uint tunnel_id_1 = 555; -uint tunnel_id_2 = 666; -uint oam_port_1 = 6799; -uint oam_port_2 = 6800; +extern uint tunnel_id_1; +extern uint tunnel_id_2; +extern uint oam_port_1; +extern uint oam_port_2; uint parent_position_in_port_info = 0; uint child_position_in_port_info = 1; @@ -199,7 +200,7 @@ void aca_test_zeta_setup(string zeta_gateway_path_config_file) ASSERT_EQ(overall_rc, EXIT_SUCCESS); } -TEST(zeta_programming_test_cases, create_or_update_zeta_config_valid) +TEST(zeta_programming_test_cases, create_zeta_config_valid) { int retcode = 0; @@ -218,8 +219,7 @@ TEST(zeta_programming_test_cases, create_or_update_zeta_config_valid) destination->set_ip_address(remote_ip_2); destination->set_mac_address(node_mac_address_4); - retcode = ACA_Zeta_Programming::get_instance().create_or_update_zeta_config( - new_auxGateway, vpc_id_2, tunnel_id_2); + retcode = ACA_Zeta_Programming::get_instance().create_zeta_config(new_auxGateway, tunnel_id_2); EXPECT_EQ(retcode, EXIT_SUCCESS); } @@ -243,13 +243,12 @@ TEST(zeta_programming_test_cases, delete_zeta_config_valid) destination->set_ip_address(remote_ip_2); destination->set_mac_address(node_mac_address_4); - retcode = ACA_Zeta_Programming::get_instance().delete_zeta_config( - new_auxGateway, vpc_id_2, tunnel_id_2); + retcode = ACA_Zeta_Programming::get_instance().delete_zeta_config(new_auxGateway, tunnel_id_2); EXPECT_EQ(retcode, EXIT_SUCCESS); } -TEST(zeta_programming_test_cases, DISABLED_auxgateway_test) +TEST(zeta_programming_test_cases, create_auxgateway_test) { // from here. int retcode; @@ -317,9 +316,9 @@ TEST(zeta_programming_test_cases, DISABLED_zeta_gateway_path_PARENT) // do some validate } - -TEST(zeta_programming_test_cases, DISABLED_zeta_scale_CHILD){ - // ulong culminative_network_configuration_time = 0; +TEST(zeta_programming_test_cases, DISABLED_zeta_scale_CHILD) +{ + // ulong culminative_network_configuration_time = 0; ulong not_care_culminative_time = 0; int overall_rc = EXIT_SUCCESS; // delete br-int and br-tun bridges @@ -343,7 +342,8 @@ TEST(zeta_programming_test_cases, DISABLED_zeta_scale_CHILD){ g_demo_mode = previous_demo_mode; } -TEST(zeta_programming_test_cases, DISABLED_zeta_scale_PARENT){ +TEST(zeta_programming_test_cases, DISABLED_zeta_scale_PARENT) +{ // ulong culminative_network_configuration_time = 0; ulong not_care_culminative_time = 0; int overall_rc = EXIT_SUCCESS;