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

#include "log.h"
#include "zclient.h"
#include "memory.h"
#include "thread.h"
#include "linklist.h"

#include "pimd.h"
#include "pim_pim.h"
#include "pim_str.h"
#include "pim_time.h"
#include "pim_iface.h"
#include "pim_join.h"
#include "pim_zlookup.h"
#include "pim_upstream.h"
#include "pim_ifchannel.h"
#include "pim_neighbor.h"
#include "pim_rpf.h"
#include "pim_zebra.h"
#include "pim_oil.h"
#include "pim_macro.h"

static void join_timer_start(struct pim_upstream *up);
static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up);

void pim_upstream_free(struct pim_upstream *up)
{
  XFREE(MTYPE_PIM_UPSTREAM, up);
}

static void upstream_channel_oil_detach(struct pim_upstream *up)
{
  if (up->channel_oil) {
    pim_channel_oil_del(up->channel_oil);
    up->channel_oil = 0;
  }
}

void pim_upstream_delete(struct pim_upstream *up)
{
  THREAD_OFF(up->t_join_timer);

  upstream_channel_oil_detach(up);

  /*
    notice that listnode_delete() can't be moved
    into pim_upstream_free() because the later is
    called by list_delete_all_node()
  */
  listnode_delete(qpim_upstream_list, up);

  pim_upstream_free(up);
}

static void send_join(struct pim_upstream *up)
{
  zassert(up->join_state == PIM_UPSTREAM_JOINED);

  
  if (PIM_DEBUG_PIM_TRACE) {
    if (PIM_INADDR_IS_ANY(up->rpf.rpf_addr)) {
      char src_str[100];
      char grp_str[100];
      char rpf_str[100];
      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
      pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
      zlog_warn("%s: can't send join upstream: RPF'(%s,%s)=%s",
		__PRETTY_FUNCTION__,
		src_str, grp_str, rpf_str);
      /* warning only */
    }
  }
  
  /* send Join(S,G) to the current upstream neighbor */
  pim_joinprune_send(up->rpf.source_nexthop.interface,
  		     up->rpf.rpf_addr,
		     up->source_addr,
		     up->group_addr,
		     1 /* join */);
}

static int on_join_timer(struct thread *t)
{
  struct pim_upstream *up;

  zassert(t);
  up = THREAD_ARG(t);
  zassert(up);

  send_join(up);

  up->t_join_timer = 0;
  join_timer_start(up);

  return 0;
}

static void join_timer_start(struct pim_upstream *up)
{
  if (PIM_DEBUG_PIM_EVENTS) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
    zlog_debug("%s: starting %d sec timer for upstream (S,G)=(%s,%s)",
	       __PRETTY_FUNCTION__,
	       qpim_t_periodic,
	       src_str, grp_str);
  }

  zassert(!up->t_join_timer);

  THREAD_TIMER_ON(master, up->t_join_timer,
		  on_join_timer,
		  up, qpim_t_periodic);
}

void pim_upstream_join_timer_restart(struct pim_upstream *up)
{
  THREAD_OFF(up->t_join_timer);
  join_timer_start(up);
}

static void pim_upstream_join_timer_restart_msec(struct pim_upstream *up,
						 int interval_msec)
{
  if (PIM_DEBUG_PIM_EVENTS) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
    zlog_debug("%s: restarting %d msec timer for upstream (S,G)=(%s,%s)",
	       __PRETTY_FUNCTION__,
	       interval_msec,
	       src_str, grp_str);
  }

  THREAD_OFF(up->t_join_timer);
  THREAD_TIMER_MSEC_ON(master, up->t_join_timer,
		       on_join_timer,
		       up, interval_msec);
}

void pim_upstream_join_suppress(struct pim_upstream *up,
				struct in_addr rpf_addr,
				int holdtime)
{
  long t_joinsuppress_msec;
  long join_timer_remain_msec;

  t_joinsuppress_msec = MIN(pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface),
			    1000 * holdtime);

  join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);

  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    char grp_str[100];
    char rpf_str[100];
    pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
    pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str));
    zlog_debug("%s %s: detected Join(%s,%s) to RPF'(S,G)=%s: join_timer=%ld msec t_joinsuppress=%ld msec",
	       __FILE__, __PRETTY_FUNCTION__, 
	       src_str, grp_str,
	       rpf_str,
	       join_timer_remain_msec, t_joinsuppress_msec);
  }

  if (join_timer_remain_msec < t_joinsuppress_msec) {
    if (PIM_DEBUG_PIM_TRACE) {
      char src_str[100];
      char grp_str[100];
      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
      zlog_debug("%s %s: suppressing Join(S,G)=(%s,%s) for %ld msec",
		 __FILE__, __PRETTY_FUNCTION__, 
		 src_str, grp_str, t_joinsuppress_msec);
    }

    pim_upstream_join_timer_restart_msec(up, t_joinsuppress_msec);
  }
}

