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; } }
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; } } }
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; } } }
bool cps_api_obj_tool_merge(cps_api_object_t main, cps_api_object_t overlay) { cps_api_object_it_t it; cps_api_object_it_begin(overlay,&it); do { CPS_CLASS_ATTR_TYPES_t _type; if (!cps_class_map_attr_class(cps_api_object_attr_id(it.attr),&_type)) { _type = CPS_CLASS_ATTR_T_LEAF; } do { cps_api_attr_id_t _id = cps_api_object_attr_id(it.attr); cps_api_object_attr_delete(main,_id); if (_type==CPS_CLASS_ATTR_T_LEAF_LIST) { if (cps_api_object_attr_get(main,_id)!=nullptr) { continue; } } } while (0); } while (cps_api_object_it_next(&it)); cps_api_object_it_begin(overlay,&it); do { size_t _attr_len = cps_api_object_attr_len(it.attr); if (_attr_len==0) continue; if (!cps_api_object_attr_add(main,cps_api_object_attr_id(it.attr),cps_api_object_attr_data_bin(it.attr), _attr_len)) { return false; } } while (cps_api_object_it_next(&it)); return true; }
/** * 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); }
bool get_netlink_data(int rt_msg_type, struct nlmsghdr *hdr, void *data) { cps_api_object_t obj=cps_api_object_create(); if (!nl_get_if_info(rt_msg_type,hdr,obj)) return false; cps_api_object_attr_t attr = cps_api_object_attr_get(obj,cps_api_if_STRUCT_A_NAME); if (attr==CPS_API_ATTR_NULL) return false; char buff[1024]; printf("OID = %s\n",cps_api_key_print(cps_api_object_key(obj),buff,sizeof(buff))); printf("Name:%s \n", (char*)cps_api_object_attr_data_bin(attr)); cps_api_object_delete(obj); return true; }
bool cps_api_obj_tool_attr_matches(cps_api_object_t obj, cps_api_attr_id_t *ids, void ** values, size_t *len, size_t mx_) { for ( size_t ix = 0 ; ix < mx_ ; ++ix ) { cps_api_object_attr_t attr = cps_api_get_key_data(obj,ids[ix]); if (attr==nullptr) return false; size_t _len = cps_api_object_attr_len(attr); void * _data = cps_api_object_attr_data_bin(attr); if (len[ix]==_len) { if (memcmp(_data,values[ix],len[ix])==0) continue; } return false; } return true; }
static void _set_mac(cps_api_object_t obj, struct nlmsghdr *nlh, struct ifinfomsg * inf,size_t len) { cps_api_object_attr_t attr = cps_api_object_attr_get(obj, DELL_IF_IF_INTERFACES_INTERFACE_PHYS_ADDRESS); if (attr==NULL) return; void *addr = cps_api_object_attr_data_bin(attr); hal_mac_addr_t mac_addr; int addr_len = strlen(static_cast<char *>(addr)); if (std_string_to_mac(&mac_addr, static_cast<const char *>(addr), addr_len)) { char mac_str[40] = {0}; EV_LOG(INFO, NAS_OS, ev_log_s_MAJOR, "NAS-OS", "Setting mac address %s, actual string %s, len %d", std_mac_to_string(&mac_addr,mac_str,sizeof(mac_str)), static_cast<char *>(addr), addr_len); nlmsg_add_attr(nlh,len,IFLA_ADDRESS, mac_addr , cps_api_object_attr_len(attr)); } }
extern "C" t_std_error dn_hal_get_interface_mac(hal_ifindex_t if_index, hal_mac_addr_t mac_addr) { if(mac_addr == NULL) { EV_LOG_TRACE(ev_log_t_INTERFACE, 2, "INTF-C","mac_addr_ptr NULL"); return(STD_ERR_MK(e_std_err_INTERFACE, e_std_err_code_PARAM, 0)); } cps_api_get_params_t gp; cps_api_get_request_init(&gp); cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters); t_std_error rc = STD_ERR_MK(e_std_err_INTERFACE, e_std_err_code_FAIL, 0); do { if (!cps_api_key_from_attr_with_qual(cps_api_object_key(obj), DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_OBJ, cps_api_qualifier_TARGET)) { break; } cps_api_object_attr_add_u32(obj,DELL_BASE_IF_CMN_IF_INTERFACES_INTERFACE_IF_INDEX, if_index); if (cps_api_get(&gp) != cps_api_ret_code_OK) break; if (0 == cps_api_object_list_size(gp.list)) break; obj = cps_api_object_list_get(gp.list,0); cps_api_object_attr_t attr = cps_api_object_attr_get(obj,DELL_IF_IF_INTERFACES_INTERFACE_PHYS_ADDRESS); if (attr != NULL) { void *_mac_str = cps_api_object_attr_data_bin(attr); size_t addr_len = strlen(static_cast<char *>(_mac_str)); EV_LOG_TRACE(ev_log_t_INTERFACE, 2, "INTF-C","mac_addr %s, len %d", _mac_str, addr_len); if (std_string_to_mac((hal_mac_addr_t *)mac_addr, static_cast<const char *>(_mac_str), addr_len)) { rc = STD_ERR_OK; } } } while (0); cps_api_get_request_close(&gp); return rc; }
t_std_error nas_switch_get_sys_mac_base(hal_mac_addr_t *mac_base) { if(mac_base == NULL) { EV_LOG(ERR,NAS_L2,0,"NAS-L2-SWITCH","invalid parameter"); return(STD_ERR_MK(e_std_err_BOARD, e_std_err_code_PARAM, 0)); } cps_api_get_params_t gp; cps_api_get_request_init(&gp); cps_api_object_t obj = cps_api_object_list_create_obj_and_append(gp.filters); t_std_error rc = STD_ERR_MK(e_std_err_BOARD, e_std_err_code_FAIL, 0); do { if (!cps_api_key_from_attr_with_qual(cps_api_object_key(obj), BASE_SWITCH_SWITCHING_ENTITIES_SWITCHING_ENTITY, cps_api_qualifier_TARGET)) { break; } uint32_t switch_id = 0; /* default switch ID. @TODO add switch id */ cps_api_set_key_data_uint(obj, BASE_SWITCH_SWITCHING_ENTITIES_SWITCHING_ENTITY_SWITCH_ID, &switch_id, sizeof(switch_id)); if (cps_api_get(&gp) != cps_api_ret_code_OK) break; if (0 == cps_api_object_list_size(gp.list)) break; obj = cps_api_object_list_get(gp.list,0); cps_api_object_attr_t attr = cps_api_object_attr_get(obj, BASE_SWITCH_SWITCHING_ENTITIES_SWITCHING_ENTITY_DEFAULT_MAC_ADDRESS); if (attr != NULL) { memcpy(*mac_base,cps_api_object_attr_data_bin(attr),sizeof(*mac_base)); rc = STD_ERR_OK; } } while (0); cps_api_get_request_close(&gp); return rc; }
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; }
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; }
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 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_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; }
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 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; }
/** * 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 void _set_name(cps_api_object_t obj, struct nlmsghdr *nlh, struct ifinfomsg * inf,size_t len) { cps_api_object_attr_t attr = cps_api_object_attr_get(obj, IF_INTERFACES_INTERFACE_NAME); if (attr==NULL) return; const char *name = (const char*)cps_api_object_attr_data_bin(attr); nlmsg_add_attr(nlh,len,IFLA_IFNAME, name , strlen(name)+1); }
static void _set_ifalias(cps_api_object_t obj, struct nlmsghdr *nlh, struct ifinfomsg * inf,size_t len) { cps_api_object_attr_t attr = cps_api_object_attr_get(obj,NAS_OS_IF_ALIAS); if (attr==NULL) return; const char *name = (const char*)cps_api_object_attr_data_bin(attr); nlmsg_add_attr(nlh,len,IFLA_IFALIAS, name , strlen(name)+1); }
bool cps_api_nodes::load_groups() { cps_api_object_guard og(cps_api_object_create()); if (!cps_api_key_from_attr_with_qual(cps_api_object_key(og.get()),CPS_NODE_GROUP, cps_api_qualifier_TARGET)) { EV_LOG(ERR,DSAPI,0,"CPS-CLS-MAP","Meta data for cluster set is not loaded."); return false; } cps_db::connection_request b(cps_db::ProcessDBCache(),DEFAULT_REDIS_ADDR); if (!b.valid()) { return false; } group_data_t cpy; cps_api_object_list_guard lg(cps_api_object_list_create()); if (!cps_db::get_objects(b.get(),og.get(),lg.get())) return false; for (size_t ix = 0,mx = cps_api_object_list_size(lg.get()); ix < mx ; ++ix ) { cps_api_object_t o = cps_api_object_list_get(lg.get(),ix); std::vector<_db_node_data> v; const char *name = (const char*) cps_api_object_get_data(o,CPS_NODE_GROUP_NAME); _node_data nd; cps_api_node_data_type_t *_type = (cps_api_node_data_type_t*)cps_api_object_get_data(o,CPS_NODE_GROUP_TYPE); if (_type==nullptr) { EV_LOGGING(DSAPI,ERR,"NODE-LOAD","Could not get the group type for group %s",name); return false; } nd.type = *_type; cps_api_object_attr_t _node_group = cps_api_object_attr_get(o,CPS_NODE_GROUP_NODE); if (_node_group==nullptr) continue; ///TODO log cps_api_object_it_t it; cps_api_object_it_from_attr(_node_group,&it); cps_api_object_it_inside(&it); while (cps_api_object_it_valid(&it)) { cps_api_attr_id_t id = cps_api_object_attr_id(it.attr); (void)id; cps_api_object_it_t elem = it; cps_api_object_it_inside(&elem); if (!cps_api_object_it_valid(&elem)) continue; _db_node_data db_node; cps_api_object_attr_t _ip =cps_api_object_it_find(&elem,CPS_NODE_GROUP_NODE_IP); cps_api_object_attr_t _name =cps_api_object_it_find(&elem,CPS_NODE_GROUP_NODE_NAME); if (_ip==nullptr || _name==nullptr) continue; const char *__ip = (const char*)cps_api_object_attr_data_bin(_ip); const char *__name =(const char*)cps_api_object_attr_data_bin(_name); if(nd.type == cps_api_node_data_1_PLUS_1_REDUNDENCY) { db_node._name = __name; if(get_port_info(name,&db_node)) { auto lst = cps_string::split(std::string(__ip),":"); if (lst.size()!=2) { return false; } db_node._addr = lst[0] + ':'+ db_node._addr; v.push_back(std::move(db_node)); } else { EV_LOGGING(DSAPI,ERR,"CPS-DB","Failed to get port info for group %s and node %s", name,__name); } } if(v.size()>0) { _db_node_map[name] = v; update_slaves(name); } _alias_map[__name] = __ip; const char * _alias = this->addr(__ip); if (_alias!=nullptr) __ip = _alias; nd._addrs.push_back(__ip); cps_api_object_it_next(&it); } cpy[name] = nd; } size_t _new_hash = cps_api_nodes::gen_hash(cpy); if (_new_hash==_hash) return false; ///TODO is this unique enough? std::swap(_groups,cpy); _hash = _new_hash; return true; }