/*
 * Copyright (c) 2019 Cisco and/or its affiliates.
 * 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.
 */

#include <vnet/ip/ip6_link.h>
#include <vnet/ip/ip6_ll_table.h>

#include <vnet/ethernet/ethernet.h>
#include <vnet/mfib/ip6_mfib.h>
#include <vnet/adj/adj_mcast.h>

typedef struct ip6_link_delegate_t_
{
  u32 ild_sw_if_index;
  ip6_link_delegate_id_t ild_type;
  index_t ild_index;
} ip6_link_delegate_t;

const static ip6_link_delegate_t ip6_link_delegate_uninit = {
  .ild_sw_if_index = ~0,
};

typedef struct ip6_link_t_
{
  /** interface ip6 is enabled on */
  u32 il_sw_if_index;

  /** link-local address - if unset that IP6 is disabled*/
  ip6_address_t il_ll_addr;

  /** list of delegates */
  ip6_link_delegate_t *il_delegates;

  /** multicast adjacency for this link */
  adj_index_t il_mcast_adj;

  /** number of references to IP6 enabled on this link */
  u32 il_locks;
} ip6_link_t;

#define FOREACH_IP6_LINK_DELEGATE(_ild, _il, body)      \
{                                                       \
 if (NULL != _il) {                                     \
   vec_foreach (_ild, _il->il_delegates) {              \
     if (ip6_link_delegate_is_init(_ild))               \
       body;                                            \
   }                                                    \
 }                                                      \
}

#define FOREACH_IP6_LINK_DELEGATE_ID(_id) \
  for (_id = 0; _id < il_delegate_id; _id++)

/** last used delegate ID */
static ip6_link_delegate_id_t il_delegate_id;

/** VFT registered per-delegate type */
static ip6_link_delegate_vft_t *il_delegate_vfts;

/** Per interface configs */
static ip6_link_t *ip6_links;

/** Randomizer */
static u64 il_randomizer;

/** Logging */
static vlib_log_class_t ip6_link_logger;

#define IP6_LINK_DBG(...)                       \
    vlib_log_debug (ip6_link_logger, __VA_ARGS__);

#define IP6_LINK_INFO(...)                              \
    vlib_log_notice (ip6_link_logger, __VA_ARGS__);

static bool
ip6_link_delegate_is_init (const ip6_link_delegate_t * ild)
{
  return (~0 != ild->ild_sw_if_index);
}

static bool
ip6_link_is_enabled_i (const ip6_link_t * il)
{
  return (!ip6_address_is_zero (&il->il_ll_addr));
}

static void
ip6_link_local_address_from_mac (ip6_address_t * ip, const u8 * mac)
{
  ip->as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
  /* Invert the "u" bit */
  ip->as_u8[8] = mac[0] ^ (1 << 1);
  ip->as_u8[9] = mac[1];
  ip->as_u8[10] = mac[2];
  ip->as_u8[11] = 0xFF;
  ip->as_u8[12] = 0xFE;
  ip->as_u8[13] = mac[3];
  ip->as_u8[14] = mac[4];
  ip->as_u8[15] = mac[5];
}

static void
ip6_mac_address_from_link_local (u8 * mac, const ip6_address_t * ip)
{
  /* Invert the previously inverted "u" bit */
  mac[0] = ip->as_u8[8] ^ (1 << 1);
  mac[1] = ip->as_u8[9];
  mac[2] = ip->as_u8[10];
  mac[3] = ip->as_u8[13];
  mac[4] = ip->as_u8[14];
  mac[5] = ip->as_u8[15];
}

static ip6_link_t *
ip6_link_get (u32 sw_if_index)
{
  ip6_link_t *il;

  if (sw_if_index >= vec_len (ip6_links))
    return (NULL);

  il = &ip6_links[sw_if_index];

  if (!ip6_link_is_enabled_i (il))
    return (NULL);

  return (il);
}

bool
ip6_link_is_enabled (u32 sw_if_index)
{
  return (NULL != ip6_link_get (sw_if_index));
}


