/*
  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 "if.h"
#include "log.h"
#include "vty.h"
#include "memory.h"
#include "prefix.h"

#include "pimd.h"
#include "pim_iface.h"
#include "pim_igmp.h"
#include "pim_mroute.h"
#include "pim_oil.h"
#include "pim_str.h"
#include "pim_pim.h"
#include "pim_neighbor.h"
#include "pim_ifchannel.h"
#include "pim_rand.h"
#include "pim_sock.h"

static void pim_if_igmp_join_del_all(struct interface *ifp);

void pim_if_init()
{
  if_init();
}

static void *if_list_clean(struct pim_interface *pim_ifp)
{
  if (pim_ifp->igmp_join_list) {
    list_delete(pim_ifp->igmp_join_list);
  }

  if (pim_ifp->igmp_socket_list) {
    list_delete(pim_ifp->igmp_socket_list);
  }

  if (pim_ifp->pim_neighbor_list) {
    list_delete(pim_ifp->pim_neighbor_list);
  }

  if (pim_ifp->pim_ifchannel_list) {
    list_delete(pim_ifp->pim_ifchannel_list);
  }

  XFREE(MTYPE_PIM_INTERFACE, pim_ifp);

  return 0;
}

struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
{
  struct pim_interface *pim_ifp;

  zassert(ifp);
  zassert(!ifp->info);

  pim_ifp = XMALLOC(MTYPE_PIM_INTERFACE, sizeof(*pim_ifp));
  if (!pim_ifp) {
    zlog_err("PIM XMALLOC(%d) failure", sizeof(*pim_ifp));
    return 0;
  }

  pim_ifp->options                           = 0;
  pim_ifp->mroute_vif_index                  = -1;

  pim_ifp->igmp_default_robustness_variable  = IGMP_DEFAULT_ROBUSTNESS_VARIABLE;
  pim_ifp->igmp_default_query_interval       = IGMP_GENERAL_QUERY_INTERVAL;
  pim_ifp->igmp_query_max_response_time_dsec = IGMP_QUERY_MAX_RESPONSE_TIME_DSEC;

  /*
    RFC 3376: 8.3. Query Response Interval
    The number of seconds represented by the [Query Response Interval]
    must be less than the [Query Interval].
   */
  zassert(pim_ifp->igmp_query_max_response_time_dsec < pim_ifp->igmp_default_query_interval);

  if (pim)
    PIM_IF_DO_PIM(pim_ifp->options);
  if (igmp)
    PIM_IF_DO_IGMP(pim_ifp->options);

#if 0
  /* FIXME: Should join? */
  PIM_IF_DO_IGMP_LISTEN_ALLROUTERS(pim_ifp->options);
#endif

  pim_ifp->igmp_join_list = 0;
  pim_ifp->igmp_socket_list = 0;
  pim_ifp->pim_neighbor_list = 0;
  pim_ifp->pim_ifchannel_list = 0;

  /* list of struct igmp_sock */
  pim_ifp->igmp_socket_list = list_new();
  if (!pim_ifp->igmp_socket_list) {
    zlog_err("%s %s: failure: igmp_socket_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return if_list_clean(pim_ifp);
  }
  pim_ifp->igmp_socket_list->del = (void (*)(void *)) igmp_sock_free;

  /* list of struct pim_neighbor */
  pim_ifp->pim_neighbor_list = list_new();
  if (!pim_ifp->pim_neighbor_list) {
    zlog_err("%s %s: failure: pim_neighbor_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return if_list_clean(pim_ifp);
  }
  pim_ifp->pim_neighbor_list->del = (void (*)(void *)) pim_neighbor_free;

  /* list of struct pim_ifchannel */
  pim_ifp->pim_ifchannel_list = list_new();
  if (!pim_ifp->pim_ifchannel_list) {
    zlog_err("%s %s: failure: pim_ifchannel_list=list_new()",
	     __FILE__, __PRETTY_FUNCTION__);
    return if_list_clean(pim_ifp);
  }
  pim_ifp->pim_ifchannel_list->del = (void (*)(void *)) pim_ifchannel_free;

  ifp->info = pim_ifp;

  pim_sock_reset(ifp);

  zassert(PIM_IF_TEST_PIM(pim_ifp->options) || PIM_IF_TEST_IGMP(pim_ifp->options));

  if (PIM_MROUTE_IS_ENABLED) {
    pim_if_add_vif(ifp);
  }

  return pim_ifp;
}

void pim_if_delete(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

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

  if (pim_ifp->igmp_join_list) {
    pim_if_igmp_join_del_all(ifp);
  }
  zassert(!pim_ifp->igmp_join_list);

  zassert(pim_ifp->igmp_socket_list);
  zassert(!listcount(pim_ifp->igmp_socket_list));

  zassert(pim_ifp->pim_neighbor_list);
  zassert(!listcount(pim_ifp->pim_neighbor_list));

  zassert(pim_ifp->pim_ifchannel_list);
  zassert(!listcount(pim_ifp->pim_ifchannel_list));

  if (PIM_MROUTE_IS_ENABLED) {
    pim_if_del_vif(ifp);
  }

  list_delete(pim_ifp->igmp_socket_list);
  list_delete(pim_ifp->pim_neighbor_list);
  list_delete(pim_ifp->pim_ifchannel_list);

  XFREE(MTYPE_PIM_INTERFACE, pim_ifp);

  ifp->info = 0;
}

void pim_if_update_could_assert(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  struct listnode      *node;
  struct listnode      *next_node;
  struct pim_ifchannel *ch;

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

  for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
    pim_ifchannel_update_could_assert(ch);
  }
}