void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label,
						    struct pim_upstream *up,
						    struct in_addr rpf_addr)
{
  long join_timer_remain_msec;
  int t_override_msec;

  join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer);
  t_override_msec = pim_if_t_override_msec(up->rpf.source_nexthop.interface);

  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    char grp_str[100];
    char rpf_str[100];
    pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
    pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str));
    zlog_debug("%s: to RPF'(%s,%s)=%s: join_timer=%ld msec t_override=%d msec",
	       debug_label,
	       src_str, grp_str, rpf_str,
	       join_timer_remain_msec, t_override_msec);
  }
    
  if (join_timer_remain_msec > t_override_msec) {
    if (PIM_DEBUG_PIM_TRACE) {
      char src_str[100];
      char grp_str[100];
      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
      zlog_debug("%s: decreasing (S,G)=(%s,%s) join timer to t_override=%d msec",
		 debug_label,
		 src_str, grp_str,
		 t_override_msec);
    }

    pim_upstream_join_timer_restart_msec(up, t_override_msec);
  }
}

static void forward_on(struct pim_upstream *up)
{
  struct listnode      *ifnode;
  struct listnode      *ifnextnode;
  struct listnode      *chnode;
  struct listnode      *chnextnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  struct pim_ifchannel *ch;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    /* scan per-interface (S,G) state */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {

      if (ch->upstream != up)
	continue;

      if (pim_macro_chisin_oiflist(ch))
	pim_forward_start(ch);

    } /* scan iface channel list */
  } /* scan iflist */
}

static void forward_off(struct pim_upstream *up)
{
  struct listnode      *ifnode;
  struct listnode      *ifnextnode;
  struct listnode      *chnode;
  struct listnode      *chnextnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  struct pim_ifchannel *ch;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    /* scan per-interface (S,G) state */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {

      if (ch->upstream != up)
	continue;

      pim_forward_stop(ch);

    } /* scan iface channel list */
  } /* scan iflist */
}

static void pim_upstream_switch(struct pim_upstream *up,
				enum pim_upstream_state new_state)
{
  enum pim_upstream_state old_state = up->join_state;

  zassert(old_state != new_state);
  
  up->join_state       = new_state;
  up->state_transition = pim_time_monotonic_sec();

  if (PIM_DEBUG_PIM_EVENTS) {
    char src_str[100];
    char grp_str[100];
    pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
    pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
    zlog_debug("%s: PIM_UPSTREAM_%s: (S,G)=(%s,%s)",
	       __PRETTY_FUNCTION__,
	       ((new_state == PIM_UPSTREAM_JOINED) ? "JOINED" : "NOTJOINED"),
	       src_str, grp_str);
  }

  pim_upstream_update_assert_tracking_desired(up);

  if (new_state == PIM_UPSTREAM_JOINED) {
    forward_on(up);
    send_join(up);
    join_timer_start(up);
  }
  else {
    forward_off(up);
    pim_joinprune_send(up->rpf.source_nexthop.interface,
		       up->rpf.rpf_addr,
		       up->source_addr,
		       up->group_addr,
		       0 /* prune */);
    zassert(up->t_join_timer);
    THREAD_OFF(up->t_join_timer);
  }

}

static struct pim_upstream *pim_upstream_new(struct in_addr source_addr,
					     struct in_addr group_addr)
{
  struct pim_upstream *up;
  enum pim_rpf_result rpf_result;

  up = XMALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
  if (!up) {
    zlog_err("%s: PIM XMALLOC(%zu) failure",
	     __PRETTY_FUNCTION__, sizeof(*up));
    return 0;
  }
  
  up->source_addr                = source_addr;
  up->group_addr                 = group_addr;
  up->flags                      = 0;
  up->ref_count                  = 1;
  up->t_join_timer               = 0;
  up->join_state                 = 0;
  up->state_transition           = pim_time_monotonic_sec();
  up->channel_oil                = 0;

