summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOle Troan <ot@cisco.com>2016-04-27 14:15:48 +0200
committerDave Barach <openvpp@barachs.net>2016-04-27 18:23:40 +0000
commitae65f5b6a8c0920143ad274b0c25e99d5153711e (patch)
tree6cbebbaf8d6c2c14f84bb7a929e4793b1d960f44
parent644ec43b5e82cf682698c0efb5d5bb24cbe75849 (diff)
VPP-18: Creating tap interface through API broken. Fixed and removed duplicate code by CLI to create TAPs.
Change-Id: Ib6b30e3dc20ddad7c78d2038955df7af020f0671 Signed-off-by: Ole Troan <ot@cisco.com>
-rw-r--r--vnet/vnet/unix/tapcli.c188
1 files changed, 50 insertions, 138 deletions
diff --git a/vnet/vnet/unix/tapcli.c b/vnet/vnet/unix/tapcli.c
index 596f8d184ab..a2999362713 100644
--- a/vnet/vnet/unix/tapcli.c
+++ b/vnet/vnet/unix/tapcli.c
@@ -764,6 +764,7 @@ int vnet_tap_connect (vlib_main_t * vm, u8 * intfc_name, u8 *hwaddr_arg,
}
ti = tapcli_get_new_tapif();
+ ti->per_interface_next_index = ~0;
if (hwaddr_arg != 0)
clib_memcpy(hwaddr, hwaddr_arg, 6);
@@ -1006,14 +1007,10 @@ tap_connect_command_fn (vlib_main_t * vm,
{
u8 * intfc_name;
tapcli_main_t * tm = &tapcli_main;
- tapcli_interface_t * ti;
- struct ifreq ifr;
- int flags;
- int dev_net_tun_fd;
- int dev_tap_fd = -1;
- clib_error_t * error;
int user_hwaddr = 0;
u8 hwaddr[6];
+ u8 *hwaddr_arg = 0;
+ u32 sw_if_index;
if (tm->is_disabled)
{
@@ -1030,97 +1027,6 @@ tap_connect_command_fn (vlib_main_t * vm,
&hwaddr))
user_hwaddr = 1;
- flags = IFF_TAP | IFF_NO_PI;
-
- if ((dev_net_tun_fd = open ("/dev/net/tun", O_RDWR)) < 0)
- {
- vlib_cli_output (vm, "Couldn't open /dev/net/tun");
- return 0;
- }
-
- memset (&ifr, 0, sizeof (ifr));
- strncpy(ifr.ifr_name, (char *) intfc_name, sizeof (ifr.ifr_name)-1);
- ifr.ifr_flags = flags;
- if (ioctl (dev_net_tun_fd, TUNSETIFF, (void *)&ifr) < 0)
- {
- vlib_cli_output (vm, "Error setting flags on '%s'", intfc_name);
- goto error;
- }
-
- /* Open a provisioning socket */
- if ((dev_tap_fd = socket(PF_PACKET, SOCK_RAW,
- htons(ETH_P_ALL))) < 0 )
- {
- vlib_cli_output (vm, "Couldn't open provisioning socket");
- goto error;
- }
-
- /* Find the interface index. */
- {
- struct ifreq ifr;
- struct sockaddr_ll sll;
-
- memset (&ifr, 0, sizeof(ifr));
- strncpy (ifr.ifr_name, (char *) intfc_name, sizeof (ifr.ifr_name)-1);
- if (ioctl (dev_tap_fd, SIOCGIFINDEX, &ifr) < 0 )
- {
- vlib_cli_output (vm, "Couldn't get if_index");
- goto error;
- }
-
- /* Bind the provisioning socket to the interface. */
- memset(&sll, 0, sizeof(sll));
- sll.sll_family = AF_PACKET;
- sll.sll_ifindex = ifr.ifr_ifindex;
- sll.sll_protocol = htons(ETH_P_ALL);
-
- if (bind(dev_tap_fd, (struct sockaddr*) &sll, sizeof(sll)) < 0)
- {
- vlib_cli_output (vm, "Couldn't bind provisioning socket");
- goto error;
- }
- }
-
- /* non-blocking I/O on /dev/tapX */
- {
- int one = 1;
- if (ioctl (dev_net_tun_fd, FIONBIO, &one) < 0)
- {
- vlib_cli_output (0, "Couldn't set device non-blocking flag");
- goto error;
- }
- }
- ifr.ifr_mtu = tm->mtu_bytes;
- if (ioctl (dev_tap_fd, SIOCSIFMTU, &ifr) < 0)
- {
- vlib_cli_output (0, "Couldn't set device MTU");
- goto error;
- }
-
- /* get flags, modify to bring up interface... */
- if (ioctl (dev_tap_fd, SIOCGIFFLAGS, &ifr) < 0)
- {
- vlib_cli_output (0, "Couldn't get interface flags");
- goto error;
- }
-
- ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
-
- if (ioctl (dev_tap_fd, SIOCSIFFLAGS, &ifr) < 0)
- {
- vlib_cli_output (0, "Couldn't set intfc admin state up");
- goto error;
- }
-
- if (ioctl (dev_tap_fd, SIOCGIFHWADDR, &ifr) < 0)
- {
- vlib_cli_output (0, "Couldn't get intfc MAC address");
- goto error;
- }
-
- ti = tapcli_get_new_tapif();
- ti->per_interface_next_index = ~0;
-
if (unformat(input, "hwaddr random"))
{
f64 now = vlib_time_now(vm);
@@ -1133,58 +1039,64 @@ tap_connect_command_fn (vlib_main_t * vm,
hwaddr[1] = 0xfe;
user_hwaddr = 1;
}
-
- error = ethernet_register_interface
- (tm->vnet_main,
- tapcli_dev_class.index,
- ti - tm->tapcli_interfaces /* device instance */,
- user_hwaddr ? hwaddr :
- (u8 *) ifr.ifr_hwaddr.sa_data /* ethernet address */,
- &ti->hw_if_index,
- tapcli_flag_change);
+ if (user_hwaddr) hwaddr_arg = hwaddr;
- if (error)
- clib_error_report (error);
+ int rv = vnet_tap_connect(vm, intfc_name, hwaddr_arg, &sw_if_index);
+ if (rv) {
+ switch (rv) {
+ case VNET_API_ERROR_SYSCALL_ERROR_1:
+ vlib_cli_output (vm, "Couldn't open /dev/net/tun");
+ break;
- {
- unix_file_t template = {0};
- template.read_function = tapcli_read_ready;
- template.file_descriptor = dev_net_tun_fd;
- ti->unix_file_index = unix_file_add (&unix_main, &template);
- ti->unix_fd = dev_net_tun_fd;
- ti->provision_fd = dev_tap_fd;
- clib_memcpy (&ti->ifr, &ifr, sizeof (ifr));
- }
+ case VNET_API_ERROR_SYSCALL_ERROR_2:
+ vlib_cli_output (vm, "Error setting flags on '%s'", intfc_name);
+ break;
- {
- vnet_hw_interface_t * hw;
- hw = vnet_get_hw_interface (tm->vnet_main, ti->hw_if_index);
- ti->sw_if_index = hw->sw_if_index;
- hw->min_supported_packet_bytes = TAP_MTU_MIN;
- hw->max_supported_packet_bytes = TAP_MTU_MAX;
- hw->max_l3_packet_bytes[VLIB_RX] = hw->max_l3_packet_bytes[VLIB_TX] = hw->max_supported_packet_bytes - sizeof(ethernet_header_t);
- }
+ case VNET_API_ERROR_SYSCALL_ERROR_3:
+ vlib_cli_output (vm, "Couldn't open provisioning socket");
+ break;
- ti->active = 1;
+ case VNET_API_ERROR_SYSCALL_ERROR_4:
+ vlib_cli_output (vm, "Couldn't get if_index");
+ break;
+
+ case VNET_API_ERROR_SYSCALL_ERROR_5:
+ vlib_cli_output (vm, "Couldn't bind provisioning socket");
+ break;
- hash_set (tm->tapcli_interface_index_by_sw_if_index, ti->sw_if_index,
- ti - tm->tapcli_interfaces);
+ case VNET_API_ERROR_SYSCALL_ERROR_6:
+ vlib_cli_output (0, "Couldn't set device non-blocking flag");
+ break;
- hash_set (tm->tapcli_interface_index_by_unix_fd, ti->unix_fd,
- ti - tm->tapcli_interfaces);
+ case VNET_API_ERROR_SYSCALL_ERROR_7:
+ vlib_cli_output (0, "Couldn't set device MTU");
+ break;
+
+ case VNET_API_ERROR_SYSCALL_ERROR_8:
+ vlib_cli_output (0, "Couldn't get interface flags");
+ break;
+
+ case VNET_API_ERROR_SYSCALL_ERROR_9:
+ vlib_cli_output (0, "Couldn't set intfc admin state up");
+ break;
+
+ case VNET_API_ERROR_INVALID_REGISTRATION:
+ vlib_cli_output (0, "Invalid registration");
+ break;
+ default:
+ vlib_cli_output (0, "Unknown error: %d", rv);
+ break;
+ }
+ return 0;
+ }
vlib_cli_output (vm, "Created %U for Linux tap '%s'",
- format_vnet_sw_if_index_name, tm->vnet_main,
- ti->sw_if_index, intfc_name);
+ format_vnet_sw_if_index_name, tm->vnet_main,
+ sw_if_index, intfc_name);
return 0;
- error:
- close (dev_net_tun_fd);
- close (dev_tap_fd);
-
- return 0;
-}
+ }
VLIB_CLI_COMMAND (tap_connect_command, static) = {
.path = "tap connect",