static void pim_if_update_my_assert_metric(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  struct listnode      *node;
  struct listnode      *next_node;
  struct pim_ifchannel *ch;

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

  for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
    pim_ifchannel_update_my_assert_metric(ch);
  }
}

static void pim_addr_change(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

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

  pim_if_dr_election(ifp); /* Done TODO T30 */
  pim_if_update_join_desired(pim_ifp); /* depends on DR */
  pim_if_update_could_assert(ifp); /* depends on DR */
  pim_if_update_my_assert_metric(ifp); /* depends on could_assert */
  pim_if_update_assert_tracking_desired(ifp); /* depends on DR, join_desired */

  /*
    RFC 4601: 4.3.1.  Sending Hello Messages

    1) Before an interface goes down or changes primary IP address, a
    Hello message with a zero HoldTime should be sent immediately
    (with the old IP address if the IP address changed).
    -- FIXME See CAVEAT C13

    2) After an interface has changed its IP address, it MUST send a
    Hello message with its new IP address.
    -- DONE below

    3) If an interface changes one of its secondary IP addresses, a
    Hello message with an updated Address_List option and a non-zero
    HoldTime should be sent immediately.
    -- FIXME See TODO T31
   */
  pim_ifp->pim_ifstat_hello_sent = 0; /* reset hello counter */
  if (pim_ifp->pim_sock_fd < 0)
    return;
  pim_hello_restart_now(ifp);         /* send hello and restart timer */
}

static void on_primary_address_change(struct interface *ifp,
				      const char *caller,
				      struct in_addr old_addr,
				      struct in_addr new_addr)
{
  struct pim_interface *pim_ifp;

  {
    char old_str[100];
    char new_str[100];
    pim_inet4_dump("<old?>", old_addr, old_str, sizeof(old_str));
    pim_inet4_dump("<new?>", new_addr, new_str, sizeof(new_str));
    zlog_info("%s: %s: primary address changed from %s to %s on interface %s",
	      __PRETTY_FUNCTION__, caller,
	      old_str, new_str, ifp->name);
  }

  pim_ifp = ifp->info;

  if (pim_ifp) {
    if (PIM_IF_TEST_PIM(pim_ifp->options)) {
      pim_addr_change(ifp);
    }
  }
}

static void detect_primary_address_change(struct interface *ifp,
					  const char *caller)
{
  struct pim_interface *pim_ifp;
  struct in_addr new_prim_addr;

  pim_ifp = ifp->info;
  if (!pim_ifp)
    return;

  new_prim_addr = pim_find_primary_addr(ifp);

  if (PIM_DEBUG_ZEBRA) {
    char new_prim_str[100];
    char old_prim_str[100];
    pim_inet4_dump("<new?>", new_prim_addr, new_prim_str, sizeof(new_prim_str));
    pim_inet4_dump("<old?>", pim_ifp->primary_address, old_prim_str, sizeof(old_prim_str));
    zlog_debug("%s: old primary addr %s, new primary addr %s on interface %s",
	       __PRETTY_FUNCTION__, 
	       old_prim_str, new_prim_str, ifp->name);
  }

  if (new_prim_addr.s_addr != pim_ifp->primary_address.s_addr) {
    struct in_addr old_addr = pim_ifp->primary_address;
    pim_ifp->primary_address = new_prim_addr;

    on_primary_address_change(ifp, caller, old_addr, new_prim_addr);
  }
}