  up->rpf.source_nexthop.interface                = 0;
  up->rpf.source_nexthop.mrib_nexthop_addr.s_addr = PIM_NET_INADDR_ANY;
  up->rpf.source_nexthop.mrib_metric_preference   = qpim_infinite_assert_metric.metric_preference;
  up->rpf.source_nexthop.mrib_route_metric        = qpim_infinite_assert_metric.route_metric;
  up->rpf.rpf_addr.s_addr                         = PIM_NET_INADDR_ANY;

  rpf_result = pim_rpf_update(up, 0);
  if (rpf_result == PIM_RPF_FAILURE) {
    XFREE(MTYPE_PIM_UPSTREAM, up);
    return NULL;
  }

  listnode_add(qpim_upstream_list, up);

  return up;
}

struct pim_upstream *pim_upstream_find(struct in_addr source_addr,
				       struct in_addr group_addr)
{
  struct listnode     *up_node;
  struct pim_upstream *up;

  for (ALL_LIST_ELEMENTS_RO(qpim_upstream_list, up_node, up)) {
    if (
	(source_addr.s_addr == up->source_addr.s_addr) &&
	(group_addr.s_addr == up->group_addr.s_addr)
	) {
      return up;
    }
  }

  return 0;
}

struct pim_upstream *pim_upstream_add(struct in_addr source_addr,
				      struct in_addr group_addr)
{
  struct pim_upstream *up;

  up = pim_upstream_find(source_addr, group_addr);
  if (up) {
    ++up->ref_count;
  }
  else {
    up = pim_upstream_new(source_addr, group_addr);
  }

  return up;
}

void pim_upstream_del(struct pim_upstream *up)
{
  --up->ref_count;

  if (up->ref_count < 1) {
    pim_upstream_delete(up);
  }
}

/*
  Evaluate JoinDesired(S,G):

  JoinDesired(S,G) is true if there is a downstream (S,G) interface I
  in the set:

  inherited_olist(S,G) =
  joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G)

  JoinDesired(S,G) may be affected by changes in the following:

  pim_ifp->primary_address
  pim_ifp->pim_dr_addr
  ch->ifassert_winner_metric
  ch->ifassert_winner
  ch->local_ifmembership 
  ch->ifjoin_state
  ch->upstream->rpf.source_nexthop.mrib_metric_preference
  ch->upstream->rpf.source_nexthop.mrib_route_metric
  ch->upstream->rpf.source_nexthop.interface

  See also pim_upstream_update_join_desired() below.
 */
int pim_upstream_evaluate_join_desired(struct pim_upstream *up)
{
  struct listnode      *ifnode;
  struct listnode      *ifnextnode;
  struct listnode      *chnode;
  struct listnode      *chnextnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  struct pim_ifchannel *ch;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    /* scan per-interface (S,G) state */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
      if (ch->upstream != up)
	continue;

      if (pim_macro_ch_lost_assert(ch))
	continue; /* keep searching */

      if (pim_macro_chisin_joins_or_include(ch))
	return 1; /* true */
    } /* scan iface channel list */
  } /* scan iflist */

  return 0; /* false */
}

/*
  See also pim_upstream_evaluate_join_desired() above.
*/
void pim_upstream_update_join_desired(struct pim_upstream *up)
{
  int was_join_desired; /* boolean */
  int is_join_desired; /* boolean */

  was_join_desired = PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(up->flags);

  is_join_desired = pim_upstream_evaluate_join_desired(up);
  if (is_join_desired)
    PIM_UPSTREAM_FLAG_SET_DR_JOIN_DESIRED(up->flags);
  else
    PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED(up->flags);

  /* switched from false to true */
  if (is_join_desired && !was_join_desired) {
    zassert(up->join_state == PIM_UPSTREAM_NOTJOINED);
    pim_upstream_switch(up, PIM_UPSTREAM_JOINED);
    return;
  }
      
  /* switched from true to false */
  if (!is_join_desired && was_join_desired) {
    zassert(up->join_state == PIM_UPSTREAM_JOINED);
    pim_upstream_switch(up, PIM_UPSTREAM_NOTJOINED);
    return;
  }
}

