/*
  PIM for Quagga
  Copyright (C) 2008  Everton da Silva Marques

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING; if not, write to the
  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  MA 02110-1301 USA
  
  $QuaggaId: $Format:%an, %ai, %h$ $
*/

#include <zebra.h>

#include "log.h"

#include "pimd.h"
#include "pim_pim.h"
#include "pim_str.h"
#include "pim_tlv.h"
#include "pim_util.h"
#include "pim_hello.h"
#include "pim_iface.h"
#include "pim_neighbor.h"
#include "pim_upstream.h"

static void on_trace(const char *label,
		     struct interface *ifp, struct in_addr src)
{
  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    pim_inet4_dump("<src?>", src, src_str, sizeof(src_str));
    zlog_debug("%s: from %s on %s",
	       label, src_str, ifp->name);
  }
}

static void tlv_trace_bool(const char *label, const char *tlv_name,
			   const char *ifname, struct in_addr src_addr,
			   int isset, int value)
{
  if (isset) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_debug("%s: PIM hello option from %s on interface %s: %s=%d",
	       label, 
	       src_str, ifname,
	       tlv_name, value);
  }
}

static void tlv_trace_uint16(const char *label, const char *tlv_name,
			     const char *ifname, struct in_addr src_addr,
			     int isset, uint16_t value)
{
  if (isset) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_debug("%s: PIM hello option from %s on interface %s: %s=%u",
	       label, 
	       src_str, ifname,
	       tlv_name, value);
  }
}

static void tlv_trace_uint32(const char *label, const char *tlv_name,
			     const char *ifname, struct in_addr src_addr,
			     int isset, uint32_t value)
{
  if (isset) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_debug("%s: PIM hello option from %s on interface %s: %s=%u",
	       label, 
	       src_str, ifname,
	       tlv_name, value);
  }
}

static void tlv_trace_uint32_hex(const char *label, const char *tlv_name,
				 const char *ifname, struct in_addr src_addr,
				 int isset, uint32_t value)
{
  if (isset) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_debug("%s: PIM hello option from %s on interface %s: %s=%08x",
	       label, 
	       src_str, ifname,
	       tlv_name, value);
  }
}

#if 0
static void tlv_trace(const char *label, const char *tlv_name,
		      const char *ifname, struct in_addr src_addr,
		      int isset)
{
  if (isset) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_debug("%s: PIM hello option from %s on interface %s: %s",
	       label, 
	       src_str, ifname,
	       tlv_name);
  }
}
#endif

static void tlv_trace_list(const char *label, const char *tlv_name,
			   const char *ifname, struct in_addr src_addr,
			   int isset, struct list *addr_list)
{
  if (isset) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_debug("%s: PIM hello option from %s on interface %s: %s size=%d list=%x",
	       label, 
	       src_str, ifname,
	       tlv_name,
	       addr_list ? ((int) listcount(addr_list)) : -1,
	       (unsigned) addr_list);
  }
}

#define FREE_ADDR_LIST \
  if (hello_option_addr_list) { \
    list_delete(hello_option_addr_list); \
  }

#define FREE_ADDR_LIST_THEN_RETURN(code) \
{ \
  FREE_ADDR_LIST \
  return (code); \
}

