/*
 * OSPF version 2  Interface State Machine
 *   From RFC2328 [OSPF Version 2] 
 * Copyright (C) 1999, 2000 Toshiaki Takada
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra 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, or (at your option) any
 * later version.
 *
 * GNU Zebra 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 GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <zebra.h>

#include "thread.h"
#include "linklist.h"
#include "prefix.h"
#include "if.h"
#include "table.h"
#include "log.h"

#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_ism.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nsm.h"
#include "ospfd/ospf_network.h"
#include "ospfd/ospf_dump.h"
#include "ospfd/ospf_packet.h"
#include "ospfd/ospf_flood.h"
#include "ospfd/ospf_abr.h"
#include "ospfd/ospf_snmp.h"

/* elect DR and BDR. Refer to RFC2319 section 9.4 */
static struct ospf_neighbor *
ospf_dr_election_sub (struct list *routers)
{
  struct listnode *node;
  struct ospf_neighbor *nbr, *max = NULL;

  /* Choose highest router priority.
     In case of tie, choose highest Router ID. */
  for (ALL_LIST_ELEMENTS_RO (routers, node, nbr))
    {
      if (max == NULL)
	max = nbr;
      else
	{
	  if (max->priority < nbr->priority)
	    max = nbr;
	  else if (max->priority == nbr->priority)
	    if (IPV4_ADDR_CMP (&max->router_id, &nbr->router_id) < 0)
	      max = nbr;
	}
    }

  return max;
}

static struct ospf_neighbor *
ospf_elect_dr (struct ospf_interface *oi, struct list *el_list)
{
  struct list *dr_list;
  struct listnode *node;
  struct ospf_neighbor *nbr, *dr = NULL, *bdr = NULL;

  dr_list = list_new ();

  /* Add neighbors to the list. */
  for (ALL_LIST_ELEMENTS_RO (el_list, node, nbr))
    {
      /* neighbor declared to be DR. */
      if (NBR_IS_DR (nbr))
	listnode_add (dr_list, nbr);

      /* Preserve neighbor BDR. */
      if (IPV4_ADDR_SAME (&BDR (oi), &nbr->address.u.prefix4))
	bdr = nbr;
    }

  /* Elect Designated Router. */
  if (listcount (dr_list) > 0)
    dr = ospf_dr_election_sub (dr_list);
  else
    dr = bdr;

  /* Set DR to interface. */
  if (dr)
    DR (oi) = dr->address.u.prefix4;
  else
    DR (oi).s_addr = 0;

  list_delete (dr_list);

  return dr;
}

static struct ospf_neighbor *
ospf_elect_bdr (struct ospf_interface *oi, struct list *el_list)
{
  struct list *bdr_list, *no_dr_list;
  struct listnode *node;
  struct ospf_neighbor *nbr, *bdr = NULL;

  bdr_list = list_new ();
  no_dr_list = list_new ();

  /* Add neighbors to the list. */
  for (ALL_LIST_ELEMENTS_RO (el_list, node, nbr))
    {
      /* neighbor declared to be DR. */
      if (NBR_IS_DR (nbr))
	continue;

      /* neighbor declared to be BDR. */
      if (NBR_IS_BDR (nbr))
	listnode_add (bdr_list, nbr);

      listnode_add (no_dr_list, nbr);
    }

  /* Elect Backup Designated Router. */
  if (listcount (bdr_list) > 0)
    bdr = ospf_dr_election_sub (bdr_list);
  else
    bdr = ospf_dr_election_sub (no_dr_list);

  /* Set BDR to interface. */
  if (bdr)
    BDR (oi) = bdr->address.u.prefix4;
  else
    BDR (oi).s_addr = 0;

  list_delete (bdr_list);
  list_delete (no_dr_list);

  return bdr;
}

static int
ospf_ism_state (struct ospf_interface *oi)
{
  if (IPV4_ADDR_SAME (&DR (oi), &oi->address->u.prefix4))
    return ISM_DR;
  else if (IPV4_ADDR_SAME (&BDR (oi), &oi->address->u.prefix4))
    return ISM_Backup;
  else
    return ISM_DROther;
}

static void
ospf_dr_eligible_routers (struct route_table *nbrs, struct list *el_list)
{
  struct route_node *rn;
  struct ospf_neighbor *nbr;

  for (rn = route_top (nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info) != NULL)
      /* Ignore 0.0.0.0 node*/
      if (nbr->router_id.s_addr != 0)
	/* Is neighbor eligible? */
	if (nbr->priority > 0)
	  /* Is neighbor upper 2-Way? */
	  if (nbr->state >= NSM_TwoWay)
	    listnode_add (el_list, nbr);
}

