bool nas_acl_counter_t::push_create_obj_to_npu (npu_id_t npu_id, void* ndi_obj) { ndi_obj_id_t ndi_cntr_id = 0; t_std_error rc = STD_ERR_OK; ndi_acl_counter_t ndi_counter = {0}; ndi_counter.table_id = get_table().get_ndi_obj_id(npu_id); ndi_counter.enable_pkt_count = _enable_pkt_count; ndi_counter.enable_byte_count = _enable_byte_count; if ((rc = ndi_acl_counter_create (npu_id, &ndi_counter, &ndi_cntr_id)) != STD_ERR_OK) { throw nas::base_exception {rc, __PRETTY_FUNCTION__, std::string {"NDI Fail: counter Create Failed for NPU "} + std::to_string (npu_id)}; } // Cache the new counter ID generated by NDI _ndi_obj_ids[npu_id] = ndi_cntr_id; NAS_ACL_LOG_DETAIL ("Switch %d: Created ACL counter in NPU %d; NDI ID 0x%" PRIx64, get_switch().id(), npu_id, ndi_cntr_id); return true; }
bool nas_acl_action_t::_ndi_copy_obj_id_list (ndi_acl_entry_action_t& ndi_action, npu_id_t npu_id, nas::mem_alloc_helper_t& mem_trakr) const { bool found = false; ndi_action.values.ndi_obj_ref_list.count = _nas2ndi_oid_tbl.size(); ndi_action.values.ndi_obj_ref_list.list = mem_trakr.alloc<ndi_obj_id_t> (_nas2ndi_oid_tbl.size()); ndi_obj_id_t* oid_list = ndi_action.values.ndi_obj_ref_list.list; uint_t count = 0; for (auto& nas2ndi_oid_pair: _nas2ndi_oid_tbl) { auto& ndi_oid_tbl = nas2ndi_oid_pair.second; auto it = ndi_oid_tbl.find (npu_id); if (it != ndi_oid_tbl.end ()) { found = true; NAS_ACL_LOG_DETAIL ("%s: NPU ID %d, NDI Obj Id %" PRIx64, name(), npu_id, it->second); oid_list[count++] = it->second; } } return found; }
bool nas_acl_table::push_leaf_attr_to_npu (nas_attr_id_t attr_id, npu_id_t npu_id) { t_std_error rc = STD_ERR_OK; switch (attr_id) { case BASE_ACL_TABLE_PRIORITY: if ((rc = ndi_acl_table_set_priority (npu_id, _ndi_obj_ids.at(npu_id), priority())) != STD_ERR_OK) { throw nas::base_exception {rc, __PRETTY_FUNCTION__, std::string {"NDI Fail: Table "} + std::to_string (table_id()) + std::string {" Priority Set Failed for NPU "} + std::to_string (npu_id)}; } NAS_ACL_LOG_DETAIL ("Switch %d: Modified ACL table %ld Priority in NPU %d", get_switch().id(), table_id(), npu_id); break; default: STD_ASSERT (0); } return true; }
bool nas_acl_action_t::_ndi_copy_one_obj_id (ndi_acl_entry_action_t& ndi_action, npu_id_t npu_id) const { auto it_nas2ndi_oid = _nas2ndi_oid_tbl.begin(); if (it_nas2ndi_oid == _nas2ndi_oid_tbl.end()) {return false;} auto& ndi_oid_tbl = it_nas2ndi_oid->second; auto it_npu2ndi_oid = ndi_oid_tbl.find (npu_id); if (it_npu2ndi_oid == ndi_oid_tbl.end ()) { return false; } NAS_ACL_LOG_DETAIL ("%s: NPU ID %d, NDI Obj Id %" PRIx64, name(), npu_id, it_npu2ndi_oid->second); ndi_action.values.ndi_obj_ref = it_npu2ndi_oid->second; return true; }
bool nas_acl_counter_t::push_delete_obj_to_npu (npu_id_t npu_id) { t_std_error rc = STD_ERR_OK; if ((rc = ndi_acl_counter_delete (npu_id, _ndi_obj_ids.at (npu_id))) != STD_ERR_OK) { throw nas::base_exception {rc, __PRETTY_FUNCTION__, std::string {"NDI Fail: Counter "} + std::to_string (counter_id()) + std::string {" Delete Failed for NPU "} + std::to_string (npu_id)}; } NAS_ACL_LOG_DETAIL ("Switch %d: Deleted ACL counter %ld in NPU %d NDI-ID 0x%" PRIx64, get_switch().id(), counter_id(), npu_id, _ndi_obj_ids.at (npu_id)); _ndi_obj_ids.erase (npu_id); return true; }
bool nas_acl_table::push_create_obj_to_npu (npu_id_t npu_id, void* ndi_obj) { ndi_obj_id_t ndi_tbl_id; t_std_error rc; auto ndi_tbl_p = static_cast<ndi_acl_table_t*> (ndi_obj); if ((rc = ndi_acl_table_create (npu_id, ndi_tbl_p, &ndi_tbl_id)) != STD_ERR_OK) { throw nas::base_exception {rc, __PRETTY_FUNCTION__, std::string {"NDI Fail: Table Create Failed for NPU "} + std::to_string (npu_id)}; } // Cache the new Table ID generated by NDI _ndi_obj_ids[npu_id] = ndi_tbl_id; NAS_ACL_LOG_DETAIL ("Switch %d: Created ACL table in NPU %d; NDI ID 0x%" PRIx64, get_switch().id(), npu_id, ndi_tbl_id); return true; }
bool nas_acl_action_t::operator!= (const nas_acl_action_t& rhs) const { if (action_type() != rhs.action_type()) return true; switch (_a_info.values_type) { case NDI_ACL_ACTION_PORT: if (_ifindex_list != rhs._ifindex_list) { return true; } break; case NDI_ACL_ACTION_OBJ_ID: if (_nas_oid != rhs._nas_oid) { return true; } /* Intentional Fall through */ case NDI_ACL_ACTION_OBJ_ID_LIST: if (_nas2ndi_oid_tbl != rhs._nas2ndi_oid_tbl) { NAS_ACL_LOG_DETAIL ("NAS to NDI OID Table modified for action %s", name()); return true; } break; case NDI_ACL_ACTION_NO_VALUE: break; default: if (memcmp (&_a_info, &rhs._a_info, sizeof(_a_info))) return true; break; } return false; }
bool nas_acl_action_t::copy_action_ndi (ndi_acl_action_list_t& ndi_alist, npu_id_t npu_id, nas::mem_alloc_helper_t& mem_trakr) const { // For actions with value_type other than Obj ID // the NDI value would be readily available - just copy it. ndi_alist.push_back (_a_info); // For actions of value_type NDI Obj ID data - // NDI value has to be extracted based on the NPU // // Exception - Counter actions - the NDI Obj ID is stored externally // in the Counter object if (_a_info.values_type == NDI_ACL_ACTION_OBJ_ID && !is_counter ()) { if (!_ndi_copy_one_obj_id (ndi_alist.back(), npu_id)) { throw nas::base_exception {NAS_ACL_E_FAIL, __PRETTY_FUNCTION__, std::string {name()} + ": Could not find object id for NPU " + std::to_string (npu_id)}; } } if (_a_info.values_type == NDI_ACL_ACTION_OBJ_ID_LIST) { if (!_ndi_copy_obj_id_list (ndi_alist.back(), npu_id, mem_trakr)) { throw nas::base_exception {NAS_ACL_E_FAIL, __PRETTY_FUNCTION__, std::string {name()} + ": Could not find object id for NPU " + std::to_string (npu_id)}; } } if (_a_info.values_type == NDI_ACL_ACTION_PORT) { auto& ndi_action = ndi_alist.back(); if (ndi_action.values.ndi_port.npu_id != npu_id) { ndi_alist.pop_back(); } } if (_a_info.values_type == NDI_ACL_ACTION_PORTLIST) { // Assert to ensure that we are not overwriting existing portlist STD_ASSERT (_a_info.values.ndi_portlist.port_list == NULL); // Build the list of NPU specific ports std::vector<ndi_port_t> ndi_plist; for (auto ifindex: _ifindex_list) { // Convert to NPU and port interface_ctrl_t intf_ctrl {}; nas_acl_utl_ifidx_to_ndi_port (ifindex, &intf_ctrl); if (intf_ctrl.npu_id != npu_id) { continue; } ndi_plist.push_back (ndi_port_t {intf_ctrl.npu_id, intf_ctrl.port_id}); } if (ndi_plist.empty()) { NAS_ACL_LOG_DETAIL("%s: port list is empty, ignore this action", name()); ndi_alist.pop_back(); return true; } auto& ndi_action = ndi_alist.back(); ndi_action.values.ndi_portlist.port_count = ndi_plist.size(); ndi_port_t* plist = mem_trakr.alloc<ndi_port_t> (ndi_plist.size()); ndi_action.values.ndi_portlist.port_list = plist; memcpy (plist, ndi_plist.data(), sizeof (ndi_port_t) * ndi_plist.size()); } 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); } }