void processFdbEntriesForAging() { SWSS_LOG_ENTER(); if (!g_recursive_mutex.try_lock()) { return; } SWSS_LOG_INFO("fdb infos to process: %zu", g_fdb_info_set.size()); uint32_t current = (uint32_t)time(NULL); // find aged fdb entries for (auto it = g_fdb_info_set.begin(); it != g_fdb_info_set.end();) { sai_attribute_t attr; attr.id = SAI_SWITCH_ATTR_FDB_AGING_TIME; sai_status_t status = vs_generic_get(SAI_OBJECT_TYPE_SWITCH, it->fdb_entry.switch_id, 1, &attr); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_WARN("failed to get FDB aging time for switch %s", sai_serialize_object_id(it->fdb_entry.switch_id).c_str()); ++it; continue; } uint32_t aging_time = attr.value.u32; if (aging_time == 0) { // aging is disabled ++it; continue; } if ((current - it->timestamp) >= aging_time) { fdb_info_t fi = *it; processFdbInfo(fi, SAI_FDB_EVENT_AGED); it = g_fdb_info_set.erase(it); } else { ++it; } } g_recursive_mutex.unlock(); }
static sai_status_t create_bridge_ports() { SWSS_LOG_ENTER(); sai_object_id_t switch_id = ss->getSwitchId(); /* * Create bridge port for 1q router. */ sai_attribute_t attr; attr.id = SAI_BRIDGE_PORT_ATTR_TYPE; attr.value.s32 = SAI_BRIDGE_PORT_TYPE_1Q_ROUTER; CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_BRIDGE_PORT, &default_bridge_port_1q_router, ss->getSwitchId(), 1, &attr)); attr.id = SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID; CHECK_STATUS(vs_generic_get(SAI_OBJECT_TYPE_SWITCH, switch_id, 1, &attr)); /* * Create bridge ports for regular ports. */ sai_object_id_t default_1q_bridge_id = attr.value.oid; bridge_port_list_port_based.clear(); for (const auto &port_id: port_list) { SWSS_LOG_DEBUG("create bridge port for port %s", sai_serialize_object_id(port_id).c_str()); sai_attribute_t attrs[4]; attrs[0].id = SAI_BRIDGE_PORT_ATTR_BRIDGE_ID; attrs[0].value.oid = default_1q_bridge_id; attrs[1].id = SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE; attrs[1].value.s32 = SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW; attrs[2].id = SAI_BRIDGE_PORT_ATTR_PORT_ID; attrs[2].value.oid = port_id; attrs[3].id = SAI_BRIDGE_PORT_ATTR_TYPE; attrs[3].value.s32 = SAI_BRIDGE_PORT_TYPE_PORT; sai_object_id_t bridge_port_id; CHECK_STATUS(vs_generic_create(SAI_OBJECT_TYPE_BRIDGE_PORT, &bridge_port_id, switch_id, 4, attrs)); bridge_port_list_port_based.push_back(bridge_port_id); } return SAI_STATUS_SUCCESS; }
static sai_status_t create_scheduler_group_tree( _In_ const std::vector<sai_object_id_t>& sgs, _In_ sai_object_id_t port_id) { SWSS_LOG_ENTER(); sai_attribute_t attrq; std::vector<sai_object_id_t> queues; // in this implementation we have 20 queues per port // (10 in and 10 out), which will be assigned to schedulers uint32_t queues_count = 20; queues.resize(queues_count); attrq.id = SAI_PORT_ATTR_QOS_QUEUE_LIST; attrq.value.objlist.count = queues_count; attrq.value.objlist.list = queues.data(); // NOTE it will do recalculate CHECK_STATUS(vs_generic_get(SAI_OBJECT_TYPE_PORT, port_id, 1, &attrq)); // schedulers groups: 0 1 2 3 4 5 6 7 8 9 a b c // tree index // 0 = 1 2 // 1 = 3 4 5 6 7 8 9 a // 2 = b c (bug on brcm) // 3..c - have both QUEUES, each one 2 // sg 0 (2 groups) { sai_object_id_t sg_0 = sgs.at(0); sai_attribute_t attr; attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT; attr.value.u32 = 2; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, sg_0, &attr)); uint32_t list_count = 2; std::vector<sai_object_id_t> list; list.push_back(sgs.at(1)); list.push_back(sgs.at(2)); attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; attr.value.objlist.count = list_count; attr.value.objlist.list = list.data(); CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, sg_0, &attr)); } uint32_t queue_index = 0; // sg 1 (8 groups) { sai_object_id_t sg_1 = sgs.at(1); sai_attribute_t attr; attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT; attr.value.u32 = 8; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, sg_1, &attr)); uint32_t list_count = 8; std::vector<sai_object_id_t> list; list.push_back(sgs.at(3)); list.push_back(sgs.at(4)); list.push_back(sgs.at(5)); list.push_back(sgs.at(6)); list.push_back(sgs.at(7)); list.push_back(sgs.at(8)); list.push_back(sgs.at(9)); list.push_back(sgs.at(0xa)); attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; attr.value.objlist.count = list_count; attr.value.objlist.list = list.data(); CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, sg_1, &attr)); // now assign queues to level 1 scheduler groups, for (size_t i = 0; i < list.size(); ++i) { sai_object_id_t childs[2]; childs[0] = queues[queue_index]; // first half are in queues childs[1] = queues[queue_index + queues_count/2]; // second half are out queues // for each scheduler set 2 queues attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; attr.value.objlist.count = 2; attr.value.objlist.list = childs; queue_index++; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, list.at(i), &attr)); attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT; attr.value.u32 = 2; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, list.at(i), &attr)); } } // sg 2 (2 groups) { sai_object_id_t sg_2 = sgs.at(2); sai_attribute_t attr; attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT; attr.value.u32 = 2; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, sg_2, &attr)); uint32_t list_count = 2; std::vector<sai_object_id_t> list; list.push_back(sgs.at(0xb)); list.push_back(sgs.at(0xc)); attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; attr.value.objlist.count = list_count; attr.value.objlist.list = list.data(); CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, sg_2, &attr)); for (size_t i = 0; i < list.size(); ++i) { sai_object_id_t childs[2]; // for each scheduler set 2 queues childs[0] = queues[queue_index]; // first half are in queues childs[1] = queues[queue_index + queues_count/2]; // second half are out queues attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_LIST; attr.value.objlist.count = 2; attr.value.objlist.list = childs; queue_index++; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, list.at(i), &attr)); attr.id = SAI_SCHEDULER_GROUP_ATTR_CHILD_COUNT; attr.value.u32 = 2; CHECK_STATUS(vs_generic_set(SAI_OBJECT_TYPE_SCHEDULER_GROUP, list.at(i), &attr)); } } return SAI_STATUS_SUCCESS; }