/*
 * ip/ip6_neighbor.c: IP6 neighbor handling
 *
 * Copyright (c) 2010 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/ip6-nd/ip6_nd.h>

#include <vnet/ip/ip.h>
#include <vnet/ip-neighbor/ip_neighbor_dp.h>

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

#include <vnet/ethernet/ethernet.h>

/**
 * @file
 * @brief IPv6 Neighbor Adjacency and Neighbor Discovery.
 *
 * The files contains the API and CLI code for managing IPv6 neighbor
 * adjacency tables and neighbor discovery logic.
 */

/* multicast listener report packet format for ethernet. */
typedef CLIB_PACKED (struct
{
    ip6_hop_by_hop_ext_t ext_hdr;
    ip6_router_alert_option_t alert;
    ip6_padN_option_t pad;
    icmp46_header_t icmp;
    u16 rsvd;
    u16 num_addr_records;
    icmp6_multicast_address_record_t records[0];
}) icmp6_multicast_listener_report_header_t;

typedef CLIB_PACKED (struct
{
  ip6_header_t ip;
  icmp6_multicast_listener_report_header_t report_hdr;
}) icmp6_multicast_listener_report_packet_t;

typedef struct
{
  /* group information */
  u16 num_sources;
  u8 type;
  ip6_address_t mcast_address;
  ip6_address_t *mcast_source_address_pool;
} ip6_mldp_group_t;

typedef struct ip6_nd_t_
{
  /* local information */
  u32 sw_if_index;
  int all_routers_mcast;

  /* MLDP  group information */
  ip6_mldp_group_t *mldp_group_pool;

  /* Hash table mapping address to index in mldp address pool. */
  mhash_t address_to_mldp_index;

} ip6_mld_t;


static ip6_link_delegate_id_t ip6_mld_delegate_id;
static ip6_mld_t *ip6_mld_pool;

/////

static inline ip6_mld_t *
ip6_mld_get_itf (u32 sw_if_index)
{
  index_t imi;

  imi = ip6_link_delegate_get (sw_if_index, ip6_mld_delegate_id);

  if (INDEX_INVALID != imi)
    return (pool_elt_at_index (ip6_mld_pool, imi));

  return (NULL);
}

/**
 * @brief Add a multicast Address to the advertised MLD set
 */
static void
ip6_neighbor_add_mld_prefix (ip6_mld_t * imd, ip6_address_t * addr)
{
  ip6_mldp_group_t *mcast_group_info;
  uword *p;

  /* lookup  mldp info for this interface */
  p = mhash_get (&imd->address_to_mldp_index, addr);
  mcast_group_info = p ? pool_elt_at_index (imd->mldp_group_pool, p[0]) : 0;

  /* add address */
  if (!mcast_group_info)
    {
      /* add */
      u32 mi;
      pool_get_zero (imd->mldp_group_pool, mcast_group_info);

      mi = mcast_group_info - imd->mldp_group_pool;
      mhash_set (&imd->address_to_mldp_index, addr, mi,	/* old_value */
		 0);

      mcast_group_info->type = 4;
      mcast_group_info->mcast_source_address_pool = 0;
      mcast_group_info->num_sources = 0;
      clib_memcpy (&mcast_group_info->mcast_address, addr,
		   sizeof (ip6_address_t));
    }
}

/**
 * @brief Delete a multicast Address from the advertised MLD set
 */
static void
ip6_neighbor_del_mld_prefix (ip6_mld_t * imd, ip6_address_t * addr)
{
  ip6_mldp_group_t *mcast_group_info;
  uword *p;

  p = mhash_get (&imd->address_to_mldp_index, addr);
  mcast_group_info = p ? pool_elt_at_index (imd->mldp_group_pool, p[0]) : 0;

  if (mcast_group_info)
    {
      mhash_unset (&imd->address_to_mldp_index, addr,
		   /* old_value */ 0);
      pool_put (imd->mldp_group_pool, mcast_group_info);
    }
}

/**
 * @brief Add a multicast Address to the advertised MLD set
 */