void pim_if_addr_add(struct connected *ifc)
{
  struct pim_interface *pim_ifp;
  struct interface *ifp;
  struct in_addr ifaddr;

  zassert(ifc);

  ifp = ifc->ifp;
  zassert(ifp);
  pim_ifp = ifp->info;
  if (!pim_ifp)
    return;

  if (!if_is_operative(ifp))
    return;

  ifaddr = ifc->address->u.prefix4;

  detect_primary_address_change(ifp, __PRETTY_FUNCTION__);

  if (PIM_IF_TEST_IGMP(pim_ifp->options)) {
    struct igmp_sock *igmp;

    /* lookup IGMP socket */
    igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
				       ifaddr);
    if (!igmp) {
      /* if addr new, add IGMP socket */
      pim_igmp_sock_add(pim_ifp->igmp_socket_list, ifaddr, ifp);
    }
  } /* igmp */

  if (PIM_IF_TEST_PIM(pim_ifp->options)) {

    /* Interface has a valid primary address ? */
    if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {

      /* Interface has a valid socket ? */
      if (pim_ifp->pim_sock_fd < 0) {
	if (pim_sock_add(ifp)) {
	  zlog_warn("Failure creating PIM socket for interface %s",
		    ifp->name);
	}
      }

    }
  } /* pim */

  if (PIM_MROUTE_IS_ENABLED) {
    /*
      PIM or IGMP is enabled on interface, and there is at least one
      address assigned, then try to create a vif_index.
    */
    if (pim_ifp->mroute_vif_index < 0) {
      pim_if_add_vif(ifp);
    }
  }
}

static void pim_if_addr_del_igmp(struct connected *ifc)
{
  struct pim_interface *pim_ifp = ifc->ifp->info;
  struct igmp_sock *igmp;
  struct in_addr ifaddr;

  if (ifc->address->family != AF_INET) {
    /* non-IPv4 address */
    return;
  }

  if (!pim_ifp) {
    /* IGMP not enabled on interface */
    return;
  }

  ifaddr = ifc->address->u.prefix4;

  /* lookup IGMP socket */
  igmp = pim_igmp_sock_lookup_ifaddr(pim_ifp->igmp_socket_list,
				     ifaddr);
  if (igmp) {
    /* if addr found, del IGMP socket */
    igmp_sock_delete(igmp);
  }
}

static void pim_if_addr_del_pim(struct connected *ifc)
{
  struct pim_interface *pim_ifp = ifc->ifp->info;

  if (ifc->address->family != AF_INET) {
    /* non-IPv4 address */
    return;
  }

  if (!pim_ifp) {
    /* PIM not enabled on interface */
    return;
  }

  if (PIM_INADDR_ISNOT_ANY(pim_ifp->primary_address)) {
    /* Interface keeps a valid primary address */
    return;
  }

  if (pim_ifp->pim_sock_fd < 0) {
    /* Interface does not hold a valid socket any longer */
    return;
  }

  /*
    pim_sock_delete() closes the socket, stops read and timer threads,
    and kills all neighbors.
   */
  pim_sock_delete(ifc->ifp, "last address has been removed from interface");
}

void pim_if_addr_del(struct connected *ifc)
{
  struct interface *ifp;

  zassert(ifc);
  ifp = ifc->ifp;
  zassert(ifp);

  detect_primary_address_change(ifp, __PRETTY_FUNCTION__);

  pim_if_addr_del_igmp(ifc);
  pim_if_addr_del_pim(ifc);
}

void pim_if_addr_add_all(struct interface *ifp)
{
  struct connected *ifc;
  struct listnode *node;
  struct listnode *nextnode;

  /* PIM/IGMP enabled ? */
  if (!ifp->info)
    return;

  for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
    struct prefix *p = ifc->address;
    
    if (p->family != AF_INET)
      continue;

    pim_if_addr_add(ifc);
  }
}

