static switch_l3_hash_t *switch_l3_lookup_lpm_trie(switch_handle_t vrf, switch_ip_addr_t *ip_addr) { switch_lpm_trie_t *lpm_trie = NULL; void *temp = NULL; switch_l3_hash_t *hash_entry; char *prefix; uint32_t v4addr; if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { JLG(temp, switch_vrf_v4_lpm_tries, vrf); v4addr = htonl(ip_addr->ip.v4addr); prefix = (char *)(&v4addr); } else { JLG(temp, switch_vrf_v6_lpm_tries, vrf); prefix = (char *)(ip_addr->ip.v6addr); } if (!temp) { SWITCH_API_ERROR( "%s:%d: No LPM trie for this vrf %u!", __FUNCTION__, __LINE__, vrf); return NULL; } lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp); if (switch_lpm_trie_lookup(lpm_trie, prefix, (unsigned long *)(&hash_entry))) return hash_entry; SWITCH_API_ERROR("%s: hash_entry not found.\n", __FUNCTION__); return NULL; }
switch_handle_t switch_api_neighbor_entry_add(switch_device_t device, switch_api_neighbor_t *neighbor) { switch_neighbor_info_t *neighbor_info = NULL; switch_interface_info_t *intf_info = NULL; switch_handle_t handle = SWITCH_API_INVALID_HANDLE; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_nhop_info_t *nhop_info = NULL; switch_spath_info_t *spath_info = NULL; switch_handle_t nhop_handle = 0; intf_info = switch_api_interface_get(neighbor->interface); if (!intf_info) { SWITCH_API_ERROR( "%s:%d: invalid interface for rewrite!", __FUNCTION__, __LINE__); return SWITCH_STATUS_INVALID_INTERFACE; } handle = switch_neighbor_info_create(); neighbor_info = switch_neighbor_info_get(handle); memcpy(&neighbor_info->neighbor, neighbor, sizeof(switch_api_neighbor_t)); #ifdef SWITCH_PD nhop_handle = neighbor->nhop_handle; if (neighbor->nhop_handle == SWITCH_API_INVALID_HANDLE) { // check for neighbor type if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_NONE && neighbor->rw_type == SWITCH_API_NEIGHBOR_RW_TYPE_L3) { switch_nhop_key_t nhop_key; // allocate nhop and set neighbor handle memset(&nhop_key, 0, sizeof(nhop_key)); nhop_key.ip_addr = neighbor->ip_addr; nhop_key.intf_handle = neighbor->interface; nhop_key.ip_addr_valid = 1; nhop_handle = switch_api_nhop_create(device, &nhop_key); } } if (nhop_handle != SWITCH_API_INVALID_HANDLE && nhop_handle) { nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { return SWITCH_API_INVALID_HANDLE; } spath_info = &(SWITCH_NHOP_SPATH_INFO(nhop_info)); spath_info->neighbor_handle = handle; neighbor_info->neighbor.nhop_handle = nhop_handle; status = switch_api_nhop_update(device, nhop_handle); status = switch_api_neighbor_entry_add_rewrite(device, handle, neighbor_info); } else { status = switch_api_neighbor_entry_add_tunnel_rewrite(device, neighbor_info); } #endif if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR( "%s:%d: failed to create neighbor entry!", __FUNCTION__, __LINE__); } neighbor->nhop_handle = nhop_handle; return handle; }
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; }
static uint16_t switch_dmac_rewrite_insert_hash(switch_device_t device, switch_mac_addr_t *mac) { unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; unsigned int len = 0; uint32_t hash = 0; uint16_t mac_index = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_dmac_rewrite_t *dmac_rewrite = NULL; dmac_rewrite = switch_dmac_rewrite_search_hash(mac); if (dmac_rewrite) { mac_index = dmac_rewrite->index; dmac_rewrite->ref_count++; } else { switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); dmac_rewrite = switch_malloc(sizeof(switch_dmac_rewrite_t), 1); if (!dmac_rewrite) { return mac_index; } mac_index = switch_api_id_allocator_allocate(dmac_rewrite_index_allocator); memcpy(&dmac_rewrite->mac, mac, sizeof(switch_mac_addr_t)); dmac_rewrite->index = mac_index; dmac_rewrite->ref_count = 1; status = switch_pd_tunnel_dmac_rewrite_table_add_entry( device, mac_index, mac, &dmac_rewrite->rewrite_entry); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR( "%s:%d: unable to add tunnel dmac entry!", __FUNCTION__, __LINE__); return mac_index; } tommy_hashtable_insert( &switch_dmac_rewrite_table, &(dmac_rewrite->node), dmac_rewrite, hash); } return mac_index; }
static switch_status_t switch_dmac_rewrite_delete_hash(switch_device_t device, switch_mac_addr_t *mac) { switch_dmac_rewrite_t *dmac_rewrite = NULL; unsigned char key[SWITCH_DMAC_REWRITE_HASH_KEY_SIZE]; unsigned int len = 0; uint32_t hash = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; dmac_rewrite = switch_dmac_rewrite_search_hash(mac); if (!dmac_rewrite) { return SWITCH_STATUS_ITEM_NOT_FOUND; } dmac_rewrite->ref_count--; if (dmac_rewrite->ref_count == 0) { switch_dmac_rewrite_hash_key_init(key, mac, &len, &hash); dmac_rewrite = tommy_hashtable_remove( &switch_dmac_rewrite_table, switch_dmac_rewrite_hash_cmp, key, hash); status = switch_pd_tunnel_dmac_rewrite_table_delete_entry( device, dmac_rewrite->rewrite_entry); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR( "%s:%d unabl to delete tunnel dmac entry!", __FUNCTION__, __LINE__); return status; } switch_api_id_allocator_release(dmac_rewrite_index_allocator, dmac_rewrite->index); switch_free(dmac_rewrite); } return status; }
void switch_packet_tx_switched(switch_packet_header_t *packet_header, char *in_packet, int in_packet_size) { int packet_size = 0; static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; switch_ethernet_header_t *eth_header = NULL; switch_vlan_header_t *vlan_header = NULL; switch_vlan_t vlan_id1 = 0; switch_packet_tx_entry_t tx_entry; switch_packet_tx_info_t *tx_info = NULL; switch_status_t status; eth_header = (switch_ethernet_header_t *)in_packet; if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { vlan_header = (switch_vlan_header_t *)(in_packet + 2 * ETH_LEN); uint16_t *vlan_h = (uint16_t *)(vlan_header) + 1; vlan_id1 = ntohs(*vlan_h); } tx_entry.fd_valid = false; tx_entry.vlan_id = vlan_id1; status = switch_packet_tx_info_get(&tx_entry, &tx_info); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("net filter tx not found. dropping packet"); return; } memset(packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE); switch_packet_tx_bd_transform( in_packet, in_packet_size, packet, &packet_size, tx_info); switch_packet_tx_to_hw(packet_header, packet, packet_size); }
switch_status_t switch_api_l3_route_lookup(switch_device_t device, switch_handle_t vrf, switch_ip_addr_t *ip_addr, switch_handle_t *nhop_handle) { switch_l3_hash_t *hash_entry = NULL; switch_nhop_info_t *nhop_info = NULL; if (switch_l3_host_entry(ip_addr)) { // host entry, first search hash hash_entry = switch_l3_search_hash(vrf, ip_addr); } if (!hash_entry) { // try LPM lookup hash_entry = switch_l3_lookup_lpm_trie(vrf, ip_addr); } if (!hash_entry) { *nhop_handle = SWITCH_API_INVALID_HANDLE; return SWITCH_STATUS_ITEM_NOT_FOUND; } nhop_info = switch_nhop_get(hash_entry->nhop_handle); if (!nhop_info) { SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__); *nhop_handle = SWITCH_API_INVALID_HANDLE; return SWITCH_STATUS_ITEM_NOT_FOUND; } *nhop_handle = hash_entry->nhop_handle; return SWITCH_STATUS_SUCCESS; }
static switch_status_t switch_l3_remove_from_lpm_trie( switch_handle_t vrf, switch_ip_addr_t *ip_addr) { switch_lpm_trie_t *lpm_trie = NULL; void *temp = NULL; char *prefix; uint32_t v4addr; switch_status_t status = SWITCH_STATUS_SUCCESS; if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { JLG(temp, switch_vrf_v4_lpm_tries, vrf); v4addr = htonl(ip_addr->ip.v4addr); prefix = (char *)(&v4addr); } else { JLG(temp, switch_vrf_v6_lpm_tries, vrf); prefix = (char *)(ip_addr->ip.v6addr); } if (!temp) { SWITCH_API_ERROR( "%s:%d: No LPM trie for this vrf %u!", __FUNCTION__, __LINE__, vrf); return SWITCH_STATUS_ITEM_NOT_FOUND; } lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp); switch_lpm_trie_delete(lpm_trie, prefix, ip_addr->prefix_len); if (switch_lpm_trie_size(lpm_trie) == 0) { if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { JLD(status, switch_vrf_v4_lpm_tries, vrf); } else { JLD(status, switch_vrf_v6_lpm_tries, vrf); } } return status; }
switch_status_t switch_api_neighbor_entry_remove( switch_device_t device, switch_handle_t neighbor_handle) { switch_neighbor_info_t *neighbor_info = NULL; switch_api_neighbor_t *neighbor = NULL; switch_nhop_info_t *nhop_info = NULL; switch_interface_info_t *intf_info = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!SWITCH_NEIGHBOR_HANDLE_VALID(neighbor_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } neighbor_info = switch_neighbor_info_get(neighbor_handle); if (!neighbor_info) { return SWITCH_STATUS_ITEM_NOT_FOUND; } #ifdef SWITCH_PD if (neighbor_info->neighbor.nhop_handle) { status = switch_pd_rewrite_table_delete_entry(device, neighbor_info->rewrite_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } neighbor = &neighbor_info->neighbor; intf_info = switch_api_interface_get(neighbor->interface); if (!intf_info) { SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__); return SWITCH_STATUS_INVALID_INTERFACE; } switch_neighbor_dmac_delete_hash( device, intf_info->bd_handle, &neighbor->mac_addr); } else { status = switch_dmac_rewrite_delete_hash(device, &neighbor_info->neighbor.mac_addr); if (status != SWITCH_STATUS_SUCCESS) { return status; } status = switch_pd_tunnel_rewrite_table_delete_entry( device, neighbor_info->rewrite_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } } #endif switch_neighbor_info_delete(neighbor_handle); nhop_info = switch_nhop_get(neighbor_info->neighbor.nhop_handle); if (nhop_info) { nhop_info->u.spath.neighbor_handle = 0; status = switch_api_nhop_update(device, neighbor_info->neighbor.nhop_handle); if (nhop_info->valid == 0) { switch_api_nhop_delete(device, neighbor_info->neighbor.nhop_handle); } } return status; }
static switch_status_t switch_l3_insert_into_lpm_trie( switch_handle_t vrf, switch_ip_addr_t *ip_addr, switch_l3_hash_t *hash_entry) { switch_lpm_trie_t *lpm_trie = NULL; void *temp = NULL; size_t key_width_bytes; char *prefix; uint32_t v4addr; if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { JLG(temp, switch_vrf_v4_lpm_tries, vrf); key_width_bytes = 4; v4addr = htonl(ip_addr->ip.v4addr); prefix = (char *)(&v4addr); } else { JLG(temp, switch_vrf_v6_lpm_tries, vrf); key_width_bytes = 16; prefix = (char *)(ip_addr->ip.v6addr); } if (!temp) { lpm_trie = switch_lpm_trie_create(key_width_bytes, TRUE); if (!lpm_trie) { SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); return SWITCH_STATUS_NO_MEMORY; } if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { JLI(temp, switch_vrf_v4_lpm_tries, vrf); } else { JLI(temp, switch_vrf_v6_lpm_tries, vrf); } *(unsigned long *)temp = (unsigned long)(lpm_trie); } lpm_trie = (switch_lpm_trie_t *)(*(unsigned long *)temp); switch_lpm_trie_insert( lpm_trie, prefix, ip_addr->prefix_len, (unsigned long)hash_entry); return SWITCH_STATUS_SUCCESS; }
switch_status_t switch_smac_rewrite_delete_entry(switch_mac_addr_t *mac) { switch_smac_entry_t *smac_entry = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_device_t device = SWITCH_DEV_ID; smac_entry = switch_smac_rewrite_search_entry(mac); if (!smac_entry) { SWITCH_API_ERROR("%s:%d: unable to find mac!", __FUNCTION__, __LINE__); return SWITCH_STATUS_ITEM_NOT_FOUND; } smac_entry->ref_count--; if (smac_entry->ref_count == 0) { switch_pd_smac_rewrite_table_delete_entry(device, smac_entry); switch_smac_rewrite_hash_delete(smac_entry); switch_api_id_allocator_release(smac_rewrite_index_allocator, smac_entry->smac_index); free(smac_entry); } return status; }
void switch_packet_rx_to_host(switch_packet_header_t *packet_header, char *packet, int packet_size) { switch_cpu_header_t *cpu_header = NULL; switch_packet_rx_info_t *rx_info = NULL; static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; switch_packet_rx_entry_t rx_entry; int intf_fd = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; cpu_header = &packet_header->cpu_header; memset(&rx_entry, 0x0, sizeof(rx_entry)); rx_entry.port = cpu_header->ingress_port; rx_entry.ifindex = cpu_header->ingress_ifindex; rx_entry.bd = cpu_header->ingress_bd; rx_entry.reason_code = cpu_header->reason_code; status = switch_packet_rx_info_get(&rx_entry, &rx_info); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("failed to find fd. dropping packet"); return; } SWITCH_API_INFO("Rx packet reason_code 0x%x - send to fd %d, action %d\n", rx_entry.reason_code, rx_info->intf_fd, rx_info->vlan_action); switch_packet_rx_transform(packet_header, in_packet, packet, &packet_size); intf_fd = rx_info->intf_fd; if (write(intf_fd, in_packet, packet_size) < 0) { perror("sendto host interface failed"); return; } return; }
static switch_status_t switch_l3_insert_into_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; 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) { vrf_route_list = switch_malloc(sizeof(switch_vrf_route_list_t), 1); if (!vrf_route_list) { SWITCH_API_ERROR("%s:%d: No memory!", __FUNCTION__, __LINE__); return SWITCH_STATUS_NO_MEMORY; } tommy_list_init(&(vrf_route_list->routes)); vrf_route_list->num_entries = 0; if (ip_addr.type == SWITCH_API_IP_ADDR_V4) { JLI(temp, switch_vrf_v4_routes, vrf_handle); } else { JLI(temp, switch_vrf_v6_routes, vrf_handle); } *(unsigned long *)temp = (unsigned long)(vrf_route_list); } vrf_route_list = (switch_vrf_route_list_t *)(*(unsigned long *)temp); tommy_list_insert_tail( &(vrf_route_list->routes), &(hash_entry->vrf_route_node), hash_entry); vrf_route_list->num_entries++; return SWITCH_STATUS_SUCCESS; }
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; }
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; }
void switch_packet_rx_transform(switch_packet_header_t *packet_header, char *transformed_packet, char *packet, int *packet_size) { switch_cpu_header_t *cpu_header = NULL; switch_packet_rx_info_t *rx_info = NULL; switch_ethernet_header_t *eth_header = NULL; switch_vlan_header_t *vlan_header = NULL; switch_packet_rx_entry_t rx_entry; uint16_t offset = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; cpu_header = &packet_header->cpu_header; memset(&rx_entry, 0x0, sizeof(rx_entry)); rx_entry.port = cpu_header->ingress_port; rx_entry.ifindex = cpu_header->ingress_ifindex; rx_entry.bd = cpu_header->ingress_bd; rx_entry.reason_code = cpu_header->reason_code; status = switch_packet_rx_info_get(&rx_entry, &rx_info); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("failed to find filter. packet not transformed"); memcpy(transformed_packet, packet, *packet_size); return; } if (rx_info->vlan_action == SWITCH_PACKET_VLAN_ADD) { eth_header = (switch_ethernet_header_t *)packet; if (ntohs(eth_header->ether_type) != SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { offset = 2 * ETH_LEN; memcpy(transformed_packet, packet, offset); vlan_header = (switch_vlan_header_t *)(transformed_packet + offset); vlan_header->tpid = htons(SWITCH_ETHERTYPE_DOT1Q); uint16_t *vlan_h = (uint16_t *)(vlan_header) + 1; *vlan_h = htons(rx_info->vlan_id); memcpy(transformed_packet + offset + sizeof(switch_vlan_header_t), packet + offset, *packet_size - offset); *packet_size += sizeof(switch_vlan_header_t); } else { memcpy(transformed_packet, packet, *packet_size); } } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_REMOVE) { eth_header = (switch_ethernet_header_t *)packet; if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { offset = 2 * ETH_LEN; memcpy(transformed_packet, packet, offset); memcpy(transformed_packet, packet + offset, *packet_size - offset); *packet_size -= sizeof(switch_vlan_header_t); } else { memcpy(transformed_packet, packet, *packet_size); } } else if (rx_info->vlan_action == SWITCH_PACKET_VLAN_SWAP) { eth_header = (switch_ethernet_header_t *)packet; if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q && rx_info->vlan_id) { offset = 2 * ETH_LEN; vlan_header = (switch_vlan_header_t *)(transformed_packet + offset); vlan_header->vid = htons(rx_info->vlan_id); } else { memcpy(transformed_packet, packet, *packet_size); } } else { memcpy(transformed_packet, packet, *packet_size); } }
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_neighbor_entry_add_rewrite( switch_device_t device, switch_handle_t neighbor_handle, switch_neighbor_info_t *neighbor_info) { switch_status_t status = SWITCH_STATUS_SUCCESS; uint16_t nhop_index = 0; switch_api_neighbor_t *neighbor = NULL; switch_interface_info_t *intf_info = NULL; switch_tunnel_info_t *tunnel_info = NULL; uint16_t tunnel_index = 0; switch_encap_type_t encap_type = 0; uint16_t bd = 0; neighbor = &neighbor_info->neighbor; nhop_index = handle_to_id(neighbor->nhop_handle); intf_info = switch_api_interface_get(neighbor->interface); if (!intf_info) { SWITCH_API_ERROR("%s:%d invalid interface!", __FUNCTION__, __LINE__); return SWITCH_STATUS_INVALID_INTERFACE; } if (intf_info->ln_bd_handle) { bd = handle_to_id(intf_info->ln_bd_handle); } else { bd = handle_to_id(intf_info->bd_handle); } if (neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L2VPN || neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_L3VPN || neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L2VPN || neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_SWAP_PUSH_L3VPN || neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L2VPN || neighbor->neigh_type == SWITCH_API_NEIGHBOR_MPLS_PUSH_L3VPN) { tunnel_index = handle_to_id(neighbor->interface); status = switch_pd_rewrite_table_mpls_rewrite_add_entry( device, bd, nhop_index, tunnel_index, neighbor->neigh_type, neighbor->mac_addr, neighbor->mpls_label, neighbor->header_count, &neighbor_info->rewrite_entry); } else if (SWITCH_INTF_TYPE(intf_info) == SWITCH_API_INTERFACE_TUNNEL) { tunnel_index = handle_to_id(neighbor->interface); tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); status = switch_pd_rewrite_table_tunnel_rewrite_add_entry( device, bd, nhop_index, neighbor->mac_addr, neighbor->neigh_type, neighbor->rw_type, tunnel_index, encap_type, &neighbor_info->rewrite_entry); } } else { status = switch_pd_rewrite_table_unicast_rewrite_add_entry( device, bd, nhop_index, neighbor->mac_addr, neighbor->rw_type, &neighbor_info->rewrite_entry); } switch_neighbor_dmac_insert_hash( device, intf_info->bd_handle, &neighbor->mac_addr, neighbor_handle); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR( "%s:%d: Unable to add unicast rewrite entry!.", __FUNCTION__, __LINE__); } return status; }
void switch_packet_tx_from_host(int intf_fd) { switch_hostif_info_t *hostif_info = NULL; int packet_size = 0; int in_packet_size = 0; static char in_packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; static char packet[SWITCH_PACKET_MAX_BUFFER_SIZE]; void *temp = NULL; switch_packet_header_t packet_header; switch_fabric_header_t *fabric_header = NULL; switch_cpu_header_t *cpu_header = NULL; switch_ethernet_header_t *eth_header = NULL; switch_vlan_header_t *vlan_header = NULL; switch_vlan_t vlan_id1 = 0; switch_packet_tx_entry_t tx_entry; switch_packet_tx_info_t *tx_info = NULL; switch_device_t device = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; memset(in_packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE); memset(packet, 0x0, SWITCH_PACKET_MAX_BUFFER_SIZE); while ((in_packet_size = read(intf_fd, in_packet, sizeof(in_packet))) > 0) { JLG(temp, switch_intf_fd_array, intf_fd); hostif_info = (switch_hostif_info_t *)(*(unsigned long *)temp); if (!hostif_info) { perror("invalid hostif fd"); return; } SWITCH_API_TRACE("Received packet from host port %s through netdev\n", hostif_info->hostif.intf_name); eth_header = (switch_ethernet_header_t *)in_packet; if (ntohs(eth_header->ether_type) == SWITCH_ETHERTYPE_DOT1Q) { vlan_header = (switch_vlan_header_t *)(in_packet + 2 * ETH_LEN); uint16_t *vlan_h = (uint16_t *)(vlan_header) + 1; vlan_id1 = ntohs(*vlan_h); } tx_entry.intf_fd = intf_fd; tx_entry.vlan_id = vlan_id1; status = switch_packet_tx_info_get(&tx_entry, &tx_info); if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR("net filter tx not found. dropping packet"); continue; } memset(&packet_header, 0x0, sizeof(packet_header)); cpu_header = &packet_header.cpu_header; fabric_header = &packet_header.fabric_header; if (tx_info->bypass_flags == SWITCH_BYPASS_ALL) { cpu_header->tx_bypass = TRUE; cpu_header->reason_code = tx_info->bypass_flags; fabric_header->dst_port_or_group = tx_info->port; memcpy(packet, in_packet, in_packet_size); packet_size = in_packet_size; } else { cpu_header->tx_bypass = FALSE; cpu_header->reason_code = tx_info->bypass_flags; switch_packet_tx_bd_transform( in_packet, in_packet_size, packet, &packet_size, tx_info); } fabric_header = &packet_header.fabric_header; cpu_header = &packet_header.cpu_header; fabric_header->dst_device = device; fabric_header->packet_type = SWITCH_FABRIC_HEADER_TYPE_CPU; fabric_header->ether_type = SWITCH_FABRIC_HEADER_ETHTYPE; switch_packet_tx_to_hw(&packet_header, packet, packet_size); } }
switch_status_t switch_api_neighbor_entry_add_tunnel_rewrite( switch_device_t device, switch_neighbor_info_t *neighbor_info) { switch_interface_info_t *intf_info = NULL; switch_api_neighbor_t *neighbor = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; uint16_t smac_index = 1; uint16_t dmac_index = 0; uint16_t sip_index = 0; uint16_t dip_index = 0; switch_handle_t vrf_handle = 0; switch_ip_encap_t *ip_encap = NULL; switch_mpls_encap_t *mpls_encap = NULL; switch_tunnel_info_t *tunnel_info = NULL; switch_ip_addr_t *src_ip = NULL; switch_ip_addr_t *dst_ip = NULL; switch_encap_type_t encap_type = SWITCH_API_ENCAP_TYPE_NONE; neighbor = &neighbor_info->neighbor; intf_info = switch_api_interface_get(neighbor->interface); if (!intf_info) { SWITCH_API_ERROR( "%s:%d: invalid interface for tunnel rewrite!", __FUNCTION__, __LINE__); return SWITCH_STATUS_INVALID_INTERFACE; } tunnel_info = &(SWITCH_INTF_TUNNEL_INFO(intf_info)); dmac_index = switch_dmac_rewrite_insert_hash(device, &neighbor->mac_addr); if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_IP) { ip_encap = &(SWITCH_INTF_TUNNEL_IP_ENCAP(intf_info)); vrf_handle = ip_encap->vrf_handle; encap_type = SWITCH_INTF_TUNNEL_ENCAP_TYPE(intf_info); src_ip = &ip_encap->src_ip; sip_index = switch_tunnel_src_vtep_index_get(vrf_handle, encap_type, src_ip); dst_ip = &ip_encap->dst_ip; dip_index = switch_tunnel_dst_vtep_index_get(vrf_handle, encap_type, dst_ip); status = switch_pd_tunnel_rewrite_table_add_entry( device, handle_to_id(neighbor->interface), sip_index, dip_index, smac_index, dmac_index, &neighbor_info->rewrite_entry); } else if (tunnel_info->encap_mode == SWITCH_API_TUNNEL_ENCAP_MODE_MPLS) { mpls_encap = &(SWITCH_INTF_TUNNEL_MPLS_ENCAP(intf_info)); status = switch_pd_tunnel_rewrite_table_mpls_add_entry( device, handle_to_id(neighbor->interface), smac_index, dmac_index, mpls_encap, &neighbor_info->rewrite_entry); } if (status != SWITCH_STATUS_SUCCESS) { SWITCH_API_ERROR( "%s:%d unable to add tunnel rewrite entry", __FUNCTION__, __LINE__); return status; } return status; }
switch_status_t switch_api_l3_route_add(switch_device_t device, switch_handle_t vrf, switch_ip_addr_t *ip_addr, switch_handle_t nhop_handle) { switch_l3_hash_t *hash_entry = NULL; switch_nhop_info_t *nhop_info = NULL; uint32_t nhop_index = 0; switch_status_t status = SWITCH_STATUS_SUCCESS; unsigned int v4_mask = 0; uint8_t v6_mask[16]; switch_ip_addr_t masked_ip; if (!SWITCH_VRF_HANDLE_VALID(vrf)) { return SWITCH_STATUS_INVALID_HANDLE; } if (!SWITCH_NHOP_HANDLE_VALID(nhop_handle)) { return SWITCH_STATUS_INVALID_HANDLE; } nhop_index = handle_to_id(nhop_handle); nhop_info = switch_nhop_get(nhop_handle); if (!nhop_info) { SWITCH_API_ERROR("%s:%d: Invalid nexthop!", __FUNCTION__, __LINE__); return SWITCH_STATUS_ITEM_NOT_FOUND; } hash_entry = switch_l3_search_hash(vrf, ip_addr); if (hash_entry) { hash_entry->nhop_handle = nhop_handle; #ifdef SWITCH_PD status = switch_pd_ip_fib_update_entry(device, handle_to_id(vrf), ip_addr, SWITCH_NHOP_TYPE_IS_ECMP(nhop_info), nhop_index, hash_entry->hw_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } status = switch_pd_urpf_update_entry(device, handle_to_id(vrf), ip_addr, handle_to_id(nhop_handle), hash_entry->urpf_entry); #endif } else { memcpy(&masked_ip, ip_addr, sizeof(switch_ip_addr_t)); if (ip_addr->type == SWITCH_API_IP_ADDR_V4) { v4_mask = prefix_to_v4_mask(ip_addr->prefix_len); masked_ip.ip.v4addr = ip_addr->ip.v4addr & v4_mask; } else { int i = 0; prefix_to_v6_mask(ip_addr->prefix_len, v6_mask); for (i = 0; i < 16; i++) { masked_ip.ip.v6addr[i] = ip_addr->ip.v6addr[i] & v6_mask[i]; } } hash_entry = switch_l3_insert_hash(vrf, ip_addr, nhop_handle); if (!hash_entry) { return SWITCH_STATUS_NO_MEMORY; } hash_entry->nhop_handle = nhop_handle; #ifdef SWITCH_PD // set the HW entry status = switch_pd_ip_fib_add_entry(device, handle_to_id(vrf), ip_addr, SWITCH_NHOP_TYPE_IS_ECMP(nhop_info), nhop_index, &hash_entry->hw_entry); if (status != SWITCH_STATUS_SUCCESS) { return status; } status = switch_pd_urpf_add_entry(device, handle_to_id(vrf), ip_addr, handle_to_id(nhop_handle), &hash_entry->urpf_entry); #endif } return status; }
switch_status_t switch_api_packet_net_filter_tx_create( switch_device_t device, switch_packet_tx_key_t *tx_key, switch_packet_tx_action_t *tx_action) { switch_packet_tx_entry_t tx_entry; switch_packet_tx_info_t *tx_info = NULL; switch_hostif_info_t *hostif_info = NULL; switch_handle_t bd_handle = 0; switch_interface_info_t *intf_info = NULL; switch_handle_type_t handle_type = 0; switch_bd_info_t *bd_info = NULL; switch_status_t status = SWITCH_STATUS_SUCCESS; if (!tx_key || !tx_action) { SWITCH_API_ERROR("filter tx create failed. invalid params"); return SWITCH_STATUS_INVALID_PARAMETER; } 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; } } memset(&tx_entry, 0x0, sizeof(tx_entry)); if (tx_key->handle_valid) { tx_entry.intf_fd = hostif_info->intf_fd; } tx_entry.fd_valid = tx_key->handle_valid; tx_entry.vlan_id = tx_key->vlan_id; tx_entry.vlan_valid = tx_key->vlan_valid; tx_entry.priority = tx_key->priority; tx_info = switch_malloc(sizeof(switch_packet_tx_info_t), 0x1); if (!tx_info) { SWITCH_API_ERROR("hif %lx vlan %x malloc failure", tx_key->hostif_handle, tx_key->vlan_id); return SWITCH_STATUS_NO_MEMORY; } if (tx_action->bypass_flags != SWITCH_BYPASS_ALL) { bd_handle = tx_action->handle; handle_type = switch_handle_get_type(tx_action->handle); if (handle_type == SWITCH_HANDLE_TYPE_INTERFACE) { intf_info = switch_api_interface_get(tx_action->handle); if (!intf_info) { SWITCH_API_ERROR("intf_handle %lx is invalid", tx_action->handle); return SWITCH_STATUS_INVALID_HANDLE; } if (!SWITCH_INTF_IS_PORT_L3(intf_info)) { SWITCH_API_ERROR("intf_handle %lx is not l3", tx_action->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( "hif %lx vlan %x invalid bd", tx_key->hostif_handle, tx_key->vlan_id); return SWITCH_STATUS_INVALID_HANDLE; } } memcpy(&tx_info->tx_entry, &tx_entry, sizeof(tx_entry)); tx_info->bd = handle_to_id(bd_handle); tx_info->bypass_flags = tx_action->bypass_flags; tx_info->port = handle_to_id(tx_action->port_handle); SWITCH_API_INFO( "net_filter_tx_create: hostif 0x%lx, vlan_id = %d, fd 0x%x, bypass " "0x%x\n", tx_key->hostif_handle, tx_key->vlan_valid ? tx_key->vlan_id : 0xFFF, tx_entry.intf_fd, tx_info->bypass_flags); tommy_list_insert_head(&packet_tx_filter_list, &(tx_info->node), tx_info); tommy_list_sort(&packet_tx_filter_list, switch_packet_tx_filter_priority_compare); return status; }