/*
  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 "prefix.h"

#include "pimd.h"
#include "pim_str.h"
#include "pim_tlv.h"
#include "pim_msg.h"
#include "pim_pim.h"
#include "pim_time.h"
#include "pim_iface.h"
#include "pim_hello.h"
#include "pim_macro.h"
#include "pim_assert.h"
#include "pim_ifchannel.h"

static int assert_action_a3(struct pim_ifchannel *ch);
static void assert_action_a2(struct pim_ifchannel *ch,
			     struct pim_assert_metric winner_metric);
static void assert_action_a6(struct pim_ifchannel *ch,
			     struct pim_assert_metric winner_metric);

void pim_ifassert_winner_set(struct pim_ifchannel     *ch,
			     enum pim_ifassert_state   new_state,
			     struct in_addr            winner,
			     struct pim_assert_metric  winner_metric)
{
  int winner_changed = (ch->ifassert_winner.s_addr != winner.s_addr);
  int metric_changed = !pim_assert_metric_match(&ch->ifassert_winner_metric,
						&winner_metric);

  if (ch->ifassert_state != new_state) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    zlog_info("%s: (S,G)=(%s,%s) assert state changed from %s to %s on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str,
	      pim_ifchannel_ifassert_name(ch->ifassert_state),
	      pim_ifchannel_ifassert_name(new_state),
	      ch->interface->name);
  }

  {
    char src_str[100];
    char grp_str[100];
    char winner_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    pim_inet4_dump("<winner?>", winner, winner_str, sizeof(winner_str));
    zlog_info("%s: (S,G)=(%s,%s) assert winner now is %s on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str,
	      winner_str, ch->interface->name);
  }

  ch->ifassert_state         = new_state;
  ch->ifassert_winner        = winner;
  ch->ifassert_winner_metric = winner_metric;
  ch->ifassert_creation      = pim_time_monotonic_sec();

  if (winner_changed || metric_changed) {
    pim_upstream_update_join_desired(ch->upstream);
    pim_ifchannel_update_could_assert(ch);
    pim_ifchannel_update_assert_tracking_desired(ch);
  }
}

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 int preferred_assert(const struct pim_ifchannel *ch,
			    const struct pim_assert_metric *recv_metric)
{
  return pim_assert_metric_better(recv_metric,
				  &ch->ifassert_winner_metric);
}

static int acceptable_assert(const struct pim_assert_metric *my_metric,
			     const struct pim_assert_metric *recv_metric)
{
  return pim_assert_metric_better(recv_metric,
				  my_metric);
}

static int inferior_assert(const struct pim_assert_metric *my_metric,
			   const struct pim_assert_metric *recv_metric)
{
  return pim_assert_metric_better(my_metric,
				  recv_metric);
}

static int cancel_assert(const struct pim_assert_metric *recv_metric)
{
  return (recv_metric->metric_preference == PIM_ASSERT_METRIC_PREFERENCE_MAX)
    &&
    (recv_metric->route_metric == PIM_ASSERT_ROUTE_METRIC_MAX);
}

static void if_could_assert_do_a1(const char *caller,
				  struct pim_ifchannel *ch)
{
  if (PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
    if (assert_action_a1(ch)) {
      char src_str[100];
      char grp_str[100];
      pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
      zlog_warn("%s: %s: (S,G)=(%s,%s) assert_action_a1 failure on interface %s",
		__PRETTY_FUNCTION__, caller,
		src_str, grp_str, ch->interface->name);
      /* log warning only */
    }
  }
}

static int dispatch_assert(struct interface *ifp,
			   struct in_addr source_addr,
			   struct in_addr group_addr,
			   struct pim_assert_metric recv_metric)
{
  struct pim_ifchannel *ch;

  ch = pim_ifchannel_add(ifp, source_addr, group_addr);
  if (!ch) {
    char source_str[100];
    char group_str[100];
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    zlog_warn("%s: (S,G)=(%s,%s) failure creating channel on interface %s",
	      __PRETTY_FUNCTION__,
	      source_str, group_str, ifp->name);
    return -1;
  }