int
ip6_link_enable (u32 sw_if_index, const ip6_address_t * link_local_addr)
{
  ip6_link_t *il;
  int rv;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    {
      const vnet_sw_interface_t *sw, *sw_sup;
      const ethernet_interface_t *eth;
      vnet_main_t *vnm;

      vnm = vnet_get_main ();

      IP6_LINK_INFO ("enable: %U",
		     format_vnet_sw_if_index_name, vnm, sw_if_index);

      sw_sup = vnet_get_sup_sw_interface (vnm, sw_if_index);
      if (sw_sup->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
	{
	  rv = VNET_API_ERROR_UNSUPPORTED;
	  goto out;
	}

      eth = ethernet_get_interface (&ethernet_main, sw_sup->hw_if_index);

      if (NULL == eth)
	{
	  rv = VNET_API_ERROR_UNSUPPORTED;
	  goto out;
	}

      vec_validate (ip6_links, sw_if_index);

      il = &ip6_links[sw_if_index];
      il->il_locks = 1;
      il->il_sw_if_index = sw_if_index;

      sw = vnet_get_sup_sw_interface (vnm, sw_if_index);

      if (NULL != link_local_addr)
	ip6_address_copy (&il->il_ll_addr, link_local_addr);
      else if (sw->type == VNET_SW_INTERFACE_TYPE_SUB ||
	       sw->type == VNET_SW_INTERFACE_TYPE_PIPE ||
	       sw->type == VNET_SW_INTERFACE_TYPE_P2P)
	{
	  il->il_ll_addr.as_u64[0] =
	    clib_host_to_net_u64 (0xFE80000000000000ULL);

	  /* make up an interface id */
	  il->il_ll_addr.as_u64[1] = random_u64 (&il_randomizer);

	  /* clear u bit */
	  il->il_ll_addr.as_u8[8] &= 0xfd;
	}
      else
	{
	  ip6_link_local_address_from_mac (&il->il_ll_addr, eth->address);
	}

      {
	ip6_ll_prefix_t ilp = {
	  .ilp_addr = il->il_ll_addr,
	  .ilp_sw_if_index = sw_if_index,
	};

	ip6_ll_table_entry_update (&ilp, FIB_ROUTE_PATH_LOCAL);
      }

      /* essentially "enables" ipv6 on this interface */
      ip6_mfib_interface_enable_disable (sw_if_index, 1);
      ip6_sw_interface_enable_disable (sw_if_index, 1);

      il->il_mcast_adj = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6,
						VNET_LINK_IP6, sw_if_index);

      /* inform all register clients */
      ip6_link_delegate_id_t id;
      FOREACH_IP6_LINK_DELEGATE_ID (id)
      {
	if (NULL != il_delegate_vfts[id].ildv_enable)
	  il_delegate_vfts[id].ildv_enable (il->il_sw_if_index);
      }

      rv = 0;
    }
  else
    {
      rv = VNET_API_ERROR_VALUE_EXIST;
    }

out:
  return (rv);
}

static void
ip6_link_delegate_flush (ip6_link_t * il)
{
  ip6_link_delegate_t *ild;

  /* *INDENT-OFF* */
  FOREACH_IP6_LINK_DELEGATE (ild, il,
  ({
    il_delegate_vfts[ild->ild_type].ildv_disable(ild->ild_index);
  }));
  /* *INDENT-ON* */

  vec_free (il->il_delegates);
  il->il_delegates = NULL;
}

static void
ip6_link_last_lock_gone (ip6_link_t * il)
{
  ip6_ll_prefix_t ilp = {
    .ilp_addr = il->il_ll_addr,
    .ilp_sw_if_index = il->il_sw_if_index,
  };

  IP6_LINK_INFO ("last-lock: %U",
		 format_vnet_sw_if_index_name,
		 vnet_get_main (), il->il_sw_if_index);

  ip6_link_delegate_flush (il);
  ip6_ll_table_entry_delete (&ilp);

  ip6_mfib_interface_enable_disable (il->il_sw_if_index, 0);
  ip6_sw_interface_enable_disable (il->il_sw_if_index, 0);

  ip6_address_set_zero (&il->il_ll_addr);
  adj_unlock (il->il_mcast_adj);
  il->il_mcast_adj = ADJ_INDEX_INVALID;
}

