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; }
switch_status_t switch_api_packet_net_filter_rx_create( switch_device_t device, switch_packet_rx_key_t *rx_key, switch_packet_rx_action_t *rx_action) { switch_hostif_info_t *hostif_info = NULL; switch_lag_info_t *lag_info = NULL; switch_port_info_t *port_info = NULL; switch_packet_rx_entry_t rx_entry; switch_packet_rx_info_t *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; switch_ifindex_t ifindex = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!rx_key || !rx_action) { SWITCH_API_ERROR("filter rx create failed. invalid params"); return SWITCH_STATUS_INVALID_PARAMETER; } memset(&rx_entry, 0x0, sizeof(rx_entry)); if (rx_key->port_lag_valid) { 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; } 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; } ifindex = port_info->ifindex; } rx_entry.ifindex_valid = TRUE; } 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_valid = TRUE; } if (rx_action->hostif_handle) { hostif_info = switch_hostif_get(rx_action->hostif_handle); if (!hostif_info) { SWITCH_API_ERROR("invalid hostif handle"); return SWITCH_STATUS_INVALID_HANDLE; } } rx_entry.bd = handle_to_id(bd_handle); rx_entry.ifindex = ifindex; rx_entry.port_valid = rx_key->port_valid; rx_entry.port = handle_to_id(rx_key->port_handle); rx_entry.reason_code_valid = rx_key->reason_code_valid; rx_entry.reason_code = rx_key->reason_code; rx_entry.reason_code_mask = rx_key->reason_code_mask; rx_entry.priority = rx_key->priority; rx_info = switch_malloc(sizeof(switch_packet_rx_info_t), 0x1); if (!rx_info) { SWITCH_API_ERROR("port %lx port_lag %lx handle %lx malloc failed", rx_key->port_handle, rx_key->port_lag_handle, rx_key->handle); return SWITCH_STATUS_NO_MEMORY; } memset(rx_info, 0x0, sizeof(switch_packet_rx_info_t)); memcpy(&rx_info->rx_entry, &rx_entry, sizeof(rx_entry)); rx_info->vlan_id = rx_action->vlan_id; rx_info->vlan_action = rx_action->vlan_action; if (hostif_info) { rx_info->intf_fd = hostif_info->intf_fd; } SWITCH_API_INFO( "net_filter_rx_create: port 0x%lx, port_lag_hdl = 0x%lx, " "if_bd_hdl 0x%lx, rcode 0x%x, rcode_mask 0x%x " "vlan_id %d, fd %d, action %d\n", rx_key->port_valid ? rx_key->port_handle : 0, rx_key->port_lag_valid ? rx_key->port_lag_handle : 0, rx_key->handle_valid ? rx_key->handle : 0, rx_key->reason_code_valid ? rx_key->reason_code : 0, rx_key->reason_code_mask, rx_info->vlan_id, rx_info->vlan_action, rx_info->intf_fd); /* * Adding an element to the list results in sorting the list. * tommy does not have a way to compare and insert the elements */ tommy_list_insert_head(&packet_rx_filter_list, &(rx_info->node), rx_info); tommy_list_sort(&packet_rx_filter_list, switch_packet_rx_filter_priority_compare); return status; }
switch_status_t switch_nhop_ifindex_get(switch_handle_t nhop_handle, switch_ifindex_t *ifindex, bool *flood, uint32_t *mc_index) { switch_nhop_info_t *nhop_info = NULL; switch_interface_info_t *intf_info = NULL; switch_neighbor_info_t *neighbor_info = NULL; switch_api_neighbor_t *neighbor = NULL; switch_api_mac_entry_t mac_entry; switch_mac_info_t *mac_info = NULL; switch_handle_t neighbor_handle; switch_bd_info_t *bd_info = NULL; switch_port_info_t *tmp_port_info = NULL; switch_lag_info_t *tmp_lag_info = NULL; switch_interface_info_t *tmp_intf_info = NULL; switch_api_mac_entry_t *tmp_mac_entry = NULL; switch_handle_type_t handle_type = 0; switch_handle_t encap_if; switch_spath_info_t *spath_info = NULL; nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { return SWITCH_STATUS_INVALID_HANDLE; } spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); intf_info = switch_api_interface_get(spath_info->nhop_key.intf_handle); if (!intf_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = intf_info->ifindex; *flood = FALSE; *mc_index = 0; if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { encap_if = SWITCH_INTF_TUNNEL_ENCAP_OUT_IF(intf_info); intf_info = switch_api_interface_get(encap_if); if (!intf_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = intf_info->ifindex; SWITCH_API_TRACE("%s:%d ifindex for tunnel interface: %x", __FUNCTION__, __LINE__, *ifindex); } if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_L3_VLAN) { neighbor_handle = spath_info->neighbor_handle; if (neighbor_handle == SWITCH_API_INVALID_HANDLE || neighbor_handle == 0) { *ifindex = switch_api_cpu_glean_ifindex(); } else { neighbor_info = switch_neighbor_info_get(neighbor_handle); if (!neighbor_info) { return SWITCH_STATUS_INVALID_HANDLE; } neighbor = &neighbor_info->neighbor; memset(&mac_entry, 0, sizeof(switch_api_mac_entry_t)); mac_entry.vlan_handle = intf_info->bd_handle; memcpy(&mac_entry.mac, &neighbor->mac_addr, ETH_LEN); mac_info = switch_mac_table_entry_find(&mac_entry); if (!mac_info) { bd_info = switch_bd_get(intf_info->bd_handle); if (!bd_info) { return SWITCH_STATUS_INVALID_HANDLE; } *mc_index = handle_to_id(bd_info->uuc_mc_index); *flood = TRUE; } else { tmp_mac_entry = &mac_info->mac_entry; handle_type = switch_handle_get_type(tmp_mac_entry->handle); switch (handle_type) { case SWITCH_HANDLE_TYPE_PORT: tmp_port_info = switch_api_port_get_internal(tmp_mac_entry->handle); if (!tmp_port_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = tmp_port_info->ifindex; break; case SWITCH_HANDLE_TYPE_LAG: tmp_lag_info = switch_api_lag_get_internal(tmp_mac_entry->handle); if (!tmp_lag_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = tmp_lag_info->ifindex; break; case SWITCH_HANDLE_TYPE_INTERFACE: tmp_intf_info = switch_api_interface_get(tmp_mac_entry->handle); if (!tmp_intf_info) { return SWITCH_STATUS_INVALID_HANDLE; } *ifindex = tmp_intf_info->ifindex; break; default: return SWITCH_STATUS_INVALID_HANDLE; } } } } return SWITCH_STATUS_SUCCESS; }