Пример #1
0
static bool get_src_intf_attr(cps_api_object_t obj, nas_mirror_src_intf_map_t & intf_map,
                              const cps_api_object_it_t & it){

    cps_api_object_it_t it_lvl_1 = it;
    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 (cps_api_object_it_inside (&it_lvl_1); cps_api_object_it_valid (&it_lvl_1);
         cps_api_object_it_next (&it_lvl_1)) {

        ids[1] = cps_api_object_attr_id (it_lvl_1.attr);
        ids[2]=BASE_MIRROR_ENTRY_INTF_SRC;
        cps_api_object_attr_t src_intf = cps_api_object_e_get(obj,ids,ids_len);
        ids[2]=BASE_MIRROR_ENTRY_INTF_DIRECTION;
        cps_api_object_attr_t direction = cps_api_object_e_get(obj,ids,ids_len);

        if(src_intf == NULL){
            NAS_MIRROR_LOG(ERR,0,"Source Interface Index not passed for creating/updating a session");
            return false;
        }

        if(direction == NULL){
           NAS_MIRROR_LOG(ERR,0,"Mirroring Direction not passed for creating/updating a session");
           return false;
        }
        hal_ifindex_t ifindex = cps_api_object_attr_data_u32(src_intf);
        BASE_CMN_TRAFFIC_PATH_t dir = (BASE_CMN_TRAFFIC_PATH_t)cps_api_object_attr_data_u32(direction);
        if(intf_map.find(ifindex) == intf_map.end()){
            intf_map[ifindex] = dir;
        }
    }

    return true;
}
static t_std_error _phy_media_type_with_default_config_set(npu_id_t npu, port_t port,
                                        PLATFORM_MEDIA_TYPE_t media_type)
{
    t_std_error rc;
    if ((rc = ndi_port_media_type_set(npu, port, media_type)) != STD_ERR_OK) {
        return rc;
    }
    /*  set default speed and autoneg setting  corresponding to the media type */
    cps_api_object_t obj = cps_api_object_create();
    cps_api_object_guard og(obj);
    if ((rc = dn_nas_get_phy_media_default_setting(media_type, obj)) != STD_ERR_OK) {
        return rc;
    }

    /* First set AN and then speed */
    cps_api_object_attr_t autoneg_attr = cps_api_object_attr_get(obj, BASE_MEDIA_MEDIA_INFO_AUTONEG);
    if (autoneg_attr != nullptr) {
        bool autoneg = (bool)cps_api_object_attr_data_u32(autoneg_attr);
        if (ndi_port_auto_neg_set(npu,port,autoneg)!=STD_ERR_OK) {
            EV_LOG(ERR,INTERFACE,0,"NAS-IF-REG","Failed to set autoneg %d for "
                   "npu %d port %d return Error 0x%x",autoneg,npu,port,rc);
            return STD_ERR(INTERFACE,FAIL,0);
        }
    }

    BASE_IF_PHY_BREAKOUT_MODE_t cur_mode;
    if ((rc = ndi_port_breakout_mode_get(npu, port, &cur_mode)) != STD_ERR_OK) {
            EV_LOG(ERR,INTERFACE,0,"NAS-IF-REG","Failed to get breakout mode for "
                   "npu %d port %d return error 0x%x",npu,port, rc);
            return STD_ERR(INTERFACE,FAIL,0);
    }
    /* if the port is fanout skip setting the default speed say 40G */
    if (BASE_IF_PHY_BREAKOUT_MODE_BREAKOUT_1X1 == cur_mode) {
        cps_api_object_attr_t speed_attr = cps_api_object_attr_get(obj, BASE_MEDIA_MEDIA_INFO_SPEED);
        if (speed_attr != nullptr) {
            BASE_IF_SPEED_t speed = (BASE_IF_SPEED_t)cps_api_object_attr_data_u32(speed_attr);
            if ((rc = ndi_port_speed_set(npu,port,speed))!=STD_ERR_OK) {
                EV_LOG(ERR,INTERFACE,0,"NAS-IF-REG","Failed to set speed %d for "
                       "npu %d port %d return error 0x%x",speed,npu,port, rc);
                return STD_ERR(INTERFACE,FAIL,0);
            }
        }
    }
    cps_api_object_attr_t duplex_attr = cps_api_object_attr_get(obj, BASE_MEDIA_MEDIA_INFO_DUPLEX);
    if (duplex_attr != nullptr) {
        BASE_CMN_DUPLEX_TYPE_t duplex = (BASE_CMN_DUPLEX_TYPE_t)cps_api_object_attr_data_u32(duplex_attr);
        if ((rc = ndi_port_duplex_set(npu,port,duplex))!=STD_ERR_OK) {
            EV_LOG(ERR,INTERFACE,0,"NAS-IF-REG","Failed to set duplex %d for "
                   "npu %d port %d return error 0x%x",duplex,npu,port, rc);
            return STD_ERR(INTERFACE,FAIL,0);
        }
    }
    return STD_ERR_OK;
}
Пример #3
0
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;
        }
    }
}
/* 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;
}
Пример #5
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);
}
Пример #6
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);
}
Пример #7
0
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;
        }
    }
}
/**
  * This function provides NAS-QoS priority_group CPS API read function
  * @Param      Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_priority_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 port_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_PORT_ID);
    cps_api_object_attr_t local_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_LOCAL_ID);

    uint_t switch_id = 0;

    if (port_id_attr == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Port Id must be specified\n");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint_t port_id = cps_api_object_attr_data_u32(port_id_attr);

    bool local_id_specified = false;
    uint8_t local_id;
    if (local_id_attr) {
        local_id = *(uint8_t *)cps_api_object_attr_data_bin(local_id_attr);
        local_id_specified = true;
    }

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Read switch id %u, port_id id %u\n",
                    switch_id, port_id);

    std_mutex_simple_lock_guard p_m(&priority_group_mutex);

    // If the port priority group is not initialized yet, initialize it in NAS
    nas_qos_port_priority_group_init(port_id);

    return nas_qos_cps_get_priority_group_info(param, switch_id, port_id,
                                            local_id_specified, local_id);
}
Пример #9
0
extern "C" t_std_error nas_os_get_interface(cps_api_object_t filter,cps_api_object_list_t result) {
    cps_api_object_attr_t ifix = cps_api_object_attr_get(filter, DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_IF_INDEX);
    hal_ifindex_t ifindex = 0;
    if (ifix!=NULL) {
        ifindex = cps_api_object_attr_data_u32(ifix);
    }
    _get_interfaces(result,ifindex, ifix==NULL);
    return STD_ERR_OK;
}
Пример #10
0
static cps_api_return_code_t cps_nas_switch_log_set_function(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_ACTION) {
        EV_LOG(ERR,SYSTEM,0,"NAS-DIAG","Invalid operation %d for setting switch log",op);
        return cps_api_ret_code_ERR;
    }

    BASE_SWITCH_SUBSYSTEM_t switch_system_id;
    cps_api_object_attr_t switch_system_id_attr;

    if ((switch_system_id_attr = cps_api_get_key_data(obj,BASE_SWITCH_SET_LOG_INPUT_SUBSYSTEM_ID)) == NULL) {
        EV_LOG(ERR,SYSTEM,0,"NAS-DIAG","No Module id passed for Updating sai log level");
        return cps_api_ret_code_ERR;
    }

    switch_system_id = (BASE_SWITCH_SUBSYSTEM_t) cps_api_object_attr_data_u32(switch_system_id_attr);
    cps_api_attr_id_t log_level_attr_id = BASE_SWITCH_SET_LOG_INPUT_LEVEL;
    cps_api_object_attr_t log_level_attr = cps_api_object_e_get (obj, &log_level_attr_id, 1);

    if(log_level_attr == NULL){
        EV_LOG(ERR,SYSTEM,0,"NAS-DIAG","No log level passed for Updating sai log level"
                            "for module %d",switch_system_id);
        return cps_api_ret_code_ERR;
    }

    BASE_SWITCH_LOG_LEVEL_t log_level = (BASE_SWITCH_LOG_LEVEL_t)
                                        cps_api_object_attr_data_u32(log_level_attr);
    t_std_error rc;
    if( (rc =ndi_switch_set_sai_log_level(switch_system_id,log_level)) != STD_ERR_OK ){
        EV_LOG(ERR,SYSTEM,0,"NAS-DIAG","Failed to set log_level to %d for sai module %d "
                "got the return code %d ",log_level,switch_system_id,rc);
        return cps_api_ret_code_ERR;
    }

    return cps_api_ret_code_OK;
}
static cps_api_return_code_t _phy_int_get (void * context, cps_api_get_params_t * param,
        size_t key_ix) {

    cps_api_object_t filt = cps_api_object_list_get(param->filters,key_ix);

    npu_id_t npu = 0;
    npu_id_t npu_max = (npu_id_t)nas_switch_get_max_npus();

    cps_api_object_attr_t _npu = cps_api_get_key_data(filt,BASE_IF_PHY_PHYSICAL_NPU_ID);
    cps_api_object_attr_t _port = cps_api_get_key_data(filt,BASE_IF_PHY_PHYSICAL_PORT_ID);
    cps_api_object_attr_t _hw_port = cps_api_get_key_data(filt,BASE_IF_PHY_PHYSICAL_HARDWARE_PORT_ID);

    for ( npu = 0; npu<  npu_max ; ++npu){
        if (_npu!=NULL && cps_api_object_attr_data_u32(_npu)!=(uint32_t)npu) continue;

        unsigned int intf_max_ports = ndi_max_npu_port_get(npu);
        for (port_t port = 0; port < intf_max_ports ; ++port ) {
            if (_port!=NULL && cps_api_object_attr_data_u32(_port)!=port) continue;

            if (_hw_port!=NULL) {
                uint32_t hwport;
                if (get_hw_port(npu,port,hwport)) {
                    if (cps_api_object_attr_data_u32(_hw_port)!=hwport) continue;
                }
            }

            // skip invalid port or cpu port
            if (!ndi_port_is_valid(npu, port) || _is_cpu_port(npu, port)) {
                continue;
            }

            cps_api_object_t o = cps_api_object_list_create_obj_and_append(param->list);
            if (o==NULL) return cps_api_ret_code_ERR;

            make_phy_port_details(npu,port,o);
        }
    }
    return cps_api_ret_code_OK;
}
Пример #12
0
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;
    }
}
Пример #13
0
static cps_api_return_code_t ds_set_interface (cps_api_object_list_t list,
        cps_api_object_t elem) {

    uint_t ifix = cps_api_key_element_at(cps_api_object_key(elem),
            CPS_API_INT_IF_OBJ_KEY_IFIX);

    char if_name[HAL_IF_NAME_SZ+1];
    if (cps_api_interface_if_index_to_name(ifix,if_name,
            sizeof(if_name))==NULL) {
        return cps_api_ret_code_ERR;
    }

    cps_api_object_attr_t mtu = cps_api_object_attr_get(elem,cps_api_if_STRUCT_A_MTU);
    cps_api_object_attr_t astate = cps_api_object_attr_get(elem,cps_api_if_STRUCT_A_ADMIN_STATE);
    cps_api_object_attr_t ostate = cps_api_object_attr_get(elem,cps_api_if_STRUCT_A_OPER_STATE);
    cps_api_object_attr_t mac = cps_api_object_attr_get(elem,cps_api_if_STRUCT_A_IF_MACADDR);

    if (mtu!=CPS_API_ATTR_NULL) {
        if (nas_os_util_int_mtu_set(if_name,cps_api_object_attr_data_u32(mtu))!=STD_ERR_OK)
            return cps_api_ret_code_ERR;
    }

    if (astate!=CPS_API_ATTR_NULL && ostate!=CPS_API_ATTR_NULL) {
        if (nas_os_util_int_admin_state_set(if_name,
                cps_api_object_attr_data_u32(astate),
                cps_api_object_attr_data_u32(ostate))!=STD_ERR_OK) return cps_api_ret_code_ERR;
    }
    if (mac!=CPS_API_ATTR_NULL) {
        hal_mac_addr_t mac_addr;
        void * data = cps_api_object_attr_data_bin(mac);
        memcpy(mac_addr,data,sizeof(mac_addr));
        if (nas_os_util_int_mac_addr_set(if_name,
                &mac_addr)!=STD_ERR_OK) return cps_api_ret_code_ERR;
    }
    return cps_api_ret_code_OK;
}
Пример #14
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;
}
bool nas::ndi_obj_id_table_cps_unserialize (ndi_obj_id_table_t&  table,
                                            cps_api_object_t cps_obj,
                                            cps_api_attr_id_t *attr_id_list,
                                            size_t attr_id_size)
{
    cps_api_object_it_t it_list;

    if (!cps_api_object_it(cps_obj, attr_id_list, attr_id_size, &it_list)) {
        // Opaque data not found
        NAS_COM_ERR ("Could not find opaque attribute \n");
        return false;
    }

    int inst = 0;
    nas::ndi_obj_id_table_t  temp_table;

    for (cps_api_object_it_inside (&it_list); cps_api_object_it_valid(&it_list);
         cps_api_object_it_next (&it_list), inst++) {

        npu_id_t npu_id = 0;
        ndi_obj_id_t ndi_obj_id = 0;

        NAS_COM_TRACE (3, "Unserializing entry %d\n", inst+1);

        cps_api_object_it_t it_map_entry = it_list;

        for (cps_api_object_it_inside (&it_map_entry); cps_api_object_it_valid (&it_map_entry);
             cps_api_object_it_next (&it_map_entry)) {

            switch (cps_api_object_attr_id (it_map_entry.attr)) {
                case OPAQUE_NPU_ATTR_ID:
                    npu_id = cps_api_object_attr_data_u32 (it_map_entry.attr);
                    NAS_COM_TRACE (3, "NPU ID %d\n", npu_id);
                    break;
                case OPAQUE_NDI_OBJ_ATTR_ID:
                    ndi_obj_id = cps_api_object_attr_data_u64 (it_map_entry.attr);
                    NAS_COM_TRACE (3, "NDI Obj ID 0x%lx\n", ndi_obj_id);
                    break;
            }
        }
        temp_table[npu_id] = ndi_obj_id;
    }

    table = std::move (temp_table);
    return true;
}
Пример #16
0
static bool nas_mirror_fill_rspan_attr(cps_api_object_t obj, nas_mirror_entry * entry, bool update){

    nas::attr_set_t attrs;

    cps_api_object_attr_t vlan_attr;
    cps_api_attr_id_t vlan_attr_id = BASE_MIRROR_ENTRY_VLAN;

    vlan_attr = cps_api_object_e_get (obj, &vlan_attr_id, 1);
    if(!update && vlan_attr == NULL){
        NAS_MIRROR_LOG(ERR,0,"No VLAN Id Passed for creating rspan mirror session");
        return false;
    }

    if(vlan_attr != NULL){
        attrs.add(BASE_MIRROR_ENTRY_VLAN);
        entry->set_vlan(cps_api_object_attr_data_u32(vlan_attr));

        if(update){
           return nas_mirror_update_attrs(entry,attrs);
        }
    }

    return true;
}
Пример #17
0
void nas_acl_set_action_list (const cps_api_object_t     obj,
                              const cps_api_object_it_t& it,
                              nas_acl_entry&             entry)
{
    /*
     * Encoding of ACL Entry Action parameters, with the following
     * sample action parameters:
     *   1. Ingress Mirroring
     *   2. Redirect Port
     *   3. Forward
     *
     * ------------------------------------------------------------------------
     * | Type : BASE_ACL_ENTRY_ACTION  (ACTION-List-Attr)                     |
     * | Len  : Length of Val                                                 |
     * | Val  ----------------------------------------------------------------|
     * |      | Type : 'list_index' = 0                                       |
     * |      | Len  : Length of Val                                          |
     * |      | Val  ---------------------------------------------------------|
     * |      |      | Type : BASE_ACL_ENTRY_ACTION_TYPE                      |
     * |      |      | Len  : Length of Val                                   |
     * |      |      | Val  : BASE_ACL_ACTION_TYPE_SET_POLICER     <--        |
     * |      |      |                                               |        |
     * |      |      |                                  --------------------  |
     * |      |      |                                  |'action_type_val' |  |
     * |      |      |                                  --------------------  |
     * |      |      |--------------------------------------------------------|
     * |      |      | Type : BASE_ACL_ENTRY_ACTION_POLICER_VALUE  <--        |
     * |      |      |                                               |        |
     * |      |      |                             -------------------------- |
     * |      |      |                             |'action_map.val.attr_id'| |
     * |      |      |                             -------------------------- |
     * |      |      | Len  : Length of Val                                   |
     * |      |      | Val  --------------------------------------------------|
     * |      |      |      | Type : BASE_ACL_ENTRY_ACTION_POLICER_VALUE_INDEX|
     * |      |      |      | Len  : Length of Val                            |
     * |      |      |      | Val  : <mirror-id>                              |
     * |      |      |      |                                                 |
     * |      |      |      | Type : BASE_ACL_ENTRY_ACTION_POLICER_VALUE_DATA |
     * |      |      |      | Len  : Length of Val                            |
     * |      |      |      | Val  : <mirror-blob-data>                       |
     * |      |      |      --------------------------------------------------|
     * |      |      |                                                        |
     * |      |      ---------------------------------------------------------|
     * |      |                                                               |
     * |      ----------------------------------------------------------------|
     * |      | Type : 'list_index' = 1                                       |
     * |      | Len  : Length of Val                                          |
     * |      | Val  ---------------------------------------------------------|
     * |      |      | Type : BASE_ACL_ENTRY_ACTION_TYPE                      |
     * |      |      | Len  : Length of Val                                   |
     * |      |      | Val  : BASE_ACL_ACTION_TYPE_FORWARD   <----            |
     * |      |      |                                           |            |
     * |      |      |                                  -------------------   |
     * |      |      |                                 |'action_type_val' |   |
     * |      |      |                                  -------------------   |
     * |      |      |     NOTE: There is no further data for this action.    |
     * |      |      ---------------------------------------------------------|
     * |      |                                                               |
     * |      ----------------------------------------------------------------|
     * |      |                                                               |
     * |      |                           ...                                 |
     * |      |                                                               |
     * |      ----------------------------------------------------------------|
     * |      | Type : 'list_index' = N                                       |
     * |      | Len  : Length of Val                                          |
     * |      | Val  ---------------------------------------------------------|
     * |      |      | Type : BASE_ACL_ENTRY_ACTION_TYPE                      |
     * |      |      | Len  : Length of Val                                   |
     * |      |      | Val  : BASE_ACL_ACTION_TYPE_REDIRECT_PORT      <--     |
     * |      |      |                                                  |     |
     * |      |      |                                 --------------------   |
     * |      |      |                                 |'action_type_val' |   |
     * |      |      |                                 --------------------   |
     * |      |      |--------------------------------------------------------|
     * |      |      | Type : BASE_ACL_ENTRY_ACTION_REDIRECT_PORT_VALUE       |
     * |      |      |                                              ^         |
     * |      |      |                                              |         |
     * |      |      |                             -------------------------- |
     * |      |      |                             |'action_map.val.attr_id'| |
     * |      |      |                             -------------------------- |
     * |      |      | Len  : Length of Val                                   |
     * |      |      | Val  : <if-index>                                      |
     * |      |      ---------------------------------------------------------|
     * |      |                                                               |
     * |      ----------------------------------------------------------------|
     * |                                                                      |
     * ------------------------------------------------------------------------
     */

    BASE_ACL_ACTION_TYPE_t     action_type_val;
    cps_api_object_it_t        it_action_list = it;
    cps_api_attr_id_t          list_index = 0;
    nas::attr_list_t           parent_attr_id_list;
    nas_acl_common_data_list_t common_data_list;

    // Parent attr list to build attr hierarchy
    //  - ACTION-List-Attr . Action-ListIndex . Action-Value-Attr . Action-Value-Child-Attr
    parent_attr_id_list.reserve(NAS_ACL_MAX_ATTR_DEPTH);

    //  Of this the following hierarchy is filled in this function
    //  - ACTION-List-Attr . Action-ListIndex

    for (cps_api_object_it_inside (&it_action_list);
         cps_api_object_it_valid (&it_action_list);
         cps_api_object_it_next (&it_action_list)) {

        parent_attr_id_list.clear ();
        parent_attr_id_list.push_back (BASE_ACL_ENTRY_ACTION);

        list_index = cps_api_object_attr_id (it_action_list.attr);

        parent_attr_id_list.push_back (list_index);

        cps_api_object_it_t it_action_attr = it_action_list;
        cps_api_object_it_inside (&it_action_attr);
        if (!cps_api_object_it_valid (&it_action_attr)) {
            throw nas::base_exception {NAS_ACL_E_MISSING_ATTR, __PRETTY_FUNCTION__,
                                       "Missing list container for ACTION in object"};
        }

        bool is_dupl;
        auto attr_action_type = nas_acl_get_attr (it_action_attr,
                                                 BASE_ACL_ENTRY_ACTION_TYPE, &is_dupl);

        if (attr_action_type == NULL) {
            throw nas::base_exception {NAS_ACL_E_MISSING_ATTR, __PRETTY_FUNCTION__,
                                       "Missing ACTION_TYPE attribute"};
        }
        if (is_dupl) {
            throw nas::base_exception {NAS_ACL_E_DUPLICATE, __PRETTY_FUNCTION__,
                                       "Duplicate ACTION_TYPE attribute"};
        }

        action_type_val = (BASE_ACL_ACTION_TYPE_t)
            cps_api_object_attr_data_u32 (attr_action_type);

        NAS_ACL_LOG_DETAIL ("action_type_val: %d (%s)", action_type_val,
                            nas_acl_action_t::type_name (action_type_val));

        nas_acl_set_action_attr (obj, entry, action_type_val,
                                 parent_attr_id_list, true);
    }
}
static cps_api_return_code_t _phy_set(cps_api_object_t req, cps_api_object_t prev) {
    STD_ASSERT(prev!=nullptr && req!=nullptr);

    cps_api_object_attr_t _npu = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_NPU_ID);
    cps_api_object_attr_t _port = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_PORT_ID);

    if (_npu==nullptr || _port==nullptr) {
        EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Set req missing key instances");
        return cps_api_ret_code_ERR;
    }

    npu_id_t npu = cps_api_object_attr_data_u32(_npu);
    port_t port = cps_api_object_attr_data_u32(_port);

    if (_is_cpu_port(npu, port)) {
        EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Can't modify the CPU port %d:%d",npu,port);
        return cps_api_ret_code_ERR;
    }

    uint32_t hwport;
    if (!get_hw_port(npu,port,hwport)) {
        return cps_api_ret_code_ERR;
    }

    cps_api_object_attr_t _fp = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_FRONT_PANEL_NUMBER);
    cps_api_object_attr_t _media_type = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_PHY_MEDIA);
    cps_api_object_attr_t _loopback = cps_api_get_key_data(req,BASE_IF_PHY_PHYSICAL_LOOPBACK);

    auto it = _phy_port.find(hwport);
    if (it == _phy_port.end()) {
        _phy_port[hwport].front_panel_port = 0;
        _phy_port[hwport].sub_port = 0;
        _phy_port[hwport].media_type = 0;
        _phy_port[hwport].loopback = 0;
    }

    if (_fp!=nullptr) {
        _phy_port[hwport].front_panel_port = cps_api_object_attr_data_u32(_fp);
    }

    if (_media_type != nullptr) {
        PLATFORM_MEDIA_TYPE_t media_type = (PLATFORM_MEDIA_TYPE_t) cps_api_object_attr_data_u32(_media_type);
        if (_phy_port[hwport].media_type != media_type) {
            if (_phy_media_type_with_default_config_set(npu, port, media_type) != STD_ERR_OK)  {
                EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Failed to set phy media type for %d:%d",npu,port);
                return cps_api_ret_code_ERR;
            }
            _phy_port[hwport].media_type = media_type;
        }
    }

    if (_loopback != nullptr) {
        if (ndi_port_loopback_set(npu, port,
                    (BASE_CMN_LOOPBACK_TYPE_t) cps_api_object_attr_data_u32(_loopback)) != STD_ERR_OK)  {
            EV_LOG(ERR,INTERFACE,0,"NAS-PHY","Failed to set loopback for %d:%d",npu,port);
            return cps_api_ret_code_ERR;
        }
        _phy_port[hwport].loopback = cps_api_object_attr_data_u32(_loopback);
    }
    cps_api_key_set(cps_api_object_key(req),CPS_OBJ_KEY_INST_POS,cps_api_qualifier_OBSERVED);
    hal_interface_send_event(req);
    cps_api_key_set(cps_api_object_key(req),CPS_OBJ_KEY_INST_POS,cps_api_qualifier_TARGET);

    return cps_api_ret_code_OK;
}
Пример #19
0
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;
}
Пример #20
0
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);
}
Пример #21
0
static cps_api_return_code_t _op(cps_api_operation_types_t op,void * context, cps_api_object_t obj, cps_api_object_t prev) {

    char buff[1024];
    memset(buff,0,sizeof(buff));
    cps_api_object_attr_t list[cps_api_if_ROUTE_A_MAX];
    cps_api_object_attr_fill_list(obj,0,list,sizeof(list)/sizeof(*list));

    if (list[cps_api_if_ROUTE_A_PREFIX]==NULL) return cps_api_ret_code_ERR;
    if (list[cps_api_if_ROUTE_A_PREFIX_LEN]==NULL) return cps_api_ret_code_ERR;
    if (list[cps_api_if_ROUTE_A_FAMILY]==NULL) return cps_api_ret_code_ERR;

    uint32_t prefix_len =  cps_api_object_attr_data_u32(list[cps_api_if_ROUTE_A_PREFIX_LEN]);

    struct nlmsghdr *nlh = (struct nlmsghdr *) nlmsg_reserve((struct nlmsghdr *)buff,sizeof(buff),sizeof(struct nlmsghdr));
    struct rtmsg * rm = (struct rtmsg *) nlmsg_reserve(nlh,sizeof(buff),sizeof(struct rtmsg));

    //sizeof structure + attrs nlh->nlmsg_len
    nlh->nlmsg_pid = 0;
    nlh->nlmsg_seq = 0;
    nlh->nlmsg_type =RTM_NEWROUTE;
    nlh->nlmsg_flags =  NLM_F_REQUEST | NLM_F_ACK ;

    if (op==cps_api_oper_CREATE) {
        nlh->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
    }
    if (op==cps_api_oper_SET) {
        nlh->nlmsg_flags |=NLM_F_REPLACE;
    }
    if (op==cps_api_oper_DELETE) {
        nlh->nlmsg_type =RTM_DELROUTE;
    }

    rm->rtm_table = RT_TABLE_MAIN;
    rm->rtm_protocol = RTPROT_BOOT;
    rm->rtm_dst_len = prefix_len;
    rm->rtm_scope = RT_SCOPE_UNIVERSE;
    rm->rtm_type = RTN_UNICAST;

    rm->rtm_family = (unsigned char) cps_api_object_attr_data_u32(list[cps_api_if_ROUTE_A_FAMILY]);

    EV_LOG(INFO,NETLINK,3,"ROUTEADD","Family is %d",rm->rtm_family);

    if (list[cps_api_if_ROUTE_A_PREFIX]!=NULL) nas_nl_add_attr_ip(nlh,sizeof(buff),RTA_DST,list[cps_api_if_ROUTE_A_PREFIX]);

    if (list[cps_api_if_ROUTE_A_HOP_COUNT]==NULL) return cps_api_ret_code_ERR;
    uint32_t hc =  cps_api_object_attr_data_u32(list[cps_api_if_ROUTE_A_HOP_COUNT]);
    EV_LOG(INFO,NETLINK,3,"ROUTEADD","hopcount is %d",hc);

    if (hc==1) {
        cps_api_attr_id_t ids[3] = { cps_api_if_ROUTE_A_NH, 0, cps_api_if_ROUTE_A_NEXT_HOP_ADDR};
        const int ids_len = sizeof(ids)/sizeof(*ids);
        cps_api_object_attr_t gw = cps_api_object_e_get(obj,ids,ids_len);

        EV_LOG(INFO,NETLINK,3,"ROUTEADD","nh addr is %d",(int)(size_t)gw);
        if (gw!=NULL) nas_nl_add_attr_ip(nlh,sizeof(buff),RTA_GATEWAY,gw);

        ids[2] = cps_api_if_ROUTE_A_NH_IFINDEX;
        cps_api_object_attr_t gwix = cps_api_object_e_get(obj,ids,ids_len);
        EV_LOG(INFO,NETLINK,3,"ROUTEADD","nh index is %d",(int)(size_t)gwix);
        if (gwix!=NULL) nas_nl_add_attr_int(nlh,sizeof(buff),RTA_OIF,gwix);

        ids[2] = cps_api_if_ROUTE_A_NEXT_HOP_WEIGHT;
        cps_api_object_attr_t weight = cps_api_object_e_get(obj,ids,ids_len);
        if (weight!=NULL) nas_nl_add_attr_int(nlh,sizeof(buff),RTA_PRIORITY,weight);

    } else {
        struct nlattr * attr_nh = nlmsg_nested_start(nlh, sizeof(buff));

        attr_nh->nla_len = 0;
        attr_nh->nla_type = RTA_MULTIPATH;
        size_t ix = 0;
        for (ix = 0; ix < hc ; ++ix) {
            struct rtnexthop * rtnh = (struct rtnexthop * )nlmsg_reserve(nlh,sizeof(buff), sizeof(struct rtnexthop));
            memset(rtnh,0,sizeof(*rtnh));

            cps_api_attr_id_t ids[3] = { cps_api_if_ROUTE_A_NH, ix, cps_api_if_ROUTE_A_NEXT_HOP_ADDR};
            const int ids_len = sizeof(ids)/sizeof(*ids);
            cps_api_object_attr_t attr = cps_api_object_e_get(obj,ids,ids_len);
            if (attr!=NULL) nas_nl_add_attr_ip(nlh,sizeof(buff),RTA_GATEWAY,attr);

            ids[2] = cps_api_if_ROUTE_A_NH_IFINDEX;
            attr = cps_api_object_e_get(obj,ids,ids_len);
            if (attr!=NULL) rtnh->rtnh_ifindex = (int)cps_api_object_attr_data_u32(attr);

            ids[2] = cps_api_if_ROUTE_A_NEXT_HOP_WEIGHT;
            attr = cps_api_object_e_get(obj,ids,ids_len);
            if (attr!=NULL) rtnh->rtnh_hops = (char)cps_api_object_attr_data_u32(attr);

            ids[2] = cps_api_if_ROUTE_A_NEXT_HOP_FLAGS;
            attr = cps_api_object_e_get(obj,ids,ids_len);
            if (attr!=NULL) rtnh->rtnh_flags = (char)cps_api_object_attr_data_u32(attr);


            rtnh->rtnh_len = (char*)nlmsg_tail(nlh) - (char*)rtnh;
        }
        nlmsg_nested_end(nlh,attr_nh);
    }
    return (cps_api_return_code_t) nl_do_set_request(nas_nl_sock_T_ROUTE,nlh,buff,sizeof(buff));
}
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;
}
/**
  * 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;
}
Пример #24
0
cps_api_return_code_t nas_os_update_neighbor(cps_api_object_t obj, msg_type m_type)
{
    static char buff[NL_RT_MSG_BUFFER_LEN];
    hal_mac_addr_t mac_addr;
    char            addr_str[INET6_ADDRSTRLEN];
    memset(buff,0,sizeof(buff));
    memset(mac_addr, 0, sizeof(mac_addr));

    cps_api_object_attr_t ip  = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_ADDRESS);
    cps_api_object_attr_t af  = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_AF);
    cps_api_object_attr_t mac = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_MAC_ADDR);
    cps_api_object_attr_t if_index = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_IFINDEX);
    cps_api_object_attr_t nbr_type = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_NBR_TYPE);

    if (ip == CPS_API_ATTR_NULL || af == CPS_API_ATTR_NULL || if_index == CPS_API_ATTR_NULL
        || (m_type != NAS_RT_DEL && mac == CPS_API_ATTR_NULL)) {
        EV_LOG(ERR, NAS_OS, ev_log_s_CRITICAL, "NEIGH-UPD", "Missing neighbor params");
        return cps_api_ret_code_ERR;
    }

    struct nlmsghdr *nlh = (struct nlmsghdr *)
                         nlmsg_reserve((struct nlmsghdr *)buff,sizeof(buff),sizeof(struct nlmsghdr));
    struct ndmsg * ndm = (struct ndmsg *) nlmsg_reserve(nlh,sizeof(buff),sizeof(struct ndmsg));


    ndm->ndm_ifindex = cps_api_object_attr_data_u32(if_index);
    ndm->ndm_family = (unsigned char) cps_api_object_attr_data_u32(af);
    if (nbr_type != CPS_API_ATTR_NULL) {
        if (((unsigned char) cps_api_object_attr_data_u32(nbr_type))
            == BASE_ROUTE_RT_TYPE_STATIC){
            /* Static ARP handling */
            ndm->ndm_state = NUD_PERMANENT;
            /* Set this flag to replace the dynamic ARP to static if exists */
            if (m_type == NAS_RT_ADD)
                m_type = NAS_RT_SET;
        }else{
            ndm->ndm_state = NUD_REACHABLE;
        }
    } else {
        /* if NH type is not given, assume the state as permanent */
        ndm->ndm_state = NUD_PERMANENT;
        /* Set this flag to replace the dynamic ARP to static if exists */
        if (m_type == NAS_RT_ADD)
            m_type = NAS_RT_SET;
    }
    uint16_t flags = nas_os_get_nl_flags(m_type);
    uint16_t type = (m_type == NAS_RT_DEL)?RTM_DELNEIGH:RTM_NEWNEIGH;
    nas_os_pack_nl_hdr(nlh, type, flags);

    ndm->ndm_type = RTN_UNICAST;

    uint32_t addr_len = (ndm->ndm_family == AF_INET)?HAL_INET4_LEN:HAL_INET6_LEN;
    nlmsg_add_attr(nlh,sizeof(buff),NDA_DST,cps_api_object_attr_data_bin(ip),addr_len);

    if (mac != CPS_API_ATTR_NULL) {
        void * data = cps_api_object_attr_data_bin(mac);
        memcpy(mac_addr,data,sizeof(mac_addr));
        nlmsg_add_attr(nlh,sizeof(buff),NDA_LLADDR, &mac_addr, HAL_MAC_ADDR_LEN);
    }

    t_std_error rc = nl_do_set_request(nas_nl_sock_T_NEI,nlh,buff,sizeof(buff));
    int err_code = STD_ERR_EXT_PRIV (rc);
    EV_LOG(INFO, NAS_OS, 2,"NEIGH-UPD","Operation:%s family:%s NH:%s MAC:%s out-intf:%d state:%s rc:%d",
           ((m_type == NAS_RT_DEL) ? "Arp-Del" : "Arp-Add"), ((ndm->ndm_family == AF_INET) ? "IPv4" : "IPv6"),
           ((ndm->ndm_family == AF_INET) ?
            (inet_ntop(ndm->ndm_family, cps_api_object_attr_data_bin(ip), addr_str, INET_ADDRSTRLEN)) :
            (inet_ntop(ndm->ndm_family, cps_api_object_attr_data_bin(ip), addr_str, INET6_ADDRSTRLEN))),
           nl_neigh_mac_to_str(&mac_addr), ndm->ndm_ifindex,
           ((ndm->ndm_state == NUD_REACHABLE) ? "Dynamic" : "Static"), err_code);
    return rc;
}
Пример #25
0
static t_std_error nas_os_publish_route(int rt_msg_type, cps_api_object_t obj)
{
    static char buff[MAX_CPS_MSG_SIZE];

    cps_api_object_t new_obj = cps_api_object_init(buff,sizeof(buff));
    cps_api_key_init(cps_api_object_key(new_obj),cps_api_qualifier_TARGET,
            cps_api_obj_cat_ROUTE,cps_api_route_obj_ROUTE,0 );

    cps_api_object_attr_t prefix   = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_ROUTE_PREFIX);
    cps_api_object_attr_t af       = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_AF);
    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);

    if(rt_msg_type == RTM_NEWROUTE) {
        cps_api_object_attr_add_u32(new_obj, cps_api_if_ROUTE_A_MSG_TYPE,ROUTE_ADD);
    } else if(rt_msg_type == RTM_DELROUTE) {
        cps_api_object_attr_add_u32(new_obj, cps_api_if_ROUTE_A_MSG_TYPE,ROUTE_DEL);
    } else {
        return false;
    }

    cps_api_object_attr_add_u32(new_obj,cps_api_if_ROUTE_A_FAMILY,
            cps_api_object_attr_data_u32(af));

    uint32_t addr_len;
    hal_ip_addr_t ip;
    if(cps_api_object_attr_data_u32(af) == AF_INET) {
        struct in_addr *inp = (struct in_addr *) cps_api_object_attr_data_bin(prefix);
        std_ip_from_inet(&ip,inp);
        addr_len = HAL_INET4_LEN;
    } else {
        struct in6_addr *inp6 = (struct in6_addr *) cps_api_object_attr_data_bin(prefix);
        std_ip_from_inet6(&ip,inp6);
        addr_len = HAL_INET6_LEN;
    }

    cps_api_attr_id_t attr = cps_api_if_ROUTE_A_PREFIX;
    cps_api_object_e_add(new_obj, &attr, 1, cps_api_object_ATTR_T_BIN, &ip, sizeof(ip));

    cps_api_object_attr_add_u32(new_obj,cps_api_if_ROUTE_A_PREFIX_LEN,
            cps_api_object_attr_data_u32(pref_len));

    uint32_t nhc = 0;
    if (nh_count != CPS_API_ATTR_NULL) nhc = cps_api_object_attr_data_u32(nh_count);

    if (nhc == 1) {
        cps_api_object_attr_add_u32(new_obj,cps_api_if_ROUTE_A_HOP_COUNT,nhc);

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

        cps_api_object_attr_t gw = cps_api_object_e_get(obj,ids,ids_len);

        ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_IFINDEX;
        cps_api_object_attr_t gwix = cps_api_object_e_get(obj,ids,ids_len);

        cps_api_attr_id_t new_ids[3];
        new_ids[0] = cps_api_if_ROUTE_A_NH;
        new_ids[1] = 0;

        if (gw != CPS_API_ATTR_NULL) {
            new_ids[2] = cps_api_if_ROUTE_A_NEXT_HOP_ADDR;

            hal_ip_addr_t ip;
            if(addr_len == HAL_INET4_LEN) {
                ip.af_index = AF_INET;
                memcpy(&(ip.u.v4_addr), cps_api_object_attr_data_bin(gw),addr_len);
            } else {
                ip.af_index = AF_INET6;
                memcpy(&(ip.u.v6_addr), cps_api_object_attr_data_bin(gw),addr_len);
            }
            cps_api_object_e_add(new_obj, new_ids, ids_len, cps_api_object_ATTR_T_BIN,
                    &ip,sizeof(ip));
        }

        if (gwix != CPS_API_ATTR_NULL) {
            new_ids[2] = cps_api_if_ROUTE_A_NH_IFINDEX;
            uint32_t gw_idx = cps_api_object_attr_data_u32(gwix);
            cps_api_object_e_add(new_obj,new_ids,ids_len,cps_api_object_ATTR_T_U32,
                     (void *)&gw_idx, sizeof(uint32_t));
        }
    }

    EV_LOG(INFO, NAS_OS, 2,"ROUTE-UPD","Publishing object");

    net_publish_event(new_obj);

    return STD_ERR_OK;
}
Пример #26
0
cps_api_return_code_t nas_os_update_route (cps_api_object_t obj, msg_type m_type)
{
    static char buff[NL_RT_MSG_BUFFER_LEN]; // Allocate from DS
    char            addr_str[INET6_ADDRSTRLEN];
    memset(buff,0,sizeof(buff));

    cps_api_object_attr_t prefix   = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_ROUTE_PREFIX);
    cps_api_object_attr_t af       = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_AF);
    cps_api_object_attr_t nh_count = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_NH_COUNT);
    cps_api_object_attr_t pref_len = cps_api_object_attr_get(obj, BASE_ROUTE_OBJ_ENTRY_PREFIX_LEN);

    if (prefix == CPS_API_ATTR_NULL || af == CPS_API_ATTR_NULL ||  pref_len == CPS_API_ATTR_NULL
        || (m_type != NAS_RT_DEL && nh_count == CPS_API_ATTR_NULL)) {
        EV_LOG(ERR, NAS_OS, ev_log_s_CRITICAL, "ROUTE-UPD", "Missing route params");
        return cps_api_ret_code_ERR;
    }

    struct nlmsghdr *nlh = (struct nlmsghdr *)
                         nlmsg_reserve((struct nlmsghdr *)buff,sizeof(buff),sizeof(struct nlmsghdr));
    struct rtmsg * rm = (struct rtmsg *) nlmsg_reserve(nlh,sizeof(buff),sizeof(struct rtmsg));

    uint16_t flags = nas_os_get_nl_flags(m_type);
    uint16_t type = (m_type == NAS_RT_DEL)?RTM_DELROUTE:RTM_NEWROUTE;

    nas_os_pack_nl_hdr(nlh, type, flags);

    rm->rtm_table = RT_TABLE_MAIN;
    rm->rtm_protocol = RTPROT_UNSPEC; // This could be assigned to correct owner in future

    /* For route delete, initialize scope to no-where and
     * this will get updated to link when Nh addr/ifx is provided.
     */
    if (type != RTM_DELROUTE)
        rm->rtm_scope = RT_SCOPE_UNIVERSE;
    else
        rm->rtm_scope = RT_SCOPE_NOWHERE;

    rm->rtm_type = RTN_UNICAST;

    rm->rtm_dst_len = cps_api_object_attr_data_u32(pref_len);
    rm->rtm_family = (unsigned char) cps_api_object_attr_data_u32(af);

    uint32_t addr_len = (rm->rtm_family == AF_INET)?HAL_INET4_LEN:HAL_INET6_LEN;
    nlmsg_add_attr(nlh,sizeof(buff),RTA_DST,cps_api_object_attr_data_bin(prefix),addr_len);

    uint32_t nhc = 0;
    if (nh_count != CPS_API_ATTR_NULL) nhc = cps_api_object_attr_data_u32(nh_count);

    EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","NH count:%d family:%s msg:%s for prefix:%s len:%d scope:%d", nhc,
           ((rm->rtm_family == AF_INET) ? "IPv4" : "IPv6"), ((m_type == NAS_RT_ADD) ? "Route-Add" : ((m_type == NAS_RT_DEL) ? "Route-Del" : "Route-Set")),
           ((rm->rtm_family == AF_INET) ?
            (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(prefix), addr_str, INET_ADDRSTRLEN)) :
            (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(prefix), addr_str, INET6_ADDRSTRLEN))),
           rm->rtm_dst_len, rm->rtm_scope);

    if (nhc == 1) {
        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);
        cps_api_object_attr_t gw = cps_api_object_e_get(obj,ids,ids_len);
        if (gw != CPS_API_ATTR_NULL) {
            nlmsg_add_attr(nlh,sizeof(buff),RTA_GATEWAY,cps_api_object_attr_data_bin(gw),addr_len);
            rm->rtm_scope = RT_SCOPE_UNIVERSE; // set scope to universe when gateway is specified
            EV_LOG(INFO, NAS_OS, 2,"ROUTE-UPD","NH:%s scope:%d",
                   ((rm->rtm_family == AF_INET) ?
                    (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(gw), addr_str, INET_ADDRSTRLEN)) :
                    (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(gw), addr_str, INET6_ADDRSTRLEN))),
                   rm->rtm_scope);
        } else {
            EV_LOG(INFO, NAS_OS, ev_log_s_MINOR, "ROUTE-UPD", "Missing Gateway, could be intf route");
            /*
             * This could be an interface route, do not return from here!
             */
        }

        ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_IFINDEX;
        cps_api_object_attr_t gwix = cps_api_object_e_get(obj,ids,ids_len);
        if (gwix != CPS_API_ATTR_NULL) {
            if (gw == CPS_API_ATTR_NULL) {
                rm->rtm_scope = RT_SCOPE_LINK;
            }

            EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","out-intf: %d scope:%d",
                   (int)cps_api_object_attr_data_u32(gwix), rm->rtm_scope);
            nas_nl_add_attr_int(nlh,sizeof(buff),RTA_OIF,gwix);
        }

        ids[2] = BASE_ROUTE_OBJ_ENTRY_NH_LIST_WEIGHT;
        cps_api_object_attr_t weight = cps_api_object_e_get(obj,ids,ids_len);
        if (weight != CPS_API_ATTR_NULL) nas_nl_add_attr_int(nlh,sizeof(buff),RTA_PRIORITY,weight);

    } else if (nhc > 1){
        struct nlattr * attr_nh = nlmsg_nested_start(nlh, sizeof(buff));

        attr_nh->nla_len = 0;
        attr_nh->nla_type = RTA_MULTIPATH;
        size_t ix = 0;
        for (ix = 0; ix < nhc ; ++ix) {
            struct rtnexthop * rtnh =
                (struct rtnexthop * )nlmsg_reserve(nlh,sizeof(buff), sizeof(struct rtnexthop));
            memset(rtnh,0,sizeof(*rtnh));

            cps_api_attr_id_t ids[3] = { BASE_ROUTE_OBJ_ENTRY_NH_LIST,
                                         ix, BASE_ROUTE_OBJ_ENTRY_NH_LIST_NH_ADDR};
            const int ids_len = sizeof(ids)/sizeof(*ids);
            cps_api_object_attr_t attr = cps_api_object_e_get(obj,ids,ids_len);
            if (attr != CPS_API_ATTR_NULL) {
                nlmsg_add_attr(nlh,sizeof(buff),RTA_GATEWAY,
                               cps_api_object_attr_data_bin(attr),addr_len);
                rm->rtm_scope = RT_SCOPE_UNIVERSE; // set scope to universe when gateway is specified
                EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","MP-NH:%d %s scope:%d",ix,
                       ((rm->rtm_family == AF_INET) ?
                        (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(attr), addr_str, INET_ADDRSTRLEN)) :
                        (inet_ntop(rm->rtm_family, cps_api_object_attr_data_bin(attr), addr_str, INET6_ADDRSTRLEN))),
                       rm->rtm_scope);
            } else {
                EV_LOG(ERR, NAS_OS, ev_log_s_CRITICAL, "ROUTE-UPD", "Error - Missing Gateway");
                return cps_api_ret_code_ERR;
            }

            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)
                rtnh->rtnh_ifindex = (int)cps_api_object_attr_data_u32(attr);

            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) rtnh->rtnh_hops = (char)cps_api_object_attr_data_u32(attr);

            rtnh->rtnh_len = (char*)nlmsg_tail(nlh) - (char*)rtnh;
        }
        nlmsg_nested_end(nlh,attr_nh);
    }

    t_std_error rc = nl_do_set_request(nas_nl_sock_T_ROUTE,nlh,buff,sizeof(buff));
    int err_code = STD_ERR_EXT_PRIV (rc);
    EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","Netlink error_code %d", err_code);

    /*
     * Return success if the error is exist, in case of addition, or
     * no-exist, in case of deletion. This is because, kernel might have
     * deleted the route entries (when interface goes down) but has not sent netlink
     * events for those routes and RTM is trying to delete after that.
     * Similarly, during ip address configuration, kernel may add the routes
     * before RTM tries to configure kernel.
     *
     */
    if(err_code == ESRCH || err_code == EEXIST ) {
        EV_LOG(INFO, NAS_OS,2,"ROUTE-UPD","No such process or Entry already exists");
        /*
         * Kernel may or may not have the routes but NAS routing needs to be informed
         * as is from kernel netlink to program NPU for the route addition/deletion to
         * ensure stale routes are cleaned
         */
        if(err_code == ESRCH)
            nas_os_publish_route(RTM_DELROUTE, obj);
        else
            nas_os_publish_route(RTM_NEWROUTE, obj);
        rc = STD_ERR_OK;
    }

    return rc;

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

}
/**
  * 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 cps_api_return_code_t nas_qos_cps_api_priority_group_set(
                                cps_api_object_t obj,
                                cps_api_object_t sav_obj)
{
    cps_api_object_t tmp_obj;

    cps_api_object_attr_t port_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_PORT_ID);
    cps_api_object_attr_t local_id_attr = cps_api_get_key_data(obj, BASE_QOS_PRIORITY_GROUP_LOCAL_ID);

    if (port_id_attr == NULL ||
        local_id_attr == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key incomplete in the message\n");
        return NAS_QOS_E_MISSING_KEY;
    }

    uint32_t switch_id = 0;
    uint_t port_id = cps_api_object_attr_data_u32(port_id_attr);
    uint8_t local_id = *(uint8_t *)cps_api_object_attr_data_bin(local_id_attr);

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
            "Modify switch id %u, port id %u,  local_id %u \n",
            switch_id, port_id,  local_id);

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

    nas_qos_priority_group_key_t key;
    key.port_id = port_id;
    key.local_id = local_id;
    nas_qos_priority_group * priority_group_p = nas_qos_cps_get_priority_group(switch_id, key);
    if (priority_group_p == NULL) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                        "priority_group not found in switch id %u\n",
                        switch_id);
        return NAS_QOS_E_FAIL;
    }

    /* make a local copy of the existing priority_group */
    nas_qos_priority_group priority_group(*priority_group_p);

    cps_api_return_code_t rc = cps_api_ret_code_OK;
    if ((rc = nas_qos_cps_parse_attr(obj, priority_group)) != cps_api_ret_code_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Invalid information in the packet");
        return rc;
    }


    try {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Modifying switch id %u, port id %u priority_group info \n",
                switch_id, port_id);

        nas::attr_set_t modified_attr_list = priority_group.commit_modify(
                                    *priority_group_p, (sav_obj? false: true));


        // set attribute with full copy
        // save rollback info if caller requests it.
        // use modified attr list, current priority_group value
        if (sav_obj) {
            tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return cps_api_ret_code_ERR;
            }
            nas_qos_store_prev_attr(tmp_obj, modified_attr_list, *priority_group_p);
        }

        // update the local cache with newly set values
        *priority_group_p = priority_group;

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS priority_group Attr Modify error code: %d ",
                    e.err_code);
        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS priority_group Modify Unexpected error code");
        return NAS_QOS_E_FAIL;
    }


    return cps_api_ret_code_OK;
}
Пример #30
0
/**
  * This function provides NAS-QoS Map CPS API read function
  * @Param    Standard CPS API params
  * @Return   Standard Error Code
  */