/* Generate AdjOK? NSM event. */
static void
ospf_dr_change (struct ospf *ospf, struct route_table *nbrs)
{
  struct route_node *rn;
  struct ospf_neighbor *nbr;

  for (rn = route_top (nbrs); rn; rn = route_next (rn))
    if ((nbr = rn->info) != NULL)
      /* Ignore 0.0.0.0 node*/
      if (nbr->router_id.s_addr != 0)
	/* Is neighbor upper 2-Way? */
	if (nbr->state >= NSM_TwoWay)
	  /* Ignore myself. */
	  if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf->router_id))
	    OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_AdjOK);
}

static int
ospf_dr_election (struct ospf_interface *oi)
{
  struct in_addr old_dr, old_bdr;
  int old_state, new_state;
  struct list *el_list;

  /* backup current values. */
  old_dr = DR (oi);
  old_bdr = BDR (oi);
  old_state = oi->state;

  el_list = list_new ();

  /* List eligible routers. */
  ospf_dr_eligible_routers (oi->nbrs, el_list);

  /* First election of DR and BDR. */
  ospf_elect_bdr (oi, el_list);
  ospf_elect_dr (oi, el_list);

  new_state = ospf_ism_state (oi);

  zlog_debug ("DR-Election[1st]: Backup %s", inet_ntoa (BDR (oi)));
  zlog_debug ("DR-Election[1st]: DR     %s", inet_ntoa (DR (oi)));

  if (new_state != old_state &&
      !(new_state == ISM_DROther && old_state < ISM_DROther))
    {
      ospf_elect_bdr (oi, el_list);
      ospf_elect_dr (oi, el_list); 

      new_state = ospf_ism_state (oi);

      zlog_debug ("DR-Election[2nd]: Backup %s", inet_ntoa (BDR (oi)));
      zlog_debug ("DR-Election[2nd]: DR     %s", inet_ntoa (DR (oi)));
    }

  list_delete (el_list);

  /* if DR or BDR changes, cause AdjOK? neighbor event. */
  if (!IPV4_ADDR_SAME (&old_dr, &DR (oi)) ||
      !IPV4_ADDR_SAME (&old_bdr, &BDR (oi)))
    ospf_dr_change (oi->ospf, oi->nbrs);

  return new_state;
}