  switch (ch->ifassert_state) {
  case PIM_IFASSERT_NOINFO:
    if (recv_metric.rpt_bit_flag) {
      /* RPT bit set */
      if_could_assert_do_a1(__PRETTY_FUNCTION__, ch);
    }
    else {
      /* RPT bit clear */
      if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
	if_could_assert_do_a1(__PRETTY_FUNCTION__, ch);
      }
      else if (acceptable_assert(&ch->ifassert_my_metric, &recv_metric)) {
	if (PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags)) {
	  assert_action_a6(ch, recv_metric);
	}
      }
    }
    break;
  case PIM_IFASSERT_I_AM_WINNER:
    if (preferred_assert(ch, &recv_metric)) {
      assert_action_a2(ch, recv_metric);
    }
    else {
      if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
	zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER); /* a3 requirement */
	assert_action_a3(ch);
      }
    }
    break;
  case PIM_IFASSERT_I_AM_LOSER:
    if (recv_metric.ip_address.s_addr == ch->ifassert_winner.s_addr) {
      /* Assert from current winner */

      if (cancel_assert(&recv_metric)) {
	assert_action_a5(ch);
      }
      else {
	if (inferior_assert(&ch->ifassert_my_metric, &recv_metric)) {
	  assert_action_a5(ch);
	}
	else if (acceptable_assert(&ch->ifassert_my_metric, &recv_metric)) {
	  if (!recv_metric.rpt_bit_flag) {
	    assert_action_a2(ch, recv_metric);
	  }
	}
      }
    }
    else if (preferred_assert(ch, &recv_metric)) {
      assert_action_a2(ch, recv_metric);
    }
    break;
  default:
    {
      char source_str[100];
      char group_str[100];
      pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
      pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
      zlog_warn("%s: (S,G)=(%s,%s) invalid assert state %d on interface %s",
		__PRETTY_FUNCTION__,
		source_str, group_str, ch->ifassert_state, ifp->name);
    }
    return -2;
  }

  return 0;
}

int pim_assert_recv(struct interface *ifp,
		    struct pim_neighbor *neigh,
		    struct in_addr src_addr,
		    char *buf, int buf_size)
{
  struct prefix            msg_group_addr;
  struct prefix            msg_source_addr;
  struct pim_assert_metric msg_metric;
  int offset;
  char *curr;
  int curr_size;

  on_trace(__PRETTY_FUNCTION__, ifp, src_addr);

  curr      = buf;
  curr_size = buf_size;

  /*
    Parse assert group addr
   */
  offset = pim_parse_addr_group(ifp->name, src_addr,
				&msg_group_addr,
				curr, curr_size);
  if (offset < 1) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_warn("%s: pim_parse_addr_group() failure: from %s on %s",
	      __PRETTY_FUNCTION__,
	      src_str, ifp->name);
    return -1;
  }
  curr      += offset;
  curr_size -= offset;

  /*
    Parse assert source addr
  */
  offset = pim_parse_addr_ucast(ifp->name, src_addr,
				&msg_source_addr,
				curr, curr_size);
  if (offset < 1) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s",
	      __PRETTY_FUNCTION__,
	      src_str, ifp->name);
    return -2;
  }
  curr      += offset;
  curr_size -= offset;

  if (curr_size != 8) {
    char src_str[100];
    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str));
    zlog_warn("%s: preference/metric size is not 8: size=%d from %s on interface %s",
	      __PRETTY_FUNCTION__,
	      curr_size,
	      src_str, ifp->name);
    return -3;
  }

  /*
    Parse assert metric preference
  */

  msg_metric.metric_preference = ntohl(*(const uint32_t *) curr);

  msg_metric.rpt_bit_flag = msg_metric.metric_preference & 0x80000000; /* save highest bit */
  msg_metric.metric_preference &= ~0x80000000; /* clear highest bit */

  curr += 4;

  /*
    Parse assert route metric
  */

  msg_metric.route_metric = ntohl(*(const uint32_t *) curr);

  if (PIM_DEBUG_PIM_TRACE) {
    char neigh_str[100];
    char source_str[100];
    char group_str[100];
    pim_inet4_dump("<neigh?>", src_addr, neigh_str, sizeof(neigh_str));
    pim_inet4_dump("<src?>", msg_source_addr.u.prefix4, source_str, sizeof(source_str));
    pim_inet4_dump("<grp?>", msg_group_addr.u.prefix4, group_str, sizeof(group_str));
    zlog_debug("%s: from %s on %s: (S,G)=(%s,%s) pref=%u metric=%u rpt_bit=%u",
	       __PRETTY_FUNCTION__, neigh_str, ifp->name,
	       source_str, group_str,
	       msg_metric.metric_preference,
	       msg_metric.route_metric,
	       PIM_FORCE_BOOLEAN(msg_metric.rpt_bit_flag));
  }

  msg_metric.ip_address = src_addr;

  return dispatch_assert(ifp,
			 msg_source_addr.u.prefix4,
			 msg_group_addr.u.prefix4,
			 msg_metric);
}

