/*
 * 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/fib/ip6_fib.h>
#include <vnet/ip/ip6_link.h>
#include <vnet/ip/ip6_ll_table.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.
 */

/* *INDENT-OFF*/
/* 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;
/* *INDENT-ON*/

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 */
  /* *INDENT-OFF* */
  pool_flush (m, imd->mldp_group_pool,
  ({
    mhash_unset (&imd->address_to_mldp_index, &m->mcast_address, 0);
  }));
  /* *INDENT-ON* */

  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;

  /* *INDENT-OFF* */
  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);
  }));
  /* *INDENT-ON* */

  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 */
  /* *INDENT-OFF* */
  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;
      }
  }));
  /* *INDENT-ON* */

  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;
}

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

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);

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

  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);
}

/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (ip6_mld_init) =
{
  .runs_after = VLIB_INITS("icmp6_init"),
};
/* *INDENT-ON* */

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