bool cps_api_nodes::get_port_info(const char *group, _db_node_data *nd) {
    cps_api_object_guard og(cps_api_object_create());

    if (!cps_api_key_from_attr_with_qual(cps_api_object_key(og.get()),CPS_DB_INSTANCE_OBJ,
                                         cps_api_qualifier_TARGET)) {
        EV_LOGGING(DSAPI,ERR,"CPS-CLS-MAP","Meta data for cluster set is not loaded.");
        return false;
    }

    cps_db::connection_request b(cps_db::ProcessDBCache(),DEFAULT_REDIS_ADDR);

    if (!b.valid()) {
        return false;
    }

    cps_api_set_key_data(og.get(),CPS_DB_INSTANCE_GROUP,cps_api_object_ATTR_T_BIN,group,strlen(group)+1);
    cps_api_set_key_data(og.get(),CPS_DB_INSTANCE_NODE_ID,cps_api_object_ATTR_T_BIN,nd->_name.c_str(),strlen(nd->_name.c_str())+1);

    if (cps_db::get_object(b.get(),og.get())) {

        const char *port = (const char*) cps_api_object_get_data(og.get(),CPS_DB_INSTANCE_PORT);
        if(port == nullptr) {
            return false;
        }
        nd->_addr = port;
        return true;
    }
    return false;
}
TEST(std_nas_route_test, nas_route_arp_get) {
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_ROUTE_OBJ_NBR,
                                        cps_api_qualifier_TARGET);
    unsigned short af = 2;
    cps_api_set_key_data(obj,BASE_ROUTE_OBJ_NBR_AF,cps_api_object_ATTR_T_U16,
                                 &af,sizeof(af));

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t mx = cps_api_object_list_size(gp.list);

        for ( size_t ix = 0 ; ix < mx ; ++ix ) {
            obj = cps_api_object_list_get(gp.list,ix);
            std::cout<<"ARP ENTRY "<<std::endl;
            std::cout<<"================================="<<std::endl;
            nas_route_dump_arp_object_content(obj);
            std::cout<<std::endl;
        }
    }

    cps_api_get_request_close(&gp);

}
bool cps_api_db_del_node_group(const char *group) {
    std::lock_guard<std::recursive_mutex> lg(_mutex);

    cps_api_node_data_type_t type;
    if(!_nodes->get_group_type(std::string(group),type)) {
        EV_LOGGING(DSAPI,ERR,"DEL-MASTER","Failed to get group type for %s",group);
        return false;
    }

    if(type != cps_api_node_data_1_PLUS_1_REDUNDENCY) {
        return true;
    }

    auto it = _nodes->_db_node_map.find(group);
    if( it == _nodes->_db_node_map.end()) {
        EV_LOGGING(DSAPI,ERR,"CPS-DB","No group named %s found",group);
        return false;
    }

    for ( auto node_it : it->second) {
        cps_db::connection_request b(cps_db::ProcessDBCache(),DEFAULT_REDIS_ADDR);
        if (!b.valid()) {
            return false;
        }
        cps_api_object_guard og(cps_api_object_create());

        if (!cps_api_key_from_attr_with_qual(cps_api_object_key(og.get()),CPS_DB_INSTANCE_OBJ,
                                             cps_api_qualifier_TARGET)) {
            EV_LOGGING(DSAPI,ERR,"CPS-CLS-MAP","Meta data for cluster set is not loaded.");
            return false;
        }


        cps_api_set_key_data(og.get(),CPS_DB_INSTANCE_GROUP,cps_api_object_ATTR_T_BIN,group,strlen(group)+1);
        cps_api_set_key_data(og.get(),CPS_DB_INSTANCE_NODE_ID,cps_api_object_ATTR_T_BIN,node_it._name.c_str(),
                             strlen(node_it._name.c_str())+1);

        cps_db::delete_object(b.get(),og.get());
    }

    _nodes->_master.erase(std::string(group));
    _nodes->_db_node_map.erase(std::string(group));
    _nodes->remove_master_set(std::string(group));

    return cps_api_clean_db_instance(group);

}
static cps_api_return_code_t nas_qos_store_prev_attr(cps_api_object_t obj,
                                                    const nas::attr_set_t attr_set,
                                                    const nas_qos_scheduler_group &scheduler_group)
{
    // filling in the keys
    uint32_t switch_id = scheduler_group.switch_id();
    nas_obj_id_t sg_id = scheduler_group.get_scheduler_group_id();
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_QOS_SCHEDULER_GROUP_OBJ,
            cps_api_qualifier_TARGET);
    cps_api_set_key_data(obj, BASE_QOS_SCHEDULER_GROUP_SWITCH_ID,
            cps_api_object_ATTR_T_U32,
            &switch_id, sizeof(uint32_t));
    cps_api_set_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID,
            cps_api_object_ATTR_T_U64,
            &sg_id, sizeof(uint64_t));


    for (auto attr_id: attr_set) {
        switch (attr_id) {
        case BASE_QOS_SCHEDULER_GROUP_ID:
            /* key */
            break;

        case BASE_QOS_SCHEDULER_GROUP_CHILD_COUNT:
        case BASE_QOS_SCHEDULER_GROUP_CHILD_LIST:
            /* Read only attributes, no need to save */
            break;

        case BASE_QOS_SCHEDULER_GROUP_PORT_ID:
            cps_api_object_attr_add_u32(obj, attr_id,
                    scheduler_group.get_level());
            break;

        case BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID:
            cps_api_object_attr_add_u64(obj, attr_id,
                    scheduler_group.get_scheduler_profile_id());
            break;

        default:
            break;
        }
    }

    return cps_api_ret_code_OK;
}
Exemple #5
0
t_std_error nas_sflow_create_session(cps_api_object_t obj){

    cps_api_object_attr_t ifindex_attr;
    cps_api_attr_id_t ifindex_attr_id = BASE_SFLOW_ENTRY_IFINDEX;

    ifindex_attr = cps_api_object_e_get (obj, &ifindex_attr_id, 1);

    if (ifindex_attr == NULL) {
        NAS_SFLOW_LOG(ERR,ev_log_s_MINOR,"No Interface Index passed for creating sFlow session");
        return STD_ERR(SFLOW,CFG,0);
    }

    nas_sflow_entry_t nas_sflow_entry;

    if(!nas_sflow_fill_session_info(obj,&nas_sflow_entry)){
        return STD_ERR(SFLOW,CFG,0);
    }

    interface_ctrl_t intf_ctrl;
    memset(&intf_ctrl, 0, sizeof(interface_ctrl_t));

    intf_ctrl.q_type = HAL_INTF_INFO_FROM_IF;
    intf_ctrl.if_index = nas_sflow_entry.ifindex;

    if (dn_hal_get_interface_info(&intf_ctrl) != STD_ERR_OK) {
        NAS_SFLOW_LOG(ERR,0,"Interface %d has NO slot %d, port %d",
                intf_ctrl.if_index, intf_ctrl.npu_id, intf_ctrl.port_id);
        return STD_ERR(SFLOW,FAIL,0);
    }

    nas_sflow_entry.ndi_sflow_entry.port_id = intf_ctrl.port_id;
    nas_sflow_entry.ndi_sflow_entry.npu_id = intf_ctrl.npu_id;
    nas_sflow_entry.ndi_sflow_entry.enabled = true;

    std_mutex_simple_lock_guard lock(&nas_sflow_mutex);

    if(ndi_sflow_create_session(&(nas_sflow_entry.ndi_sflow_entry)) != STD_ERR_OK){
        return STD_ERR(SFLOW,FAIL,0);
    }

    if(!nas_sflow_update_direction(&nas_sflow_entry.ndi_sflow_entry,true)){
        NAS_SFLOW_LOG(ERR,0,"Failed to add source ports to session %llu ",
                      nas_sflow_entry.ndi_sflow_entry.ndi_sflow_id);
        ndi_sflow_delete_session(&nas_sflow_entry.ndi_sflow_entry);
        return STD_ERR(SFLOW,FAIL,0);
    }

    nas_sflow_entry.nas_sflow_id= nas_sflow_get_next_index();
    cps_api_set_key_data(obj,BASE_SFLOW_ENTRY_ID,cps_api_object_ATTR_T_U32,
                         &nas_sflow_entry.nas_sflow_id,sizeof(nas_sflow_entry.nas_sflow_id));
    NAS_SFLOW_LOG(INFO,0,"Created new nas sflow entry with id %d",nas_sflow_entry.nas_sflow_id);
    nas_sflow_table.insert(nas_sflow_pair(nas_sflow_entry.nas_sflow_id,std::move(nas_sflow_entry)));

    return STD_ERR_OK;
}
static cps_api_return_code_t nas_qos_store_prev_attr(cps_api_object_t obj,
                                const nas::attr_set_t attr_set,
                                const nas_qos_priority_group &priority_group)
{
    // filling in the keys
    uint32_t val_port = priority_group.get_port_id();
    uint8_t local_id = priority_group.get_local_id();
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_QOS_PRIORITY_GROUP_OBJ,
            cps_api_qualifier_TARGET);

    cps_api_set_key_data(obj, BASE_QOS_PRIORITY_GROUP_PORT_ID,
            cps_api_object_ATTR_T_U32,
            &val_port, sizeof(uint32_t));
    cps_api_set_key_data(obj, BASE_QOS_PRIORITY_GROUP_LOCAL_ID,
            cps_api_object_ATTR_T_BIN,
            &local_id, sizeof(uint8_t));


    for (auto attr_id: attr_set) {
        switch (attr_id) {
        case BASE_QOS_PRIORITY_GROUP_PORT_ID:
        case BASE_QOS_PRIORITY_GROUP_LOCAL_ID:
        case BASE_QOS_PRIORITY_GROUP_ID:
            /* non-settable attr     */
            break;

        case BASE_QOS_PRIORITY_GROUP_BUFFER_PROFILE_ID:
            cps_api_object_attr_add_u64(obj, attr_id,
                    priority_group.get_buffer_profile());
            break;


        default:
            break;
        }
    }

    return cps_api_ret_code_OK;
}
Exemple #7
0
static void nas_sflow_fill_object(cps_api_object_t obj,nas_sflow_map_it it){

    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_SFLOW_ENTRY_OBJ,
                                    cps_api_qualifier_TARGET);
    cps_api_set_key_data(obj,BASE_SFLOW_ENTRY_ID,cps_api_object_ATTR_T_U32,
                         &it->second.nas_sflow_id,sizeof(it->second.nas_sflow_id));
    cps_api_object_attr_add_u32(obj,BASE_SFLOW_ENTRY_ID,it->second.nas_sflow_id);
    cps_api_object_attr_add_u32(obj,BASE_SFLOW_ENTRY_IFINDEX,it->second.ifindex);
    cps_api_object_attr_add_u32(obj,BASE_SFLOW_ENTRY_DIRECTION,
                                   it->second.ndi_sflow_entry.sflow_direction);
    cps_api_object_attr_add_u32(obj,BASE_SFLOW_ENTRY_SAMPLING_RATE,
                                   it->second.ndi_sflow_entry.sampling_rate);
}
static void nas_mirror_fill_object(cps_api_object_t obj, nas_mirror_table_it it){

    nas_mirror_entry & entry = it->second;
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_MIRROR_ENTRY_OBJ,
                                    cps_api_qualifier_TARGET);
    nas_mirror_id_t id = entry.get_id();
    cps_api_set_key_data(obj,BASE_MIRROR_ENTRY_ID,cps_api_object_ATTR_T_U32,
                         &id,sizeof(id));
    cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_ID,id);

    nas::ndi_obj_id_table_t mirror_opaque_data_table;
    mirror_opaque_data_table[entry.get_npu_id()] = entry.get_ndi_id();
    cps_api_attr_id_t  attr_id_list[] = {BASE_MIRROR_ENTRY_OPAQUE_DATA};
    nas::ndi_obj_id_table_cps_serialize (mirror_opaque_data_table, obj, attr_id_list,
                                         sizeof(attr_id_list)/sizeof(attr_id_list[0]));


    cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_DST_INTF,entry.get_dst_intf());
    cps_api_attr_id_t ids[3] = {BASE_MIRROR_ENTRY_INTF,0,BASE_MIRROR_ENTRY_INTF_SRC };
    const int ids_len = sizeof(ids)/sizeof(ids[0]);

    for(auto src_it = entry.get_src_intf_map()->begin() ; src_it != entry.get_src_intf_map()->end() ; ++src_it){
        cps_api_object_e_add(obj,ids,ids_len,cps_api_object_ATTR_T_U32,&(src_it->first),sizeof(src_it->first));
        ids[2]=BASE_MIRROR_ENTRY_INTF_DIRECTION;
        cps_api_object_e_add(obj,ids,ids_len,cps_api_object_ATTR_T_U32,&(src_it->second),sizeof(src_it->second));
        ids[2]=BASE_MIRROR_ENTRY_INTF_SRC;
        ++ids[1];
    }

    cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_FLOW_ENABLED,entry.get_flow());
    cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_TYPE,entry.get_mode());

    if(entry.get_mode() == BASE_MIRROR_MODE_RSPAN){
        cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_VLAN,entry.get_vlan_id());
    }

    if(entry.get_mode() == BASE_MIRROR_MODE_ERSPAN){
        cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_SOURCE_IP,entry.get_dst_ip()->u.v4_addr);
        cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_DESTINATION_IP,entry.get_src_ip()->u.v4_addr);
        cps_api_object_attr_add(obj,BASE_MIRROR_ENTRY_SOURCE_MAC,(void *)entry.get_src_mac(),sizeof(hal_mac_addr_t));
        cps_api_object_attr_add(obj,BASE_MIRROR_ENTRY_DEST_MAC,(void *)entry.get_dst_mac(),sizeof(hal_mac_addr_t));
        cps_api_object_attr_add_u32(obj,BASE_MIRROR_ENTRY_ERSPAN_VLAN_ID,entry.get_vlan_id());
    }
}
static cps_api_return_code_t nas_qos_store_prev_attr(cps_api_object_t obj,
                                                    const nas::attr_set_t attr_set,
                                                    const nas_qos_map_entry &entry)
{
    // fill in keys
    nas_qos_map_entry_key_t key = entry.get_key();
    nas_obj_id_t map_id = entry.get_map_id();
    nas_qos_map_type_t map_type = entry.get_type();

    nas_attr_id_t obj_id = qos_map_entry_obj_id(map_type);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),
            obj_id,
            cps_api_qualifier_TARGET);

    obj_id = qos_map_map_id_obj_id(map_type);
    cps_api_set_key_data(obj,
            obj_id,
            cps_api_object_ATTR_T_U64,
            &map_id, sizeof(uint64_t));

    _fill_entry_key_data(obj, key, map_type);

    nas_qos_map_entry_value_t value = entry.get_value();
    for (auto attr_id: attr_set) {
        uint_t val;
        cps_api_object_ATTR_TYPE_t attr_type;
        if (attr_id == qos_map_entry_attr_1_obj_id(map_type)) {
            val = qos_map_entry_attr_1_get_fn(map_type)(value);
            attr_type = qos_map_get_attr_1_type(map_type);
            if (qos_map_add_int_by_type(obj, attr_id, val, attr_type) != true)
                return cps_api_ret_code_ERR;
        }

        if (attr_id == qos_map_entry_attr_2_obj_id(map_type)) {
            val = qos_map_entry_attr_2_get_fn(map_type)(value);
            attr_type = qos_map_get_attr_2_type(map_type);
            if (qos_map_add_int_by_type(obj, attr_id, val, attr_type) != true)
                return cps_api_ret_code_ERR;
        }
    }

    return cps_api_ret_code_OK;
}
t_std_error nas_mirror_create_session(cps_api_object_t obj) {

    nas_mirror_entry entry;
    nas_mirror_src_intf_map_t intf_map;
    if(!nas_mirror_fill_entry(obj,&entry,intf_map,false)){
        return STD_ERR(MIRROR,CFG,0);
    }

    std_mutex_simple_lock_guard lock(&nas_mirror_mutex);

    if(ndi_mirror_create_session(entry.get_ndi_entry()) != STD_ERR_OK){
        return STD_ERR(MIRROR,FAIL,0);
    }

    if(!entry.update_src_intf_map(intf_map)){
        if(!entry.remove_src_intf()){
            NAS_MIRROR_LOG(ERR,0,"Failed to remove source ports while create failure "
                           "for Mirror Session");
            return STD_ERR(MIRROR,FAIL,0);
        }
        NAS_MIRROR_LOG(ERR,0,"Failed to Enable Mirroring on Source Ports");
        ndi_mirror_delete_session(entry.get_ndi_entry());
        return STD_ERR(MIRROR,FAIL,0);
    }

    nas_mirror_id_t id = nas_mirror_get_next_id();
    entry.set_id(id);
    cps_api_set_key_data(obj,BASE_MIRROR_ENTRY_ID,cps_api_object_ATTR_T_U32,
                &id,sizeof(id));
    nas::ndi_obj_id_table_t mirror_opaque_data_table;
    mirror_opaque_data_table[entry.get_npu_id()] = entry.get_ndi_id();
    cps_api_attr_id_t  attr_id_list[] = {BASE_MIRROR_ENTRY_OPAQUE_DATA};
    nas::ndi_obj_id_table_cps_serialize (mirror_opaque_data_table, obj, attr_id_list,
                                                sizeof(attr_id_list)/sizeof(attr_id_list[0]));
    NAS_MIRROR_LOG(INFO,3,"Created New Mirror Session with id %d",entry.get_id());
    nas_mirror_table.insert(nas_mirror_table_pair(entry.get_id(),std::move(entry)));

    return STD_ERR_OK;
}
static cps_api_return_code_t _append_one_map(cps_api_get_params_t * param,
                                        uint_t switch_id,
                                        nas_qos_map *map,
                                        nas_qos_map_type_t map_type,
                                        nas_qos_map_entry_key_t search_key,
                                        bool is_map_entry
                                        )
{
    /* fill in data */
    cps_api_object_t ret_obj;

    ret_obj = cps_api_object_list_create_obj_and_append(param->list);
    if (ret_obj == NULL) {
        return cps_api_ret_code_ERR;
    }

    nas_attr_id_t obj_id = (is_map_entry? qos_map_entry_obj_id(map_type):
                            qos_map_obj_id(map_type));
    cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),
            obj_id,
            cps_api_qualifier_TARGET);

    obj_id = qos_map_map_id_obj_id(map_type);
    nas_obj_id_t map_id = map->get_map_id();
    cps_api_set_key_data(ret_obj, obj_id,
            cps_api_object_ATTR_T_U64,
            &map_id, sizeof(uint64_t));

    map_entries *entries = map->get_map_entries();
    if (entries == NULL)
        return NAS_QOS_E_FAIL;

    if (is_map_entry) {
        return _fill_matching_map_entries(ret_obj, search_key, entries, map_type);
    }
    else {
        return _fill_matching_map(ret_obj, entries, map_type);
    }
}
static cps_api_return_code_t nas_qos_store_prev_attr(cps_api_object_t obj,
                                                    const nas::attr_set_t attr_set,
                                                    const nas_qos_map &map)
{
    // fill in keys
    nas_obj_id_t map_id = map.get_map_id();
    nas_qos_map_type_t map_type = map.get_type();

    nas_attr_id_t obj_id = qos_map_obj_id(map_type);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),
            obj_id,
            cps_api_qualifier_TARGET);

    obj_id = qos_map_map_id_obj_id(map_type);
    cps_api_set_key_data(obj,
            obj_id,
            cps_api_object_ATTR_T_U64,
            &map_id, sizeof(uint64_t));

    // Attributes: no-op

    return cps_api_ret_code_OK;
}
TEST(std_nas_route_test, nas_route_ipv6_get) {
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters);
    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),BASE_ROUTE_OBJ_ENTRY,
                                        cps_api_qualifier_TARGET);
    unsigned int af = AF_INET6;
    cps_api_set_key_data(obj,BASE_ROUTE_OBJ_ENTRY_AF,cps_api_object_ATTR_T_U32,
                                 &af,sizeof(af));

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t mx = cps_api_object_list_size(gp.list);

        std::cout<<"IPv6 FIB Entries"<<std::endl;
        std::cout<<"================================="<<std::endl;
        for ( size_t ix = 0 ; ix < mx ; ++ix ) {
            obj = cps_api_object_list_get(gp.list,ix);
            nas_route_dump_route_object_content(obj);
            std::cout<<std::endl;
        }
    }
    cps_api_get_request_close(&gp);
}
/**
  * This function provides NAS-QoS SCHEDULER_GROUP CPS API read function
  * @Param      Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_scheduler_group_read (void * context,
                                            cps_api_get_params_t * param,
                                            size_t ix)
{
    cps_api_object_t obj = cps_api_object_list_get(param->filters, ix);
    cps_api_object_attr_t sg_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID);
    uint32_t port_id = 0, level;
    bool have_port = false, have_level = false;
    if (!sg_attr) {
        cps_api_object_it_t it;
        cps_api_object_it_begin(obj, &it);
        for ( ; cps_api_object_it_valid(&it); cps_api_object_it_next(&it)) {
            cps_api_attr_id_t id = cps_api_object_attr_id(it.attr);
            if (id == BASE_QOS_SCHEDULER_GROUP_PORT_ID) {
                port_id = cps_api_object_attr_data_u32(it.attr);
                have_port = true;
            } else if (id == BASE_QOS_SCHEDULER_GROUP_LEVEL) {
                level = cps_api_object_attr_data_u32(it.attr);
                have_level = true;
            }
        }
    }

    if (!sg_attr && !have_port) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MINOR, "NAS-QOS",
                     "Invalid input attributes for reading");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint_t switch_id = 0;
    nas_obj_id_t scheduler_group_id = (sg_attr? cps_api_object_attr_data_u64(sg_attr): 0);

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Read switch id %u, scheduler_group id 0x%016lX\n",
                    switch_id, scheduler_group_id);

    std_mutex_simple_lock_guard p_m(&scheduler_group_mutex);

    if (have_port) {
        nas_qos_port_scheduler_group_init(port_id);
    }
    nas_qos_switch * p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    std::vector<nas_qos_scheduler_group *> sg_list;
    if (sg_attr) {
        nas_qos_scheduler_group *scheduler_group = p_switch->get_scheduler_group(scheduler_group_id);
        if (scheduler_group == NULL) {
            EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MINOR, "NAS-QOS",
                         "Could not find scheduler group with ID %llu", scheduler_group_id);
            return NAS_QOS_E_FAIL;
        }
        sg_list.push_back(scheduler_group);
    } else {
        int match_level = have_level ? (int)level : -1;
        p_switch->get_port_scheduler_groups(port_id, match_level, sg_list);
    }

    /* fill in data */
    cps_api_object_t ret_obj;

    for (auto scheduler_group: sg_list) {
        ret_obj = cps_api_object_list_create_obj_and_append (param->list);
        if (ret_obj == NULL) {
            EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MINOR, "NAS-QOS",
                         "Failed to create cps object");
            return cps_api_ret_code_ERR;
        }

        cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),BASE_QOS_SCHEDULER_GROUP_OBJ,
                cps_api_qualifier_TARGET);
        cps_api_set_key_data(ret_obj, BASE_QOS_SCHEDULER_GROUP_SWITCH_ID,
                cps_api_object_ATTR_T_U32,
                &switch_id, sizeof(uint32_t));
        scheduler_group_id = scheduler_group->get_scheduler_group_id();
        cps_api_set_key_data(ret_obj, BASE_QOS_SCHEDULER_GROUP_ID,
                cps_api_object_ATTR_T_U64,
                &scheduler_group_id, sizeof(uint64_t));

        cps_api_object_attr_add_u32(ret_obj,
                                    BASE_QOS_SCHEDULER_GROUP_CHILD_COUNT,
                                    scheduler_group->get_child_count());

        for (uint32_t idx = 0; idx < scheduler_group->get_child_count(); idx++) {
            cps_api_object_attr_add_u64(ret_obj,
                                        BASE_QOS_SCHEDULER_GROUP_CHILD_LIST,
                                        scheduler_group->get_child_id(idx));
        }

        cps_api_object_attr_add_u32(ret_obj, BASE_QOS_SCHEDULER_GROUP_PORT_ID,
                                    scheduler_group->get_port_id());
        cps_api_object_attr_add_u32(ret_obj, BASE_QOS_SCHEDULER_GROUP_LEVEL,
                                    scheduler_group->get_level());
        cps_api_object_attr_add_u64(ret_obj, BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID,
                                    scheduler_group->get_scheduler_profile_id());
    }

    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_scheduler_group_create(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj)
{
#ifndef R_1_0_DISABLE_SG_CREATE
    nas_obj_id_t scheduler_group_id = 0;

    cps_api_object_attr_t switch_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_SWITCH_ID);
    if (switch_attr == NULL ) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " switch id not specified in the message\n");
        return NAS_QOS_E_FAIL;
    }

    uint_t switch_id = cps_api_object_attr_data_u32(switch_attr);

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    nas_qos_scheduler_group scheduler_group(p_switch);

    if (nas_qos_cps_parse_attr(obj, scheduler_group) != cps_api_ret_code_OK)
        return NAS_QOS_E_FAIL;

    if (scheduler_group.get_level() == 0 &&
        scheduler_group.dirty_attr_list().contains(BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID)) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                " Scheduler Group Level 0 node does not accept Scheduler Profile ID; "
                " Use Port Egress Object to configure Scheduler Profile!\n");
        return NAS_QOS_E_FAIL;
    }

    try {
        scheduler_group_id = p_switch->alloc_scheduler_group_id();

        scheduler_group.set_scheduler_group_id(scheduler_group_id);

        scheduler_group.commit_create(sav_obj? false: true);

        p_switch->add_scheduler_group(scheduler_group);

        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Created new scheduler_group %u\n",
                     scheduler_group.get_scheduler_group_id());

        // update obj with new scheduler_group-id key
        cps_api_set_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID,
                cps_api_object_ATTR_T_U64,
                &scheduler_group_id, sizeof(uint64_t));

        // save for rollback if caller requests it.
        if (sav_obj) {
            cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return NAS_QOS_E_FAIL;
            }
            cps_api_object_clone(tmp_obj, obj);

        }

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Create error code: %d ",
                    e.err_code);
        if (scheduler_group_id)
            p_switch->release_scheduler_group_id(scheduler_group_id);

        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Create Unexpected error code");
        if (scheduler_group_id)
            p_switch->release_scheduler_group_id(scheduler_group_id);

        return NAS_QOS_E_FAIL;
    }