int pim_hello_recv(struct interface *ifp,
		   struct in_addr src_addr,
		   char *tlv_buf, int tlv_buf_size)
{
  struct pim_interface *pim_ifp;
  struct pim_neighbor *neigh;
  char *tlv_curr;
  char *tlv_pastend;
  pim_hello_options hello_options = 0; /* bit array recording options found */
  uint16_t hello_option_holdtime = 0;
  uint16_t hello_option_propagation_delay = 0;
  uint16_t hello_option_override_interval = 0;
  uint32_t hello_option_dr_priority = 0;
  uint32_t hello_option_generation_id = 0;
  struct list *hello_option_addr_list = 0;

  on_trace(__PRETTY_FUNCTION__, ifp, src_addr);

  pim_ifp = ifp->info;
  zassert(pim_ifp);

  ++pim_ifp->pim_ifstat_hello_recv;

  /*
    Parse PIM hello TLVs
   */
  zassert(tlv_buf_size >= 0);
  tlv_curr = tlv_buf;
  tlv_pastend = tlv_buf + tlv_buf_size;

  while (tlv_curr < tlv_pastend) {
    uint16_t option_type; 
    uint16_t option_len;
    int remain = tlv_pastend - tlv_curr;

    if (remain < PIM_TLV_MIN_SIZE) {
      char src_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      zlog_warn("%s: short PIM hello TLV size=%d < min=%d from %s on interface %s",
		__PRETTY_FUNCTION__,
		remain, PIM_TLV_MIN_SIZE,
		src_str, ifp->name);
      FREE_ADDR_LIST_THEN_RETURN(-1);
    }

    option_type = PIM_TLV_GET_TYPE(tlv_curr);
    tlv_curr += PIM_TLV_TYPE_SIZE;
    option_len = PIM_TLV_GET_LENGTH(tlv_curr);
    tlv_curr += PIM_TLV_LENGTH_SIZE;

    if ((tlv_curr + option_len) > tlv_pastend) {
      char src_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      zlog_warn("%s: long PIM hello TLV type=%d length=%d > left=%d from %s on interface %s",
		__PRETTY_FUNCTION__,
		option_type, option_len, tlv_pastend - tlv_curr,
		src_str, ifp->name);
      FREE_ADDR_LIST_THEN_RETURN(-2);
    }

    if (PIM_DEBUG_PIM_TRACE) {
      char src_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      zlog_debug("%s: parse left_size=%d: PIM hello TLV type=%d length=%d from %s on %s",
		 __PRETTY_FUNCTION__,
		 remain,
		 option_type, option_len,
		 src_str, ifp->name);
    }

    switch (option_type) {
    case PIM_MSG_OPTION_TYPE_HOLDTIME:
      if (pim_tlv_parse_holdtime(ifp->name, src_addr,
				 &hello_options,
				 &hello_option_holdtime,
				 option_len,
				 tlv_curr)) {
	FREE_ADDR_LIST_THEN_RETURN(-3);
      }
      break;
    case PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY:
      if (pim_tlv_parse_lan_prune_delay(ifp->name, src_addr,
					&hello_options,
					&hello_option_propagation_delay,
					&hello_option_override_interval,
					option_len,
					tlv_curr)) {
	FREE_ADDR_LIST_THEN_RETURN(-4);
      }
      break;
    case PIM_MSG_OPTION_TYPE_DR_PRIORITY:
      if (pim_tlv_parse_dr_priority(ifp->name, src_addr,
				    &hello_options,
				    &hello_option_dr_priority,
				    option_len,
				    tlv_curr)) {
	FREE_ADDR_LIST_THEN_RETURN(-5);
      }
      break;
    case PIM_MSG_OPTION_TYPE_GENERATION_ID:
      if (pim_tlv_parse_generation_id(ifp->name, src_addr,
				      &hello_options,
				      &hello_option_generation_id,
				      option_len,
				      tlv_curr)) {
	FREE_ADDR_LIST_THEN_RETURN(-6);
      }
      break;
    case PIM_MSG_OPTION_TYPE_ADDRESS_LIST:
      if (pim_tlv_parse_addr_list(ifp->name, src_addr,
				  &hello_options,
				  &hello_option_addr_list,
				  option_len,
				  tlv_curr)) {
	return -7;
      }
      break;
    case PIM_MSG_OPTION_TYPE_DM_STATE_REFRESH:
      if (PIM_DEBUG_PIM_TRACE) {
	char src_str[100];
	pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
	zlog_debug("%s: ignoring PIM hello dense-mode state refresh TLV option type=%d length=%d from %s on interface %s",
		   __PRETTY_FUNCTION__,
		   option_type, option_len,
		   src_str, ifp->name);
      }
      break;
    default:
      {
	char src_str[100];
	pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
	zlog_warn("%s: ignoring unknown PIM hello TLV type=%d length=%d from %s on interface %s",
		  __PRETTY_FUNCTION__,
		  option_type, option_len,
		  src_str, ifp->name);
      }
    }

    tlv_curr += option_len;
  }

  /*
    Check received PIM hello options
  */

  if (PIM_DEBUG_PIM_TRACE) {
    tlv_trace_uint16(__PRETTY_FUNCTION__, "holdtime",
		     ifp->name, src_addr,
		     PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME),
		     hello_option_holdtime);
    tlv_trace_uint16(__PRETTY_FUNCTION__, "propagation_delay",
		     ifp->name, src_addr,
		     PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY),
		     hello_option_propagation_delay);
    tlv_trace_uint16(__PRETTY_FUNCTION__, "override_interval",
		     ifp->name, src_addr,
		     PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY),
		     hello_option_override_interval);
    tlv_trace_bool(__PRETTY_FUNCTION__, "can_disable_join_suppression",
		   ifp->name, src_addr,
		   PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_LAN_PRUNE_DELAY),
		   PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_CAN_DISABLE_JOIN_SUPPRESSION));
    tlv_trace_uint32(__PRETTY_FUNCTION__, "dr_priority",
		     ifp->name, src_addr,
		     PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_DR_PRIORITY),
		     hello_option_dr_priority);
    tlv_trace_uint32_hex(__PRETTY_FUNCTION__, "generation_id",
			 ifp->name, src_addr,
			 PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_GENERATION_ID),
			 hello_option_generation_id);
    tlv_trace_list(__PRETTY_FUNCTION__, "address_list",
		   ifp->name, src_addr,
		   PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_ADDRESS_LIST),
		   hello_option_addr_list);
  }

  if (!PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_HOLDTIME)) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_warn("%s: PIM hello missing holdtime from %s on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, ifp->name);
  }

  /*
    New neighbor?
  */

  neigh = pim_neighbor_find(ifp, src_addr);
  if (!neigh) {
    /* Add as new neighbor */
    
    neigh = pim_neighbor_add(ifp, src_addr,
			     hello_options,
			     hello_option_holdtime,
			     hello_option_propagation_delay,
			     hello_option_override_interval,
			     hello_option_dr_priority,
			     hello_option_generation_id,
			     hello_option_addr_list);
    if (!neigh) {
      char src_str[100];
      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
      zlog_warn("%s: failure creating PIM neighbor %s on interface %s",
		__PRETTY_FUNCTION__,
		src_str, ifp->name);
      FREE_ADDR_LIST_THEN_RETURN(-8);
    }

    /* actual addr list has been saved under neighbor */
    return 0;
  }

  /*
    Received generation ID ?
  */
  
  if (PIM_OPTION_IS_SET(hello_options, PIM_OPTION_MASK_GENERATION_ID)) {
    /* GenID mismatch ? */
    if (!PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_GENERATION_ID) ||
	(hello_option_generation_id != neigh->generation_id)) {

      /* GenID changed */

      pim_upstream_rpf_genid_changed(neigh->source_addr);

      /* GenID mismatch, then replace neighbor */
      
      if (PIM_DEBUG_PIM_TRACE) {
	char src_str[100];
	pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
	zlog_debug("%s: GenId mismatch new=%08x old=%08x: replacing neighbor %s on %s",
		   __PRETTY_FUNCTION__,
		   hello_option_generation_id,
		   neigh->generation_id,
		   src_str, ifp->name);
      }

      pim_upstream_rpf_genid_changed(neigh->source_addr);
      
      pim_neighbor_delete(ifp, neigh, "GenID mismatch");
      neigh = pim_neighbor_add(ifp, src_addr,
			       hello_options,
			       hello_option_holdtime,
			       hello_option_propagation_delay,
			       hello_option_override_interval,
			       hello_option_dr_priority,
			       hello_option_generation_id,
			       hello_option_addr_list);
      if (!neigh) {
	char src_str[100];
	pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
	zlog_warn("%s: failure re-creating PIM neighbor %s on interface %s",
		  __PRETTY_FUNCTION__,
		  src_str, ifp->name);
	FREE_ADDR_LIST_THEN_RETURN(-9);
      }
      /* actual addr list is saved under neighbor */
      return 0;

    } /* GenId mismatch: replace neighbor */
    
  } /* GenId received */

  /*
    Update existing neighbor
  */

  pim_neighbor_update(neigh,
		      hello_options,
		      hello_option_holdtime,
		      hello_option_dr_priority,
		      hello_option_addr_list);
  /* actual addr list is saved under neighbor */
  return 0;
}

