/** * @brief Remove Qos Map * * @param[in] qos_map_id Qos Map id to be removed. * * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_remove_qos_map(_In_ sai_object_id_t qos_map_id) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(qos_map_id) == SAI_OBJECT_TYPE_QOS_MAPS); status = switch_api_qos_map_ingress_delete(device, qos_map_id); if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_INVALID_HANDLE) { SAI_LOG_ERROR("failed to remove ingress qos map %s", sai_status_to_string(status)); return status; } status = switch_api_qos_map_egress_delete(device, qos_map_id); if (status != SWITCH_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to remove egress qos map %s", sai_status_to_string(status)); return status; } SAI_LOG_EXIT(); return (sai_status_t)status; }
void redisSetDummyAsicStateForRealObjectId(sai_object_id_t rid) { SWSS_LOG_ENTER(); sai_object_type_t objectType = sai_object_type_query(rid); if (objectType == SAI_OBJECT_TYPE_NULL) { SWSS_LOG_ERROR("sai_object_type_query returned NULL type for RID %llx", rid); exit(EXIT_FAILURE); } std::string strObjectType; sai_serialize_primitive(objectType, strObjectType); sai_object_id_t vid = redis_create_virtual_object_id(objectType); std::string strVid; sai_serialize_primitive(vid, strVid); std::string strKey = "ASIC_STATE:" + strObjectType + ":" + strVid; g_redisClient->hset(strKey, "NULL", "NULL"); redisCreateRidAndVidMapping(rid, vid); }
sai_object_id_t translate_rid_to_vid( _In_ sai_object_id_t rid) { SWSS_LOG_ENTER(); if (rid == SAI_NULL_OBJECT_ID) { SWSS_LOG_DEBUG("translated RID null to VID null"); return SAI_NULL_OBJECT_ID; } sai_object_id_t vid; std::string str_rid; std::string str_vid; sai_serialize_primitive(rid, str_rid); auto pvid = g_redisClient->hget(RIDTOVID, str_rid); if (pvid != NULL) { // object exists str_vid = *pvid; int index = 0; sai_deserialize_primitive(str_vid, index, vid); SWSS_LOG_DEBUG("translated RID %llx to VID %llx", rid, vid); return vid; } SWSS_LOG_INFO("spotted new RID %llx", rid); sai_object_type_t object_type = sai_object_type_query(rid); if (object_type == SAI_OBJECT_TYPE_NULL) { SWSS_LOG_ERROR("sai_object_type_query returned NULL type for RID %llx", rid); exit(EXIT_FAILURE); } vid = redis_create_virtual_object_id(object_type); SWSS_LOG_DEBUG("translated RID %llx to VID %llx", rid, vid); sai_serialize_primitive(vid, str_vid); g_redisClient->hset(RIDTOVID, str_rid, str_vid); g_redisClient->hset(VIDTORID, str_vid, str_rid); return vid; }
static void sai_neighbor_entry_parse( const sai_neighbor_entry_t *neighbor_entry, switch_api_neighbor_t *api_neighbor) { SAI_ASSERT(sai_object_type_query(neighbor_entry->rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); api_neighbor->interface = (switch_handle_t) neighbor_entry->rif_id; api_neighbor->rw_type = SWITCH_API_NEIGHBOR_RW_TYPE_L3; sai_ip_addr_to_switch_ip_addr(&neighbor_entry->ip_address, &api_neighbor->ip_addr); }
sai_status_t sai_set_qos_map_attribute(_In_ sai_object_id_t qos_map_id, _In_ const sai_attribute_t *attr) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(qos_map_id) == SAI_OBJECT_TYPE_QOS_MAPS); SAI_LOG_EXIT(); return (sai_status_t)status; }
/** * @brief Set buffer pool attribute * @param[in] pool_id buffer pool id * @param[in] attr attribute * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_set_buffer_pool_attribute(_In_ sai_object_id_t pool_id, _In_ const sai_attribute_t *attr) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(pool_id) == SAI_OBJECT_TYPE_BUFFER_POOL); SAI_LOG_EXIT(); return status; }
/** * @brief Set ingress priority group attribute * @param[in] ingress_pg_id ingress priority group id * @param[in] attr attribute to set * * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_set_ingress_priority_group_attribute( _In_ sai_object_id_t ingress_pg_id, _In_ const sai_attribute_t *attr) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(ingress_pg_id) == SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP); SAI_ASSERT(sai_object_type_query(attr->value.oid) == SAI_OBJECT_TYPE_BUFFER_PROFILE); status = switch_api_priority_group_buffer_profile_set( device, ingress_pg_id, attr->value.oid); if (status != SAI_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to set pg buffer profile :%s", sai_status_to_string(status)); } SAI_LOG_EXIT(); return status; }
/* * Routine Description: * Set router interface attribute * * Arguments: * [in] rif_id - router interface id * [in] attr - attribute * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_set_router_interface_attribute( _In_ sai_object_id_t rif_id, _In_ const sai_attribute_t *attr) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; switch_status_t switch_status = SWITCH_STATUS_SUCCESS; if (!attr) { status = SAI_STATUS_INVALID_PARAMETER; SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); return status; } SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); switch (attr->id) { case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: switch_status = switch_api_interface_ipv4_unicast_enabled_set( rif_id, attr->value.booldata); break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: switch_status = switch_api_interface_ipv6_unicast_enabled_set( rif_id, attr->value.booldata); break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE: switch_status = switch_api_interface_ipv4_multicast_enabled_set( rif_id, attr->value.booldata); break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE: switch_status = switch_api_interface_ipv6_multicast_enabled_set( rif_id, attr->value.booldata); break; case SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE: switch_status = switch_api_interface_ipv4_urpf_mode_set( rif_id, sai_to_switch_urpf_mode(attr->value.s32)); break; case SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE: switch_status = switch_api_interface_ipv6_urpf_mode_set( rif_id, sai_to_switch_urpf_mode(attr->value.s32)); break; default: return SAI_STATUS_INVALID_PARAMETER; } SAI_LOG_EXIT(); status = sai_switch_status_to_sai_status(switch_status); return status; }
/** * @brief Get buffer profile attributes * @param[in] buffer_profile_id buffer profile id * @param[in] attr_count number of attributes * @param[inout] attr_list array of attributes * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_get_buffer_profile_attribute( _In_ sai_object_id_t buffer_profile_id, _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(buffer_profile_id) == SAI_OBJECT_TYPE_BUFFER_PROFILE); SAI_LOG_EXIT(); return status; }
/** * @brief Set Policer attribute * * @param[in] policer_id - Policer id * @param[in] attr - attribute * * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_set_policer_attribute(_In_ sai_object_id_t policer_id, _In_ const sai_attribute_t *attr) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; if (!attr) { status = SAI_STATUS_INVALID_PARAMETER; SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); return status; } SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); SAI_LOG_EXIT(); return (sai_status_t)status; }
/** * @brief Remove buffer pool * @param[in] pool_id buffer pool id * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_remove_buffer_pool(_In_ sai_object_id_t pool_id) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(pool_id) == SAI_OBJECT_TYPE_BUFFER_POOL); status = switch_api_buffer_pool_delete(device, pool_id); if (status != SAI_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to delete buffer pool: %s", sai_status_to_string(status)); } SAI_LOG_EXIT(); return status; }
/* * Routine Description: * Set virtual router attribute Value * * Arguments: * [in] vr_id - virtual router id * [in] attr - attribute * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_set_virtual_router_entry_attribute( _In_ sai_object_id_t vr_id, _In_ const sai_attribute_t *attr) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; if (!attr) { status = SAI_STATUS_INVALID_PARAMETER; SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); return status; } SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); SAI_LOG_EXIT(); return (sai_status_t)status; }
static void sai_ipmc_entry_parse(_In_ const sai_ipmc_entry_t *ipmc_entry, _Out_ switch_handle_t *vrf_handle, _Out_ switch_ip_addr_t *src_addr, _Out_ switch_ip_addr_t *grp_addr) { SAI_ASSERT(sai_object_type_query(ipmc_entry->vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); *vrf_handle = (switch_handle_t)ipmc_entry->vr_id; memset(src_addr, 0, sizeof(switch_ip_addr_t)); sai_ip_addr_to_switch_ip_addr(&(ipmc_entry->source), src_addr); if (((src_addr->type == SWITCH_API_IP_ADDR_V4) && (src_addr->ip.v4addr == 0)) || ((src_addr->type == SWITCH_API_IP_ADDR_V6) && (memcmp(src_addr->ip.v6addr, &in6addr_any, sizeof(in6addr_any)) == 0))) { src_addr->prefix_len = 0; } sai_ip_prefix_to_switch_ip_addr(&(ipmc_entry->group), grp_addr); }
/* * Routine Description: * Remove virtual router * * Arguments: * [in] vr_id - virtual router id * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_remove_virtual_router_entry(_In_ sai_object_id_t vr_id) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; switch_status_t switch_status = SWITCH_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(vr_id) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); switch_status = switch_api_vrf_delete(device, vr_id); status = sai_switch_status_to_sai_status(switch_status); if (status != SAI_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to remove virtual router entry %lx : %s", vr_id, sai_status_to_string(status)); } SAI_LOG_EXIT(); return (sai_status_t)status; }
/* * Routine Description: * Remove router interface * * Arguments: * [in] rif_id - router interface id * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_remove_router_interface(_In_ sai_object_id_t rif_id) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; switch_status_t switch_status = SWITCH_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); switch_status = switch_api_interface_delete(device, (switch_handle_t)rif_id); status = sai_switch_status_to_sai_status(switch_status); if (status != SAI_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to remove router interface: %s", sai_status_to_string(status)); } SAI_LOG_EXIT(); return (sai_status_t)status; }
/** * @brief Delete policer * * @param[in] policer_id - Policer id * * @return SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_remove_policer(_In_ sai_object_id_t policer_id) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; switch_status_t switch_status = SWITCH_STATUS_SUCCESS; SAI_ASSERT(sai_object_type_query(policer_id) == SAI_OBJECT_TYPE_POLICER); switch_status = switch_api_meter_delete(device, policer_id); status = sai_switch_status_to_sai_status(switch_status); if (status != SAI_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to delete policer %lx: %s", policer_id, sai_status_to_string(status)); } SAI_LOG_EXIT(); return (sai_status_t)status; }
void helperCheckPortIds() { SWSS_LOG_ENTER(); auto laneMap = saiGetHardwareLaneMap(); for (auto kv: laneMap) { sai_object_id_t portId = kv.second; // translate will create entry if missing // we assume here that port numbers didn't changed // during restarts sai_object_id_t vid = translate_rid_to_vid(portId); sai_object_type_t objectType = sai_object_type_query(portId); if (objectType == SAI_OBJECT_TYPE_NULL) { SWSS_LOG_ERROR("sai_object_type_query returned NULL type for RID %llx", portId); exit(EXIT_FAILURE); } std::string strObjectType; sai_serialize_primitive(objectType, strObjectType); std::string strVid; sai_serialize_primitive(vid, strVid); std::string strKey = "ASIC_STATE:" + strObjectType + ":" + strVid; g_redisClient->hset(strKey, "NULL", "NULL"); } }
/* * Routine Description: * Create host interface. * * Arguments: * [out] hif_id - host interface id * [in] attr_count - number of attributes * [in] attr_list - array of attributes * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t stub_create_host_interface(_Out_ sai_object_id_t * hif_id, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { sai_status_t status; int ret; const sai_attribute_value_t *type, *rif_port, *name; uint32_t type_index, rif_port_index, name_index, rif_data; char key_str[MAX_KEY_STR_LEN]; char list_str[MAX_LIST_VALUE_STR_LEN]; static uint32_t next_id = 0; char system_cmd[1024]; STUB_LOG_ENTER(); if (NULL == hif_id) { STUB_LOG_ERR("NULL host interface ID param\n"); return SAI_STATUS_INVALID_PARAMETER; } if (SAI_STATUS_SUCCESS != (status = check_attribs_metadata(attr_count, attr_list, host_interface_attribs, host_interface_vendor_attribs, SAI_OPERATION_CREATE))) { STUB_LOG_ERR("Failed attribs check\n"); return status; } sai_attr_list_to_str(attr_count, attr_list, host_interface_attribs, MAX_LIST_VALUE_STR_LEN, list_str); STUB_LOG_NTC("Create host interface, %s\n", list_str); assert(SAI_STATUS_SUCCESS == find_attrib_in_list(attr_count, attr_list, SAI_HOSTIF_ATTR_TYPE, &type, &type_index)); assert(SAI_STATUS_SUCCESS == find_attrib_in_list(attr_count, attr_list, SAI_HOSTIF_ATTR_NAME, &name, &name_index)); if (SAI_HOSTIF_TYPE_NETDEV == type->s32) { if (SAI_STATUS_SUCCESS != (status = find_attrib_in_list(attr_count, attr_list, SAI_HOSTIF_ATTR_RIF_OR_PORT_ID, &rif_port, &rif_port_index))) { STUB_LOG_ERR("Missing mandatory attribute rif port id on create of host if netdev type\n"); return SAI_STATUS_MANDATORY_ATTRIBUTE_MISSING; } if (SAI_OBJECT_TYPE_ROUTER_INTERFACE == sai_object_type_query(rif_port->oid)) { if (SAI_STATUS_SUCCESS != (status = stub_object_to_type(rif_port->oid, SAI_OBJECT_TYPE_ROUTER_INTERFACE, &rif_data))) { return status; } } else if (SAI_OBJECT_TYPE_PORT == sai_object_type_query(rif_port->oid)) { if (SAI_STATUS_SUCCESS != (status = stub_object_to_type(rif_port->oid, SAI_OBJECT_TYPE_PORT, &rif_data))) { return status; } } else { STUB_LOG_ERR("Invalid rif port object type %s", SAI_TYPE_STR(sai_object_type_query(rif_port->oid))); return SAI_STATUS_INVALID_ATTR_VALUE_0 + rif_port_index; } snprintf(system_cmd, sizeof(system_cmd), "ip link add name %s type dummy", name->chardata); ret = system(system_cmd); if (0 != ret) { STUB_LOG_INF("Error on attempt to create dummy interface. Possibly interface already exists"); return SAI_STATUS_SUCCESS; } } else if (SAI_HOSTIF_TYPE_FD == type->s32) { } else { STUB_LOG_ERR("Invalid host interface type %d\n", type->s32); return SAI_STATUS_INVALID_ATTR_VALUE_0 + type_index; } if (SAI_STATUS_SUCCESS != (status = stub_create_object(SAI_OBJECT_TYPE_HOST_INTERFACE, next_id++, hif_id))) { return status; } host_interface_key_to_str(*hif_id, key_str); STUB_LOG_NTC("Created host interface %s\n", key_str); STUB_LOG_EXIT(); return SAI_STATUS_SUCCESS; }
sai_status_t redis_generic_stats_function( _In_ sai_object_type_t object_type, _In_ sai_object_id_t object_id, _In_ const sai_enum_metadata_t *enum_metadata, _In_ uint32_t number_of_counters, _In_ const int32_t *counter_ids, _In_ sai_stats_mode_t mode, _Out_ uint64_t *counters) { SWSS_LOG_ENTER(); /* * Do all parameter validation. */ if (object_id == SAI_NULL_OBJECT_ID) { SWSS_LOG_ERROR("object id is NULL"); return SAI_STATUS_INVALID_PARAMETER; } sai_object_type_t ot = sai_object_type_query(object_id); if (ot != object_type) { SWSS_LOG_ERROR("object %s is %s but expected %s", sai_serialize_object_id(object_id).c_str(), sai_serialize_object_type(ot).c_str(), sai_serialize_object_type(object_type).c_str()); return SAI_STATUS_INVALID_PARAMETER; } sai_object_id_t switch_id = sai_switch_id_query(object_id); if (switch_id == SAI_NULL_OBJECT_ID) { SWSS_LOG_ERROR("object %s does not correspond to any switch object", sai_serialize_object_id(object_id).c_str()); return SAI_STATUS_INVALID_PARAMETER; } uint32_t count = number_of_counters & ~REDIS_COUNTERS_COUNT_MSB; if (count > REDIS_MAX_COUNTERS) { SWSS_LOG_ERROR("max supported counters to get/clear is %u, but %u given", REDIS_MAX_COUNTERS, count); return SAI_STATUS_INVALID_PARAMETER; } if (counter_ids == NULL) { SWSS_LOG_ERROR("counter ids pointer is NULL"); return SAI_STATUS_INVALID_PARAMETER; } if (counters == NULL) { SWSS_LOG_ERROR("counters output pointer is NULL"); return SAI_STATUS_INVALID_PARAMETER; } if (enum_metadata == NULL) { SWSS_LOG_ERROR("enum metadata pointer is NULL, bug?"); return SAI_STATUS_FAILURE; } for (uint32_t i = 0; i < count; i++) { if (sai_metadata_get_enum_value_name(enum_metadata, counter_ids[i]) == NULL) { SWSS_LOG_ERROR("counter id %u is not allowed on %s", counter_ids[i], enum_metadata->name); return SAI_STATUS_INVALID_PARAMETER; } } switch (mode) { case SAI_STATS_MODE_READ: case SAI_STATS_MODE_READ_AND_CLEAR: break; default: SWSS_LOG_ERROR("counters mode is invalid %d", mode); return SAI_STATUS_INVALID_PARAMETER; } return internal_redis_generic_stats_function( object_type, object_id, switch_id, enum_metadata, number_of_counters, counter_ids, mode, counters); }
/* * Routine Description: * Get router interface attribute * * Arguments: * [in] rif_id - router interface id * [in] attr_count - number of attributes * [inout] attr_list - array of attributes * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_get_router_interface_attribute( _In_ sai_object_id_t rif_id, _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; if (!attr_list) { status = SAI_STATUS_INVALID_PARAMETER; SAI_LOG_ERROR("null attribute: %s", sai_status_to_string(status)); return status; } uint32_t index; uint64_t value; switch_status_t switch_status = -1; sai_attribute_t *attribute; for (index = 0; index < attr_count; index++) { attribute = &attr_list[index]; switch (attribute->id) { case SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID: switch_status = switch_api_interface_attribute_get( (switch_handle_t)rif_id, SWITCH_INTF_ATTR_VRF, &value); attribute->value.oid = value; break; case SAI_ROUTER_INTERFACE_ATTR_TYPE: break; case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: switch_status = switch_api_interface_attribute_get( (switch_handle_t)rif_id, SWITCH_INTF_ATTR_PORT_ID, &value); attribute->value.oid = value; break; case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: switch_status = switch_api_interface_attribute_get( (switch_handle_t)rif_id, SWITCH_INTF_ATTR_VLAN_ID, &value); attribute->value.u16 = value; break; case SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS: switch_status = switch_api_interface_attribute_get( (switch_handle_t)rif_id, SWITCH_INTF_ATTR_RMAC_ADDR, &value); memcpy(attribute->value.mac, (uint8_t *)&value, sizeof(sai_mac_t)); break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: switch_status = switch_api_interface_attribute_get( (switch_handle_t)rif_id, SWITCH_INTF_ATTR_V4_UNICAST, &value); attribute->value.booldata = value; break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: switch_status = switch_api_interface_attribute_get( (switch_handle_t)rif_id, SWITCH_INTF_ATTR_V6_UNICAST, &value); attribute->value.booldata = value; break; case SAI_ROUTER_INTERFACE_ATTR_MTU: // return the default for now attribute->value.u32 = 1514; break; default: return SAI_STATUS_INVALID_PARAMETER; } if ((status = sai_switch_status_to_sai_status(switch_status)) != SAI_STATUS_SUCCESS) { return status; } } SAI_ASSERT(sai_object_type_query(rif_id) == SAI_OBJECT_TYPE_ROUTER_INTERFACE); SAI_LOG_EXIT(); return (sai_status_t)status; }
void channelOpSetReadOnlyAttribute( _In_ const std::string &key, _In_ const std::vector<swss::FieldValueTuple> &values) { SWSS_LOG_ENTER(); for (const auto &v: values) { SWSS_LOG_DEBUG("attr: %s: %s", fvField(v).c_str(), fvValue(v).c_str()); } if (values.size() != 1) { SWSS_LOG_ERROR("expected 1 value only, but given: %zu", values.size()); return; } const std::string &str_object_type = key.substr(0, key.find(":")); const std::string &str_object_id = key.substr(key.find(":") + 1); sai_object_type_t object_type; sai_deserialize_object_type(str_object_type, object_type); if (object_type == SAI_OBJECT_TYPE_NULL || object_type >= SAI_OBJECT_TYPE_EXTENSIONS_MAX) { SWSS_LOG_ERROR("invalid object type: %d", object_type); return; } auto info = sai_metadata_get_object_type_info(object_type); if (info->isnonobjectid) { SWSS_LOG_ERROR("non object id %s is not supported yet", str_object_type.c_str()); return; } sai_object_id_t object_id; sai_deserialize_object_id(str_object_id, object_id); sai_object_type_t ot = sai_object_type_query(object_id); if (ot != object_type) { SWSS_LOG_ERROR("object type is differnt than provided %s, but oid is %s", str_object_type.c_str(), sai_serialize_object_type(ot).c_str()); return; } sai_object_id_t switch_id = sai_switch_id_query(object_id); if (switch_id == SAI_NULL_OBJECT_ID) { SWSS_LOG_ERROR("failed to find switch id for oid %s", str_object_id.c_str()); return; } // oid is validated and we got switch id const std::string &str_attr_id = fvField(values.at(0)); const std::string &str_attr_value = fvValue(values.at(0)); auto meta = sai_metadata_get_attr_metadata_by_attr_id_name(str_attr_id.c_str()); if (meta == NULL) { SWSS_LOG_ERROR("failed to find attr %s", str_attr_id.c_str()); return; } if (meta->objecttype != ot) { SWSS_LOG_ERROR("attr %s belongs to differnt object type than oid: %s", str_attr_id.c_str(), sai_serialize_object_type(ot).c_str()); return; } // we got attr metadata sai_attribute_t attr; attr.id = meta->attrid; sai_deserialize_attr_value(str_attr_value, *meta, attr); SWSS_LOG_NOTICE("switch id is %s", sai_serialize_object_id(switch_id).c_str()); sai_status_t status = meta_unittests_allow_readonly_set_once(meta->objecttype, meta->attrid); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("failed to enable SET readonly attribute once: %s", sai_serialize_status(status).c_str()); return; } sai_object_meta_key_t meta_key = { .objecttype = ot, .objectkey = { .key = { .object_id = object_id } } }; status = info->set(&meta_key, &attr); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("failed to set %s to %s on %s", str_attr_id.c_str(), str_attr_value.c_str(), str_object_id.c_str()); } else { SWSS_LOG_NOTICE("SUCCESS to set %s to %s on %s", str_attr_id.c_str(), str_attr_value.c_str(), str_object_id.c_str()); } sai_deserialize_free_attribute_value(meta->attrvaluetype, attr); }
void channelOpSetStats( _In_ const std::string &key, _In_ const std::vector<swss::FieldValueTuple> &values) { SWSS_LOG_ENTER(); // NOTE: we need to find stats for specific object, later SAI already have // this feature and this search could be optimized here: // https://github.com/opencomputeproject/SAI/commit/acc83933ff21c68e8ef10c9826de45807fdc0438 sai_object_id_t oid; sai_deserialize_object_id(key, oid); sai_object_type_t ot = sai_object_type_query(oid); if (ot == SAI_OBJECT_TYPE_NULL) { SWSS_LOG_ERROR("invalid object id: %s", key.c_str()); return; } sai_object_id_t switch_id = sai_switch_id_query(oid); if (switch_id == SAI_NULL_OBJECT_ID) { SWSS_LOG_ERROR("unable to get switch_id from oid: %s", key.c_str()); return; } /* * Check if object for statistics was created and exists on switch. */ auto &objectHash = g_switch_state_map.at(switch_id)->objectHash.at(ot); auto it = objectHash.find(key.c_str()); if (it == objectHash.end()) { SWSS_LOG_ERROR("object not found: %s", key.c_str()); return; } /* * Check if object for statistics have statistic map created, if not * create empty map. */ auto &countersMap = g_switch_state_map.at(switch_id)->countersMap; auto mapit = countersMap.find(key); if (mapit == countersMap.end()) countersMap[key] = std::map<int,uint64_t>(); /* * Find stats enum based on object type. In new metadata we have enum on * object type, but here we need to find it manually enum is in format * "sai_" + object_type + "_stat_t" */ std::string lower_ot = sai_serialize_object_type(ot).substr(16); // 16 = skip "SAI_OBJECT_TYPE_" std::transform(lower_ot.begin(), lower_ot.end(), lower_ot.begin(), ::tolower); std::string stat_enum_name = "sai_" + lower_ot + "_stat_t"; const sai_enum_metadata_t* statenum = NULL; for (size_t i = 0; i < sai_metadata_all_enums_count; ++i) { if (sai_metadata_all_enums[i]->name == stat_enum_name) { SWSS_LOG_INFO("found enum %s", stat_enum_name.c_str()); // found statenum = sai_metadata_all_enums[i]; break; } } if (statenum == NULL) { SWSS_LOG_ERROR("failed to find stat enum: %s", stat_enum_name.c_str()); return; } for (auto v: values) { // value format: stat_enum_name:uint64 auto name = fvField(v); uint64_t value; if (sscanf(fvValue(v).c_str(), "%lu", &value) != 1) { SWSS_LOG_ERROR("failed to deserialize %s as couner value uint64_t", fvValue(v).c_str()); } // linear search int enumvalue = -1; for (size_t i = 0; i < statenum->valuescount; ++i) { if (statenum->valuesnames[i] == name) { enumvalue = statenum->values[i]; break; } } if (enumvalue == -1) { SWSS_LOG_ERROR("failed to find enum value: %s", name.c_str()); continue; } SWSS_LOG_DEBUG("writting %s = %lu on %s", name.c_str(), value, key.c_str()); countersMap.at(key)[enumvalue] = value; } }
void handleUnittestChannelOp( _In_ const std::string &op, _In_ const std::string &key, _In_ const std::vector<swss::FieldValueTuple> &values) { /* * Since we will access and modify DB we need to be under mutex. * * NOTE: since this unittest channel is handled in thread, then that means * there is a DELAY from producer and consumer thread in VS, so if user * will set value on the specific READ_ONLY value he should wait for some * time until that value will be propagated to virtual switch. */ MUTEX(); SWSS_LOG_ENTER(); SWSS_LOG_NOTICE("read only SET: op = %s, key = %s", op.c_str(), key.c_str()); if (op == SAI_VS_UNITTEST_ENABLE_UNITTESTS) { bool enable = (key == "true"); meta_unittests_enable(enable); } else if (op == SAI_VS_UNITTEST_SET_RO_OP) { for (const auto &v: values) { SWSS_LOG_DEBUG("attr: %s: %s", fvField(v).c_str(), fvValue(v).c_str()); } if (values.size() != 1) { SWSS_LOG_ERROR("expected 1 value only, but given: %zu", values.size()); return; } const std::string &str_object_type = key.substr(0, key.find(":")); const std::string &str_object_id = key.substr(key.find(":") + 1); sai_object_type_t object_type; sai_deserialize_object_type(str_object_type, object_type); if (object_type == SAI_OBJECT_TYPE_NULL || object_type >= SAI_OBJECT_TYPE_MAX) { SWSS_LOG_ERROR("invalid object type: %d", object_type); return; } auto info = sai_metadata_get_object_type_info(object_type); if (info->isnonobjectid) { SWSS_LOG_ERROR("non object id %s is not supported yet", str_object_type.c_str()); return; } sai_object_id_t object_id; sai_deserialize_object_id(str_object_id, object_id); sai_object_type_t ot = sai_object_type_query(object_id); if (ot != object_type) { SWSS_LOG_ERROR("object type is differnt than provided %s, but oid is %s", str_object_type.c_str(), sai_serialize_object_type(ot).c_str()); return; } sai_object_id_t switch_id = sai_switch_id_query(object_id); if (switch_id == SAI_NULL_OBJECT_ID) { SWSS_LOG_ERROR("failed to find switch id for oid %s", str_object_id.c_str()); return; } // oid is validated and we got switch id const std::string &str_attr_id = fvField(values.at(0)); const std::string &str_attr_value = fvValue(values.at(0)); auto meta = sai_metadata_get_attr_metadata_by_attr_id_name(str_attr_id.c_str()); if (meta == NULL) { SWSS_LOG_ERROR("failed to find attr %s", str_attr_id.c_str()); return; } if (meta->objecttype != ot) { SWSS_LOG_ERROR("attr %s belongs to differnt object type than oid: %s", str_attr_id.c_str(), sai_serialize_object_type(ot).c_str()); return; } // we got attr metadata sai_attribute_t attr; attr.id = meta->attrid; sai_deserialize_attr_value(str_attr_value, *meta, attr); SWSS_LOG_NOTICE("switch id is %s", sai_serialize_object_id(switch_id).c_str()); sai_status_t status = meta_unittests_allow_readonly_set_once(meta->objecttype, meta->attrid); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("failed to enable SET readonly attribute once: %s", sai_serialize_status(status).c_str()); return; } sai_object_meta_key_t meta_key = { .objecttype = ot, .objectkey = { .key = { .object_id = object_id } } }; status = info->set(&meta_key, &attr); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("failed to set %s to %s on %s", str_attr_id.c_str(), str_attr_value.c_str(), str_object_id.c_str()); } else { SWSS_LOG_NOTICE("SUCCESS to set %s to %s on %s", str_attr_id.c_str(), str_attr_value.c_str(), str_object_id.c_str()); } sai_deserialize_free_attribute_value(meta->attrvaluetype, attr); } else {
sai_status_t sai_value_to_str(_In_ sai_attribute_value_t value, _In_ sai_attribute_value_type_t type, _In_ uint32_t max_length, _Out_ char *value_str) { uint32_t ii; uint32_t pos = 0; uint32_t count; stub_object_id_t *stub_object_id; if (NULL == value_str) { STUB_LOG_ERR("NULL value str"); return SAI_STATUS_INVALID_PARAMETER; } *value_str = '\0'; switch (type) { case SAI_ATTR_VAL_TYPE_BOOL: snprintf(value_str, max_length, "%u", value.booldata); break; case SAI_ATTR_VAL_TYPE_CHARDATA: snprintf(value_str, max_length, "%s", value.chardata); break; case SAI_ATTR_VAL_TYPE_U8: snprintf(value_str, max_length, "%u", value.u8); break; case SAI_ATTR_VAL_TYPE_S8: snprintf(value_str, max_length, "%d", value.s8); break; case SAI_ATTR_VAL_TYPE_U16: snprintf(value_str, max_length, "%u", value.u16); break; case SAI_ATTR_VAL_TYPE_S16: snprintf(value_str, max_length, "%d", value.s16); break; case SAI_ATTR_VAL_TYPE_U32: snprintf(value_str, max_length, "%u", value.u32); break; case SAI_ATTR_VAL_TYPE_S32: snprintf(value_str, max_length, "%d", value.s32); break; case SAI_ATTR_VAL_TYPE_U64: snprintf(value_str, max_length, "%" PRIu64, value.u64); break; case SAI_ATTR_VAL_TYPE_S64: snprintf(value_str, max_length, "%" PRId64, value.s64); break; case SAI_ATTR_VAL_TYPE_MAC: snprintf(value_str, max_length, "[%02x:%02x:%02x:%02x:%02x:%02x]", value.mac[0], value.mac[1], value.mac[2], value.mac[3], value.mac[4], value.mac[5]); break; /* IP is in network order */ case SAI_ATTR_VAL_TYPE_IPV4: sai_ipv4_to_str(value.ip4, max_length, value_str, NULL); break; case SAI_ATTR_VAL_TYPE_IPV6: sai_ipv6_to_str(value.ip6, max_length, value_str, NULL); break; case SAI_ATTR_VAL_TYPE_IPADDR: sai_ipaddr_to_str(value.ipaddr, max_length, value_str, NULL); break; case SAI_ATTR_VAL_TYPE_OID: stub_object_id = (stub_object_id_t*)&value.oid; snprintf(value_str, max_length, "%s %x", SAI_TYPE_STR(sai_object_type_query(value.oid)), stub_object_id->data); break; case SAI_ATTR_VAL_TYPE_OBJLIST: case SAI_ATTR_VAL_TYPE_U32LIST: case SAI_ATTR_VAL_TYPE_S32LIST: case SAI_ATTR_VAL_TYPE_VLANLIST: case SAI_ATTR_VAL_TYPE_PORTBREAKOUT: if (SAI_ATTR_VAL_TYPE_PORTBREAKOUT == type) { pos += snprintf(value_str, max_length, "breakout mode %d.", value.portbreakout.breakout_mode); } if (pos > max_length) { return SAI_STATUS_SUCCESS; } count = (SAI_ATTR_VAL_TYPE_OBJLIST == type) ? value.objlist.count : (SAI_ATTR_VAL_TYPE_U32LIST == type) ? value.u32list.count : (SAI_ATTR_VAL_TYPE_S32LIST == type) ? value.s32list.count : (SAI_ATTR_VAL_TYPE_VLANLIST == type) ? value.vlanlist.count : value.portbreakout.port_list.count; pos += snprintf(value_str + pos, max_length - pos, "%u : [", count); if (pos > max_length) { return SAI_STATUS_SUCCESS; } for (ii = 0; ii < count; ii++) { if (SAI_ATTR_VAL_TYPE_OBJLIST == type) { pos += snprintf(value_str + pos, max_length - pos, " %" PRIx64, value.objlist.list[ii]); } else if (SAI_ATTR_VAL_TYPE_U32LIST == type) { pos += snprintf(value_str + pos, max_length - pos, " %u", value.u32list.list[ii]); } else if (SAI_ATTR_VAL_TYPE_S32LIST == type) { pos += snprintf(value_str + pos, max_length - pos, " %d", value.s32list.list[ii]); } else if (SAI_ATTR_VAL_TYPE_VLANLIST == type) { pos += snprintf(value_str + pos, max_length - pos, " %u", value.vlanlist.list[ii]); } else { pos += snprintf(value_str + pos, max_length - pos, " %" PRIx64, value.portbreakout.port_list.list[ii]); } if (pos > max_length) { return SAI_STATUS_SUCCESS; } } snprintf(value_str + pos, max_length - pos, "]"); break; case SAI_ATTR_VAL_TYPE_ACLFIELD: case SAI_ATTR_VAL_TYPE_ACLACTION: /* TODO : implement if in case it is used */ snprintf(value_str, max_length, "Not implemented value type %d", type); return SAI_STATUS_NOT_IMPLEMENTED; case SAI_ATTR_VAL_TYPE_UNDETERMINED: default: snprintf(value_str, max_length, "Invalid/Unsupported value type %d", type); return SAI_STATUS_INVALID_PARAMETER; } return SAI_STATUS_SUCCESS; }
/* * Routine Description: * Create router interface. * * Arguments: * [out] rif_id - router interface id * [in] attr_count - number of attributes * [in] attr_list - array of attributes * * Return Values: * SAI_STATUS_SUCCESS on success * Failure status code on error */ sai_status_t sai_create_router_interface( _Out_ sai_object_id_t *rif_id, _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) { SAI_LOG_ENTER(); sai_status_t status = SAI_STATUS_SUCCESS; switch_api_interface_info_t intf_info; const sai_attribute_t *attribute; sai_router_interface_type_t sai_intf_type = -1; uint32_t index = 0; if (!attr_list) { status = SAI_STATUS_INVALID_PARAMETER; SAI_LOG_ERROR("null attribute list: %s", sai_status_to_string(status)); return status; } memset(&intf_info, 0, sizeof(switch_api_interface_info_t)); intf_info.ipv4_unicast_enabled = true; intf_info.ipv6_unicast_enabled = true; intf_info.ipv4_multicast_enabled = false; intf_info.ipv6_multicast_enabled = false; intf_info.ipv4_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; intf_info.ipv6_urpf_mode = SWITCH_API_RPF_CHECK_DEFAULT; for (index = 0; index < attr_count; index++) { attribute = &attr_list[index]; switch (attribute->id) { case SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID: SAI_ASSERT(sai_object_type_query(attribute->value.oid) == SAI_OBJECT_TYPE_VIRTUAL_ROUTER); intf_info.vrf_handle = (switch_handle_t)attribute->value.oid; break; case SAI_ROUTER_INTERFACE_ATTR_TYPE: sai_intf_type = attribute->value.s32; break; case SAI_ROUTER_INTERFACE_ATTR_PORT_ID: SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_PORT); intf_info.type = SWITCH_API_INTERFACE_L3; intf_info.u.port_lag_handle = attribute->value.oid; break; case SAI_ROUTER_INTERFACE_ATTR_VLAN_ID: SAI_ASSERT(sai_intf_type == SAI_ROUTER_INTERFACE_TYPE_VLAN); intf_info.type = SWITCH_API_INTERFACE_L3_VLAN; intf_info.u.vlan_id = attribute->value.u16; break; case SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS: intf_info.mac_valid = TRUE; memcpy(&intf_info.mac, &attribute->value.mac, 6); break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_STATE: intf_info.ipv4_unicast_enabled = attribute->value.booldata; break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_STATE: intf_info.ipv6_unicast_enabled = attribute->value.booldata; break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V4_MULTICAST_STATE: intf_info.ipv4_multicast_enabled = attribute->value.booldata; break; case SAI_ROUTER_INTERFACE_ATTR_ADMIN_V6_MULTICAST_STATE: intf_info.ipv6_multicast_enabled = attribute->value.booldata; break; case SAI_ROUTER_INTERFACE_ATTR_V4_URPF_MODE: intf_info.ipv4_urpf_mode = sai_to_switch_urpf_mode(attribute->value.s32); break; case SAI_ROUTER_INTERFACE_ATTR_V6_URPF_MODE: intf_info.ipv6_urpf_mode = sai_to_switch_urpf_mode(attribute->value.s32); break; case SAI_ROUTER_INTERFACE_ATTR_MTU: // TODO: break; default: return SAI_STATUS_INVALID_PARAMETER; } } *rif_id = (sai_object_id_t)switch_api_interface_create(device, &intf_info); status = (*rif_id == SWITCH_API_INVALID_HANDLE) ? SAI_STATUS_FAILURE : SAI_STATUS_SUCCESS; if (status != SAI_STATUS_SUCCESS) { SAI_LOG_ERROR("failed to create router interface: %s", sai_status_to_string(status)); } SAI_LOG_EXIT(); return (sai_status_t)status; }