/*
 * Copyright (c) 2018, Microsoft Corporation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * vmbus.c: Linux user space VMBus bus management.
 */

#include <vppinfra/linux/sysfs.h>

#include <vlib/vlib.h>
#include <vlib/vmbus/vmbus.h>
#include <vlib/unix/unix.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>

#include <uuid/uuid.h>

static const char sysfs_vmbus_dev_path[] = "/sys/bus/vmbus/devices";
static const char sysfs_vmbus_drv_path[] = "/sys/bus/vmbus/drivers";
static const char sysfs_class_net_path[] = "/sys/class/net";
static const char uio_drv_name[] = "uio_hv_generic";
static const char netvsc_uuid[] = "f8615163-df3e-46c5-913f-f2d2f965ed0e";

typedef struct
{
  int fd;
  void *addr;
  size_t size;
} linux_vmbus_region_t;

typedef struct
{
  int fd;
  u32 clib_file_index;
} linux_vmbus_irq_t;

typedef struct
{
  vlib_vmbus_dev_handle_t handle;
  vlib_vmbus_addr_t addr;

  /* Device File descriptor */
  int fd;

  /* Minor device for uio device. */
  u32 uio_minor;

  /* private data */
  uword private_data;

} linux_vmbus_device_t;

/* Pool of VMBUS devices. */
typedef struct
{
  vlib_main_t *vlib_main;
  linux_vmbus_device_t *linux_vmbus_devices;

} linux_vmbus_main_t;

linux_vmbus_main_t linux_vmbus_main;

static linux_vmbus_device_t *
linux_vmbus_get_device (vlib_vmbus_dev_handle_t h)
{
  linux_vmbus_main_t *lpm = &linux_vmbus_main;
  return pool_elt_at_index (lpm->linux_vmbus_devices, h);
}

uword
vlib_vmbus_get_private_data (vlib_vmbus_dev_handle_t h)
{
  linux_vmbus_device_t *d = linux_vmbus_get_device (h);
  return d->private_data;
}

void
vlib_vmbus_set_private_data (vlib_vmbus_dev_handle_t h, uword private_data)
{
  linux_vmbus_device_t *d = linux_vmbus_get_device (h);
  d->private_data = private_data;
}

vlib_vmbus_addr_t *
vlib_vmbus_get_addr (vlib_vmbus_dev_handle_t h)
{
  linux_vmbus_device_t *d = linux_vmbus_get_device (h);
  return &d->addr;
}

/* Call to allocate/initialize the vmbus subsystem.
   This is not an init function so that users can explicitly enable
   vmbus only when it's needed. */
clib_error_t *vmbus_bus_init (vlib_main_t * vm);

linux_vmbus_main_t linux_vmbus_main;

/*
 * Take VMBus address represented in standard form like:
 * "f2c086b2-ff2e-11e8-88de-7bad0a57de05" and convert
 * it to u8[16]
 */
uword
unformat_vlib_vmbus_addr (unformat_input_t *input, va_list *args)
{
  vlib_vmbus_addr_t *addr = va_arg (*args, vlib_vmbus_addr_t *);
  uword ret = 0;
  u8 *s;

  if (!unformat (input, "%s", &s))
    return 0;

  if (uuid_parse ((char *) s, addr->guid) == 0)
    ret = 1;

  vec_free (s);

  return ret;
}

/* Convert bus address to standard UUID string */
u8 *
format_vlib_vmbus_addr (u8 *s, va_list *va)
{
  vlib_vmbus_addr_t *addr = va_arg (*va, vlib_vmbus_addr_t *);
  char tmp[40];

  uuid_unparse (addr->guid, tmp);
  return format (s, "%s", tmp);
}

/* workaround for mlx bug, bring lower device up before unbind */
static clib_error_t *
vlib_vmbus_raise_lower (int fd, const char *upper_name)
{
  clib_error_t *error = 0;
  struct dirent *e;
  struct ifreq ifr;
  u8 *dev_net_dir;
  DIR *dir;

  clib_memset (&ifr, 0, sizeof (ifr));

  dev_net_dir = format (0, "%s/%s%c", sysfs_class_net_path, upper_name, 0);

  dir = opendir ((char *) dev_net_dir);

  if (!dir)
    {
      error = clib_error_return (0, "VMBUS failed to open %s", dev_net_dir);
      goto done;
    }

  while ((e = readdir (dir)))
    {
      /* look for lower_enXXXX */
      if (strncmp (e->d_name, "lower_", 6))
	continue;

      strncpy (ifr.ifr_name, e->d_name + 6, IFNAMSIZ - 1);
      break;
    }
  closedir (dir);

  if (!e)
    goto done;			/* no lower device */

  if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0)
    error = clib_error_return_unix (0, "ioctl fetch intf %s flags",
				    ifr.ifr_name);
  else if (!(ifr.ifr_flags & IFF_UP))
    {
      ifr.ifr_flags |= IFF_UP;

      if (ioctl (fd, SIOCSIFFLAGS, &ifr) < 0)
	error = clib_error_return_unix (0, "ioctl set intf %s flags",
					ifr.ifr_name);
    }
done:
  vec_free (dev_net_dir);
  return error;
}

static int
directory_exists (char *path)
{
  struct stat s = { 0 };
  if (stat (path, &s) == -1)
    return 0;

  return S_ISDIR (s.st_mode);
}