int pim_hello_build_tlv(const char *ifname,
			char *tlv_buf, int tlv_buf_size,
			uint16_t holdtime,
			uint32_t dr_priority,
			uint32_t generation_id,
			uint16_t propagation_delay,
			uint16_t override_interval,
			int can_disable_join_suppression,
			struct list *ifconnected)
{
  char *curr = tlv_buf;
  char *pastend = tlv_buf + tlv_buf_size;
  char *tmp;

  /*
   * Append options
   */

  /* Holdtime */
  curr = pim_tlv_append_uint16(curr,
			       pastend,
			       PIM_MSG_OPTION_TYPE_HOLDTIME,
			       holdtime);
  if (!curr) {
    zlog_warn("%s: could not set PIM hello Holdtime option for interface %s",
	      __PRETTY_FUNCTION__, ifname);
    return -1;
  }

  /* LAN Prune Delay */
  tmp = pim_tlv_append_2uint16(curr,
			       pastend,
			       PIM_MSG_OPTION_TYPE_LAN_PRUNE_DELAY,
			       propagation_delay,
			       override_interval);
  if (!tmp) {
    zlog_warn("%s: could not set PIM LAN Prune Delay option for interface %s",
	      __PRETTY_FUNCTION__, ifname);
    return -1;
  }
  if (can_disable_join_suppression) {
    *((uint8_t*)(curr) + 4) |= 0x80; /* enable T bit */
  }
  curr = tmp;

