X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fdevices%2Ftap%2Ftap.c;h=2d075f9e0fc0ba65812e93ecd9ebe9d6d7c7254e;hb=2b716b186fdfe0a40d6ddb9e43c795bb05d1ca10;hp=5b15f92051d25f0429a1bf7c48a8b094dfda511f;hpb=5b3f523918932793254b6313f78659fe0ed6320e;p=vpp.git diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 5b15f92051d..2d075f9e0fc 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +66,10 @@ VNET_HW_INTERFACE_CLASS (tun_device_hw_interface_class, static) = }; /* *INDENT-ON* */ +#define TUN_MAX_PACKET_BYTES 65355 +#define TUN_MIN_PACKET_BYTES 64 +#define TUN_DEFAULT_PACKET_BYTES 1500 + static u32 virtio_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags) @@ -75,24 +79,6 @@ virtio_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, return 0; } -static int -open_netns_fd (char *netns) -{ - u8 *s = 0; - int fd; - - if (strncmp (netns, "pid:", 4) == 0) - s = format (0, "/proc/%u/ns/net%c", atoi (netns + 4), 0); - else if (netns[0] == '/') - s = format (0, "%s%c", netns, 0); - else - s = format (0, "/var/run/netns/%s%c", netns, 0); - - fd = open ((char *) s, O_RDONLY); - vec_free (s); - return fd; -} - #define TAP_MAX_INSTANCE 1024 static void @@ -120,6 +106,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); @@ -209,38 +196,42 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) 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 = open ("/proc/self/ns/net", O_RDONLY); - if ((nfd = open_netns_fd ((char *) args->host_namespace)) == -1) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; - args->error = clib_error_return_unix (0, "open_netns_fd '%s'", - args->host_namespace); - goto error; - } - if (setns (nfd, CLONE_NEWNET) == -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; @@ -413,54 +404,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 = open ("/proc/self/ns/net", O_RDONLY); - if ((nfd = open_netns_fd ((char *) args->host_namespace)) == -1) - { - args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; - args->error = clib_error_return_unix (0, "open_netns_fd '%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 (setns (nfd, CLONE_NEWNET) == -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)) @@ -563,7 +506,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) /* switch back to old net namespace */ if (args->host_namespace) { - if (setns (old_netns_fd, CLONE_NEWNET) == -1) + if (clib_setns (old_netns_fd) == -1) { args->rv = VNET_API_ERROR_SYSCALL_ERROR_2; args->error = clib_error_return_unix (0, "setns '%s'", @@ -682,10 +625,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); @@ -741,6 +686,15 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args) { virtio_set_packet_coalesce (vif); } + 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); + } virtio_vring_set_rx_queues (vm, vif); @@ -754,7 +708,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; @@ -772,7 +725,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); } @@ -1052,13 +1009,13 @@ tap_set_speed (u32 hw_if_index, u32 speed) if (vif->net_ns) { - old_netns_fd = open ("/proc/self/ns/net", O_RDONLY); - if ((nfd = open_netns_fd ((char *) vif->net_ns)) == -1) + old_netns_fd = clib_netns_open (NULL /* self */); + if ((nfd = clib_netns_open (vif->net_ns)) == -1) { clib_warning ("Cannot open netns"); goto done; } - if (setns (nfd, CLONE_NEWNET) == -1) + if (clib_setns (nfd) == -1) { clib_warning ("Cannot set ns"); goto done; @@ -1096,7 +1053,7 @@ tap_set_speed (u32 hw_if_index, u32 speed) done: if (old_netns_fd != -1) { - if (setns (old_netns_fd, CLONE_NEWNET) == -1) + if (clib_setns (old_netns_fd) == -1) { clib_warning ("Cannot set old ns"); }