clib_error_t *
vlib_vmbus_bind_to_uio (vlib_vmbus_addr_t * addr)
{
  clib_error_t *error = 0;
  u8 *dev_dir_name;
  char *ifname = 0;
  static int uio_new_id_needed = 1;
  struct dirent *e;
  struct ifreq ifr;
  u8 *s, *driver_name;
  DIR *dir;
  int fd;

  dev_dir_name = format (0, "%s/%U", sysfs_vmbus_dev_path,
			 format_vlib_vmbus_addr, addr);
  s = format (0, "%v/driver%c", dev_dir_name, 0);

  driver_name = clib_sysfs_link_to_name ((char *) s);
  vec_reset_length (s);

  /* skip if not using the Linux kernel netvsc driver */
  if (!driver_name || strcmp ("hv_netvsc", (char *) driver_name) != 0)
    goto done;

  /* if uio_hv_generic is not loaded, then can't use native DPDK driver. */
  if (!directory_exists ("/sys/module/uio_hv_generic"))
    goto done;

  s = format (s, "%v/net%c", dev_dir_name, 0);
  dir = opendir ((char *) s);
  vec_reset_length (s);

  if (!dir)
    return clib_error_return (0, "VMBUS failed to open %s", s);

  while ((e = readdir (dir)))
    {
      if (e->d_name[0] == '.')	/* skip . and .. */
	continue;

      ifname = strdup (e->d_name);
      break;
    }
  closedir (dir);

  if (!ifname)
    {
      error = clib_error_return (0,
				 "VMBUS device %U eth not found",
				 format_vlib_vmbus_addr, addr);
      goto done;
    }


  clib_memset (&ifr, 0, sizeof (ifr));
  strncpy (ifr.ifr_name, ifname, IFNAMSIZ - 1);

  /* read up/down flags */
  fd = socket (PF_INET, SOCK_DGRAM, 0);
  if (fd < 0)
    {
      error = clib_error_return_unix (0, "socket");
      goto done;
    }

  if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0)
    {
      error = clib_error_return_unix (0, "ioctl fetch intf %s flags",
				      ifr.ifr_name);
      close (fd);
      goto done;
    }

  if (ifr.ifr_flags & IFF_UP)
    {
      error = clib_error_return (
	0, "Skipping VMBUS device %U as host interface %s is up",
	format_vlib_vmbus_addr, addr, ifname);
      close (fd);
      goto done;
    }

  /* tell uio_hv_generic about netvsc device type */
  if (uio_new_id_needed)
    {
      vec_reset_length (s);
      s = format (s, "%s/%s/new_id%c", sysfs_vmbus_drv_path, uio_drv_name, 0);
      error = clib_sysfs_write ((char *) s, "%s", netvsc_uuid);
      /* If device already exists, we can bind/unbind/override driver */
      if (error)
	{
	  if (error->code == EEXIST)
	    {
	      clib_error_free (error);
	    }
	  else
	    {
	      close (fd);
	      goto done;
	    }
	}

      uio_new_id_needed = 0;
    }

  error = vlib_vmbus_raise_lower (fd, ifname);
  close (fd);

  if (error)
    goto done;

  /* prefer the simplier driver_override model */
  vec_reset_length (s);
  s = format (s, "%/driver_override%c", dev_dir_name, 0);
  if (access ((char *) s, F_OK) == 0)
    {
      clib_sysfs_write ((char *) s, "%s", uio_drv_name);
    }
  else
    {
      vec_reset_length (s);

      s = format (s, "%v/driver/unbind%c", dev_dir_name, 0);
      error =
	clib_sysfs_write ((char *) s, "%U", format_vlib_vmbus_addr, addr);

      if (error)
	goto done;

      vec_reset_length (s);

      s = format (s, "%s/%s/bind%c", sysfs_vmbus_drv_path, uio_drv_name, 0);
      error =
	clib_sysfs_write ((char *) s, "%U", format_vlib_vmbus_addr, addr);
    }
  vec_reset_length (s);

done:
  free (ifname);
  vec_free (s);
  vec_free (dev_dir_name);
  vec_free (driver_name);
  return error;
}

static clib_error_t *
scan_vmbus_addr (void *arg, u8 * dev_dir_name, u8 * ignored)
{
  vlib_vmbus_addr_t addr, **addrv = arg;
  unformat_input_t input;
  clib_error_t *err = 0;

  unformat_init_string (&input, (char *) dev_dir_name,
			vec_len (dev_dir_name));

  if (!unformat (&input, "/sys/bus/vmbus/devices/%U",
		 unformat_vlib_vmbus_addr, &addr))
    err = clib_error_return (0, "unformat error `%v`", dev_dir_name);

  unformat_free (&input);

  if (err)
    return err;

  vec_add1 (*addrv, addr);
  return 0;
}

static int
vmbus_addr_cmp (void *v1, void *v2)
{
  vlib_vmbus_addr_t *a1 = v1;
  vlib_vmbus_addr_t *a2 = v2;

  return uuid_compare (a1->guid, a2->guid);
}

vlib_vmbus_addr_t *
vlib_vmbus_get_all_dev_addrs ()
{
  vlib_vmbus_addr_t *addrs = 0;
  clib_error_t *err;

  err =
    foreach_directory_file ((char *) sysfs_vmbus_dev_path, scan_vmbus_addr,
			    &addrs, /* scan_dirs */ 0);
  if (err)
    {
      vec_free (addrs);
      return 0;
    }

  vec_sort_with_function (addrs, vmbus_addr_cmp);

  return addrs;
}

clib_error_t *
linux_vmbus_init (vlib_main_t * vm)
{
  linux_vmbus_main_t *pm = &linux_vmbus_main;

  pm->vlib_main = vm;

  return 0;
}

/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (linux_vmbus_init) =
{
  .runs_before = VLIB_INITS("unix_input_init"),
};
/* *INDENT-ON* */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