void pim_if_addr_del_all(struct interface *ifp)
{
  struct connected *ifc;
  struct listnode *node;
  struct listnode *nextnode;

  /* PIM/IGMP enabled ? */
  if (!ifp->info)
    return;

  for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
    struct prefix *p = ifc->address;
    
    if (p->family != AF_INET)
      continue;

    pim_if_addr_del(ifc);
  }
}

void pim_if_addr_del_all_igmp(struct interface *ifp)
{
  struct connected *ifc;
  struct listnode *node;
  struct listnode *nextnode;

  /* PIM/IGMP enabled ? */
  if (!ifp->info)
    return;

  for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
    struct prefix *p = ifc->address;
    
    if (p->family != AF_INET)
      continue;

    pim_if_addr_del_igmp(ifc);
  }
}

void pim_if_addr_del_all_pim(struct interface *ifp)
{
  struct connected *ifc;
  struct listnode *node;
  struct listnode *nextnode;

  /* PIM/IGMP enabled ? */
  if (!ifp->info)
    return;

  for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
    struct prefix *p = ifc->address;
    
    if (p->family != AF_INET)
      continue;

    pim_if_addr_del_pim(ifc);
  }
}

static struct in_addr find_first_addr(struct interface *ifp)
{
  struct connected *ifc;
  struct listnode *node;
  struct in_addr addr;

  for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
    struct prefix *p = ifc->address;
    
    if (p->family != AF_INET)
      continue;

    if (PIM_INADDR_IS_ANY(p->u.prefix4)) {
      zlog_warn("%s: null IPv4 address connected to interface %s",
		__PRETTY_FUNCTION__, ifp->name);
      continue;
    }

    return p->u.prefix4;
  }

  addr.s_addr = PIM_NET_INADDR_ANY;

  return addr;
}

struct in_addr pim_find_primary_addr(struct interface *ifp)
{
  return find_first_addr(ifp);
}

/*
  pim_if_add_vif() uses ifindex as vif_index

  see also pim_if_find_vifindex_by_ifindex()
 */
int pim_if_add_vif(struct interface *ifp)
{
  struct pim_interface *pim_ifp = ifp->info;
  struct in_addr ifaddr;

  zassert(pim_ifp);

  if (pim_ifp->mroute_vif_index > 0) {
    zlog_warn("%s: vif_index=%d > 0 on interface %s ifindex=%d",
	      __PRETTY_FUNCTION__,
	      pim_ifp->mroute_vif_index, ifp->name, ifp->ifindex);
    return -1;
  }

  if (ifp->ifindex < 1) {
    zlog_warn("%s: ifindex=%d < 1 on interface %s",
	      __PRETTY_FUNCTION__,
	      ifp->ifindex, ifp->name);
    return -2;
  }

  if (ifp->ifindex >= MAXVIFS) {
    zlog_warn("%s: ifindex=%d >= MAXVIFS=%d on interface %s",
	      __PRETTY_FUNCTION__,
	      ifp->ifindex, MAXVIFS, ifp->name);
    return -3;
  }

  ifaddr = pim_ifp->primary_address;
  if (PIM_INADDR_IS_ANY(ifaddr)) {
    zlog_warn("%s: could not get address for interface %s ifindex=%d",
	      __PRETTY_FUNCTION__,
	      ifp->name, ifp->ifindex);
    return -4;
  }

  if (pim_mroute_add_vif(ifp->ifindex, ifaddr)) {
    /* pim_mroute_add_vif reported error */
    return -5;
  }

  pim_ifp->mroute_vif_index = ifp->ifindex;

  /*
    Update highest vif_index
   */
  if (pim_ifp->mroute_vif_index > qpim_mroute_oif_highest_vif_index) {
    qpim_mroute_oif_highest_vif_index = pim_ifp->mroute_vif_index;
  }

  return 0;
}

static int iflist_find_highest_vif_index()
{
  struct listnode      *ifnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  int                   highest_vif_index = -1;

  for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    if (pim_ifp->mroute_vif_index > highest_vif_index) {
      highest_vif_index = pim_ifp->mroute_vif_index;
    }
  }

  return highest_vif_index;
}