static void
ip6_link_unlock (ip6_link_t * il)
{
  if (NULL == il)
    return;

  il->il_locks--;

  if (0 == il->il_locks)
    ip6_link_last_lock_gone (il);
}

int
ip6_link_disable (u32 sw_if_index)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (VNET_API_ERROR_IP6_NOT_ENABLED);

  IP6_LINK_INFO ("disable: %U",
		 format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index);

  ip6_link_unlock (il);

  return (0);
}

const ip6_address_t *
ip6_get_link_local_address (u32 sw_if_index)
{
  const ip6_link_t *il;

  vec_validate (ip6_links, sw_if_index);

  il = &ip6_links[sw_if_index];

  return (&il->il_ll_addr);
}

adj_index_t
ip6_link_get_mcast_adj (u32 sw_if_index)
{
  const ip6_link_t *il;

  il = &ip6_links[sw_if_index];

  return (il->il_mcast_adj);
}

int
ip6_src_address_for_packet (u32 sw_if_index,
			    const ip6_address_t * dst, ip6_address_t * src)
{
  ip_lookup_main_t *lm;

  lm = &ip6_main.lookup_main;

  if (ip6_address_is_link_local_unicast (dst))
    {
      ip6_address_copy (src, ip6_get_link_local_address (sw_if_index));

      return (!0);
    }
  else
    {
      u32 if_add_index =
	lm->if_address_pool_index_by_sw_if_index[sw_if_index];
      if (PREDICT_TRUE (if_add_index != ~0))
	{
	  ip_interface_address_t *if_add =
	    pool_elt_at_index (lm->if_address_pool, if_add_index);
	  ip6_address_t *if_ip =
	    ip_interface_address_get_address (lm, if_add);
	  *src = *if_ip;
	  return (!0);
	}
    }

  src->as_u64[0] = 0;
  src->as_u64[1] = 0;

  return (0);
}

int
ip6_link_set_local_address (u32 sw_if_index, const ip6_address_t * address)
{
  ip6_link_delegate_t *ild;
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return ip6_link_enable (sw_if_index, address);

  ip6_ll_prefix_t ilp = {
    .ilp_addr = il->il_ll_addr,
    .ilp_sw_if_index = sw_if_index,
  };

  IP6_LINK_INFO ("set-ll: %U -> %U",
		 format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index,
		 format_ip6_address, address);

  ip6_ll_table_entry_delete (&ilp);
  ip6_address_copy (&il->il_ll_addr, address);
  ip6_address_copy (&ilp.ilp_addr, address);
  ip6_ll_table_entry_update (&ilp, FIB_ROUTE_PATH_LOCAL);

  /* *INDENT-OFF* */
  FOREACH_IP6_LINK_DELEGATE (ild, il,
  ({
    if (NULL != il_delegate_vfts[ild->ild_type].ildv_ll_change)
      il_delegate_vfts[ild->ild_type].ildv_ll_change(ild->ild_index,
                                                     &il->il_ll_addr);
  }));
  /* *INDENT-ON* */

  return (0);
}

ip6_link_delegate_id_t
ip6_link_delegate_register (const ip6_link_delegate_vft_t * vft)
{
  ip6_link_delegate_id_t rc = il_delegate_id++;

  ASSERT (vft->ildv_disable);

  vec_validate (il_delegate_vfts, rc);

  il_delegate_vfts[rc] = *vft;

  return (rc);
}

index_t
ip6_link_delegate_get (u32 sw_if_index, ip6_link_delegate_id_t id)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (INDEX_INVALID);

  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);

  if (!ip6_link_delegate_is_init (&il->il_delegates[id]))
    return (INDEX_INVALID);

  return (il->il_delegates[id].ild_index);
}