/*
  RFC 4601 4.5.7. Sending (S,G) Join/Prune Messages
  Transitions from Joined State
  RPF'(S,G) GenID changes

  The upstream (S,G) state machine remains in Joined state.  If the
  Join Timer is set to expire in more than t_override seconds, reset
  it so that it expires after t_override seconds.
*/
void pim_upstream_rpf_genid_changed(struct in_addr neigh_addr)
{
  struct listnode     *up_node;
  struct listnode     *up_nextnode;
  struct pim_upstream *up;

  /*
    Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
  */
  for (ALL_LIST_ELEMENTS(qpim_upstream_list, up_node, up_nextnode, up)) {

    if (PIM_DEBUG_PIM_TRACE) {
      char neigh_str[100];
      char src_str[100];
      char grp_str[100];
      char rpf_addr_str[100];
      pim_inet4_dump("<neigh?>", neigh_addr, neigh_str, sizeof(neigh_str));
      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
      pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_addr_str, sizeof(rpf_addr_str));
      zlog_debug("%s: matching neigh=%s against upstream (S,G)=(%s,%s) joined=%d rpf_addr=%s",
		 __PRETTY_FUNCTION__,
		 neigh_str, src_str, grp_str,
		 up->join_state == PIM_UPSTREAM_JOINED,
		 rpf_addr_str);
    }

    /* consider only (S,G) upstream in Joined state */
    if (up->join_state != PIM_UPSTREAM_JOINED)
      continue;

    /* match RPF'(S,G)=neigh_addr */
    if (up->rpf.rpf_addr.s_addr != neigh_addr.s_addr)
      continue;

    pim_upstream_join_timer_decrease_to_t_override("RPF'(S,G) GenID change",
						   up, neigh_addr);
  }
}


void pim_upstream_rpf_interface_changed(struct pim_upstream *up,
					struct interface *old_rpf_ifp)
{
  struct listnode  *ifnode;
  struct listnode  *ifnextnode;
  struct interface *ifp;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    struct listnode      *chnode;
    struct listnode      *chnextnode;
    struct pim_ifchannel *ch;
    struct pim_interface *pim_ifp;

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

    /* search all ifchannels */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {
      if (ch->upstream != up)
	continue;

      if (ch->ifassert_state == PIM_IFASSERT_I_AM_LOSER) {
	if (
	    /* RPF_interface(S) was NOT I */
	    (old_rpf_ifp == ch->interface)
	    &&
	    /* RPF_interface(S) stopped being I */
	    (ch->upstream->rpf.source_nexthop.interface != ch->interface)
	    ) {
	  assert_action_a5(ch);
	}
      } /* PIM_IFASSERT_I_AM_LOSER */

      pim_ifchannel_update_assert_tracking_desired(ch);
    }
  }
}

void pim_upstream_update_could_assert(struct pim_upstream *up)
{
  struct listnode      *ifnode;
  struct listnode      *ifnextnode;
  struct listnode      *chnode;
  struct listnode      *chnextnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  struct pim_ifchannel *ch;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    /* scan per-interface (S,G) state */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {

      if (ch->upstream != up)
	continue;

      pim_ifchannel_update_could_assert(ch);

    } /* scan iface channel list */
  } /* scan iflist */
}

void pim_upstream_update_my_assert_metric(struct pim_upstream *up)
{
  struct listnode      *ifnode;
  struct listnode      *ifnextnode;
  struct listnode      *chnode;
  struct listnode      *chnextnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  struct pim_ifchannel *ch;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    /* scan per-interface (S,G) state */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {

      if (ch->upstream != up)
	continue;

      pim_ifchannel_update_my_assert_metric(ch);

    } /* scan iface channel list */
  } /* scan iflist */
}

static void pim_upstream_update_assert_tracking_desired(struct pim_upstream *up)
{
  struct listnode      *ifnode;
  struct listnode      *ifnextnode;
  struct listnode      *chnode;
  struct listnode      *chnextnode;
  struct interface     *ifp;
  struct pim_interface *pim_ifp;
  struct pim_ifchannel *ch;

  /* scan all interfaces */
  for (ALL_LIST_ELEMENTS(iflist, ifnode, ifnextnode, ifp)) {
    pim_ifp = ifp->info;
    if (!pim_ifp)
      continue;

    /* scan per-interface (S,G) state */
    for (ALL_LIST_ELEMENTS(pim_ifp->pim_ifchannel_list, chnode, chnextnode, ch)) {

      if (ch->upstream != up)
	continue;

      pim_ifchannel_update_assert_tracking_desired(ch);

    } /* scan iface channel list */
  } /* scan iflist */
}