/*
  RFC 4601: 4.6.3.  Assert Metrics

   Assert metrics are defined as:

   When comparing assert_metrics, the rpt_bit_flag, metric_preference,
   and route_metric field are compared in order, where the first lower
   value wins.  If all fields are equal, the primary IP address of the
   router that sourced the Assert message is used as a tie-breaker,
   with the highest IP address winning.
*/
int pim_assert_metric_better(const struct pim_assert_metric *m1,
			     const struct pim_assert_metric *m2)
{
  if (m1->rpt_bit_flag < m2->rpt_bit_flag)
    return 1;
  if (m1->rpt_bit_flag > m2->rpt_bit_flag)
    return 0;

  if (m1->metric_preference < m2->metric_preference)
    return 1;
  if (m1->metric_preference > m2->metric_preference)
    return 0;

  if (m1->route_metric < m2->route_metric)
    return 1;
  if (m1->route_metric > m2->route_metric)
    return 0;

  return ntohl(m1->ip_address.s_addr) > ntohl(m2->ip_address.s_addr);
}

int pim_assert_metric_match(const struct pim_assert_metric *m1,
			    const struct pim_assert_metric *m2)
{
  if (m1->rpt_bit_flag != m2->rpt_bit_flag)
    return 0;
  if (m1->metric_preference != m2->metric_preference)
    return 0;
  if (m1->route_metric != m2->route_metric)
    return 0;
  
  return m1->ip_address.s_addr == m2->ip_address.s_addr;
}

int pim_assert_build_msg(char *pim_msg, int buf_size,
			 struct interface *ifp,
			 struct in_addr group_addr,
			 struct in_addr source_addr,
			 uint32_t metric_preference,
			 uint32_t route_metric,
			 uint32_t rpt_bit_flag)
{
  char *buf_pastend = pim_msg + buf_size;
  char *pim_msg_curr;
  int pim_msg_size;
  int remain;

  pim_msg_curr = pim_msg + PIM_MSG_HEADER_LEN; /* skip room for pim header */

  /* Encode group */
  remain = buf_pastend - pim_msg_curr;
  pim_msg_curr = pim_msg_addr_encode_ipv4_group(pim_msg_curr,
						remain,
						group_addr);
  if (!pim_msg_curr) {
    char group_str[100];
    pim_inet4_dump("<grp?>", group_addr, group_str, sizeof(group_str));
    zlog_warn("%s: failure encoding group address %s: space left=%d",
	      __PRETTY_FUNCTION__, group_str, remain);
    return -1;
  }

  /* Encode source */
  remain = buf_pastend - pim_msg_curr;
  pim_msg_curr = pim_msg_addr_encode_ipv4_ucast(pim_msg_curr,
						remain,
						source_addr);
  if (!pim_msg_curr) {
    char source_str[100];
    pim_inet4_dump("<src?>", source_addr, source_str, sizeof(source_str));
    zlog_warn("%s: failure encoding source address %s: space left=%d",
	      __PRETTY_FUNCTION__, source_str, remain);
    return -2;
  }

  /* Metric preference */
  *((uint32_t *) pim_msg_curr) = htonl(rpt_bit_flag ?
				       metric_preference | 0x80000000 :
				       metric_preference);
  pim_msg_curr += 4;

  /* Route metric */
  *((uint32_t *) pim_msg_curr) = htonl(route_metric);
  pim_msg_curr += 4;

  /*
    Add PIM header
  */
  pim_msg_size = pim_msg_curr - pim_msg;
  pim_msg_build_header(pim_msg, pim_msg_size,
		       PIM_MSG_TYPE_ASSERT);

  return pim_msg_size;
}

static int pim_assert_do(struct pim_ifchannel *ch,
			 struct pim_assert_metric metric)
{
  struct interface *ifp;
  struct pim_interface *pim_ifp;
  char pim_msg[1000];
  int pim_msg_size;

  ifp = ch->interface;
  zassert(ifp);

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

  pim_msg_size = pim_assert_build_msg(pim_msg, sizeof(pim_msg), ifp,
				      ch->group_addr, ch->source_addr,
				      metric.metric_preference,
				      metric.route_metric,
				      metric.rpt_bit_flag);
  if (pim_msg_size < 1) {
    zlog_warn("%s: failure building PIM assert message: msg_size=%d",
	      __PRETTY_FUNCTION__, pim_msg_size);
    return -2;
  }

  /*
    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.
  */
  pim_hello_require(ifp);