bool
ip6_link_delegate_update (u32 sw_if_index,
			  ip6_link_delegate_id_t id, index_t ii)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return (false);

  vec_validate_init_empty (il->il_delegates, id, ip6_link_delegate_uninit);

  il->il_delegates[id].ild_sw_if_index = sw_if_index;
  il->il_delegates[id].ild_type = id;
  il->il_delegates[id].ild_index = ii;

  return (true);
}

void
ip6_link_delegate_remove (u32 sw_if_index,
			  ip6_link_delegate_id_t id, index_t ii)
{
  ip6_link_t *il;

  il = ip6_link_get (sw_if_index);

  if (NULL != il)
    {
      if (vec_len (il->il_delegates) > id)
	{
	  clib_memcpy (&il->il_delegates[id],
		       &ip6_link_delegate_uninit,
		       sizeof (il->il_delegates[0]));
	}
    }
}

static void
ip6_link_add_del_address (ip6_main_t * im,
			  uword opaque,
			  u32 sw_if_index,
			  ip6_address_t * address,
			  u32 address_length,
			  u32 if_address_index, u32 is_delete)
{
  const ip6_link_delegate_t *ild;
  ip6_link_t *il;

  if (ip6_address_is_link_local_unicast (address))
    // only interested in global addresses here
    return;

  IP6_LINK_INFO ("addr-%s: %U -> %U",
		 (is_delete ? "del" : "add"),
		 format_vnet_sw_if_index_name, vnet_get_main (), sw_if_index,
		 format_ip6_address, address);

  il = ip6_link_get (sw_if_index);

  if (NULL == il)
    return;

  /* *INDENT-OFF* */
  FOREACH_IP6_LINK_DELEGATE (ild, il,
  ({
      if (is_delete)
        {
          if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_del)
            il_delegate_vfts[ild->ild_type].ildv_addr_del(ild->ild_index,
                                                          address, address_length);
        }
      else
        {
          if (NULL != il_delegate_vfts[ild->ild_type].ildv_addr_add)
            il_delegate_vfts[ild->ild_type].ildv_addr_add(ild->ild_index,
                                                          address, address_length);
        }
  }));
  /* *INDENT-ON* */
}

static clib_error_t *
ip6_link_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
{
  if (!is_add)
    {
      ip6_link_t *il;

      il = ip6_link_get (sw_if_index);

      IP6_LINK_DBG ("link-del: %U",
		    format_vnet_sw_if_index_name, vnet_get_main (),
		    sw_if_index);

      if (NULL != il)
	/* force cleanup */
	ip6_link_last_lock_gone (il);
    }

  return (NULL);
}

VNET_SW_INTERFACE_ADD_DEL_FUNCTION (ip6_link_interface_add_del);

static clib_error_t *
ip6_link_init (vlib_main_t * vm)
{
  il_randomizer = clib_cpu_time_now ();
  ip6_link_logger = vlib_log_register_class ("ip6", "link");

  {
    ip6_add_del_interface_address_callback_t cb = {
      .function = ip6_link_add_del_address,
    };
    vec_add1 (ip6_main.add_del_interface_address_callbacks, cb);
  }
  return (NULL);
}

VLIB_INIT_FUNCTION (ip6_link_init);


static clib_error_t *
test_ip6_link_command_fn (vlib_main_t * vm,
			  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  u8 mac[6];
  ip6_address_t _a, *a = &_a;

  if (unformat (input, "%U", unformat_ethernet_address, mac))
    {
      ip6_link_local_address_from_mac (a, mac);
      vlib_cli_output (vm, "Link local address: %U", format_ip6_address, a);
      ip6_mac_address_from_link_local (mac, a);
      vlib_cli_output (vm, "Original MAC address: %U",
		       format_ethernet_address, mac);
    }

  return 0;
}