  /* DR Priority */
  curr = pim_tlv_append_uint32(curr,
			       pastend,
			       PIM_MSG_OPTION_TYPE_DR_PRIORITY,
			       dr_priority);
  if (!curr) {
    zlog_warn("%s: could not set PIM hello DR Priority option for interface %s",
	      __PRETTY_FUNCTION__, ifname);
    return -2;
  }

  /* Generation ID */
  curr = pim_tlv_append_uint32(curr,
			       pastend,
			       PIM_MSG_OPTION_TYPE_GENERATION_ID,
			       generation_id);
  if (!curr) {
    zlog_warn("%s: could not set PIM hello Generation ID option for interface %s",
	      __PRETTY_FUNCTION__, ifname);
    return -3;
  }

  /* Secondary Address List */
  if (ifconnected) {
    curr = pim_tlv_append_addrlist_ucast(curr,
					 pastend,
					 ifconnected);
    if (!curr) {
      zlog_warn("%s: could not set PIM hello Secondary Address List option for interface %s",
		__PRETTY_FUNCTION__, ifname);
      return -4;
    }
  }

  return curr - tlv_buf;
}

/*
  RFC 4601: 4.3.1.  Sending Hello Messages

  Thus, if a router needs to send a Join/Prune or Assert message on an
  interface on which it has not yet sent a Hello message with the
  currently configured IP address, then it MUST immediately send the
  relevant Hello message without waiting for the Hello Timer to
  expire, followed by the Join/Prune or Assert message.
*/
void pim_hello_require(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);

  pim_ifp = ifp->info;

  zassert(pim_ifp);

  if (pim_ifp->pim_ifstat_hello_sent)
    return;

  pim_hello_restart_now(ifp); /* Send hello and restart timer */
}