int pim_if_del_vif(struct interface *ifp)
{
  struct pim_interface *pim_ifp = ifp->info;
  int old_vif_index;

  if (pim_ifp->mroute_vif_index < 1) {
    zlog_warn("%s: vif_index=%d < 1 on interface %s ifindex=%d",
	      __PRETTY_FUNCTION__,
	      pim_ifp->mroute_vif_index, ifp->name, ifp->ifindex);
    return -1;
  }

  if (pim_mroute_del_vif(pim_ifp->mroute_vif_index)) {
    /* pim_mroute_del_vif reported error */
    return -2;
  }

  /*
    Update highest vif_index
   */

  /* save old vif_index in order to compare with highest below */
  old_vif_index = pim_ifp->mroute_vif_index;

  pim_ifp->mroute_vif_index = -1;

  if (old_vif_index == qpim_mroute_oif_highest_vif_index) {
    qpim_mroute_oif_highest_vif_index = iflist_find_highest_vif_index();
  }

  return 0;
}

void pim_if_add_vif_all()
{
  struct listnode  *ifnode;
  struct listnode  *ifnextnode;
  struct interface *ifp;

  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    if (!ifp->info)
      continue;

    pim_if_add_vif(ifp);
  }
}

void pim_if_del_vif_all()
{
  struct listnode  *ifnode;
  struct listnode  *ifnextnode;
  struct interface *ifp;

  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    if (!ifp->info)
      continue;

    pim_if_del_vif(ifp);
  }
}

struct interface *pim_if_find_by_vif_index(int vif_index)
{
  struct listnode  *ifnode;
  struct interface *ifp;

  for (ALL_LIST_ELEMENTS_RO(iflist, ifnode, ifp)) {
    if (ifp->info) {
      struct pim_interface *pim_ifp;
      pim_ifp = ifp->info;
      if (vif_index == pim_ifp->mroute_vif_index)
	return ifp;
    }
  }

  return 0;
}

/*
  pim_if_add_vif() uses ifindex as vif_index
 */
int pim_if_find_vifindex_by_ifindex(int ifindex)
{
  return ifindex;
}

int pim_if_lan_delay_enabled(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

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

  return pim_ifp->pim_number_of_nonlandelay_neighbors == 0;
}

uint16_t pim_if_effective_propagation_delay_msec(struct interface *ifp)
{
  if (pim_if_lan_delay_enabled(ifp)) {
    struct pim_interface *pim_ifp;
    pim_ifp = ifp->info;
    return pim_ifp->pim_neighbors_highest_propagation_delay_msec;
  }
  else {
    return PIM_DEFAULT_PROPAGATION_DELAY_MSEC;
  }
}

uint16_t pim_if_effective_override_interval_msec(struct interface *ifp)
{
  if (pim_if_lan_delay_enabled(ifp)) {
    struct pim_interface *pim_ifp;
    pim_ifp = ifp->info;
    return pim_ifp->pim_neighbors_highest_override_interval_msec;
  }
  else {
    return PIM_DEFAULT_OVERRIDE_INTERVAL_MSEC;
  }
}

int pim_if_t_override_msec(struct interface *ifp)
{
  int effective_override_interval_msec;
  int t_override_msec;

  effective_override_interval_msec =
    pim_if_effective_override_interval_msec(ifp);

  t_override_msec = pim_rand_next(0, effective_override_interval_msec);

  return t_override_msec;
}

uint16_t pim_if_jp_override_interval_msec(struct interface *ifp)
{
  return pim_if_effective_propagation_delay_msec(ifp) +
    pim_if_effective_override_interval_msec(ifp);
}

/*
  RFC 4601: 4.1.6.  State Summarization Macros

  The function NBR( I, A ) uses information gathered through PIM Hello
  messages to map the IP address A of a directly connected PIM
  neighbor router on interface I to the primary IP address of the same
  router (Section 4.3.4).  The primary IP address of a neighbor is the
  address that it uses as the source of its PIM Hello messages.
*/
struct pim_neighbor *pim_if_find_neighbor(struct interface *ifp,
					  struct in_addr addr)
{
  struct listnode *neighnode;
  struct pim_neighbor *neigh;
  struct pim_interface *pim_ifp;

  zassert(ifp);

  pim_ifp = ifp->info;
  if (!pim_ifp) {
    zlog_warn("%s: multicast not enabled on interface %s",
	      __PRETTY_FUNCTION__,
	      ifp->name);
    return 0;
  }

  for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, neighnode, neigh)) {

    /* primary address ? */
    if (neigh->source_addr.s_addr == addr.s_addr)
      return neigh;

    /* secondary address ? */
    if (pim_neighbor_find_secondary(neigh, addr))
	return neigh;
  }

  if (PIM_DEBUG_PIM_TRACE) {
    char addr_str[100];
    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
    zlog_debug("%s: neighbor not found for address %s on interface %s",
	       __PRETTY_FUNCTION__, 
	       addr_str, ifp->name);
  }

  return 0;
}

