/*
  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_int.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,
		    uint8_t *buf, int buf_size)
{
  struct prefix            msg_group_addr;
  struct prefix            msg_source_addr;
  struct pim_assert_metric msg_metric;
  int offset;
  uint8_t *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 = pim_read_uint32_host(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 = pim_read_uint32_host(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(uint8_t *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)
{
  uint8_t *buf_pastend = pim_msg + buf_size;
  uint8_t *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 */
  pim_write_uint32(pim_msg_curr, rpt_bit_flag ?
		   metric_preference | 0x80000000 :
		   metric_preference);
  pim_msg_curr += 4;

  /* Route metric */
  pim_write_uint32(pim_msg_curr, 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;
  uint8_t 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);
}