static void
ip6_neighbor_add_mld_grp (ip6_mld_t * a,
			  ip6_multicast_address_scope_t scope,
			  ip6_multicast_link_local_group_id_t group)
{
  ip6_address_t addr;

  ip6_set_reserved_multicast_address (&addr, scope, group);

  ip6_neighbor_add_mld_prefix (a, &addr);
}

static const ethernet_interface_t *
ip6_mld_get_eth_itf (u32 sw_if_index)
{
  const vnet_sw_interface_t *sw;

  /* lookup radv container  - ethernet interfaces only */
  sw = vnet_get_sup_sw_interface (vnet_get_main (), sw_if_index);
  if (sw->type == VNET_SW_INTERFACE_TYPE_HARDWARE)
    return (ethernet_get_interface (&ethernet_main, sw->hw_if_index));

  return (NULL);
}

/**
 * @brief create and initialize router advertisement parameters with default
 * values for this intfc
 */
static void
ip6_mld_link_enable (u32 sw_if_index)
{
  const ethernet_interface_t *eth;
  ip6_mld_t *imd;

  eth = ip6_mld_get_eth_itf (sw_if_index);

  if (NULL == eth)
    return;

  ASSERT (INDEX_INVALID == ip6_link_delegate_get (sw_if_index,
						  ip6_mld_delegate_id));

  pool_get_zero (ip6_mld_pool, imd);

  imd->sw_if_index = sw_if_index;

  mhash_init (&imd->address_to_mldp_index, sizeof (uword),
	      sizeof (ip6_address_t));

  /* add multicast groups we will always be reporting  */
  ip6_neighbor_add_mld_grp (imd,
			    IP6_MULTICAST_SCOPE_link_local,
			    IP6_MULTICAST_GROUP_ID_all_hosts);
  ip6_neighbor_add_mld_grp (imd,
			    IP6_MULTICAST_SCOPE_link_local,
			    IP6_MULTICAST_GROUP_ID_all_routers);
  ip6_neighbor_add_mld_grp (imd,
			    IP6_MULTICAST_SCOPE_link_local,
			    IP6_MULTICAST_GROUP_ID_mldv2_routers);

  ip6_link_delegate_update (sw_if_index, ip6_mld_delegate_id,
			    imd - ip6_mld_pool);
}

static void
ip6_mld_delegate_disable (index_t imdi)
{
  ip6_mldp_group_t *m;
  ip6_mld_t *imd;

  imd = pool_elt_at_index (ip6_mld_pool, imdi);

  /* clean MLD pools */
  pool_flush (m, imd->mldp_group_pool,
  ({
    mhash_unset (&imd->address_to_mldp_index, &m->mcast_address, 0);
  }));

  pool_free (imd->mldp_group_pool);

  mhash_free (&imd->address_to_mldp_index);

  pool_put (ip6_mld_pool, imd);
}