long pim_if_t_suppressed_msec(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  long t_suppressed_msec;

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

  /* join suppression disabled ? */
  if (PIM_IF_TEST_PIM_CAN_DISABLE_JOIN_SUPRESSION(pim_ifp->options))
    return 0;

  /* t_suppressed = t_periodic * rand(1.1, 1.4) */

  t_suppressed_msec = qpim_t_periodic * pim_rand_next(1100, 1400);

  return t_suppressed_msec;
}

static void igmp_join_free(struct igmp_join *ij)
{
  XFREE(MTYPE_PIM_IGMP_JOIN, ij);
}

static struct igmp_join *igmp_join_find(struct list *join_list,
					struct in_addr group_addr,
					struct in_addr source_addr)
{
  struct listnode *node;
  struct igmp_join *ij;

  zassert(join_list);

  for (ALL_LIST_ELEMENTS_RO(join_list, node, ij)) {
    if ((group_addr.s_addr == ij->group_addr.s_addr) &&
	(source_addr.s_addr == ij->source_addr.s_addr))
      return ij;
  }

  return 0;
}

static int igmp_join_sock(const char *ifname,
			  int ifindex,
			  struct in_addr group_addr,
			  struct in_addr source_addr)
{
  int join_fd;

  join_fd = pim_socket_raw(IPPROTO_IGMP);
  if (join_fd < 0) {
    return -1;
  }

  if (pim_socket_join_source(join_fd, ifindex, group_addr, source_addr, ifname)) {
    close(join_fd);
    return -2;
  }

  return join_fd;
}

static struct igmp_join *igmp_join_new(struct interface *ifp,
				       struct in_addr group_addr,
				       struct in_addr source_addr)
{
  struct pim_interface *pim_ifp;
  struct igmp_join *ij;
  int join_fd;

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

  join_fd = igmp_join_sock(ifp->name, ifp->ifindex, group_addr, source_addr);
  if (join_fd < 0) {
    char group_str[100];
    char source_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_warn("%s: igmp_join_sock() failure for IGMP group %s source %s on interface %s",
	      __PRETTY_FUNCTION__,
	      group_str, source_str, ifp->name);
    return 0;
  }

  ij = XMALLOC(MTYPE_PIM_IGMP_JOIN, sizeof(*ij));
  if (!ij) {
    char group_str[100];
    char source_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_err("%s: XMALLOC(%d) failure for IGMP group %s source %s on interface %s",
	     __PRETTY_FUNCTION__,
	     sizeof(*ij), group_str, source_str, ifp->name);
    close(join_fd);
    return 0;
  }

  ij->sock_fd     = join_fd;
  ij->group_addr  = group_addr;
  ij->source_addr = source_addr;

  listnode_add(pim_ifp->igmp_join_list, ij);

  return ij;
}

int pim_if_igmp_join_add(struct interface *ifp,
			 struct in_addr group_addr,
			 struct in_addr source_addr)
{
  struct pim_interface *pim_ifp;
  struct igmp_join *ij;

  pim_ifp = ifp->info;
  if (!pim_ifp) {
    zlog_warn("%s: multicast not enabled on interface %s",
	      __PRETTY_FUNCTION__, 
	      ifp->name);
    return -1;
  }

  if (!pim_ifp->igmp_join_list) {
    pim_ifp->igmp_join_list = list_new();
    if (!pim_ifp->igmp_join_list) {
      zlog_err("%s %s: failure: igmp_join_list=list_new()",
	       __FILE__, __PRETTY_FUNCTION__);
      return -2;
    }
    pim_ifp->igmp_join_list->del = (void (*)(void *)) igmp_join_free;
  }

  ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
  if (ij) {
    char group_str[100];
    char source_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_warn("%s: can't re-join existing IGMP group %s source %s on interface %s",
	      __PRETTY_FUNCTION__,
	      group_str, source_str, ifp->name);
    return -3;
  }

  ij = igmp_join_new(ifp, group_addr, source_addr);
  if (!ij) {
    char group_str[100];
    char source_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_warn("%s: igmp_join_new() failure for IGMP group %s source %s on interface %s",
	      __PRETTY_FUNCTION__,
	      group_str, source_str, ifp->name);
    return -4;
  }