#endif
    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_get_priority_group_info(
                                cps_api_get_params_t * param,
                                uint32_t switch_id, uint_t port_id,
                                bool match_local_id, uint_t local_id)
{
    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    uint_t count = p_switch->get_number_of_port_priority_groups(port_id);

    if  (count == 0) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "switch id %u, port id %u has no priority_groups\n",
                switch_id, port_id);

        return NAS_QOS_E_FAIL;
    }

    std::vector<nas_qos_priority_group *> pg_list(count);
    p_switch->get_port_priority_groups(port_id, count, &pg_list[0]);

    /* fill in data */
    cps_api_object_t ret_obj;

    for (uint_t i = 0; i < count; i++ ) {
        nas_qos_priority_group *priority_group = pg_list[i];

        // filter out unwanted priority_groups

        if (match_local_id && (priority_group->get_local_id() != local_id))
            continue;


        ret_obj = cps_api_object_list_create_obj_and_append(param->list);
        if (ret_obj == NULL) {
            return cps_api_ret_code_ERR;
        }

        cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),
                BASE_QOS_PRIORITY_GROUP_OBJ,
                cps_api_qualifier_TARGET);
        uint32_t val_port = priority_group->get_port_id();
        uint8_t  val_local_id = priority_group->get_local_id();

        cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_PORT_ID,
                cps_api_object_ATTR_T_U32,
                &val_port, sizeof(uint32_t));
        cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_LOCAL_ID,
                cps_api_object_ATTR_T_BIN,
                &val_local_id, sizeof(uint8_t));

        cps_api_object_attr_add_u64(ret_obj, BASE_QOS_PRIORITY_GROUP_ID,
                priority_group->get_priority_group_id());

        // User configured objects
        if (priority_group->is_buffer_profile_set())
            cps_api_object_attr_add_u64(ret_obj,
                    BASE_QOS_PRIORITY_GROUP_BUFFER_PROFILE_ID,
                    priority_group->get_buffer_profile());

    }

    return cps_api_ret_code_OK;
}
/**
  * This function provides NAS-QoS priority_group stats CPS API read function
  * @Param    Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_priority_group_stat_read (void * context,
                                            cps_api_get_params_t * param,
                                            size_t ix)
{

    cps_api_object_t obj = cps_api_object_list_get(param->filters, ix);
    cps_api_object_attr_t port_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_STAT_PORT_ID);
    cps_api_object_attr_t local_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_STAT_LOCAL_ID);

    if (port_id_attr == NULL ||
        local_id_attr == NULL ) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Incomplete key: port-id, priority_group local id must be specified\n");
        return NAS_QOS_E_MISSING_KEY;
    }
    uint32_t switch_id = 0;
    nas_qos_priority_group_key_t key;
    key.port_id = cps_api_object_attr_data_u32(port_id_attr);
    key.local_id = *(uint8_t *)cps_api_object_attr_data_bin(local_id_attr);


    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
            "Read switch id %u, port_id %u priority_group local id %u stat\n",
            switch_id, key.port_id, key.local_id);

    std_mutex_simple_lock_guard p_m(&priority_group_mutex);

    // If the port is not be initialized yet, initialize it in NAS
    nas_qos_port_priority_group_init(key.port_id);

    nas_qos_switch *switch_p = nas_qos_get_switch(switch_id);
    if (switch_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "switch_id %u not found", switch_id);
        return NAS_QOS_E_FAIL;
    }

    nas_qos_priority_group * priority_group_p = switch_p->get_priority_group(key);
    if (priority_group_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Priority Group not found");
        return NAS_QOS_E_FAIL;
    }

    nas_qos_priority_group_stat_counter_t stats = {0};
    std::vector<BASE_QOS_PRIORITY_GROUP_STAT_t> counter_ids;

    cps_api_object_it_t it;
    cps_api_object_it_begin(obj,&it);
    for ( ; cps_api_object_it_valid(&it) ; cps_api_object_it_next(&it) ) {
        cps_api_attr_id_t id = cps_api_object_attr_id(it.attr);
        switch (id) {
        case BASE_QOS_PRIORITY_GROUP_STAT_PORT_ID:
        case BASE_QOS_PRIORITY_GROUP_STAT_LOCAL_ID:
            break;

        case BASE_QOS_PRIORITY_GROUP_STAT_PACKETS:
        case BASE_QOS_PRIORITY_GROUP_STAT_BYTES:
        case BASE_QOS_PRIORITY_GROUP_STAT_CURRENT_OCCUPANCY_BYTES:
        case BASE_QOS_PRIORITY_GROUP_STAT_WATERMARK_BYTES:
            counter_ids.push_back((BASE_QOS_PRIORITY_GROUP_STAT_t)id);
            break;

        default:
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Unknown priority_group STAT flag: %u, ignored", id);
            break;
        }
    }

    if (ndi_qos_get_priority_group_stats(priority_group_p->get_ndi_port_id(),
                                priority_group_p->ndi_obj_id(),
                                &counter_ids[0],
                                counter_ids.size(),
                                &stats) != STD_ERR_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Priority Group stats get failed");
        return NAS_QOS_E_FAIL;
    }

    // return stats objects to cps-app
    cps_api_object_t ret_obj = cps_api_object_list_create_obj_and_append(param->list);
    if (ret_obj == NULL) {
        return cps_api_ret_code_ERR;
    }

    cps_api_key_from_attr_with_qual(cps_api_object_key(ret_obj),
            BASE_QOS_PRIORITY_GROUP_STAT_OBJ,
            cps_api_qualifier_TARGET);
    cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_STAT_PORT_ID,
            cps_api_object_ATTR_T_U32,
            &(key.port_id), sizeof(uint32_t));
    cps_api_set_key_data(ret_obj, BASE_QOS_PRIORITY_GROUP_STAT_LOCAL_ID,
            cps_api_object_ATTR_T_BIN,
            &(key.local_id), sizeof(uint8_t));

    uint64_t val64;
    for (uint_t i=0; i< counter_ids.size(); i++) {
        BASE_QOS_PRIORITY_GROUP_STAT_t id = counter_ids[i];
        val64 = get_stats_by_type(&stats, id);
        cps_api_object_attr_add_u64(ret_obj, id, val64);
    }

    return  cps_api_ret_code_OK;

}
extern "C" bool nl_get_ip_info (int rt_msg_type, struct nlmsghdr *hdr, cps_api_object_t obj) {

    struct ifaddrmsg *ifmsg = (struct ifaddrmsg *)NLMSG_DATA(hdr);

    if(hdr->nlmsg_len < NLMSG_LENGTH(sizeof(*ifmsg)))
        return false;

    typedef enum { IP_KEY, IFINDEX, PREFIX, ADDRESS, IFNAME } attr_t ;
    static const std::map<uint32_t, std::map<int,cps_api_attr_id_t>> _ipmap = {
      {AF_INET,
      {
        {IP_KEY,  BASE_IP_IPV4_OBJ},
        {IFINDEX, BASE_IP_IPV4_IFINDEX},
        {PREFIX,  BASE_IP_IPV4_ADDRESS_PREFIX_LENGTH},
        {ADDRESS, BASE_IP_IPV4_ADDRESS_IP},
        {IFNAME,  BASE_IP_IPV4_NAME}
      }},

      {AF_INET6,
      {
        {IP_KEY,  BASE_IP_IPV6_OBJ},
        {IFINDEX, BASE_IP_IPV6_IFINDEX},
        {PREFIX,  BASE_IP_IPV6_ADDRESS_PREFIX_LENGTH},
        {ADDRESS, BASE_IP_IPV6_ADDRESS_IP},
        {IFNAME,  BASE_IP_IPV6_NAME}
      }}
    };

    cps_api_key_from_attr_with_qual(cps_api_object_key(obj),_ipmap.at(ifmsg->ifa_family).at(IP_KEY),
                                    cps_api_qualifier_TARGET);

    cps_api_set_key_data(obj,_ipmap.at(ifmsg->ifa_family).at(IFINDEX), cps_api_object_ATTR_T_U32,
                         &ifmsg->ifa_index,sizeof(ifmsg->ifa_index));

    cps_api_object_attr_add_u32(obj, _ipmap.at(ifmsg->ifa_family).at(IFINDEX), ifmsg->ifa_index);
    cps_api_object_attr_add_u32(obj, _ipmap.at(ifmsg->ifa_family).at(PREFIX), ifmsg->ifa_prefixlen);

    int nla_len = nlmsg_attrlen(hdr,sizeof(*ifmsg));
    struct nlattr *head = nlmsg_attrdata(hdr, sizeof(struct ifaddrmsg));

    struct nlattr *attrs[__IFLA_MAX];
    memset(attrs,0,sizeof(attrs));

    if (nla_parse(attrs,__IFLA_MAX,head,nla_len)!=0) {
        EV_LOG_TRACE(ev_log_t_NAS_OS,ev_log_s_WARNING,"IP-NL-PARSE","Failed to parse attributes");
        cps_api_object_delete(obj);
        return false;
    }

    if(attrs[IFA_ADDRESS]!=NULL) {
       rta_add_ip((struct nlattr*)ifmsg, ifmsg->ifa_family,
                   obj, _ipmap.at(ifmsg->ifa_family).at(ADDRESS));
    }

    if(attrs[IFA_LABEL]!=NULL) {
      rta_add_name(attrs[IFA_LABEL], obj, _ipmap.at(ifmsg->ifa_family).at(IFNAME));
    }


    if (rt_msg_type == RTM_NEWADDR)  {
        cps_api_object_set_type_operation(cps_api_object_key(obj),cps_api_oper_CREATE);
    } else if (rt_msg_type == RTM_DELADDR)  {
        cps_api_object_set_type_operation(cps_api_object_key(obj),cps_api_oper_DELETE);
    } else {
        cps_api_object_set_type_operation(cps_api_object_key(obj),cps_api_oper_SET);
    }

    return true;
}
cps_api_return_code_t cps_api_create_global_instance(cps_api_node_group_t *group) {
    if(group == nullptr) return cps_api_ret_code_ERR;

    size_t local_node_ix;
    if(!cps_api_find_local_node(group,local_node_ix)) {
        EV_LOGGING(DSAPI,ERR,"SET-GLOBAL","Failed to find local node in group %s",group);
        return cps_api_ret_code_ERR;
    }

    if(local_node_ix >= group->addr_len) {
        return cps_api_ret_code_ERR;
    }

    cps_api_transaction_params_t tr;
    if (cps_api_transaction_init(&tr)!=cps_api_ret_code_OK) {
        EV_LOGGING(DSAPI,ERR,"SET-GLOBAL","Failed to init transaction");
        return cps_api_ret_code_ERR;
    }

    cps_api_transaction_guard tg(&tr);
    cps_api_object_t  db_obj = cps_api_object_create();

    if(db_obj == nullptr ) return cps_api_ret_code_ERR;

    cps_api_key_from_attr_with_qual(cps_api_object_key(db_obj),CPS_DB_INSTANCE_OBJ,
                                    cps_api_qualifier_TARGET);

    cps_api_object_attr_add(db_obj,CPS_DB_INSTANCE_GROUP,group->id,strlen(group->id)+1);

    if(cps_api_create(&tr,db_obj) != cps_api_ret_code_OK ) {
        return cps_api_ret_code_ERR;
    }

    if(cps_api_commit(&tr) != cps_api_ret_code_OK ) {
        EV_LOGGING(DSAPI,ERR,"SET-GLOBAL","Failed to create new global instance for %s",group);
        return cps_api_ret_code_ERR;
    }

    cps_api_object_t ret_obj = cps_api_object_list_get(tr.change_list,0);
    if (ret_obj == nullptr ) {
        EV_LOGGING(DSAPI,ERR,"SET-GLOBAL","Failed to find db instance port info for %s",group);
        return cps_api_ret_code_ERR;
    }

    // Get the port where new db instance was started
    const char * db_port = (const char*) cps_api_object_get_data(ret_obj,CPS_DB_INSTANCE_PORT);
    std::string _db_port = db_port;

    /*
     * Push the group name local node id and its port to local/remote DB.
     */
    cps_api_node_ident & node = group->addrs[local_node_ix];
    cps_api_object_guard db_node(cps_api_object_create());
    if (db_node.get() == nullptr) {
        return cps_api_ret_code_ERR;
    }

    cps_api_key_from_attr_with_qual(cps_api_object_key(db_node.get()),CPS_DB_INSTANCE_OBJ, cps_api_qualifier_TARGET);

    cps_api_set_key_data(db_node.get(),CPS_DB_INSTANCE_GROUP,cps_api_object_ATTR_T_BIN,group->id,strlen(group->id)+1);
    cps_api_set_key_data(db_node.get(),CPS_DB_INSTANCE_NODE_ID,cps_api_object_ATTR_T_BIN,node.node_name,strlen(node.node_name)+1);
    cps_api_object_attr_add(db_node.get(),CPS_DB_INSTANCE_PORT,_db_port.c_str(),strlen(_db_port.c_str())+1);


    if (!cps_api_node_set_iterate(group->id,[&db_node](const std::string &name,void *c) {
    cps_db::connection_request r(cps_db::ProcessDBCache(),name.c_str());

        cps_db::store_object(r.get(),db_node.get());
        return;

    },nullptr)) {
        return cps_api_ret_code_ERR;
    }
    return cps_api_ret_code_OK;
}
static void _fill_entry_key_data(cps_api_object_t obj,
        nas_qos_map_entry_key_t key,
        nas_qos_map_type_t map_type)
{
    nas_attr_id_t obj_id = qos_map_entry_key_1_obj_id(map_type);
    switch (map_type) {
    case NDI_QOS_MAP_DOT1P_TO_TC_COLOR:
    case NDI_QOS_MAP_DOT1P_TO_TC:
    case NDI_QOS_MAP_DOT1P_TO_COLOR:
    case NDI_QOS_MAP_DSCP_TO_TC_COLOR:
    case NDI_QOS_MAP_DSCP_TO_TC:
    case NDI_QOS_MAP_DSCP_TO_COLOR:
    case NDI_QOS_MAP_TC_TO_DSCP:
    case NDI_QOS_MAP_TC_TO_DOT1P:
    case NDI_QOS_MAP_TC_TO_PG:
    {
        uint8_t val8 = (uint8_t)key.any;
        cps_api_set_key_data(obj, obj_id,
            cps_api_object_ATTR_T_BIN,
            &val8, sizeof(uint8_t));
        break;
    }

    case NDI_QOS_MAP_TC_TO_QUEUE:
    {
        // For NDI_QOS_MAP_TC_TO_QUEUE, key is a complex key
        uint8_t tc = GET_KEY1(key);
        uint32_t queue_type = GET_KEY2(key);
        obj_id = qos_map_entry_key_1_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_BIN,
                &tc, sizeof(uint8_t));
        obj_id = qos_map_entry_key_2_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_U32,
                &queue_type, sizeof(uint32_t));
        break;
    }

    case NDI_QOS_MAP_TC_COLOR_TO_DOT1P:
    case NDI_QOS_MAP_TC_COLOR_TO_DSCP:
    {
        // For NDI_QOS_MAP_TC_TO_QUEUE, key is a complex key
        uint8_t tc = GET_KEY1(key);
        uint32_t color = GET_KEY2(key);
        obj_id = qos_map_entry_key_1_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_BIN,
                &tc, sizeof(uint8_t));
        obj_id = qos_map_entry_key_2_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_U32,
                &color, sizeof(uint32_t));
        break;
    }

    case NDI_QOS_MAP_PG_TO_PFC:
    {
        // complex key
        uint8_t pg = GET_KEY1(key);
        uint8_t prio = GET_KEY2(key);
        obj_id = qos_map_entry_key_1_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_BIN,
                &pg, sizeof(uint8_t));
        obj_id = qos_map_entry_key_2_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_BIN,
                &prio, sizeof(uint8_t));
        break;
    }

    case NDI_QOS_MAP_PFC_TO_QUEUE:
    {
        //complex key
        uint8_t prio = GET_KEY1(key);
        uint32_t queue_type = GET_KEY2(key);
        obj_id = qos_map_entry_key_1_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_BIN,
                &prio, sizeof(uint8_t));
        obj_id = qos_map_entry_key_2_obj_id(map_type);
        cps_api_set_key_data(obj,
                obj_id,
                cps_api_object_ATTR_T_U32,
                &queue_type, sizeof(uint32_t));
        break;
    }

    default:
        break;
    }

}
static cps_api_return_code_t nas_qos_cps_api_map_create(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj,
                                nas_qos_map_type_t map_type)
{
    uint_t switch_id;
    nas_obj_id_t map_id = 0;
    nas_qos_map_entry_key_t key;
    cps_api_return_code_t rc = cps_api_ret_code_OK;

    // check the request is on Map level or Entry level
    bool is_map_entry;
    if ((rc = qos_map_key_check(obj, map_type, &is_map_entry)) != cps_api_ret_code_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key error");
        return rc;
    }

    if (is_map_entry) {
        if ((rc = qos_map_entry_get_key(obj, map_type, switch_id, map_id, key)) != cps_api_ret_code_OK)
            return rc;

    }
    else {
        if ((rc = qos_map_get_switch_id(obj, map_type, switch_id)) != cps_api_ret_code_OK)
            return rc;

        // while creating map id, do not accept map-entry attributes.
        // Map-entry needs to be created separately.
        if (qos_map_entry_attr_is_set(obj, map_type)) {
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Inner list map entries must be created separately after map id is created\n");
            return NAS_QOS_E_INCONSISTENT;
        }
    }

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    try {
        if (!is_map_entry) {
            // Map id create

            nas_qos_map map(p_switch, map_type);

            map_id = p_switch->alloc_map_id();

            map.set_map_id(map_id);

            map.commit_create(sav_obj? false: true);

            p_switch->add_map(map);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Created new map %u\n",
                         map.get_map_id());

            // update obj with new map-id attr and key
            nas_attr_id_t map_id_obj_id = qos_map_map_id_obj_id(map_type);
            cps_api_set_key_data(obj,
                    map_id_obj_id,
                    cps_api_object_ATTR_T_U64,
                    &map_id, sizeof(uint64_t));

            // save for rollback if caller requests it.
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                cps_api_object_clone(tmp_obj, obj);
            }
        }
        else {
            // Map entry create
            nas_qos_map * p_map = p_switch->get_map(map_id);
            if (p_map == NULL) {
                EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                        "NAS map id %lu is not found", map_id);
                return NAS_QOS_E_FAIL;
            }

            if (p_map->get_type() != map_type) {
                EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                        "NAS map id %lu has mismatched type: %d vs expected %d",
                        map_id, p_map->get_type(), map_type);
                return NAS_QOS_E_INCONSISTENT;
            }

            nas_qos_map_entry entry(p_switch, map_id, map_type, key);

            if ((rc = nas_qos_cps_parse_attr(obj, entry)) != cps_api_ret_code_OK)
                return rc;

            //push a create to NPUs
            entry.commit_create(sav_obj? false: true);

            p_map->add_map_entry(key, entry);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                    "Created new map entry with key %u\n",
                         key.any);

            // save for rollback if caller requests it.
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                cps_api_object_clone(tmp_obj, obj);
            }
        }
    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS %s Create error code: %d ",
                    (is_map_entry? "Map Entry": "Map"),
                    e.err_code);
        if (!is_map_entry && map_id)
            p_switch->release_map_id(map_id);

        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS %s Create Unexpected error code",
                    (is_map_entry? "Map Entry": "Map"));
        if (!is_map_entry && map_id)
            p_switch->release_map_id(map_id);

        return NAS_QOS_E_FAIL;
    }

    return cps_api_ret_code_OK;
}