X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fdevices%2Faf_packet%2Faf_packet.c;h=b41eaf3ba8214895f61a590a279979d117ac8b1b;hb=78ea9c2869967693b77949ec154deef6340d01f5;hp=93c8e0c6c9588fad4841540dbf375947da8e9151;hpb=83243a0ff59f90eeed9da2da85b5bb5b3e0d5881;p=vpp.git diff --git a/vnet/vnet/devices/af_packet/af_packet.c b/vnet/vnet/devices/af_packet/af_packet.c index 93c8e0c6c95..b41eaf3ba82 100644 --- a/vnet/vnet/devices/af_packet/af_packet.c +++ b/vnet/vnet/devices/af_packet/af_packet.c @@ -157,11 +157,12 @@ create_packet_v2_sock(u8 * name, tpacket_req_t * rx_req, tpacket_req_t * tx_req, return 0; error: close(*fd); + *fd = -1; return ret; } int -af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) +af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set, u32 *sw_if_index) { af_packet_main_t * apm = &af_packet_main; int ret, fd = -1; @@ -200,7 +201,7 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) goto error; /* So far everything looks good, let's create interface */ - vec_add2 (apm->interfaces, apif, 1); + pool_get (apm->interfaces, apif); if_index = apif - apm->interfaces; apif->fd = fd; @@ -209,6 +210,9 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) apif->rx_req = rx_req; apif->tx_req = tx_req; apif->host_if_name = host_if_name; + apif->per_interface_next_index = ~0; + apif->next_tx_frame = 0; + apif->next_rx_frame = 0; { unix_file_t template = {0}; @@ -221,7 +225,7 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) /*use configured or generate random MAC address */ if (hw_addr_set) - memcpy(hw_addr, hw_addr_set, 6); + clib_memcpy(hw_addr, hw_addr_set, 6); else { f64 now = vlib_time_now(vm); @@ -229,7 +233,7 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) rnd = (u32) (now * 1e6); rnd = random_u32 (&rnd); - memcpy (hw_addr+2, &rnd, sizeof(rnd)); + clib_memcpy (hw_addr+2, &rnd, sizeof(rnd)); hw_addr[0] = 2; hw_addr[1] = 0xfe; } @@ -241,7 +245,7 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) if (error) { memset(apif, 0, sizeof(*apif)); - _vec_len(apm->interfaces) -= 1; + pool_put(apm->interfaces, apif); clib_error_report (error); ret = VNET_API_ERROR_SYSCALL_ERROR_1; goto error; @@ -254,7 +258,8 @@ af_packet_create_if(vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set) VNET_HW_INTERFACE_FLAG_LINK_UP); mhash_set_mem (&apm->if_index_by_host_if_name, host_if_name, &if_index, 0); - + if (sw_if_index) + *sw_if_index = apif->sw_if_index; return 0; error: @@ -264,6 +269,58 @@ error: return ret; } +int +af_packet_delete_if(vlib_main_t *vm, u8 *host_if_name) +{ + vnet_main_t *vnm = vnet_get_main(); + af_packet_main_t *apm = &af_packet_main; + af_packet_if_t *apif; + uword *p; + uword if_index; + u32 ring_sz; + + p = mhash_get(&apm->if_index_by_host_if_name, host_if_name); + if (p == NULL) { + clib_warning("Host interface %s does not exist", host_if_name); + return VNET_API_ERROR_SYSCALL_ERROR_1; + } + apif = pool_elt_at_index(apm->interfaces, p[0]); + if_index = apif - apm->interfaces; + + /* bring down the interface */ + vnet_hw_interface_set_flags(vnm, apif->hw_if_index, 0); + + /* clean up */ + if (apif->unix_file_index != ~0) { + unix_file_del(&unix_main, unix_main.file_pool + apif->unix_file_index); + apif->unix_file_index = ~0; + } + ring_sz = apif->rx_req->tp_block_size * apif->rx_req->tp_block_nr + + apif->tx_req->tp_block_size * apif->tx_req->tp_block_nr; + if (munmap(apif->rx_ring, ring_sz)) + clib_warning("Host interface %s could not free rx/tx ring", host_if_name); + apif->rx_ring = NULL; + apif->tx_ring = NULL; + close(apif->fd); + apif->fd = -1; + + vec_free(apif->rx_req); + apif->rx_req = NULL; + vec_free(apif->tx_req); + apif->tx_req = NULL; + + vec_free(apif->host_if_name); + apif->host_if_name = NULL; + + mhash_unset(&apm->if_index_by_host_if_name, host_if_name, &if_index); + + ethernet_delete_interface(vnm, apif->hw_if_index); + + pool_put(apm->interfaces, apif); + + return 0; +} + static clib_error_t * af_packet_init (vlib_main_t * vm) {