/* send an mldpv2 report  */
static void
ip6_neighbor_send_mldpv2_report (u32 sw_if_index)
{
  vnet_main_t *vnm = vnet_get_main ();
  vlib_main_t *vm = vnm->vlib_main;
  int bogus_length;

  ip6_mld_t *imd;
  u16 payload_length;
  vlib_buffer_t *b0;
  ip6_header_t *ip0;
  u32 *to_next;
  vlib_frame_t *f;
  u32 bo0;
  u32 n_to_alloc = 1;

  icmp6_multicast_listener_report_header_t *rh0;
  icmp6_multicast_listener_report_packet_t *rp0;

  if (!vnet_sw_interface_is_admin_up (vnm, sw_if_index))
    return;

  imd = ip6_mld_get_itf (sw_if_index);

  if (NULL == imd)
    return;

  /* send report now - build a mldpv2 report packet  */
  if (0 == vlib_buffer_alloc (vm, &bo0, n_to_alloc))
    {
    alloc_fail:
      clib_warning ("buffer allocation failure");
      return;
    }

  b0 = vlib_get_buffer (vm, bo0);

  /* adjust the sizeof the buffer to just include the ipv6 header */
  b0->current_length = sizeof (icmp6_multicast_listener_report_packet_t);

  payload_length = sizeof (icmp6_multicast_listener_report_header_t);

  b0->error = ICMP6_ERROR_NONE;

  rp0 = vlib_buffer_get_current (b0);
  ip0 = (ip6_header_t *) & rp0->ip;
  rh0 = (icmp6_multicast_listener_report_header_t *) & rp0->report_hdr;

  clib_memset (rp0, 0x0, sizeof (icmp6_multicast_listener_report_packet_t));

  ip0->ip_version_traffic_class_and_flow_label =
    clib_host_to_net_u32 (0x6 << 28);

  ip0->protocol = IP_PROTOCOL_IP6_HOP_BY_HOP_OPTIONS;
  /* for DEBUG - vnet driver won't seem to emit router alerts */
  /* ip0->protocol = IP_PROTOCOL_ICMP6; */
  ip0->hop_limit = 1;

  rh0->icmp.type = ICMP6_multicast_listener_report_v2;

  /* source address MUST be the link-local address */
  ip6_address_copy (&ip0->src_address,
		    ip6_get_link_local_address (sw_if_index));

  /* destination is all mldpv2 routers */
  ip6_set_reserved_multicast_address (&ip0->dst_address,
				      IP6_MULTICAST_SCOPE_link_local,
				      IP6_MULTICAST_GROUP_ID_mldv2_routers);

  /* add reports here */
  ip6_mldp_group_t *m;
  int num_addr_records = 0;
  icmp6_multicast_address_record_t rr;

  /* fill in the hop-by-hop extension header (router alert) info */
  rh0->ext_hdr.next_hdr = IP_PROTOCOL_ICMP6;
  rh0->ext_hdr.n_data_u64s = 0;

  rh0->alert.type = IP6_MLDP_ALERT_TYPE;
  rh0->alert.len = 2;
  rh0->alert.value = 0;

  rh0->pad.type = 1;
  rh0->pad.len = 0;

  rh0->icmp.checksum = 0;

  pool_foreach (m, imd->mldp_group_pool)
   {
    rr.type = m->type;
    rr.aux_data_len_u32s = 0;
    rr.num_sources = clib_host_to_net_u16 (m->num_sources);
    clib_memcpy(&rr.mcast_addr, &m->mcast_address, sizeof(ip6_address_t));

    num_addr_records++;

    if(vlib_buffer_add_data (vm, &bo0, (void *)&rr,
			     sizeof(icmp6_multicast_address_record_t)))
      {
        vlib_buffer_free (vm, &bo0, 1);
        goto alloc_fail;
      }

    payload_length += sizeof( icmp6_multicast_address_record_t);
  }

  rh0->rsvd = 0;
  rh0->num_addr_records = clib_host_to_net_u16 (num_addr_records);

  /* update lengths */
  ip0->payload_length = clib_host_to_net_u16 (payload_length);

  rh0->icmp.checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip0,
							  &bogus_length);
  ASSERT (bogus_length == 0);

  /*
   * OK to override w/ no regard for actual FIB, because
   * ip6-rewrite only looks at the adjacency.
   */
  vnet_buffer (b0)->sw_if_index[VLIB_RX] =
    vnet_main.local_interface_sw_if_index;

  vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
    ip6_link_get_mcast_adj (sw_if_index);
  b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;

  vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "ip6-rewrite-mcast");

  f = vlib_get_frame_to_node (vm, node->index);
  to_next = vlib_frame_vector_args (f);
  to_next[0] = bo0;
  f->n_vectors = 1;

  vlib_put_frame_to_node (vm, node->index, f);
  return;
}