  if (PIM_DEBUG_PIM_TRACE) {
    char source_str[100];
    char group_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, source_str, sizeof(source_str));
    pim_inet4_dump("<grp?>", ch->group_addr, group_str, sizeof(group_str));
    zlog_debug("%s: to %s: (S,G)=(%s,%s) pref=%u metric=%u rpt_bit=%u",
	       __PRETTY_FUNCTION__, 
	       ifp->name, source_str, group_str,
	       metric.metric_preference,
	       metric.route_metric,
	       PIM_FORCE_BOOLEAN(metric.rpt_bit_flag));
  }

  if (pim_msg_send(pim_ifp->pim_sock_fd,
		   qpim_all_pim_routers_addr,
		   pim_msg,
		   pim_msg_size,
		   ifp->name)) {
    zlog_warn("%s: could not send PIM message on interface %s",
	      __PRETTY_FUNCTION__, ifp->name);
    return -3;
  }

  return 0;
}

int pim_assert_send(struct pim_ifchannel *ch)
{
  return pim_assert_do(ch, ch->ifassert_my_metric);
}

/*
  RFC 4601: 4.6.4.  AssertCancel Messages

  An AssertCancel(S,G) is an infinite metric assert with the RPT bit
  set that names S as the source.
 */
static int pim_assert_cancel(struct pim_ifchannel *ch)
{
  struct pim_assert_metric metric;

  metric.rpt_bit_flag      = 0;
  metric.metric_preference = PIM_ASSERT_METRIC_PREFERENCE_MAX;
  metric.route_metric      = PIM_ASSERT_ROUTE_METRIC_MAX;
  metric.ip_address        = ch->source_addr;

  return pim_assert_do(ch, metric);
}

static int on_assert_timer(struct thread *t)
{
  struct pim_ifchannel *ch;
  struct interface *ifp;

  zassert(t);
  ch = THREAD_ARG(t);
  zassert(ch);

  ifp = ch->interface;
  zassert(ifp);

  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    zlog_debug("%s: (S,G)=(%s,%s) timer expired on interface %s",
	       __PRETTY_FUNCTION__,
	       src_str, grp_str, ifp->name);
  }

  ch->t_ifassert_timer = 0;

  switch (ch->ifassert_state) {
  case PIM_IFASSERT_I_AM_WINNER:
    zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER); /* a3 requirement */
    assert_action_a3(ch);
    break;
  case PIM_IFASSERT_I_AM_LOSER:
    assert_action_a5(ch);
    break;
  default:
    {
      char source_str[100];
      char group_str[100];
      pim_inet4_dump("<src?>", ch->source_addr, source_str, sizeof(source_str));
      pim_inet4_dump("<grp?>", ch->group_addr, group_str, sizeof(group_str));
      zlog_warn("%s: (S,G)=(%s,%s) invalid assert state %d on interface %s",
		__PRETTY_FUNCTION__,
		source_str, group_str, ch->ifassert_state, ifp->name);
    }
  }

  return 0;
}

static void assert_timer_off(struct pim_ifchannel *ch)
{
  struct interface *ifp;

  zassert(ch);
  ifp = ch->interface;
  zassert(ifp);

  if (PIM_DEBUG_PIM_TRACE) {
    if (ch->t_ifassert_timer) {
      char src_str[100];
      char grp_str[100];
      pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
      zlog_debug("%s: (S,G)=(%s,%s) cancelling timer on interface %s",
		 __PRETTY_FUNCTION__,
		 src_str, grp_str, ifp->name);
    }
  }
  THREAD_OFF(ch->t_ifassert_timer);
  zassert(!ch->t_ifassert_timer);
}

static void pim_assert_timer_set(struct pim_ifchannel *ch,
				 int interval)
{
  struct interface *ifp;

  zassert(ch);
  ifp = ch->interface;
  zassert(ifp);

  assert_timer_off(ch);

  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    zlog_debug("%s: (S,G)=(%s,%s) starting %u sec timer on interface %s",
	       __PRETTY_FUNCTION__,
	       src_str, grp_str, interval, ifp->name);
  }

  THREAD_TIMER_ON(master, ch->t_ifassert_timer,
		  on_assert_timer,
		  ch, interval);
}

static void pim_assert_timer_reset(struct pim_ifchannel *ch)
{
  pim_assert_timer_set(ch, PIM_ASSERT_TIME - PIM_ASSERT_OVERRIDE_INTERVAL);
}