/*?
 * This command converts the given MAC Address into an IPv6 link-local
 * address.
 *
 * @cliexpar
 * Example of how to create an IPv6 link-local address:
 * @cliexstart{test ip6 link 16:d9:e0:91:79:86}
 * Link local address: fe80::14d9:e0ff:fe91:7986
 * Original MAC address: 16:d9:e0:91:79:86
 * @cliexend
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_link_command, static) =
{
  .path = "test ip6 link",
  .function = test_ip6_link_command_fn,
  .short_help = "test ip6 link <mac-address>",
};
/* *INDENT-ON* */

static u8 *
ip6_print_addrs (u8 * s, u32 * addrs)
{
  ip_lookup_main_t *lm = &ip6_main.lookup_main;
  u32 i;

  for (i = 0; i < vec_len (addrs); i++)
    {
      ip_interface_address_t *a =
	pool_elt_at_index (lm->if_address_pool, addrs[i]);
      ip6_address_t *address = ip_interface_address_get_address (lm, a);

      s = format (s, "%U%U/%d\n",
		  format_white_space, 4,
		  format_ip6_address, address, a->address_length);
    }

  return (s);
}

static u8 *
format_ip6_link (u8 * s, va_list * arg)
{
  const ip6_link_t *il = va_arg (*arg, ip6_link_t *);
  ip_lookup_main_t *lm = &ip6_main.lookup_main;
  vnet_main_t *vnm = vnet_get_main ();

  if (!ip6_link_is_enabled_i (il))
    return (s);

  s = format (s, "%U is admin %s\n",
	      format_vnet_sw_interface_name, vnm,
	      vnet_get_sw_interface (vnm, il->il_sw_if_index),
	      (vnet_sw_interface_is_admin_up (vnm, il->il_sw_if_index) ?
	       "up" : "down"));

  u32 ai;
  u32 *link_scope = 0, *global_scope = 0;
  u32 *local_scope = 0, *unknown_scope = 0;
  ip_interface_address_t *a;
  const ip6_link_delegate_t *ild;

  vec_validate_init_empty (lm->if_address_pool_index_by_sw_if_index,
			   il->il_sw_if_index, ~0);
  ai = lm->if_address_pool_index_by_sw_if_index[il->il_sw_if_index];

  while (ai != (u32) ~ 0)
    {
      a = pool_elt_at_index (lm->if_address_pool, ai);
      ip6_address_t *address = ip_interface_address_get_address (lm, a);

      if (ip6_address_is_link_local_unicast (address))
	vec_add1 (link_scope, ai);
      else if (ip6_address_is_global_unicast (address))
	vec_add1 (global_scope, ai);
      else if (ip6_address_is_local_unicast (address))
	vec_add1 (local_scope, ai);
      else
	vec_add1 (unknown_scope, ai);

      ai = a->next_this_sw_interface;
    }

  if (vec_len (link_scope))
    {
      s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
      s = ip6_print_addrs (s, link_scope);
      vec_free (link_scope);
    }

  if (vec_len (local_scope))
    {
      s = format (s, "%ULocal unicast address(es):\n", format_white_space, 2);
      s = ip6_print_addrs (s, local_scope);
      vec_free (local_scope);
    }

  if (vec_len (global_scope))
    {
      s = format (s, "%UGlobal unicast address(es):\n",
		  format_white_space, 2);
      s = ip6_print_addrs (s, global_scope);
      vec_free (global_scope);
    }

  if (vec_len (unknown_scope))
    {
      s = format (s, "%UOther-scope address(es):\n", format_white_space, 2);
      s = ip6_print_addrs (s, unknown_scope);
      vec_free (unknown_scope);
    }

  s = format (s, "%ULink-local address(es):\n", format_white_space, 2);
  s = format (s, "%U%U\n",
	      format_white_space, 4, format_ip6_address, &il->il_ll_addr);

  /* *INDENT-OFF* */
  FOREACH_IP6_LINK_DELEGATE(ild, il,
  ({
    s = format (s, "%U", il_delegate_vfts[ild->ild_type].ildv_format,
                     ild->ild_index, 2);
  }));
  /* *INDENT-ON* */

  return (s);
}

