//:: for name, vs_info in value_sets.items(): int value_set_${name}_delete(void *value) { void *entry = tommy_list_remove_existing(&value_set_${name}, value); if(!entry) return 1; free(entry); return 0; }
static switch_status_t switch_l3_remove_from_vrf_list( switch_l3_hash_t *hash_entry) { switch_vrf_route_list_t *vrf_route_list = NULL; void *temp = NULL; switch_ip_addr_t ip_addr; switch_handle_t vrf_handle = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; memset(&ip_addr, 0, sizeof(switch_ip_addr_t)); switch_l3_hash_key_decode(hash_entry, &vrf_handle, &ip_addr); if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { JLG(temp, switch_vrf_v4_routes, vrf_handle); } else { JLG(temp, switch_vrf_v6_routes, vrf_handle); } if (!temp) { return SWITCH_STATUS_ITEM_NOT_FOUND; } vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); tommy_list_remove_existing(&(vrf_route_list->routes), &(hash_entry->vrf_route_node)); vrf_route_list->num_entries--; if (vrf_route_list->num_entries == 0) { if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { JLD(status, switch_vrf_v4_routes, vrf_handle); } else { JLD(status, switch_vrf_v6_routes, vrf_handle); } } return status; }
void* tommy_hashtable_remove_existing(tommy_hashtable* hashtable, tommy_hashtable_node* node) { unsigned pos = node->key & hashtable->bucket_mask; tommy_list_remove_existing(&hashtable->bucket[pos], node); --hashtable->count; return node->data; }
void* tommy_hashdyn_remove_existing(tommy_hashdyn* hashdyn, tommy_hashdyn_node* node) { unsigned pos = node->key & hashdyn->bucket_mask; tommy_list_remove_existing(&hashdyn->bucket[pos], node); --hashdyn->count; hashdyn_shrink_step(hashdyn); return node->data; }
switchlink_db_status_t switchlink_db_oifl_delete(switchlink_handle_t oifl_h) { switchlink_db_oifl_obj_t *obj; obj = switchlink_db_handle_get_obj(oifl_h); if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; } assert(obj->ref_count == 0); tommy_trie_inplace_remove_existing(&switchlink_db_handle_obj_map, &obj->handle_node); tommy_list_remove_existing(&switchlink_db_oifl_obj_list, &obj->list_node); switchlink_free(obj); return SWITCHLINK_DB_STATUS_SUCCESS; }
switch_status_t switch_api_stp_group_vlans_remove(switch_device_t device, switch_handle_t stg_handle, uint16_t vlan_count, switch_handle_t *vlan_handle) { switch_stp_info_t *stp_info = NULL; switch_bd_info_t *bd_info = NULL; switch_stp_vlan_entry_t *vlan_entry = NULL; tommy_node *node = NULL; switch_handle_t bd_handle; int count = 0; if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } stp_info = switch_api_stp_get_internal(stg_handle); if (!stp_info) { return SWITCH_STATUS_INVALID_HANDLE; } for (count = 0; count < vlan_count; count++) { bd_handle = vlan_handle[count]; bd_info = switch_bd_get(bd_handle); if (!bd_info) { return SWITCH_STATUS_INVALID_VLAN_ID; } node = tommy_list_head(&(stp_info->vlan_list)); while (node) { vlan_entry = node->data; if (vlan_entry->bd_handle == bd_handle) { break; } node = node->next; } if (!node) { return SWITCH_STATUS_ITEM_NOT_FOUND; } bd_info->stp_handle = 0; switch_pd_bd_table_update_entry(device, handle_to_id(bd_handle), bd_info); vlan_entry = tommy_list_remove_existing(&(stp_info->vlan_list), node); switch_free(vlan_entry); } return SWITCH_STATUS_SUCCESS; }
switch_status_t switch_api_packet_net_filter_tx_delete( switch_device_t device, switch_packet_tx_key_t *tx_key) { switch_packet_tx_entry_t *tmp_tx_entry = NULL; switch_packet_tx_info_t *tmp_tx_info = NULL; switch_packet_tx_entry_t tx_entry; tommy_node *node = NULL; switch_hostif_info_t *hostif_info = NULL; bool node_found = FALSE; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!tx_key) { SWITCH_API_ERROR("filter tx delete failed. invalid params"); return SWITCH_STATUS_INVALID_PARAMETER; } memset(&tx_entry, 0x0, sizeof(tx_entry)); if (tx_key->handle_valid) { hostif_info = switch_hostif_get(tx_key->hostif_handle); if (!hostif_info) { SWITCH_API_ERROR("invalid hostif handle"); return SWITCH_STATUS_INVALID_HANDLE; } tx_entry.intf_fd = hostif_info->intf_fd; } if (tx_key->vlan_valid) { tx_entry.vlan_id = tx_key->vlan_id; } node = tommy_list_head(&packet_tx_filter_list); while (node) { tmp_tx_info = (switch_packet_tx_info_t *)node->data; tmp_tx_entry = &tmp_tx_info->tx_entry; if (switch_packet_tx_filter_match(tmp_tx_entry, &tx_entry)) { node_found = TRUE; break; } node = node->next; } if (!node_found) { SWITCH_API_ERROR("tx filter delete failed. node find failed"); return SWITCH_STATUS_ITEM_NOT_FOUND; } tommy_list_remove_existing(&packet_tx_filter_list, node); switch_free(tmp_tx_info); return status; }
switchlink_db_status_t switchlink_db_mac_intf_delete( switchlink_handle_t intf_h) { tommy_node *node = tommy_list_head(&switchlink_db_mac_obj_list); while (node) { switchlink_db_mac_obj_t *obj = node->data; node = node->next; if (obj->intf_h == intf_h) { tommy_hashlin_remove_existing(&switchlink_db_mac_obj_hash, &obj->hash_node); tommy_list_remove_existing(&switchlink_db_mac_obj_list, &obj->list_node); switchlink_free(obj); } } return SWITCHLINK_DB_STATUS_SUCCESS; }
switch_status_t switch_sflow_match_entry_remove(switch_sflow_info_t *sflow_info, switch_handle_t entry_hdl) { tommy_node *node = tommy_list_head(&sflow_info->match_list); while (node) { switch_sflow_match_entry_t *obj = (switch_sflow_match_entry_t *)node->data; if (obj->sflow_ace_hdl == entry_hdl) { break; } node = node->next; } if (node) { tommy_list_remove_existing(&sflow_info->match_list, node); return SWITCH_STATUS_SUCCESS; } return SWITCH_STATUS_ITEM_NOT_FOUND; }
switchlink_db_status_t switchlink_db_route_delete(switchlink_db_route_info_t *route_info) { tommy_node * node = tommy_list_head(&switchlink_db_route_obj_list); while (node) { switchlink_db_route_obj_t * obj = node->data; node = node->next; if ((obj->route_info.vrf_h == route_info->vrf_h) && (memcmp(&(obj->route_info.ip_addr), &(route_info->ip_addr), sizeof(switchlink_ip_addr_t)) == 0)) { tommy_list_remove_existing(&switchlink_db_route_obj_list, &obj->list_node); switchlink_free(obj); return SWITCHLINK_DB_STATUS_SUCCESS; } } return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; }
switchlink_db_status_t switchlink_db_mac_delete(switchlink_mac_addr_t mac_addr, switchlink_handle_t bridge_h) { switchlink_db_mac_obj_t *obj; uint32_t hash; uint8_t key[SWITCHLINK_MAC_KEY_LEN]; switchlink_db_mac_key_hash(mac_addr, bridge_h, key, &hash); obj = tommy_hashlin_search( &switchlink_db_mac_obj_hash, switchlink_db_mac_cmp, key, hash); if (!obj) { return SWITCHLINK_DB_STATUS_ITEM_NOT_FOUND; } tommy_hashlin_remove_existing(&switchlink_db_mac_obj_hash, &obj->hash_node); tommy_list_remove_existing(&switchlink_db_mac_obj_list, &obj->list_node); switchlink_free(obj); return SWITCHLINK_DB_STATUS_SUCCESS; }
/* * @function: switch_api_router_mac_delete * Add Router mac to rmac group * @param device - Device to be programmed * @param rmac_handle - ID of the RMAC group * @param mac - Router mac address to be removed from the group * @return: Returns success if mac is deleted successfully */ switch_status_t switch_api_router_mac_delete(switch_device_t device, switch_handle_t rmac_handle, switch_mac_addr_t *mac) { switch_rmac_info_t *rmac_info = NULL; switch_rmac_entry_t *rmac_entry = NULL; tommy_node *node = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!SWITCH_RMAC_HANDLE_VALID(rmac_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } rmac_info = switch_api_rmac_info_get_internal(rmac_handle); if (!rmac_info) { return SWITCH_STATUS_ITEM_NOT_FOUND; } node = tommy_list_head(&(rmac_info->rmac_list)); while (node) { rmac_entry = node->data; if (memcmp(&(rmac_entry->mac), mac, sizeof(switch_mac_addr_t)) == 0) { break; } node = node->next; } if (!node) { return SWITCH_STATUS_ITEM_NOT_FOUND; } switch_smac_rewrite_delete_entry(mac); rmac_entry = tommy_list_remove_existing(&(rmac_info->rmac_list), node); #ifdef SWITCH_PD status = switch_pd_outer_rmac_table_delete_entry(device, rmac_entry->outer_rmac_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } status = switch_pd_inner_rmac_table_delete_entry(device, rmac_entry->inner_rmac_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } #endif free(rmac_entry); return status; }
void* tommy_hashtable_remove(tommy_hashtable* hashtable, tommy_compare_func* cmp, const void* cmp_arg, tommy_hash_t hash) { unsigned pos = hash & hashtable->bucket_mask; tommy_hashtable_node* i = hashtable->bucket[pos]; while (i) { /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ if (i->key == hash && cmp(cmp_arg, i->data) == 0) { tommy_list_remove_existing(&hashtable->bucket[pos], i); --hashtable->count; return i->data; } /* we assume that i->next is still valid also after removing */ i = i->next; } return 0; }
switch_status_t switch_api_sflow_session_delete(switch_device_t device, switch_handle_t sflow_hdl, bool all_cleanup) { #ifdef P4_SFLOW_ENABLE switch_sflow_info_t *sflow_info; sflow_info = switch_sflow_info_get(sflow_hdl); if (!sflow_info) { return SWITCH_STATUS_INVALID_HANDLE; } if (!tommy_list_empty(&sflow_info->match_list) && !all_cleanup) { return SWITCH_STATUS_RESOURCE_IN_USE; } if (all_cleanup) { switch_sflow_match_entry_t *entry; tommy_node *node = NULL; while ((node = tommy_list_head(&sflow_info->match_list)) && node) { entry = (switch_sflow_match_entry_t *)node->data; // could be ingress or egress match entry switch_pd_sflow_match_table_delete(device, entry); tommy_list_remove_existing(&sflow_info->match_list, node); switch_sflow_ace_handle_delete(entry->sflow_ace_hdl); } } switch_pd_sflow_session_delete(device, sflow_info); if (sflow_info->mirror_hdl != SWITCH_API_INVALID_HANDLE) { switch_api_mirror_session_delete(device, sflow_info->mirror_hdl); } switch_sflow_handle_delete(sflow_hdl); return SWITCH_STATUS_SUCCESS; #else (void)device; (void)sflow_hdl; (void)all_cleanup; return SWITCH_STATUS_FAILURE; #endif // P4_SFLOW_ENABLE }
void* tommy_hashdyn_remove(tommy_hashdyn* hashdyn, tommy_compare_func* cmp, const void* cmp_arg, tommy_hash_t hash) { unsigned pos = hash % hashdyn->bucket_max; tommy_hashdyn_node* i = hashdyn->bucket[pos]; while (i) { /* we first check if the hash matches, as in the same bucket we may have multiples hash values */ if (i->key == hash && cmp(cmp_arg, i->data) == 0) { tommy_list_remove_existing(&hashdyn->bucket[pos], i); --hashdyn->count; hashdyn_shrink_step(hashdyn); return i->data; } i = i->next; } return 0; }
switch_status_t switch_api_l3_interface_address_delete( switch_device_t device, switch_handle_t interface_handle, switch_handle_t vrf_handle, switch_ip_addr_t *ip_addr) { switch_interface_info_t *info = NULL; switch_ip_addr_info_t *ip_info = NULL; tommy_node *node = NULL; UNUSED(device); UNUSED(vrf_handle); info = switch_api_interface_get(interface_handle); if (!info) { return SWITCH_STATUS_INVALID_INTERFACE; } // delete from list and decrement member count node = tommy_list_head(&(info->ip_addr)); while (node) { ip_info = node->data; if (SWITCH_L3_IP_TYPE(ip_info) == ip_addr->type && SWITCH_L3_IP_IPV4_ADDRESS(ip_info) == ip_addr->ip.v4addr) { break; } node = node->next; } if (!node) { return SWITCH_STATUS_ITEM_NOT_FOUND; } // remove from list ip_info = tommy_list_remove_existing(&(info->ip_addr), node); info->ip_addr_count--; switch_free(ip_info); return SWITCH_STATUS_SUCCESS; }
switch_status_t switch_api_ecmp_member_delete(switch_device_t device, switch_handle_t ecmp_handle, uint16_t nhop_count, switch_handle_t *nhop_handle_list) { switch_nhop_info_t *nhop_info = NULL; switch_nhop_info_t *e_nhop_info = NULL; switch_spath_info_t *spath_info = NULL; switch_interface_info_t *intf_info = NULL; switch_ecmp_info_t *ecmp_info = NULL; switch_ecmp_member_t *ecmp_member = NULL; tommy_node *node = NULL; switch_handle_t nhop_handle; switch_status_t status = SWITCH_STATUS_SUCCESS; int count = 0; if (!SWITCH_NHOP_HANDLE_VALID(ecmp_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } e_nhop_info = switch_nhop_get(ecmp_handle); if (!e_nhop_info) { return SWITCH_STATUS_INVALID_NHOP; } for (count = 0; count < nhop_count; count++) { nhop_handle = nhop_handle_list[count]; if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { return SWITCH_STATUS_INVALID_NHOP; } spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); ecmp_info = &(SWITCH_NHOP_ECMP_INFO(e_nhop_info)); node = tommy_list_head(&(ecmp_info->members)); while (node) { ecmp_member = (switch_ecmp_member_t *) node->data; if (ecmp_member->nhop_handle == nhop_handle) { break; } node = node->next; } if (!node) { return SWITCH_STATUS_ITEM_NOT_FOUND; } intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); if (!intf_info) { return SWITCH_STATUS_INVALID_INTERFACE; } nhop_info->ref_count--; #if SWITCH_PD if (ecmp_info->count == 1) { status = switch_pd_ecmp_group_table_delete_entry(device, ecmp_info->hw_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } } status = switch_pd_ecmp_member_delete(device, ecmp_info->pd_group_hdl, ecmp_member->mbr_hdl); if (status != SWITCH_STATUS_SUCCESS) { return status; } if (SWITCH_INTF_IS_PORT_L3(intf_info) && intf_info->bd_handle) { status = switch_pd_urpf_bd_table_delete_entry(device, ecmp_member->urpf_hw_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } } #endif ecmp_info->count--; ecmp_member = tommy_list_remove_existing(&(ecmp_info->members), node); switch_free(ecmp_member); } return status; }
void test_hashlin(void) { tommy_list list; tommy_hashlin hashlin; struct object_hash* HASH; unsigned i, n; tommy_node* p; unsigned limit; unsigned count; HASH = malloc(MAX * sizeof(struct object_hash)); for(i=0;i<MAX;++i) { HASH[i].value = i; } START("hashlin stack"); limit = 10 * sqrt(MAX); for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashlin_init(&hashlin); /* insert */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashlin_insert(&hashlin, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashlin_foreach_arg(&hashlin, count_arg, &count); if (count != n) abort(); /* remove */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashlin_remove_existing(&hashlin, &obj->hashnode); } tommy_hashlin_done(&hashlin); } STOP(); START("hashlin queue"); limit = sqrt(MAX) / 8; for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashlin_init(&hashlin); /* insert first run */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashlin_insert(&hashlin, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashlin_foreach_arg(&hashlin, count_arg, &count); if (count != n) abort(); /* insert all the others */ for(;i<MAX;++i) { struct object_hash* obj; /* insert one */ tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashlin_insert(&hashlin, &HASH[i].hashnode, &HASH[i], HASH[i].value); /* remove one */ p = tommy_list_head(&list); obj = p->data; tommy_list_remove_existing(&list, p); tommy_hashlin_remove_existing(&hashlin, &obj->hashnode); } /* remove remaining */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashlin_remove_existing(&hashlin, &obj->hashnode); } tommy_hashlin_done(&hashlin); } STOP(); }
switch_status_t switch_api_packet_net_filter_rx_delete( switch_device_t device, switch_packet_rx_key_t *rx_key) { switch_lag_info_t *lag_info = NULL; switch_port_info_t *port_info = NULL; switch_packet_rx_entry_t *tmp_rx_entry = NULL; switch_packet_rx_entry_t rx_entry; switch_packet_rx_info_t *tmp_rx_info = NULL; switch_handle_type_t handle_type = 0; switch_interface_info_t *intf_info = NULL; switch_handle_t bd_handle = 0; switch_bd_info_t *bd_info = NULL; tommy_node *node = NULL; bool node_found = FALSE; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!rx_key) { SWITCH_API_ERROR("filter rx delete failed. invalid params"); return SWITCH_STATUS_INVALID_PARAMETER; } memset(&rx_entry, 0, sizeof(switch_packet_rx_entry_t)); if (rx_key->port_lag_valid && rx_key->port_lag_handle) { handle_type = switch_handle_get_type(rx_key->port_lag_handle); if (handle_type == SWITCH_HANDLE_TYPE_LAG) { lag_info = switch_api_lag_get_internal(rx_key->port_lag_handle); if (!lag_info) { SWITCH_API_ERROR("invalid lag handle"); return SWITCH_STATUS_INVALID_HANDLE; } rx_entry.ifindex = lag_info->ifindex; } else { port_info = switch_api_port_get_internal(rx_key->port_lag_handle); if (!port_info) { SWITCH_API_ERROR("invalid port handle"); return SWITCH_STATUS_INVALID_HANDLE; } rx_entry.ifindex = port_info->ifindex; } } if (rx_key->handle_valid) { bd_handle = rx_key->handle; handle_type = switch_handle_get_type(rx_key->handle); if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { intf_info = switch_api_interface_get(rx_key->handle); if (!intf_info) { SWITCH_API_ERROR("intf_handle %lx is invalid", rx_key->handle); return SWITCH_STATUS_INVALID_HANDLE; } if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { SWITCH_API_ERROR("intf_handle %lx is not l3", rx_key->handle); return SWITCH_STATUS_INVALID_HANDLE; } bd_handle = intf_info->bd_handle; } bd_info = switch_bd_get(bd_handle); if (!bd_info) { SWITCH_API_ERROR("bd derivation failed %lx", rx_key->handle); return SWITCH_STATUS_INVALID_HANDLE; } rx_entry.bd = handle_to_id(bd_handle); } if (rx_entry.port_valid) { rx_entry.port = handle_to_id(rx_key->port_handle); } rx_entry.bd_valid = rx_key->handle_valid; rx_entry.reason_code = rx_key->reason_code; node = tommy_list_head(&packet_rx_filter_list); while (node) { tmp_rx_info = (switch_packet_rx_info_t *)node->data; tmp_rx_entry = &tmp_rx_info->rx_entry; if (switch_packet_rx_filter_match(tmp_rx_entry, &rx_entry)) { node_found = TRUE; break; } node = node->next; } if (!node_found) { SWITCH_API_ERROR("tx filter delete failed. node find failed"); return SWITCH_STATUS_ITEM_NOT_FOUND; } tommy_list_remove_existing(&packet_rx_filter_list, node); switch_free(tmp_rx_info); return status; }
void *remove_elem_list(void *ll, void *ll_node) { return tommy_list_remove_existing(ll, ll_node); }
switch_status_t switch_api_stp_port_state_clear(switch_device_t device, switch_handle_t stg_handle, switch_handle_t handle) { switch_stp_info_t *stp_info = NULL; switch_interface_info_t *intf_info = NULL; switch_stp_port_entry_t *port_entry = NULL; tommy_node *node = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_handle_t intf_handle = 0; switch_handle_type_t handle_type = 0; if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } if ((!SWITCH_PORT_HANDLE_VALID(handle)) && (!SWITCH_LAG_HANDLE_VALID(handle)) && (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { return SWITCH_STATUS_INVALID_HANDLE; } stp_info = switch_api_stp_get_internal(stg_handle); if (!stp_info) { return SWITCH_STATUS_INVALID_HANDLE; } handle_type = switch_handle_get_type(handle); intf_handle = handle; if (handle_type == SWITCH_HANDLE_TYPE_PORT || handle_type == SWITCH_HANDLE_TYPE_LAG) { status = switch_interface_handle_get( handle, 0x0, &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("stp port state clear failed"); return status; } } intf_info = switch_api_interface_get(intf_handle); if (!intf_info) { return SWITCH_STATUS_INVALID_INTERFACE; } if (SWITCH_INTF_IS_PORT_L3(intf_info)) { return SWITCH_STATUS_INVALID_INTERFACE; } node = tommy_list_head(&(stp_info->port_list)); while (node) { port_entry = node->data; if (port_entry->intf_handle == intf_handle) { break; } node = node->next; } if (!node) { return SWITCH_STATUS_ITEM_NOT_FOUND; } tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node)); switch_free(port_entry); return status; }
switch_status_t switch_api_stp_port_state_set(switch_device_t device, switch_handle_t stg_handle, switch_handle_t handle, switch_stp_state_t state) { switch_stp_info_t *stp_info = NULL; switch_interface_info_t *intf_info = NULL; switch_stp_port_entry_t *port_entry = NULL; tommy_node *node = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_handle_t intf_handle; switch_handle_type_t handle_type = 0; bool new_entry = FALSE; if (!SWITCH_STP_HANDLE_VALID(stg_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } if ((!SWITCH_PORT_HANDLE_VALID(handle)) && (!SWITCH_LAG_HANDLE_VALID(handle)) && (!SWITCH_INTERFACE_HANDLE_VALID(handle))) { return SWITCH_STATUS_INVALID_HANDLE; } stp_info = switch_api_stp_get_internal(stg_handle); if (!stp_info) { return SWITCH_STATUS_INVALID_HANDLE; } handle_type = switch_handle_get_type(handle); intf_handle = handle; if (handle_type == SWITCH_HANDLE_TYPE_PORT || handle_type == SWITCH_HANDLE_TYPE_LAG) { status = switch_interface_handle_get( handle, 0x0, &intf_handle); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("stp port state set failed"); return status; } } intf_info = switch_api_interface_get(intf_handle); if (!intf_info) { return SWITCH_STATUS_INVALID_INTERFACE; } if (SWITCH_INTF_IS_PORT_L3(intf_info)) { return SWITCH_STATUS_INVALID_INTERFACE; } node = tommy_list_head(&stp_info->port_list); while (node) { port_entry = node->data; if (port_entry->intf_handle == intf_handle) { port_entry->intf_state = state; break; } node = node->next; } if (state == SWITCH_PORT_STP_STATE_NONE) { if (!node) { return SWITCH_STATUS_ITEM_NOT_FOUND; } status = switch_stp_update_flood_list(device, stg_handle, intf_handle, state); status = switch_pd_spanning_tree_table_delete_entry(device, port_entry->hw_entry); tommy_list_remove_existing(&(stp_info->port_list), &(port_entry->node)); switch_free(port_entry); } else { if (!node) { new_entry = TRUE; port_entry = switch_malloc(sizeof(switch_stp_port_entry_t), 1); if (!port_entry) { return SWITCH_STATUS_NO_MEMORY; } memset(port_entry, 0, sizeof(switch_stp_port_entry_t)); port_entry->intf_handle = intf_handle; port_entry->intf_state = state; tommy_list_insert_head(&(stp_info->port_list), &(port_entry->node), port_entry); } status = switch_stp_update_flood_list(device, stg_handle, intf_handle, state); if (new_entry) { status = switch_pd_spanning_tree_table_add_entry(device, handle_to_id(stg_handle), intf_info->ifindex, port_entry->intf_state, &port_entry->hw_entry); } else { status = switch_pd_spanning_tree_table_update_entry(device, handle_to_id(stg_handle), intf_info->ifindex, port_entry->intf_state, port_entry->hw_entry); } } return status; }