/*
  RFC 4601: 4.6.1.  (S,G) Assert Message State Machine

  (S,G) Assert State machine Actions

  A1:  Send Assert(S,G).
  Set Assert Timer to (Assert_Time - Assert_Override_Interval).
  Store self as AssertWinner(S,G,I).
  Store spt_assert_metric(S,I) as AssertWinnerMetric(S,G,I).
*/
int assert_action_a1(struct pim_ifchannel *ch)
{
  struct interface *ifp = ch->interface;
  struct pim_interface *pim_ifp;

  zassert(ifp);

  pim_ifp = ifp->info;
  if (!pim_ifp) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    zlog_warn("%s: (S,G)=(%s,%s) multicast no enabled on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str, ifp->name);
    return -1; /* must return since pim_ifp is used below */
  }

  /* Switch to I_AM_WINNER before performing action_a3 below */
  pim_ifassert_winner_set(ch, PIM_IFASSERT_I_AM_WINNER,
			  pim_ifp->primary_address,
			  pim_macro_spt_assert_metric(&ch->upstream->rpf,
						      pim_ifp->primary_address));

  zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER); /* a3 requirement */
  if (assert_action_a3(ch)) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    zlog_warn("%s: (S,G)=(%s,%s) assert_action_a3 failure on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str, ifp->name);
    /* warning only */
  }

  zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER);

  return 0;
}

/*
  RFC 4601: 4.6.1.  (S,G) Assert Message State Machine

  (S,G) Assert State machine Actions

     A2:  Store new assert winner as AssertWinner(S,G,I) and assert
          winner metric as AssertWinnerMetric(S,G,I).
          Set Assert Timer to Assert_Time.
*/
static void assert_action_a2(struct pim_ifchannel *ch,
			     struct pim_assert_metric winner_metric)
{
  pim_ifassert_winner_set(ch, PIM_IFASSERT_I_AM_LOSER,
			  winner_metric.ip_address,
			  winner_metric);
  
  pim_assert_timer_set(ch, PIM_ASSERT_TIME);

  zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER);
}

/*
  RFC 4601: 4.6.1.  (S,G) Assert Message State Machine

  (S,G) Assert State machine Actions

  A3:  Send Assert(S,G).
  Set Assert Timer to (Assert_Time - Assert_Override_Interval).
*/
static int assert_action_a3(struct pim_ifchannel *ch)
{
  zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER);

  pim_assert_timer_reset(ch);

  if (pim_assert_send(ch)) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));

    zlog_warn("%s: (S,G)=(%s,%s) failure sending assert on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str, ch->interface->name);
    return -1;
  }

  zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_WINNER);

  return 0;
}

/*
  RFC 4601: 4.6.1.  (S,G) Assert Message State Machine

  (S,G) Assert State machine Actions

     A4:  Send AssertCancel(S,G).
          Delete assert info (AssertWinner(S,G,I) and
          AssertWinnerMetric(S,G,I) will then return their default
          values).
*/
void assert_action_a4(struct pim_ifchannel *ch)
{
  if (pim_assert_cancel(ch)) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", ch->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", ch->group_addr, grp_str, sizeof(grp_str));
    zlog_warn("%s: failure sending AssertCancel(%s,%s) on interface %s",
	      __PRETTY_FUNCTION__,
	      src_str, grp_str, ch->interface->name);
    /* log warning only */
  }

  assert_action_a5(ch);

  zassert(ch->ifassert_state == PIM_IFASSERT_NOINFO);
}

/*
  RFC 4601: 4.6.1.  (S,G) Assert Message State Machine

  (S,G) Assert State machine Actions

  A5: Delete assert info (AssertWinner(S,G,I) and
  AssertWinnerMetric(S,G,I) will then return their default values).
*/
void assert_action_a5(struct pim_ifchannel *ch)
{
  reset_ifassert_state(ch);
  zassert(ch->ifassert_state == PIM_IFASSERT_NOINFO);
}

/*
  RFC 4601: 4.6.1.  (S,G) Assert Message State Machine

  (S,G) Assert State machine Actions

     A6:  Store new assert winner as AssertWinner(S,G,I) and assert
          winner metric as AssertWinnerMetric(S,G,I).
          Set Assert Timer to Assert_Time.
          If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) == true)
          set SPTbit(S,G) to TRUE.
*/
static void assert_action_a6(struct pim_ifchannel *ch,
			     struct pim_assert_metric winner_metric)
{
  assert_action_a2(ch, winner_metric);

  /*
    If (I is RPF_interface(S)) AND (UpstreamJPState(S,G) == true) set
    SPTbit(S,G) to TRUE.
    
    Notice: For PIM SSM, SPTbit(S,G) is already always true.
  */

  zassert(ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER);
}