static clib_error_t *
ip6_link_show (vlib_main_t * vm,
	       unformat_input_t * input, vlib_cli_command_t * cmd)
{
  const ip6_link_t *il;
  vnet_main_t *vnm;
  u32 sw_if_index;

  vnm = vnet_get_main ();
  sw_if_index = ~0;

  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      il = ip6_link_get (sw_if_index);

      if (NULL == il)
	{
	  vlib_cli_output (vm, "IP6 disabled");
	  return (NULL);
	}
      else
	vlib_cli_output (vm, "%U", format_ip6_link, il);
    }
  else
    {
      vec_foreach (il, ip6_links)
	vlib_cli_output (vm, "%U", format_ip6_link, il);
    }

  return (NULL);
}

/*?
 * This command is used to display various IPv6 attributes on a given
 * interface.
 *
 * @cliexpar
 * Example of how to display IPv6 settings:
 * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
 * GigabitEthernet2/0/0 is admin up
 *         Link-local address(es):
 *                 fe80::ab8/64
 *         Joined group address(es):
 *                 ff02::1
 *                 ff02::2
 *                 ff02::16
 *                 ff02::1:ff00:ab8
 *         Advertised Prefixes:
 *                 prefix fe80::fe:28ff:fe9c:75b3,  length 64
 *         MTU is 1500
 *         ICMP error messages are unlimited
 *         ICMP redirects are disabled
 *         ICMP unreachables are not sent
 *         ND DAD is disabled
 *         ND advertised reachable time is 0
 *         ND advertised retransmit interval is 0 (msec)
 *         ND router advertisements are sent every 200 seconds (min interval is 150)
 *         ND router advertisements live for 600 seconds
 *         Hosts use stateless autoconfig for addresses
 *         ND router advertisements sent 19336
 *         ND router solicitations received 0
 *         ND router solicitations dropped 0
 * @cliexend
 * Example of output if IPv6 is not enabled on the interface:
 * @cliexstart{show ip6 interface GigabitEthernet2/0/0}
 * show ip6 interface: IPv6 not enabled on interface
 * @cliexend
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (ip6_link_show_command, static) =
{
  .path = "show ip6 interface",
  .function = ip6_link_show,
  .short_help = "show ip6 interface <interface>",
};
/* *INDENT-ON* */

static clib_error_t *
enable_ip6_interface_cmd (vlib_main_t * vm,
			  unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error = NULL;
  u32 sw_if_index;

  sw_if_index = ~0;

  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      if (ip6_link_enable (sw_if_index, NULL))
	error = clib_error_return (0, "Failed\n");
    }
  else
    {
      error = clib_error_return (0, "unknown interface\n'",
				 format_unformat_error, input);

    }
  return error;
}

/*?
 * This command is used to enable IPv6 on a given interface.
 *
 * @cliexpar
 * Example of how enable IPv6 on a given interface:
 * @cliexcmd{enable ip6 interface GigabitEthernet2/0/0}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (enable_ip6_interface_command, static) =
{
  .path = "enable ip6 interface",
  .function = enable_ip6_interface_cmd,
  .short_help = "enable ip6 interface <interface>",
};
/* *INDENT-ON* */

static clib_error_t *
disable_ip6_interface_cmd (vlib_main_t * vm,
			   unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error = NULL;
  u32 sw_if_index;

  sw_if_index = ~0;

  if (unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
    {
      if (ip6_link_disable (sw_if_index))
	error = clib_error_return (0, "Failed\n");
    }
  else
    {
      error = clib_error_return (0, "unknown interface\n'",
				 format_unformat_error, input);

    }
  return error;
}

/*?
 * This command is used to disable IPv6 on a given interface.
 *
 * @cliexpar
 * Example of how disable IPv6 on a given interface:
 * @cliexcmd{disable ip6 interface GigabitEthernet2/0/0}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (disable_ip6_interface_command, static) =
{
  .path = "disable ip6 interface",
  .function = disable_ip6_interface_cmd,
  .short_help = "disable ip6 interface <interface>",
};
/* *INDENT-ON* */

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