cps_api_return_code_t nas_qos_cps_api_map_read_type (void * context,
                                            cps_api_get_params_t * param,
                                            size_t ix,
                                            nas_qos_map_type_t map_type)
{
    cps_api_object_t obj = cps_api_object_list_get(param->filters, ix);

    nas_attr_id_t obj_id;

    uint_t switch_id = 0;

    obj_id = qos_map_map_id_obj_id(map_type);
    cps_api_object_attr_t map_attr = cps_api_get_key_data(obj, obj_id);
    nas_obj_id_t map_id = (map_attr? cps_api_object_attr_data_u64(map_attr): 0);

    // check the request is on Map level or Entry level
    bool is_map_entry;
    cps_api_return_code_t rc = cps_api_ret_code_OK;
    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;
    }

    obj_id = qos_map_entry_key_1_obj_id(map_type);
    cps_api_object_attr_t entry_attr = cps_api_get_key_data(obj, obj_id);
    if (entry_attr == NULL && is_map_entry) {
        // Inner list does not support wildcard get.
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key value must be specified for inner list\n");
        return NAS_QOS_E_MISSING_KEY;
    }

    nas_qos_map_entry_key_t search_key;
    if (entry_attr) {
        search_key.any = *(uint8_t *)cps_api_object_attr_data_bin(entry_attr);
    }

    if (map_type == NDI_QOS_MAP_TC_TO_QUEUE ||
        map_type == NDI_QOS_MAP_TC_COLOR_TO_DOT1P ||
        map_type == NDI_QOS_MAP_TC_COLOR_TO_DSCP ||
        map_type == NDI_QOS_MAP_PG_TO_PFC ||
        map_type == NDI_QOS_MAP_PFC_TO_QUEUE) {
        obj_id = qos_map_entry_key_2_obj_id(map_type);
        cps_api_object_attr_t entry_key2_attr = cps_api_get_key_data(obj, obj_id);
        if (entry_key2_attr == NULL && is_map_entry) {
            // Inner list does not support wildcard get.
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                        "Secondary Key value missing for inner list\n");
            return NAS_QOS_E_MISSING_KEY;
        }

        if (entry_key2_attr) {
            uint32_t key2;

            if (map_type == NDI_QOS_MAP_PG_TO_PFC)
                key2 = *(uint8_t *)cps_api_object_attr_data_bin(entry_key2_attr);
            else
                key2 = cps_api_object_attr_data_u32(entry_key2_attr);

            // form a complex key
            uint_t comp_key = MAKE_KEY(search_key.any, key2);

            if (map_type == NDI_QOS_MAP_TC_TO_QUEUE)
                search_key.tc_queue_type = comp_key;
            else if (map_type == NDI_QOS_MAP_TC_COLOR_TO_DOT1P ||
                     map_type == NDI_QOS_MAP_TC_COLOR_TO_DSCP)
                search_key.tc_color = comp_key;
            else if (map_type == NDI_QOS_MAP_PG_TO_PFC)
                search_key.pg_prio = comp_key;
            else if (map_type == NDI_QOS_MAP_PFC_TO_QUEUE)
                search_key.prio_queue_type = comp_key;
        }
    }

    EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Read switch id %u, map id %u\n",
                    switch_id, map_id);

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

    nas_qos_map * map;
    if (map_id) {
        map = p_switch->get_map(map_id);
        if (map == NULL)
            return NAS_QOS_E_FAIL;

        rc = _append_one_map(param, switch_id, map, map_type, search_key, is_map_entry);
    }
    else {
        // map id is not specified
        for (map_iter_t it = p_switch->get_map_it_begin();
                it != p_switch->get_map_it_end();
                it++) {

            map = &it->second;
            rc = _append_one_map(param, switch_id, map, map_type, search_key, false);
            if (rc != cps_api_ret_code_OK)
                return rc;
        }
    }

    return rc;
}