/* send a RA or update the timer info etc.. */
static uword
ip6_mld_timer_event (vlib_main_t * vm,
		     vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  vnet_main_t *vnm = vnet_get_main ();
  ip6_mld_t *imd;

  /* Interface ip6 radv info list */
  pool_foreach (imd, ip6_mld_pool)
   {
    if (!vnet_sw_interface_is_admin_up (vnm, imd->sw_if_index))
      {
        imd->all_routers_mcast = 0;
        continue;
      }

    /* Make sure that we've joined the all-routers multicast group */
    if (!imd->all_routers_mcast)
      {
        /* send MDLP_REPORT_EVENT message */
        ip6_neighbor_send_mldpv2_report(imd->sw_if_index);
        imd->all_routers_mcast = 1;
      }
  }

  return 0;
}

static uword
ip6_mld_event_process (vlib_main_t * vm,
		       vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  uword event_type;

  /* init code here */

  while (1)
    {
      vlib_process_wait_for_event_or_clock (vm, 1. /* seconds */ );

      if (!vlib_process_get_event_data (vm, &event_type))
	{
	  /* No events found: timer expired. */
	  /* process interface list and send RAs as appropriate, update timer info */
	  ip6_mld_timer_event (vm, node, frame);
	}
      /* else; no events */
    }
  return frame->n_vectors;
}

VLIB_REGISTER_NODE (ip6_mld_event_process_node) = {
  .function = ip6_mld_event_process,
  .name = "ip6-mld-process",
  .type = VLIB_NODE_TYPE_PROCESS,
};

static u8 *
format_ip6_mld (u8 * s, va_list * args)
{
  index_t imi = va_arg (*args, index_t);
  u32 indent = va_arg (*args, u32);
  ip6_mldp_group_t *m;
  ip6_mld_t *imd;

  imd = pool_elt_at_index (ip6_mld_pool, imi);

  s = format (s, "%UJoined group address(es):\n", format_white_space, indent);

  pool_foreach (m, imd->mldp_group_pool)
   {
    s = format (s, "%U%U\n",
                format_white_space, indent+2,
                format_ip6_address,
                &m->mcast_address);
  }

  return (s);
}

/**
 * @brief callback when an interface address is added or deleted
 */
static void
ip6_mld_address_add (u32 imi,
		     const ip6_address_t * address, u8 address_oength)
{
  ip6_mld_t *imd;
  ip6_address_t a;

  imd = pool_elt_at_index (ip6_mld_pool, imi);

  /* create solicited node multicast address for this interface address */
  ip6_set_solicited_node_multicast_address (&a, 0);

  a.as_u8[0xd] = address->as_u8[0xd];
  a.as_u8[0xe] = address->as_u8[0xe];
  a.as_u8[0xf] = address->as_u8[0xf];

  ip6_neighbor_add_mld_prefix (imd, &a);
}

static void
ip6_mld_address_del (u32 imi,
		     const ip6_address_t * address, u8 address_oength)
{
  ip6_mld_t *imd;
  ip6_address_t a;

  imd = pool_elt_at_index (ip6_mld_pool, imi);

  /* create solicited node multicast address for this interface address */
  ip6_set_solicited_node_multicast_address (&a, 0);

  a.as_u8[0xd] = address->as_u8[0xd];
  a.as_u8[0xe] = address->as_u8[0xe];
  a.as_u8[0xf] = address->as_u8[0xf];

  ip6_neighbor_del_mld_prefix (imd, &a);
}

/**
 * VFT for registering as a delegate to an IP6 link
 */
const static ip6_link_delegate_vft_t ip6_mld_delegate_vft = {
  .ildv_disable = ip6_mld_delegate_disable,
  .ildv_enable = ip6_mld_link_enable,
  .ildv_format = format_ip6_mld,
  .ildv_addr_add = ip6_mld_address_add,
  .ildv_addr_del = ip6_mld_address_del,
};

static clib_error_t *
ip6_mld_init (vlib_main_t * vm)
{
  ip6_mld_delegate_id = ip6_link_delegate_register (&ip6_mld_delegate_vft);

  return (NULL);
}

VLIB_INIT_FUNCTION (ip6_mld_init) =
{
  .runs_after = VLIB_INITS("icmp6_init"),
};

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