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