bool cps_api_obj_tool_merge(cps_api_object_t main, cps_api_object_t overlay) {
    cps_api_object_it_t it;

    cps_api_object_it_begin(overlay,&it);
    do {
        CPS_CLASS_ATTR_TYPES_t _type;
        if (!cps_class_map_attr_class(cps_api_object_attr_id(it.attr),&_type)) {
            _type = CPS_CLASS_ATTR_T_LEAF;
        }
        do {
            cps_api_attr_id_t _id = cps_api_object_attr_id(it.attr);
            cps_api_object_attr_delete(main,_id);
            if (_type==CPS_CLASS_ATTR_T_LEAF_LIST) {
                if (cps_api_object_attr_get(main,_id)!=nullptr) {
                    continue;
                }
            }
        } while (0);
    } while (cps_api_object_it_next(&it));

    cps_api_object_it_begin(overlay,&it);
    do {
        size_t _attr_len = cps_api_object_attr_len(it.attr);
        if (_attr_len==0) continue;
        if (!cps_api_object_attr_add(main,cps_api_object_attr_id(it.attr),cps_api_object_attr_data_bin(it.attr),
                _attr_len)) {
            return false;
        }
    } while (cps_api_object_it_next(&it));
    return true;
}
extern "C" bool cps_api_obj_tool_matches_filter(cps_api_object_t filter, cps_api_object_t obj, bool require_all_attribs) {
    cps_api_object_it_t it;
    cps_api_object_it_begin(filter,&it);

    cps_api_object_it_t obj_it;
    cps_api_object_it_begin(obj,&obj_it);
    return __cps_api_obj_tool_matches_filter(it,obj_it,require_all_attribs);
}
/* Parse the attributes */
static cps_api_return_code_t  nas_qos_cps_parse_attr(cps_api_object_t obj,
                                              nas_qos_priority_group &priority_group)
{
    uint64_t val;
    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_PORT_ID:
        case BASE_QOS_PRIORITY_GROUP_LOCAL_ID:
        case BASE_QOS_PRIORITY_GROUP_ID:
            break; // These are not settable from cps

        case BASE_QOS_PRIORITY_GROUP_BUFFER_PROFILE_ID:
            val = cps_api_object_attr_data_u64(it.attr);
            priority_group.mark_attr_dirty(id);
            priority_group.set_buffer_profile(val);
            break;

        case CPS_API_ATTR_RESERVE_RANGE_END:
            // skip keys
            break;

        default:
            EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS", "Unrecognized option: %d", id);
            return NAS_QOS_E_UNSUPPORTED;
        }
    }


    return cps_api_ret_code_OK;
}
void nas_route_dump_peer_routing_object_content(cps_api_object_t obj){
    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) ) {

        switch (cps_api_object_attr_id(it.attr)) {

        case BASE_ROUTE_PEER_ROUTING_CONFIG_VRF_ID:
            std::cout<<"VRF Id "<<cps_api_object_attr_data_u32(it.attr)<<std::endl;
            break;

        case BASE_ROUTE_PEER_ROUTING_CONFIG_PEER_MAC_ADDR:
        {
              char mt[6];
              char mstring[20];
              memcpy(mt, cps_api_object_attr_data_bin(it.attr), 6);
              sprintf(mstring, "%x:%x:%x:%x:%x:%x", mt[0], mt[1], mt[2], mt[3], mt[4], mt[5]);
              std::cout<<"MAC "<<mstring<<std::endl;
        }
            break;

        default:
            break;
        }
    }
}
Example #5
0
t_std_error nas_get_lag_if_index (uint64_t ndi_port, hal_ifindex_t *lag_if_index)
{
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);
    cps_api_get_request_guard rg(&gp);

    EV_LOG_TRACE(ev_log_t_INTERFACE, 2, "INTF-C", "querying for ifindex of ndi lag id 0x%x ", ndi_port);
    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), DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_OBJ,
            cps_api_qualifier_TARGET);

    cps_api_object_attr_add_u64(obj,BASE_IF_LAG_IF_INTERFACES_INTERFACE_LAG_OPAQUE_DATA, ndi_port);
    cps_api_object_attr_add(obj,IF_INTERFACES_INTERFACE_TYPE,
                  (const char *)IF_INTERFACE_TYPE_IANAIFT_IANA_INTERFACE_TYPE_IANAIFT_IEEE8023ADLAG,
                  sizeof(IF_INTERFACE_TYPE_IANAIFT_IANA_INTERFACE_TYPE_IANAIFT_IEEE8023ADLAG));

    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 ) {
            cps_api_object_t obj = cps_api_object_list_get(gp.list,ix);
            cps_api_object_it_t it;
            cps_api_object_it_begin(obj,&it);
            cps_api_object_attr_t attr = cps_api_object_it_find(&it, DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_IF_INDEX);
            if (!attr) {
               return  STD_ERR(INTERFACE, FAIL, 0);
            }
            *lag_if_index = cps_api_object_attr_data_u32(attr);
        }
    }
    return(STD_ERR_OK);
}
Example #6
0
t_std_error nas_sflow_update_session(cps_api_object_t obj, nas_sflow_id_t id){

    unsigned int prev_sampling_rate;
    std_mutex_simple_lock_guard lock(&nas_sflow_mutex);

    nas_sflow_map_it sit = nas_sflow_table.find(id);

    if(sit == nas_sflow_table.end()){
        NAS_SFLOW_LOG(ERR,ev_log_s_MINOR,"No NAS sFlow session with Id %d exist",(int)id);
        return STD_ERR(SFLOW,NEXIST,0);
    }
    nas_sflow_entry_t & sflow_entry =  sit->second;

    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) ) {
        int attr_id = (int) cps_api_object_attr_id(it.attr);

        switch (attr_id) {

        case BASE_SFLOW_ENTRY_DIRECTION :
            if(sflow_entry.ndi_sflow_entry.sflow_direction != (BASE_CMN_TRAFFIC_PATH_t)
                    cps_api_object_attr_data_u32(it.attr)){
                if(!nas_sflow_update_session_attr(&(sflow_entry.ndi_sflow_entry),
                        BASE_SFLOW_ENTRY_DIRECTION,cps_api_object_attr_data_u32(it.attr))){
                        return STD_ERR(SFLOW,FAIL,0);
                }
                sflow_entry.ndi_sflow_entry.sflow_direction = (BASE_CMN_TRAFFIC_PATH_t)
                                                   cps_api_object_attr_data_u32(it.attr);
                NAS_SFLOW_LOG(INFO,3,"Updated sFlow session %d direction to %d",sflow_entry.nas_sflow_id,
                            sflow_entry.ndi_sflow_entry.sflow_direction);
            }
            break;

        case BASE_SFLOW_ENTRY_SAMPLING_RATE :
            if(sflow_entry.ndi_sflow_entry.sampling_rate != cps_api_object_attr_data_u32(it.attr)){
                prev_sampling_rate = sflow_entry.ndi_sflow_entry.sampling_rate;
                sflow_entry.ndi_sflow_entry.sampling_rate = cps_api_object_attr_data_u32(it.attr);
                if(!nas_sflow_update_session_attr(&(sflow_entry.ndi_sflow_entry),
                        BASE_SFLOW_ENTRY_SAMPLING_RATE, cps_api_object_attr_data_u32(it.attr))){
                    sflow_entry.ndi_sflow_entry.sampling_rate = prev_sampling_rate;
                    return STD_ERR(SFLOW,FAIL,0);
                }
                NAS_SFLOW_LOG(INFO,3,"Updated sFlow session %d sampling rate to %d",sflow_entry.nas_sflow_id,
                                    sflow_entry.ndi_sflow_entry.sampling_rate);
            }
            break;

        default:
            break;
        }
    }
    return STD_ERR_OK;
}
void nas_route_dump_route_object_content(cps_api_object_t obj) {

    char str[INET6_ADDRSTRLEN];
    char if_name[IFNAMSIZ];
    uint32_t addr_len = 0, af_data = 0;
    uint32_t nhc = 0, nh_itr = 0;

    cps_api_object_it_t it;
    cps_api_object_it_begin(obj,&it);

    cps_api_object_attr_t af       = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_AF);
    af_data = cps_api_object_attr_data_u32(af) ;

    addr_len = ((af_data == AF_INET) ? HAL_INET4_LEN : HAL_INET6_LEN);

    cps_api_object_attr_t prefix   = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_ROUTE_PREFIX);
    cps_api_object_attr_t pref_len = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_PREFIX_LEN);
    cps_api_object_attr_t nh_count = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_NH_COUNT);
    std::cout<<"AF "<<((af_data == AF_INET) ? "IPv4" : "IPv6")<<","<<
        inet_ntop(af_data, cps_api_object_attr_data_bin(prefix), str,addr_len)<<"/"<<
        cps_api_object_attr_data_u32(pref_len)<<std::endl;
    if (nh_count != CPS_API_ATTR_NULL) {
        nhc = cps_api_object_attr_data_u32(nh_count);
        std::cout<<"NHC "<<nhc<<std::endl;
    }

    for (nh_itr = 0; nh_itr < nhc; nh_itr++)
    {
        cps_api_attr_id_t ids[3] = { BASE_ROUTE_OBJ_ENTRY_NH_LIST,
            0, BASE_ROUTE_OBJ_ENTRY_NH_LIST_NH_ADDR};
        const int ids_len = sizeof(ids)/sizeof(*ids);
        ids[1] = nh_itr;

        cps_api_object_attr_t attr = cps_api_object_e_get(obj,ids,ids_len);
        if (attr != CPS_API_ATTR_NULL)
            std::cout<<"NextHop "<<inet_ntop(af_data,cps_api_object_attr_data_bin(attr),str,addr_len)<<std::endl;

        ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_IFINDEX;
        attr = cps_api_object_e_get(obj,ids,ids_len);
        if (attr != CPS_API_ATTR_NULL)
            if_indextoname((int)cps_api_object_attr_data_u32(attr), if_name);
        std::cout<<"IfIndex "<<if_name<<"("<<cps_api_object_attr_data_u32(attr)<<")"<<std::endl;

        ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_WEIGHT;
        attr = cps_api_object_e_get(obj,ids,ids_len);
        if (attr != CPS_API_ATTR_NULL)
            std::cout<<"Weight "<<cps_api_object_attr_data_u32(attr)<<std::endl;

        ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_RESOLVED;
        attr = cps_api_object_e_get(obj,ids,ids_len);
        if (attr != CPS_API_ATTR_NULL)
            std::cout<<"Is Next Hop Resolved "<<cps_api_object_attr_data_u32(attr)<<std::endl;
    }
}
/* Parse the attributes */
static cps_api_return_code_t  nas_qos_cps_parse_attr(cps_api_object_t obj,
                                              nas_qos_scheduler_group &scheduler_group)
{
    uint_t val;
    uint64_t val64;
    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_SCHEDULER_GROUP_SWITCH_ID:
        case BASE_QOS_SCHEDULER_GROUP_ID:
            break; // These are for part of the keys

        case BASE_QOS_SCHEDULER_GROUP_CHILD_COUNT:
        case BASE_QOS_SCHEDULER_GROUP_CHILD_LIST:
            // non-configurable.
            break;


        case BASE_QOS_SCHEDULER_GROUP_PORT_ID:
            val = cps_api_object_attr_data_u32(it.attr);
            if (scheduler_group.set_port_id(val) != STD_ERR_OK)
                return NAS_QOS_E_FAIL;
            break;

        case BASE_QOS_SCHEDULER_GROUP_LEVEL:
            val = cps_api_object_attr_data_u32(it.attr);
            scheduler_group.set_level(val);
            break;

        case BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID:
            val64 = cps_api_object_attr_data_u64(it.attr);
            scheduler_group.set_scheduler_profile_id(val64);
            break;

        case CPS_API_ATTR_RESERVE_RANGE_END:
            // skip keys
            break;

       default:
            EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS", "Unrecognized option: %d", id);
            return NAS_QOS_E_UNSUPPORTED;
        }
    }


    return cps_api_ret_code_OK;
}
void nas_route_dump_arp_object_content(cps_api_object_t obj){
    cps_api_object_it_t it;
    cps_api_object_it_begin(obj,&it);
    char str[INET_ADDRSTRLEN];


    for ( ; cps_api_object_it_valid(&it) ; cps_api_object_it_next(&it) ) {

        switch (cps_api_object_attr_id(it.attr)) {

        case BASE_ROUTE_OBJ_NBR_ADDRESS:
            std::cout<<"IP Address "<<inet_ntop(AF_INET,cps_api_object_attr_data_bin(it.attr),str,INET_ADDRSTRLEN)<<std::endl;
            break;

        case BASE_ROUTE_OBJ_NBR_MAC_ADDR:
        {
              char mt[6];
              char mstring[20];
              memcpy(mt, cps_api_object_attr_data_bin(it.attr), 6);
              sprintf(mstring, "%x:%x:%x:%x:%x:%x", mt[0], mt[1], mt[2], mt[3], mt[4], mt[5]);
              std::cout<<"MAC "<<mstring<<std::endl;
        }
            break;

        case BASE_ROUTE_OBJ_NBR_VRF_ID:
            std::cout<<"VRF Id "<<cps_api_object_attr_data_u32(it.attr)<<std::endl;
            break;

        case BASE_ROUTE_OBJ_NBR_IFINDEX:
            std::cout<<"Ifindex "<<cps_api_object_attr_data_u32(it.attr)<<std::endl;
            break;

        case BASE_ROUTE_OBJ_NBR_FLAGS:
            std::cout<<"Flags "<<cps_api_object_attr_data_u32(it.attr)<<std::endl;
            break;

        case BASE_ROUTE_OBJ_NBR_STATE:
            std::cout<<"State "<<cps_api_object_attr_data_u32(it.attr)<<std::endl;
            break;

        case BASE_ROUTE_OBJ_NBR_TYPE:
            std::cout<<"Type "<<cps_api_object_attr_data_u32(it.attr)<<std::endl;
            break;

        default:
            break;
        }
    }
}
Example #10
0
static bool nas_sflow_fill_session_info(cps_api_object_t obj,nas_sflow_entry_t *entry){

    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) ) {

        int id = (int) cps_api_object_attr_id(it.attr);

        switch (id) {

        case BASE_SFLOW_ENTRY_IFINDEX :
            if(entry->attr_set.contains(BASE_SFLOW_ENTRY_IFINDEX)){
                NAS_SFLOW_LOG(ERR,ev_log_s_MINOR,"Multiple Interface Index passed "
                        "for creating sFlow session");
                return false;
            }
            entry->ifindex = cps_api_object_attr_data_u32(it.attr);
            entry->attr_set.add(BASE_SFLOW_ENTRY_IFINDEX);
            break;

        case BASE_SFLOW_ENTRY_DIRECTION :
            if(entry->attr_set.contains(BASE_SFLOW_ENTRY_DIRECTION)){
                NAS_SFLOW_LOG(ERR,ev_log_s_MINOR,"Multiple Direction Attributes passed "
                                            "for creating sFlow session");
                return false;
            }
            entry->ndi_sflow_entry.sflow_direction = (BASE_CMN_TRAFFIC_PATH_t)
                                                        cps_api_object_attr_data_u32(it.attr);
            entry->attr_set.add(BASE_SFLOW_ENTRY_DIRECTION);
            break;

        case BASE_SFLOW_ENTRY_SAMPLING_RATE :
            if(entry->attr_set.contains(BASE_SFLOW_ENTRY_SAMPLING_RATE)){
                NAS_SFLOW_LOG(ERR,ev_log_s_MINOR,"Multiple Sampling Attributes passed "
                                           "for creating sFlow session");
                return false;
            }
            entry->ndi_sflow_entry.sampling_rate = cps_api_object_attr_data_u32(it.attr);
            entry->attr_set.add(BASE_SFLOW_ENTRY_SAMPLING_RATE);
            break;

        default:
            break;
        }
    }
    return nas_validate_sflow_entry(entry);
}
static bool qos_map_entry_attr_is_set(cps_api_object_t obj, nas_qos_map_type_t type)
{
    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 == qos_map_entry_obj_id(type) ||
            id == qos_map_entry_key_1_obj_id(type) ||
            id == qos_map_entry_key_2_obj_id(type) ||
            id == qos_map_entry_attr_1_obj_id(type) ||
            id == qos_map_entry_attr_2_obj_id(type))
            return true; //found
    }

    return false;

}
/* Parse the attributes */
static cps_api_return_code_t  nas_qos_cps_parse_attr(cps_api_object_t obj,
        nas_qos_map_entry  &entry )
{
    nas_qos_map_type_t type = entry.get_type();

    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);
        _attr_parse_fn fn;

        if (id == qos_map_entry_attr_1_obj_id(type)) {
            fn = qos_map_entry_attr_1_parse_fn(type);
            fn(it.attr, entry);
        }

        if (id == qos_map_entry_attr_2_obj_id(type)) {
            fn = qos_map_entry_attr_2_parse_fn(type);
            fn(it.attr, entry);
        }
    }

    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;

}
static bool nas_mirror_fill_entry(cps_api_object_t obj,nas_mirror_entry *entry
                                 ,nas_mirror_src_intf_map_t  & new_intf_map,bool update){

    nas::attr_set_t attrs;
    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) ) {

        int id = (int) cps_api_object_attr_id(it.attr);
        switch (id) {

        case BASE_MIRROR_ENTRY_DST_INTF :
            if(attrs.contains(BASE_MIRROR_ENTRY_DST_INTF) ||
               attrs.contains(BASE_MIRROR_ENTRY_LAG_OPAQUE_DATA)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple Destination Interface Index passed "
                        "for creating/updating Mirroring session");
                return false;
            }

            entry->set_dst_intf(cps_api_object_attr_data_u32(it.attr));
            interface_ctrl_t intf_ctrl;
            if(!nas_mirror_intf_to_port(entry->get_dst_intf(),&intf_ctrl)){
                return false;
            }

            entry->set_dst_port(intf_ctrl.npu_id,intf_ctrl.port_id);
            attrs.add(BASE_MIRROR_ENTRY_DST_INTF);
            break;

        case BASE_MIRROR_ENTRY_LAG_OPAQUE_DATA :
            if(attrs.contains(BASE_MIRROR_ENTRY_LAG_OPAQUE_DATA) ||
               attrs.contains(BASE_MIRROR_ENTRY_DST_INTF)){
                NAS_MIRROR_LOG(ERR,0,"Multiple Destination Lag opaque data "
                               "passed for creating/updating Mirroring session");
                return false;
            }

            {
                nas::ndi_obj_id_table_t lag_opaque_data_table;
                cps_api_attr_id_t  attr_id_list[] = {BASE_MIRROR_ENTRY_LAG_OPAQUE_DATA};
                if(!nas::ndi_obj_id_table_cps_unserialize (lag_opaque_data_table, obj,attr_id_list,
                                                           sizeof(attr_id_list)/
                                                           sizeof(attr_id_list[0]))){
                    NAS_MIRROR_LOG(ERR,0,"Failed to unserialize lag opaque data");
                    return false;
                }

                auto lag_opaue_it = lag_opaque_data_table.begin();
                if(lag_opaue_it == lag_opaque_data_table.end()){
                    NAS_MIRROR_LOG(ERR,0,"No lag opaque data passed");
                    return false;
                }

                entry->set_ndi_lag_id(lag_opaue_it->first,lag_opaue_it->second);
            }
            attrs.add(BASE_MIRROR_ENTRY_LAG_OPAQUE_DATA);
            break;

        case BASE_MIRROR_ENTRY_INTF:
            if(!update) attrs.add(BASE_MIRROR_ENTRY_INTF);
            if(!get_src_intf_attr(obj, new_intf_map , it)) return false;
            break;

        case BASE_MIRROR_ENTRY_FLOW_ENABLED :
            entry->set_flow(cps_api_object_attr_data_u32(it.attr));
            break;

        case BASE_MIRROR_ENTRY_TYPE:
            if(attrs.contains(BASE_MIRROR_ENTRY_TYPE)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple Mirror types passed "
                        "for creating Mirroring session");
                return false;
            }
            entry->set_mode((BASE_MIRROR_MODE_t)cps_api_object_attr_data_u32(it.attr));
            attrs.add(BASE_MIRROR_ENTRY_TYPE);
            break;
        }
    }

    if(update){
        if(!nas_mirror_update_attrs(entry,attrs)) return false;
        if(new_intf_map.size() > 0){
            if(!entry->update_src_intf_map(new_intf_map)) return false;
        }
    }
    else{
        if(!nas_mirror_validate_attr(attrs)) return false;
    }

    if(entry->get_mode() == BASE_MIRROR_MODE_RSPAN ){
        if(!nas_mirror_fill_rspan_attr(obj,entry,update)){
            return false;
        }
    }

    if(entry->get_mode() == BASE_MIRROR_MODE_ERSPAN){
       if(!nas_mirror_fill_erspan_attr(obj,entry,update)){
           return false;
       }
    }

    return true;
}
static bool nas_mirror_fill_erspan_attr(cps_api_object_t obj, nas_mirror_entry *entry, bool update){

    nas::attr_set_t attrs;
    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) ) {

        int id = (int) cps_api_object_attr_id(it.attr);
        switch (id) {

        case BASE_MIRROR_ENTRY_ERSPAN_VLAN_ID:
            if(attrs.contains(BASE_MIRROR_ENTRY_ERSPAN_VLAN_ID)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple VLAN Ids passed for creating ERSPAN Mirroring session");
                   return false;
            }
            entry->set_vlan(cps_api_object_attr_data_u32(it.attr));
            attrs.add(BASE_MIRROR_ENTRY_ERSPAN_VLAN_ID);
            break;

        case BASE_MIRROR_ENTRY_DESTINATION_IP:
            if( attrs.contains(BASE_MIRROR_ENTRY_DESTINATION_IP)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple Dst IP Address passed for creating ERSPAN Mirroring session");
                return false;
            }
            entry->set_dst_ip(cps_api_object_attr_data_u32(it.attr));
            attrs.add(BASE_MIRROR_ENTRY_DESTINATION_IP);
            break;

        case BASE_MIRROR_ENTRY_SOURCE_IP:
            if( attrs.contains(BASE_MIRROR_ENTRY_SOURCE_IP)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple Source IP Address passed for creating ERSPAN Mirroring session");
                return false;
            }
            entry->set_src_ip(cps_api_object_attr_data_u32(it.attr));
            attrs.add(BASE_MIRROR_ENTRY_SOURCE_IP);
            break;


        case BASE_MIRROR_ENTRY_DEST_MAC:
            if( attrs.contains(BASE_MIRROR_ENTRY_DEST_MAC)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple Dst MAC Address passed for creating ERSPAN Mirroring session");
                return false;
            }

            entry->set_dst_mac(cps_api_object_attr_data_bin(it.attr));
            attrs.add(BASE_MIRROR_ENTRY_DEST_MAC);
            break;

        case BASE_MIRROR_ENTRY_SOURCE_MAC:
            if( attrs.contains(BASE_MIRROR_ENTRY_SOURCE_MAC)){
                NAS_MIRROR_LOG(ERR,ev_log_s_MINOR,"Multiple Source MAC Address passed for creating ERSPAN Mirroring session");
                return false;
            }
            entry->set_src_mac(cps_api_object_attr_data_bin(it.attr));
            attrs.add(BASE_MIRROR_ENTRY_SOURCE_MAC);
            break;
        }
    }

    if(update){
        return nas_mirror_update_attrs(entry,attrs);
    }
    return nas_mirror_validate_erspan_attr(attrs);
}
/**
  * 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;
}
/**
  * This function provides NAS-QoS priority_group stats CPS API clear function
  * To clear the priority_group stats, set relevant counters to zero
  * @Param    Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_priority_group_stat_clear (void * context,
                                            cps_api_transaction_params_t * param,
                                            size_t ix)
{
    cps_api_object_t obj = cps_api_object_list_get(param->change_list,ix);
    cps_api_operation_types_t op = cps_api_object_type_operation(cps_api_object_key(obj));

    if (op != cps_api_oper_SET)
        return NAS_QOS_E_UNSUPPORTED;

    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;
    }

    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_WATERMARK_BYTES:
            counter_ids.push_back((BASE_QOS_PRIORITY_GROUP_STAT_t)id);
            break;

        case BASE_QOS_PRIORITY_GROUP_STAT_CURRENT_OCCUPANCY_BYTES:
            // READ-only
            break;

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

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


    return  cps_api_ret_code_OK;

}