  return 0;
}



int pim_if_igmp_join_del(struct interface *ifp,
			 struct in_addr group_addr,
			 struct in_addr source_addr)
{
  struct pim_interface *pim_ifp;
  struct igmp_join *ij;

  pim_ifp = ifp->info;
  if (!pim_ifp) {
    zlog_warn("%s: multicast not enabled on interface %s",
	      __PRETTY_FUNCTION__, 
	      ifp->name);
    return -1;
  }

  if (!pim_ifp->igmp_join_list) {
    zlog_warn("%s: no IGMP join on interface %s",
	      __PRETTY_FUNCTION__, 
	      ifp->name);
    return -2;
  }

  ij = igmp_join_find(pim_ifp->igmp_join_list, group_addr, source_addr);
  if (!ij) {
    char group_str[100];
    char source_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_warn("%s: could not find IGMP group %s source %s on interface %s",
	      __PRETTY_FUNCTION__,
	      group_str, source_str, ifp->name);
    return -3;
  }

  if (close(ij->sock_fd)) {
    int e = errno;
    char group_str[100];
    char source_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_warn("%s: failure closing sock_fd=%d for IGMP group %s source %s on interface %s: errno=%d: %s",
	      __PRETTY_FUNCTION__,
	      ij->sock_fd, group_str, source_str, ifp->name, e, safe_strerror(e));
    /* warning only */
  }
  listnode_delete(pim_ifp->igmp_join_list, ij);
  igmp_join_free(ij);
  if (listcount(pim_ifp->igmp_join_list) < 1) {
    list_delete(pim_ifp->igmp_join_list);
    pim_ifp->igmp_join_list = 0;
  }

  return 0;
}

static void pim_if_igmp_join_del_all(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  struct listnode *node;
  struct listnode *nextnode;
  struct igmp_join *ij;

  pim_ifp = ifp->info;
  if (!pim_ifp) {
    zlog_warn("%s: multicast not enabled on interface %s",
	      __PRETTY_FUNCTION__, 
	      ifp->name);
    return;
  }

  if (!pim_ifp->igmp_join_list)
    return;

  for (ALL_LIST_ELEMENTS(pim_ifp->igmp_join_list, node, nextnode, ij))
    pim_if_igmp_join_del(ifp, ij->group_addr, ij->source_addr);
}

/*
  RFC 4601

  Transitions from "I am Assert Loser" State

  Current Winner's GenID Changes or NLT Expires

  The Neighbor Liveness Timer associated with the current winner
  expires or we receive a Hello message from the current winner
  reporting a different GenID from the one it previously reported.
  This indicates that the current winner's interface or router has
  gone down (and may have come back up), and so we must assume it no
  longer knows it was the winner.
 */
void pim_if_assert_on_neighbor_down(struct interface *ifp,
				    struct in_addr neigh_addr)
{
  struct pim_interface *pim_ifp;
  struct listnode      *node;
  struct listnode      *next_node;
  struct pim_ifchannel *ch;

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

  for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
    /* Is (S,G,I) assert loser ? */
    if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
      continue;
    /* Dead neighbor was winner ? */
    if (ch->ifassert_winner.s_addr != neigh_addr.s_addr)
      continue;
    
    assert_action_a5(ch);
  }
}

void pim_if_update_join_desired(struct pim_interface *pim_ifp)
{
  struct listnode      *ch_node;
  struct pim_ifchannel *ch;

  /* clear off flag from interface's upstreams */
  for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
    PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(ch->upstream->flags);
  }

  /* scan per-interface (S,G,I) state on this I interface */
  for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list, ch_node, ch)) {
    struct pim_upstream *up = ch->upstream;

    if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(up->flags))
      continue;

    /* update join_desired for the global (S,G) state */
    pim_upstream_update_join_desired(up);
    PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED_UPDATED(up->flags);
  }
}

void pim_if_update_assert_tracking_desired(struct interface *ifp)
{
  struct pim_interface *pim_ifp;
  struct listnode      *node;
  struct listnode      *next_node;
  struct pim_ifchannel *ch;

  pim_ifp = ifp->info;
  if (!pim_ifp)
    return;

  for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, node, next_node, ch)) {
    pim_ifchannel_update_assert_tracking_desired(ch);
  }
}
