diff options
Diffstat (limited to 'src/vnet/devices/tap')
-rw-r--r-- | src/vnet/devices/tap/FEATURE.yaml | 2 | ||||
-rw-r--r-- | src/vnet/devices/tap/cli.c | 24 | ||||
-rw-r--r-- | src/vnet/devices/tap/tap.c | 242 | ||||
-rw-r--r-- | src/vnet/devices/tap/tap.h | 5 | ||||
-rw-r--r-- | src/vnet/devices/tap/tapv2.api | 80 | ||||
-rw-r--r-- | src/vnet/devices/tap/tapv2_api.c | 97 |
6 files changed, 287 insertions, 163 deletions
diff --git a/src/vnet/devices/tap/FEATURE.yaml b/src/vnet/devices/tap/FEATURE.yaml index 35ee4885b02..1a774fb0e74 100644 --- a/src/vnet/devices/tap/FEATURE.yaml +++ b/src/vnet/devices/tap/FEATURE.yaml @@ -1,6 +1,6 @@ --- name: Tap Device -maintainer: damarion@cisco.com sluong@cisco.com sykazmi@cisco.com +maintainer: damarion@cisco.com sluong@cisco.com mohsin.kazmi14@gmail.com features: - Virtio - Persistence diff --git a/src/vnet/devices/tap/cli.c b/src/vnet/devices/tap/cli.c index 10f4bb0ee2e..5c676d32d60 100644 --- a/src/vnet/devices/tap/cli.c +++ b/src/vnet/devices/tap/cli.c @@ -41,6 +41,7 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input, args.tap_flags = 0; args.rv = -1; args.num_rx_queues = 1; + args.num_tx_queues = 1; /* Get a line of input. */ if (unformat_user (input, unformat_line_input, line_input)) @@ -76,6 +77,8 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input, args.host_ip6_gw_set = 1; else if (unformat (line_input, "num-rx-queues %d", &tmp)) args.num_rx_queues = tmp; + else if (unformat (line_input, "num-tx-queues %d", &tmp)) + args.num_tx_queues = tmp; else if (unformat (line_input, "rx-ring-size %d", &tmp)) args.rx_ring_sz = tmp; else if (unformat (line_input, "tx-ring-size %d", &tmp)) @@ -133,12 +136,12 @@ tap_create_command_fn (vlib_main_t * vm, unformat_input_t * input, } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (tap_create_command, static) = { .path = "create tap", - .short_help = "create tap {id <if-id>} [hw-addr <mac-address>] " - "[num-rx-queues <n>] [rx-ring-size <size>] [tx-ring-size <size>] " - "[host-ns <netns>] [host-bridge <bridge-name>] " + .short_help = + "create tap {id <if-id>} [hw-addr <mac-address>] " + "[num-rx-queues <n>] [num-tx-queues <n>] [rx-ring-size <size>] " + "[tx-ring-size <size>] [host-ns <netns>] [host-bridge <bridge-name>] " "[host-ip4-addr <ip4addr/mask>] [host-ip6-addr <ip6-addr>] " "[host-ip4-gw <ip4-addr>] [host-ip6-gw <ip6-addr>] " "[host-mac-addr <host-mac-address>] [host-if-name <name>] " @@ -146,7 +149,6 @@ VLIB_CLI_COMMAND (tap_create_command, static) = { "[persist] [attach] [tun] [packed] [in-order]", .function = tap_create_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * tap_delete_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -187,14 +189,12 @@ tap_delete_command_fn (vlib_main_t * vm, unformat_input_t * input, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (tap_delete__command, static) = { .path = "delete tap", .short_help = "delete tap {<interface> | sw_if_index <sw_idx>}", .function = tap_delete_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * tap_offload_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -257,7 +257,6 @@ tap_offload_command_fn (vlib_main_t * vm, unformat_input_t * input, return 0; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (tap_offload_command, static) = { .path = "set tap offload", @@ -266,7 +265,6 @@ VLIB_CLI_COMMAND (tap_offload_command, static) = "csum-offload-disable>", .function = tap_offload_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * tap_show_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -296,10 +294,8 @@ tap_show_command_fn (vlib_main_t * vm, unformat_input_t * input, if (vec_len (hw_if_indices) == 0) { - /* *INDENT-OFF* */ pool_foreach (vif, mm->interfaces) vec_add1 (hw_if_indices, vif->hw_if_index); - /* *INDENT-ON* */ } virtio_show (vm, hw_if_indices, show_descr, VIRTIO_IF_TYPE_TAP); @@ -309,13 +305,11 @@ done: return error; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (tap_show_command, static) = { .path = "show tap", .short_help = "show tap {<interface>] [descriptors]", .function = tap_show_command_fn, }; -/* *INDENT-ON* */ static clib_error_t * tun_show_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -345,10 +339,8 @@ tun_show_command_fn (vlib_main_t * vm, unformat_input_t * input, if (vec_len (hw_if_indices) == 0) { - /* *INDENT-OFF* */ pool_foreach (vif, mm->interfaces) vec_add1 (hw_if_indices, vif->hw_if_index); - /* *INDENT-ON* */ } virtio_show (vm, hw_if_indices, show_descr, VIRTIO_IF_TYPE_TUN); @@ -358,13 +350,11 @@ done: return error; } -/* *INDENT-OFF* */ VLIB_CLI_COMMAND (tun_show_command, static) = { .path = "show tun", .short_help = "show tun {<interface>] [descriptors]", .function = tun_show_command_fn, }; -/* *INDENT-ON* */ clib_error_t * tap_cli_init (vlib_main_t * vm) diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 33d6e3bc84a..1e2ee87041d 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -58,13 +58,11 @@ tap_main_t tap_main; goto error; \ } - /* *INDENT-OFF* */ -VNET_HW_INTERFACE_CLASS (tun_device_hw_interface_class, static) = -{ +VNET_HW_INTERFACE_CLASS (tun_device_hw_interface_class, static) = { .name = "tun-device", .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P, + .tx_hash_fn_type = VNET_HASH_FN_TYPE_IP, }; - /* *INDENT-ON* */ #define TUN_MAX_PACKET_BYTES 65355 #define TUN_MIN_PACKET_BYTES 64 @@ -79,6 +77,14 @@ virtio_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, return 0; } +static clib_error_t * +virtio_eth_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hi, + u32 frame_size) +{ + /* nothing for now */ + return 0; +} + #define TAP_MAX_INSTANCE 1024 static void @@ -89,14 +95,14 @@ tap_free (vlib_main_t * vm, virtio_if_t * vif) clib_error_t *err = 0; int i; - /* *INDENT-OFF* */ + virtio_pre_input_node_disable (vm, vif); + vec_foreach_index (i, vif->vhost_fds) if (vif->vhost_fds[i] != -1) close (vif->vhost_fds[i]); vec_foreach_index (i, vif->rxq_vrings) virtio_vring_free_rx (vm, vif, RX_QUEUE (i)); vec_foreach_index (i, vif->txq_vrings) virtio_vring_free_tx (vm, vif, TX_QUEUE (i)); - /* *INDENT-ON* */ if (vif->tap_fds) { @@ -106,6 +112,7 @@ tap_free (vlib_main_t * vm, virtio_if_t * vif) error: vec_foreach_index (i, vif->tap_fds) close (vif->tap_fds[i]); + vec_free (vif->tap_fds); vec_free (vif->vhost_fds); vec_free (vif->rxq_vrings); vec_free (vif->txq_vrings); @@ -129,6 +136,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) tap_main_t *tm = &tap_main; vnet_sw_interface_t *sw; vnet_hw_interface_t *hw; + vnet_hw_if_caps_change_t cc; int i, num_vhost_queues; int old_netns_fd = -1; struct ifreq ifr = {.ifr_flags = IFF_NO_PI | IFF_VNET_HDR }; @@ -190,43 +198,47 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) vif->dev_instance = vif - vim->interfaces; vif->id = args->id; - vif->num_txqs = thm->n_vlib_mains; + vif->num_txqs = clib_max (args->num_tx_queues, thm->n_vlib_mains); vif->num_rxqs = clib_max (args->num_rx_queues, 1); if (args->tap_flags & TAP_FLAG_ATTACH) { - if (args->host_if_name != NULL) - { - host_if_name = (char *) args->host_if_name; - clib_memcpy (ifr.ifr_name, host_if_name, - clib_min (IFNAMSIZ, vec_len (host_if_name))); - } - else + if (args->host_if_name == NULL) { args->rv = VNET_API_ERROR_NO_MATCHING_INTERFACE; err = clib_error_return (0, "host_if_name is not provided"); goto error; } - if (args->host_namespace) + } + + /* if namespace is specified, all further netlink messages should be executed + * after we change our net namespace */ + if (args->host_namespace) + { + old_netns_fd = clib_netns_open (NULL /* self */); + if ((nfd = clib_netns_open (args->host_namespace)) == -1) { - old_netns_fd = clib_netns_open (NULL /* self */); - if ((nfd = clib_netns_open (args->host_namespace)) == -1) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; - args->error = clib_error_return_unix (0, "clib_netns_open '%s'", - args->host_namespace); - goto error; - } - if (clib_setns (nfd) == -1) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_3; - args->error = clib_error_return_unix (0, "setns '%s'", - args->host_namespace); - goto error; - } + args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; + args->error = clib_error_return_unix (0, "clib_netns_open '%s'", + args->host_namespace); + goto error; + } + if (clib_setns (nfd) == -1) + { + args->rv = VNET_API_ERROR_SYSCALL_ERROR_3; + args->error = + clib_error_return_unix (0, "setns '%s'", args->host_namespace); + goto error; } } + if (args->host_if_name != NULL) + { + host_if_name = (char *) args->host_if_name; + clib_memcpy (ifr.ifr_name, host_if_name, + clib_min (IFNAMSIZ, vec_len (host_if_name))); + } + if ((tfd = open ("/dev/net/tun", O_RDWR | O_NONBLOCK)) < 0) { args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; @@ -258,7 +270,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) else ifr.ifr_flags |= IFF_MULTI_QUEUE; - hdrsz = sizeof (virtio_net_hdr_v1_t); + hdrsz = sizeof (vnet_virtio_net_hdr_v1_t); if (args->tap_flags & TAP_FLAG_GSO) { offload = TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6; @@ -320,10 +332,10 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) args->error = clib_error_return_unix (0, "open '/dev/net/tun'"); goto error; } + vec_add1 (vif->tap_fds, qfd); _IOCTL (qfd, TUNSETIFF, (void *) &ifr); tap_log_dbg (vif, "TUNSETIFF fd %d name %s flags 0x%x", qfd, ifr.ifr_ifrn.ifrn_name, ifr.ifr_flags); - vec_add1 (vif->tap_fds, qfd); } for (i = 0; i < vif->num_rxqs; i++) @@ -399,54 +411,6 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) virtio_set_net_hdr_size (vif); - if (!(args->tap_flags & TAP_FLAG_ATTACH)) - { - /* if namespace is specified, all further netlink messages should be executed - after we change our net namespace */ - if (args->host_namespace) - { - old_netns_fd = clib_netns_open (NULL /* self */); - if ((nfd = clib_netns_open (args->host_namespace)) == -1) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; - args->error = clib_error_return_unix (0, "clib_netns_open '%s'", - args->host_namespace); - goto error; - } - args->error = vnet_netlink_set_link_netns (vif->ifindex, nfd, - host_if_name); - if (args->error) - { - args->rv = VNET_API_ERROR_NETLINK_ERROR; - goto error; - } - if (clib_setns (nfd) == -1) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_3; - args->error = clib_error_return_unix (0, "setns '%s'", - args->host_namespace); - goto error; - } - if ((vif->ifindex = if_nametoindex (host_if_name)) == 0) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_3; - args->error = clib_error_return_unix (0, "if_nametoindex '%s'", - host_if_name); - goto error; - } - } - else if (host_if_name) - { - args->error = - vnet_netlink_set_link_name (vif->ifindex, host_if_name); - if (args->error) - { - args->rv = VNET_API_ERROR_NETLINK_ERROR; - goto error; - } - } - } - if (vif->type == VIRTIO_IF_TYPE_TAP) { if (ethernet_mac_address_is_zero (args->host_mac_addr.bytes)) @@ -611,7 +575,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) vhost_vring_addr_t addr = { 0 }; vhost_vring_state_t state = { 0 }; vhost_vring_file_t file = { 0 }; - virtio_vring_t *vring; + vnet_virtio_vring_t *vring; u16 qp = i >> 1; int fd = vif->vhost_fds[qp]; @@ -629,7 +593,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) } addr.index = state.index = file.index = vring->queue_id & 1; - state.num = vring->size; + state.num = vring->queue_size; virtio_log_debug (vif, "VHOST_SET_VRING_NUM fd %d index %u num %u", fd, state.index, state.num); _IOCTL (fd, VHOST_SET_VRING_NUM, &state); @@ -668,10 +632,12 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) ethernet_mac_address_generate (args->mac_addr.bytes); clib_memcpy (vif->mac_addr, args->mac_addr.bytes, 6); - vif->host_bridge = format (0, "%s%c", args->host_bridge, 0); + if (args->host_bridge) + vif->host_bridge = format (0, "%s%c", args->host_bridge, 0); } vif->host_if_name = format (0, "%s%c", host_if_name, 0); - vif->net_ns = format (0, "%s%c", args->host_namespace, 0); + if (args->host_namespace) + vif->net_ns = format (0, "%s%c", args->host_namespace, 0); vif->host_mtu_size = args->host_mtu_size; vif->tap_flags = args->tap_flags; clib_memcpy (vif->host_mac_addr, args->host_mac_addr.bytes, 6); @@ -684,17 +650,14 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) if (vif->type != VIRTIO_IF_TYPE_TUN) { - args->error = - ethernet_register_interface (vnm, virtio_device_class.index, - vif->dev_instance, vif->mac_addr, - &vif->hw_if_index, - virtio_eth_flag_change); - if (args->error) - { - args->rv = VNET_API_ERROR_INVALID_REGISTRATION; - goto error; - } - + vnet_eth_interface_registration_t eir = {}; + + eir.dev_class_index = virtio_device_class.index; + eir.dev_instance = vif->dev_instance; + eir.address = vif->mac_addr; + eir.cb.flag_change = virtio_eth_flag_change; + eir.cb.set_max_frame_size = virtio_eth_set_max_frame_size; + vif->hw_if_index = vnet_eth_register_interface (vnm, &eir); } else { @@ -710,18 +673,16 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) args->sw_if_index = vif->sw_if_index; args->rv = 0; hw = vnet_get_hw_interface (vnm, vif->hw_if_index); - hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE; + cc.mask = VNET_HW_IF_CAP_INT_MODE | VNET_HW_IF_CAP_TCP_GSO | + VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM; + cc.val = VNET_HW_IF_CAP_INT_MODE; + if (args->tap_flags & TAP_FLAG_GSO) - { - hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO | - VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM | - VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM; - } + cc.val |= VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_TX_TCP_CKSUM | + VNET_HW_IF_CAP_TX_UDP_CKSUM; else if (args->tap_flags & TAP_FLAG_CSUM_OFFLOAD) - { - hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM | - VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM; - } + cc.val |= VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM; + if ((args->tap_flags & TAP_FLAG_GSO) && (args->tap_flags & TAP_FLAG_GRO_COALESCE)) { @@ -729,18 +690,18 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) } if (vif->type == VIRTIO_IF_TYPE_TUN) { - hw->max_supported_packet_bytes = TUN_MAX_PACKET_BYTES; - hw->min_packet_bytes = hw->min_supported_packet_bytes = - TUN_MIN_PACKET_BYTES; - hw->max_packet_bytes = - args->host_mtu_size ? args->host_mtu_size : TUN_DEFAULT_PACKET_BYTES; - vnet_sw_interface_set_mtu (vnm, hw->sw_if_index, hw->max_packet_bytes); + hw->min_frame_size = TUN_MIN_PACKET_BYTES; + vnet_hw_interface_set_mtu ( + vnm, hw->hw_if_index, + args->host_mtu_size ? args->host_mtu_size : TUN_DEFAULT_PACKET_BYTES); } + vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc); + virtio_pre_input_node_enable (vm, vif); virtio_vring_set_rx_queues (vm, vif); + virtio_vring_set_tx_queues (vm, vif); vif->per_interface_next_index = ~0; - vif->flags |= VIRTIO_IF_FLAG_ADMIN_UP; vnet_hw_interface_set_flags (vnm, vif->hw_if_index, VNET_HW_INTERFACE_FLAG_LINK_UP); /* @@ -749,7 +710,6 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) * TUNSETCARRIER ioctl(). See tap_set_carrier(). */ vif->host_carrier_up = 1; - vif->cxq_vring = NULL; goto done; @@ -767,7 +727,11 @@ done: if (vhost_mem) clib_mem_free (vhost_mem); if (old_netns_fd != -1) - close (old_netns_fd); + { + /* in case we errored with a switched netns */ + clib_setns (old_netns_fd); + close (old_netns_fd); + } if (nfd != -1) close (nfd); } @@ -812,6 +776,7 @@ tap_csum_offload_enable_disable (vlib_main_t * vm, u32 sw_if_index, virtio_main_t *mm = &virtio_main; virtio_if_t *vif; vnet_hw_interface_t *hw; + vnet_hw_if_caps_change_t cc; clib_error_t *err = 0; int i = 0; @@ -829,21 +794,19 @@ tap_csum_offload_enable_disable (vlib_main_t * vm, u32 sw_if_index, _IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload); vif->gso_enabled = 0; vif->packet_coalesce = 0; - vif->csum_offload_enabled = enable_disable ? 1 : 0; - - if ((hw->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) != 0) - { - hw->caps &= ~VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO; - } + cc.mask = VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_L4_TX_CKSUM; if (enable_disable) { - hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM; + cc.val = VNET_HW_IF_CAP_L4_TX_CKSUM; + vif->csum_offload_enabled = 1; } else { - hw->caps &= ~VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM; + cc.val = 0; + vif->csum_offload_enabled = 0; } + vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc); error: if (err) @@ -863,6 +826,7 @@ tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index, int enable_disable, virtio_main_t *mm = &virtio_main; virtio_if_t *vif; vnet_hw_interface_t *hw; + vnet_hw_if_caps_change_t cc; clib_error_t *err = 0; int i = 0; @@ -878,29 +842,25 @@ tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index, int enable_disable, unsigned int offload = enable_disable ? gso_on : gso_off; vec_foreach_index (i, vif->tap_fds) _IOCTL (vif->tap_fds[i], TUNSETOFFLOAD, offload); - vif->gso_enabled = enable_disable ? 1 : 0; - vif->csum_offload_enabled = 0; + + cc.mask = VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_L4_TX_CKSUM; + if (enable_disable) { - if ((hw->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) == 0) - { - hw->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO | - VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM; - } + cc.val = cc.mask; + vif->gso_enabled = 1; + vif->csum_offload_enabled = 1; if (is_packet_coalesce) - { - virtio_set_packet_coalesce (vif); - } + virtio_set_packet_coalesce (vif); } else { - if ((hw->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) != 0) - { - hw->caps &= ~(VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO | - VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM); - } + cc.val = 0; + vif->gso_enabled = 0; + vif->csum_offload_enabled = 0; vif->packet_coalesce = 0; } + vnet_hw_if_change_caps (vnm, vif->hw_if_index, &cc); error: if (err) @@ -918,12 +878,11 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids) vnet_main_t *vnm = vnet_get_main (); virtio_main_t *mm = &virtio_main; virtio_if_t *vif; - virtio_vring_t *vring; + vnet_virtio_vring_t *vring; vnet_hw_interface_t *hi; tap_interface_details_t *r_tapids = NULL; tap_interface_details_t *tapid = NULL; - /* *INDENT-OFF* */ pool_foreach (vif, mm->interfaces) { if ((vif->type != VIRTIO_IF_TYPE_TAP) && (vif->type != VIRTIO_IF_TYPE_TUN)) @@ -936,9 +895,9 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids) clib_memcpy(tapid->dev_name, hi->name, MIN (ARRAY_LEN (tapid->dev_name) - 1, vec_len (hi->name))); vring = vec_elt_at_index (vif->rxq_vrings, RX_QUEUE_ACCESS(0)); - tapid->rx_ring_sz = vring->size; + tapid->rx_ring_sz = vring->queue_size; vring = vec_elt_at_index (vif->txq_vrings, TX_QUEUE_ACCESS(0)); - tapid->tx_ring_sz = vring->size; + tapid->tx_ring_sz = vring->queue_size; tapid->tap_flags = vif->tap_flags; clib_memcpy(&tapid->host_mac_addr, vif->host_mac_addr, 6); if (vif->host_if_name) @@ -967,7 +926,6 @@ tap_dump_ifs (tap_interface_details_t ** out_tapids) tapid->host_ip6_prefix_len = vif->host_ip6_prefix_len; tapid->host_mtu_size = vif->host_mtu_size; } - /* *INDENT-ON* */ *out_tapids = r_tapids; diff --git a/src/vnet/devices/tap/tap.h b/src/vnet/devices/tap/tap.h index 2efaa511a49..6b88c34fe41 100644 --- a/src/vnet/devices/tap/tap.h +++ b/src/vnet/devices/tap/tap.h @@ -44,7 +44,8 @@ typedef struct u32 id; u8 mac_addr_set; mac_address_t mac_addr; - u8 num_rx_queues; + u16 num_rx_queues; + u16 num_tx_queues; u16 rx_ring_sz; u16 tx_ring_sz; u32 tap_flags; @@ -98,8 +99,10 @@ typedef struct /* host mtu size, configurable through startup.conf */ int host_mtu_size; + u16 msg_id_base; } tap_main_t; +extern tap_main_t tap_main; void tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args); int tap_delete_if (vlib_main_t * vm, u32 sw_if_index); int tap_gso_enable_disable (vlib_main_t * vm, u32 sw_if_index, diff --git a/src/vnet/devices/tap/tapv2.api b/src/vnet/devices/tap/tapv2.api index 6b6618411a6..bf53d1bc6fe 100644 --- a/src/vnet/devices/tap/tapv2.api +++ b/src/vnet/devices/tap/tapv2.api @@ -43,6 +43,82 @@ enum tap_flags { @param use_random_mac - let the system generate a unique mac address @param mac_address - mac addr to assign to the interface if use_random not set @param num_rx_queues - number of rx queues + @param num_tx_queues - number of tx queues + @param tx_ring_sz - the number of entries of TX ring, optional, default is 256 entries, must be power of 2 + @param rx_ring_sz - the number of entries of RX ring, optional, default is 256 entries, must be power of 2 + @param host_mtu_set - host MTU should be set + @param host_mtu_size - host MTU size + @param host_mac_addr_set - host side interface mac address should be set + @param host_mac_addr - host side interface mac address + @param host_ip4_prefix_set - host IPv4 ip address should be set + @param host_ip4_prefix - host IPv4 ip address + @param host_ip6_prefix_set - host IPv6 ip address should be set + @param host_ip6_prefix - host IPv6 ip address + @param host_ip4_gw_set - host IPv4 default gateway should be set + @param host_ip4_gw - host IPv4 default gateway + @param host_ip6_gw_set - host IPv6 default gateway should be set + @param host_ip6_gw - host IPv6 default gateway + @param tap_flags - flags for the TAP interface creation + @param host_if_name_set - host side interface name should be set + @param host_if_name - host side interface name + @param host_namespace_set - host namespace should be set + @param host_namespace - host namespace to attach interface to + @param host_bridge_set - host bridge should be set + @param host_bridge - host bridge to attach interface to + @param tag - tag +*/ +autoendian define tap_create_v3 +{ + u32 client_index; + u32 context; + u32 id [default=0xffffffff]; + bool use_random_mac [default=true]; + vl_api_mac_address_t mac_address; + u16 num_rx_queues [default=1]; + u16 num_tx_queues [default=1]; + u16 tx_ring_sz [default=256]; + u16 rx_ring_sz [default=256]; + bool host_mtu_set; + u32 host_mtu_size; + bool host_mac_addr_set; + vl_api_mac_address_t host_mac_addr; + bool host_ip4_prefix_set; + vl_api_ip4_address_with_prefix_t host_ip4_prefix; + bool host_ip6_prefix_set; + vl_api_ip6_address_with_prefix_t host_ip6_prefix; + bool host_ip4_gw_set; + vl_api_ip4_address_t host_ip4_gw; + bool host_ip6_gw_set; + vl_api_ip6_address_t host_ip6_gw; + vl_api_tap_flags_t tap_flags; + bool host_namespace_set; + string host_namespace[64]; + bool host_if_name_set; + string host_if_name[64]; + bool host_bridge_set; + string host_bridge[64]; + string tag[]; +}; + +/** \brief Reply for tap create reply + @param context - returned sender context, to match reply w/ request + @param retval - return code + @param sw_if_index - software index allocated for the new tap interface +*/ +autoendian define tap_create_v3_reply +{ + u32 context; + i32 retval; + vl_api_interface_index_t sw_if_index; +}; + +/** \brief Initialize a new tap interface with the given parameters + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param id - interface id, 0xffffffff means auto + @param use_random_mac - let the system generate a unique mac address + @param mac_address - mac addr to assign to the interface if use_random not set + @param num_rx_queues - number of rx queues @param tx_ring_sz - the number of entries of TX ring, optional, default is 256 entries, must be power of 2 @param rx_ring_sz - the number of entries of RX ring, optional, default is 256 entries, must be power of 2 @param host_mtu_set - host MTU should be set @@ -68,6 +144,8 @@ enum tap_flags { */ define tap_create_v2 { + option deprecated; + u32 client_index; u32 context; u32 id [default=0xffffffff]; @@ -105,6 +183,8 @@ define tap_create_v2 */ define tap_create_v2_reply { + option deprecated; + u32 context; i32 retval; vl_api_interface_index_t sw_if_index; diff --git a/src/vnet/devices/tap/tapv2_api.c b/src/vnet/devices/tap/tapv2_api.c index 08dca0dc92b..ab4189ab607 100644 --- a/src/vnet/devices/tap/tapv2_api.c +++ b/src/vnet/devices/tap/tapv2_api.c @@ -32,10 +32,102 @@ #include <vnet/devices/tap/tapv2.api_enum.h> #include <vnet/devices/tap/tapv2.api_types.h> -#define REPLY_MSG_ID_BASE msg_id_base +#define REPLY_MSG_ID_BASE tap_main.msg_id_base #include <vlibapi/api_helper_macros.h> -static u16 msg_id_base; +static void +vl_api_tap_create_v3_t_handler (vl_api_tap_create_v3_t *mp) +{ + vl_api_registration_t *reg; + int rv; + + reg = vl_api_client_index_to_registration (mp->client_index); + if (!reg) + return; + + vnet_main_t *vnm = vnet_get_main (); + vlib_main_t *vm = vlib_get_main (); + vl_api_tap_create_v3_reply_t *rmp; + + tap_create_if_args_t _a, *ap = &_a; + + clib_memset (ap, 0, sizeof (*ap)); + + ap->id = mp->id; + if (!mp->use_random_mac) + { + mac_address_decode (mp->mac_address, &ap->mac_addr); + ap->mac_addr_set = 1; + } + ap->rx_ring_sz = mp->rx_ring_sz; + ap->tx_ring_sz = mp->tx_ring_sz; + ap->sw_if_index = (u32) ~0; + ap->num_rx_queues = clib_max (1, mp->num_rx_queues); + ap->num_tx_queues = mp->num_tx_queues; + + if (mp->host_if_name_set) + ap->host_if_name = format (0, "%s%c", mp->host_if_name, 0); + + if (mp->host_mac_addr_set) + { + mac_address_decode (mp->host_mac_addr, &ap->host_mac_addr); + } + + if (mp->host_namespace_set) + ap->host_namespace = format (0, "%s%c", mp->host_namespace, 0); + + if (mp->host_bridge_set) + ap->host_bridge = format (0, "%s%c", mp->host_bridge, 0); + + if (mp->host_ip4_prefix_set) + { + ip4_address_decode (mp->host_ip4_prefix.address, &ap->host_ip4_addr); + ap->host_ip4_prefix_len = mp->host_ip4_prefix.len; + } + + if (mp->host_ip6_prefix_set) + { + ip6_address_decode (mp->host_ip6_prefix.address, &ap->host_ip6_addr); + ap->host_ip6_prefix_len = mp->host_ip6_prefix.len; + } + + if (mp->host_ip4_gw_set) + { + ip4_address_decode (mp->host_ip4_gw, &ap->host_ip4_gw); + ap->host_ip4_gw_set = 1; + } + + if (mp->host_ip6_gw_set) + { + ip6_address_decode (mp->host_ip6_gw, &ap->host_ip6_gw); + ap->host_ip6_gw_set = 1; + } + + if (mp->host_mtu_set) + { + ap->host_mtu_size = mp->host_mtu_size; + ap->host_mtu_set = 1; + } + + ap->tap_flags = mp->tap_flags; + + tap_create_if (vm, ap); + + /* If a tag was supplied... */ + if (vl_api_string_len (&mp->tag)) + { + u8 *tag = vl_api_from_api_to_new_vec (mp, &mp->tag); + vnet_set_sw_interface_tag (vnm, tag, ap->sw_if_index); + } + + vec_free (ap->host_if_name); + vec_free (ap->host_namespace); + vec_free (ap->host_bridge); + + rv = ap->rv; + REPLY_MACRO2_END (VL_API_TAP_CREATE_V3_REPLY, + ({ rmp->sw_if_index = ap->sw_if_index; })); +} static void vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp) @@ -63,6 +155,7 @@ vl_api_tap_create_v2_t_handler (vl_api_tap_create_v2_t * mp) ap->tx_ring_sz = ntohs (mp->tx_ring_sz); ap->sw_if_index = (u32) ~ 0; ap->num_rx_queues = 1; + ap->num_tx_queues = 1; if (mp->num_rx_queues > 1) ap->num_rx_queues = mp->num_rx_queues; |