int
ospf_hello_timer (struct thread *thread)
{
  struct ospf_interface *oi;

  oi = THREAD_ARG (thread);
  oi->t_hello = NULL;

  if (IS_DEBUG_OSPF (ism, ISM_TIMERS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: Timer (Hello timer expire)",
	  IF_NAME (oi));

  /* Sending hello packet. */
  ospf_hello_send (oi);

  /* Hello timer set. */
  OSPF_HELLO_TIMER_ON (oi);
  
  return 0;
}

static int
ospf_wait_timer (struct thread *thread)
{
  struct ospf_interface *oi;

  oi = THREAD_ARG (thread);
  oi->t_wait = NULL;

  if (IS_DEBUG_OSPF (ism, ISM_TIMERS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: Timer (Wait timer expire)",
	  IF_NAME (oi));

  OSPF_ISM_EVENT_SCHEDULE (oi, ISM_WaitTimer);

  return 0;
}

/* Hook function called after ospf ISM event is occured. And vty's
   network command invoke this function after making interface
   structure. */
static void
ism_timer_set (struct ospf_interface *oi)
{
  switch (oi->state)
    {
    case ISM_Down:
      /* First entry point of ospf interface state machine. In this state
	 interface parameters must be set to initial values, and timers are
	 reset also. */
      OSPF_ISM_TIMER_OFF (oi->t_hello);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
      break;
    case ISM_Loopback:
      /* In this state, the interface may be looped back and will be
	 unavailable for regular data traffic. */
      OSPF_ISM_TIMER_OFF (oi->t_hello);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
      break;
    case ISM_Waiting:
      /* The router is trying to determine the identity of DRouter and
	 BDRouter. The router begin to receive and send Hello Packets. */
      /* send first hello immediately */
      OSPF_ISM_TIMER_MSEC_ON (oi->t_hello, ospf_hello_timer, 1);
      OSPF_ISM_TIMER_ON (oi->t_wait, ospf_wait_timer,
			 OSPF_IF_PARAM (oi, v_wait));
      OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
      break;
    case ISM_PointToPoint:
      /* The interface connects to a physical Point-to-point network or
	 virtual link. The router attempts to form an adjacency with
	 neighboring router. Hello packets are also sent. */
      /* send first hello immediately */
      OSPF_ISM_TIMER_MSEC_ON (oi->t_hello, ospf_hello_timer, 1);      
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    case ISM_DROther:
      /* The network type of the interface is broadcast or NBMA network,
	 and the router itself is neither Designated Router nor
	 Backup Designated Router. */
      OSPF_HELLO_TIMER_ON (oi);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    case ISM_Backup:
      /* The network type of the interface is broadcast os NBMA network,
	 and the router is Backup Designated Router. */
      OSPF_HELLO_TIMER_ON (oi);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    case ISM_DR:
      /* The network type of the interface is broadcast or NBMA network,
	 and the router is Designated Router. */
      OSPF_HELLO_TIMER_ON (oi);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    }
}

static int
ism_interface_up (struct ospf_interface *oi)
{
  int next_state = 0;

  /* if network type is point-to-point, Point-to-MultiPoint or virtual link,
     the state transitions to Point-to-Point. */
  if (oi->type == OSPF_IFTYPE_POINTOPOINT ||
      oi->type == OSPF_IFTYPE_POINTOMULTIPOINT ||
      oi->type == OSPF_IFTYPE_VIRTUALLINK)
    next_state = ISM_PointToPoint;
  /* Else if the router is not eligible to DR, the state transitions to
     DROther. */
  else if (PRIORITY (oi) == 0) /* router is eligible? */
    next_state = ISM_DROther;
  else
    /* Otherwise, the state transitions to Waiting. */
    next_state = ISM_Waiting;

  if (oi->type == OSPF_IFTYPE_NBMA)
    ospf_nbr_nbma_if_update (oi->ospf, oi);

  /*  ospf_ism_event (t); */
  return next_state;
}

static int
ism_loop_ind (struct ospf_interface *oi)
{
  int ret = 0;

  /* call ism_interface_down. */
  /* ret = ism_interface_down (oi); */

  return ret;
}

/* Interface down event handler. */
static int
ism_interface_down (struct ospf_interface *oi)
{
  ospf_if_cleanup (oi);
  return 0;
}


static int
ism_backup_seen (struct ospf_interface *oi)
{
  return ospf_dr_election (oi);
}

static int
ism_wait_timer (struct ospf_interface *oi)
{
  return ospf_dr_election (oi);
}

static int
ism_neighbor_change (struct ospf_interface *oi)
{
  return ospf_dr_election (oi);
}

static int
ism_ignore (struct ospf_interface *oi)
{
  if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: ism_ignore called", IF_NAME (oi));

  return 0;
}

/* Interface State Machine */
struct {
  int (*func) (struct ospf_interface *);
  int next_state;
} ISM [OSPF_ISM_STATE_MAX][OSPF_ISM_EVENT_MAX] =
{
  {
    /* DependUpon: dummy state. */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_DependUpon },    /* InterfaceUp    */
    { ism_ignore,          ISM_DependUpon },    /* WaitTimer      */
    { ism_ignore,          ISM_DependUpon },    /* BackupSeen     */
    { ism_ignore,          ISM_DependUpon },    /* NeighborChange */
    { ism_ignore,          ISM_DependUpon },    /* LoopInd        */
    { ism_ignore,          ISM_DependUpon },    /* UnloopInd      */
    { ism_ignore,          ISM_DependUpon },    /* InterfaceDown  */
  },
  {
    /* Down:*/
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_interface_up,    ISM_DependUpon },    /* InterfaceUp    */
    { ism_ignore,          ISM_Down },          /* WaitTimer      */
    { ism_ignore,          ISM_Down },          /* BackupSeen     */
    { ism_ignore,          ISM_Down },          /* NeighborChange */
    { ism_loop_ind,        ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_Down },          /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
  {
    /* Loopback: */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_Loopback },      /* InterfaceUp    */
    { ism_ignore,          ISM_Loopback },      /* WaitTimer      */
    { ism_ignore,          ISM_Loopback },      /* BackupSeen     */
    { ism_ignore,          ISM_Loopback },      /* NeighborChange */
    { ism_ignore,          ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_Down },          /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
  {
    /* Waiting: */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_Waiting },       /* InterfaceUp    */
    { ism_wait_timer,	   ISM_DependUpon },    /* WaitTimer      */
    { ism_backup_seen,     ISM_DependUpon },    /* BackupSeen     */
    { ism_ignore,          ISM_Waiting },       /* NeighborChange */
    { ism_loop_ind,	   ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_Waiting },       /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
  {
    /* Point-to-Point: */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_PointToPoint },  /* InterfaceUp    */
    { ism_ignore,          ISM_PointToPoint },  /* WaitTimer      */
    { ism_ignore,          ISM_PointToPoint },  /* BackupSeen     */
    { ism_ignore,          ISM_PointToPoint },  /* NeighborChange */
    { ism_loop_ind,	   ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_PointToPoint },  /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
  {
    /* DROther: */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_DROther },       /* InterfaceUp    */
    { ism_ignore,          ISM_DROther },       /* WaitTimer      */
    { ism_ignore,          ISM_DROther },       /* BackupSeen     */
    { ism_neighbor_change, ISM_DependUpon },    /* NeighborChange */
    { ism_loop_ind,        ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_DROther },       /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
  {
    /* Backup: */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_Backup },        /* InterfaceUp    */
    { ism_ignore,          ISM_Backup },        /* WaitTimer      */
    { ism_ignore,          ISM_Backup },        /* BackupSeen     */
    { ism_neighbor_change, ISM_DependUpon },    /* NeighborChange */
    { ism_loop_ind,        ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_Backup },        /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
  {
    /* DR: */
    { ism_ignore,          ISM_DependUpon },    /* NoEvent        */
    { ism_ignore,          ISM_DR },            /* InterfaceUp    */
    { ism_ignore,          ISM_DR },            /* WaitTimer      */
    { ism_ignore,          ISM_DR },            /* BackupSeen     */
    { ism_neighbor_change, ISM_DependUpon },    /* NeighborChange */
    { ism_loop_ind,        ISM_Loopback },      /* LoopInd        */
    { ism_ignore,          ISM_DR },            /* UnloopInd      */
    { ism_interface_down,  ISM_Down },          /* InterfaceDown  */
  },
};  

static const char *ospf_ism_event_str[] =
{
  "NoEvent",
  "InterfaceUp",
  "WaitTimer",
  "BackupSeen",
  "NeighborChange",
  "LoopInd",
  "UnLoopInd",
  "InterfaceDown",
};

static void
ism_change_state (struct ospf_interface *oi, int state)
{
  int old_state;
  struct ospf_lsa *lsa;

  /* Logging change of state. */
  if (IS_DEBUG_OSPF (ism, ISM_STATUS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: State change %s -> %s", IF_NAME (oi),
	  LOOKUP (ospf_ism_state_msg, oi->state),
	  LOOKUP (ospf_ism_state_msg, state));

  old_state = oi->state;
  oi->state = state;
  oi->state_change++;

#ifdef HAVE_SNMP
  /* Terminal state or regression */ 
  if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) ||
      (state == ISM_PointToPoint) || (state < old_state))
    {
      /* ospfVirtIfStateChange */
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
        ospfTrapVirtIfStateChange (oi);
      /* ospfIfStateChange */
      else
        ospfTrapIfStateChange (oi);
    }
#endif

  /* Set multicast memberships appropriately for new state. */
  ospf_if_set_multicast(oi);

  if (old_state == ISM_Down || state == ISM_Down)
    ospf_check_abr_status (oi->ospf);

  /* Originate router-LSA. */
  if (state == ISM_Down)
    {
      if (oi->area->act_ints > 0)
        oi->area->act_ints--;
    }
  else if (old_state == ISM_Down)
    oi->area->act_ints++;

  /* schedule router-LSA originate. */
  ospf_router_lsa_update_area (oi->area);

  /* Originate network-LSA. */
  if (old_state != ISM_DR && state == ISM_DR)
    ospf_network_lsa_update (oi);
  else if (old_state == ISM_DR && state != ISM_DR)
    {
      /* Free self originated network LSA. */
      lsa = oi->network_lsa_self;
      if (lsa)
        ospf_lsa_flush_area (lsa, oi->area);

      ospf_lsa_unlock (&oi->network_lsa_self);
      oi->network_lsa_self = NULL;
    }

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_ism_change (oi, old_state);
#endif /* HAVE_OPAQUE_LSA */

  /* Check area border status.  */
  ospf_check_abr_status (oi->ospf);
}

/* Execute ISM event process. */
int
ospf_ism_event (struct thread *thread)
{
  int event;
  int next_state;
  struct ospf_interface *oi;

  oi = THREAD_ARG (thread);
  event = THREAD_VAL (thread);

  /* Call function. */
  next_state = (*(ISM [oi->state][event].func))(oi);

  if (! next_state)
    next_state = ISM [oi->state][event].next_state;

  if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: %s (%s)", IF_NAME (oi),
	  LOOKUP (ospf_ism_state_msg, oi->state),
	  ospf_ism_event_str[event]);

  /* If state is changed. */
  if (next_state != oi->state)
    ism_change_state (oi, next_state);

  /* Make sure timer is set. */
  ism_timer_set (oi);

  return 0;
}

