/*
 * Copyright (C) 1999 Yasuhiro Ohara
 *
 * 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.  
 */

/* Interface State Machine */

#include "ospf6d.h"

int
ifs_change (state_t ifs_next, char *reason, struct ospf6_interface *o6i)
{
  state_t ifs_prev;

  ifs_prev = o6i->state;

  if (ifs_prev == ifs_next)
    return 0;

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: %s -> %s (%s)",
               o6i->interface->name,
               ospf6_interface_state_string[ifs_prev],
               ospf6_interface_state_string[ifs_next], reason);

  if ((ifs_prev == IFS_DR || ifs_prev == IFS_BDR) &&
      (ifs_next != IFS_DR && ifs_next != IFS_BDR))
    ospf6_leave_alldrouters (o6i->interface->ifindex);
  else if ((ifs_prev != IFS_DR && ifs_prev != IFS_BDR) &&
           (ifs_next == IFS_DR || ifs_next == IFS_BDR))
    ospf6_join_alldrouters (o6i->interface->ifindex);

  o6i->state = ifs_next;

  if (o6i->prevdr != o6i->dr || o6i->prevbdr != o6i->bdr)
    {
      if (IS_OSPF6_DUMP_INTERFACE)
        {
          char dr[16], bdr[16], prevdr[16], prevbdr[16];
          inet_ntop (AF_INET, &o6i->prevdr, prevdr, sizeof (prevdr));
          inet_ntop (AF_INET, &o6i->prevbdr, prevbdr, sizeof (prevbdr));
          inet_ntop (AF_INET, &o6i->dr, dr, sizeof (dr));
          inet_ntop (AF_INET, &o6i->bdr, bdr, sizeof (bdr));
          zlog_info ("I/F: %s: DR: %s -> %s", o6i->interface->name,
                     prevdr, dr);
          zlog_info ("I/F: %s: BDR: %s -> %s", o6i->interface->name,
                     prevbdr, bdr);
        }
    }

  CALL_CHANGE_HOOK (&interface_hook, o6i);
  return 0;
}


/* Interface State Machine */
int
interface_up (struct thread *thread)
{
  struct ospf6_interface *ospf6_interface;

  ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);

  assert (ospf6_interface);
  assert (ospf6_interface->interface);

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: InterfaceUp",
               ospf6_interface->interface->name);

  /* check physical interface is up */
  if (!if_is_up (ospf6_interface->interface))
    {
      if (IS_OSPF6_DUMP_INTERFACE)
        zlog_warn ("  interface %s down, can't execute InterfaceUp",
                   ospf6_interface->interface->name);
      return -1;
    }

  /* if already enabled, do nothing */
  if (ospf6_interface->state > IFS_DOWN)
    {
      zlog_warn ("Interface %s already up",
                 ospf6_interface->interface->name);
      return 0;
    }

  /* ifid of this interface */
  ospf6_interface->if_id = ospf6_interface->interface->ifindex;

  /* Join AllSPFRouters */
  ospf6_join_allspfrouters (ospf6_interface->interface->ifindex);

  /* set socket options */
  ospf6_set_reuseaddr ();
  ospf6_reset_mcastloop ();
  ospf6_set_pktinfo ();
  ospf6_set_checksum ();

  /* Schedule Hello */
  if (! CHECK_FLAG (ospf6_interface->flag, OSPF6_INTERFACE_FLAG_PASSIVE))
    thread_add_event (master, ospf6_send_hello, ospf6_interface, 0);

  /* decide next interface state */
  if (if_is_pointopoint (ospf6_interface->interface))
    ifs_change (IFS_PTOP, "IF Type PointToPoint", ospf6_interface);
  else if (ospf6_interface->priority == 0)
    ifs_change (IFS_DROTHER, "Router Priority = 0", ospf6_interface);
  else
    {
      ifs_change (IFS_WAITING, "Priority > 0", ospf6_interface);
      thread_add_timer (master, wait_timer, ospf6_interface,
                        ospf6_interface->dead_interval);
    }

  CALL_FOREACH_LSA_HOOK (hook_interface, hook_change, ospf6_interface);

  return 0;
}

int
wait_timer (struct thread *thread)
{
  struct ospf6_interface *ospf6_interface;

  ospf6_interface = (struct ospf6_interface *)THREAD_ARG  (thread);
  assert (ospf6_interface);

  if (ospf6_interface->state != IFS_WAITING)
    return 0;

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: WaitTimer", ospf6_interface->interface->name);

  ifs_change (dr_election (ospf6_interface),
              "WaitTimer:DR Election", ospf6_interface);
  return 0;
}

int backup_seen (struct thread *thread)
{
  struct ospf6_interface *ospf6_interface;

  ospf6_interface = (struct ospf6_interface *)THREAD_ARG  (thread);
  assert (ospf6_interface);

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: BackupSeen", ospf6_interface->interface->name);

  if (ospf6_interface->state == IFS_WAITING)
    ifs_change (dr_election (ospf6_interface),
                "BackupSeen:DR Election", ospf6_interface);

  return 0;
}

int neighbor_change (struct thread *thread)
{
  struct ospf6_interface *ospf6_interface;

  ospf6_interface = (struct ospf6_interface *)THREAD_ARG  (thread);
  assert (ospf6_interface);

  if (ospf6_interface->state != IFS_DROTHER &&
      ospf6_interface->state != IFS_BDR &&
      ospf6_interface->state != IFS_DR)
    return 0;

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: NeighborChange", ospf6_interface->interface->name);

  ifs_change (dr_election (ospf6_interface),
              "NeighborChange:DR Election", ospf6_interface);

  return 0;
}

int
loopind (struct thread *thread)
{
  struct ospf6_interface *ospf6_interface;

  ospf6_interface = (struct ospf6_interface *)THREAD_ARG (thread);
  assert (ospf6_interface);

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: LoopInd", ospf6_interface->interface->name);

  /* XXX not yet */

  return 0;
}

int
interface_down (struct thread *thread)
{
  struct ospf6_interface *ospf6_interface;

  ospf6_interface = (struct ospf6_interface *) THREAD_ARG (thread);
  assert (ospf6_interface);

  if (IS_OSPF6_DUMP_INTERFACE)
    zlog_info ("I/F: %s: InterfaceDown", ospf6_interface->interface->name);

  if (ospf6_interface->state == IFS_NONE)
    return 1;

  /* Leave AllSPFRouters */
  if (ospf6_interface_is_enabled (ospf6_interface->interface->ifindex))
    ospf6_leave_allspfrouters (ospf6_interface->interface->ifindex);

  ifs_change (IFS_DOWN, "Configured", ospf6_interface);

  return 0;
}


/* 9.4 of RFC2328 */
int
dr_election (struct ospf6_interface *ospf6_interface)
{
  list candidate_list = list_new ();
  listnode i, j, n;
  ifid_t prevdr, prevbdr, dr = 0, bdr;
  struct ospf6_neighbor *nbpi, *nbpj, myself, *nbr;
  int declare = 0;
  int gofive = 0;

  /* statistics */
  ospf6_interface->ospf6_stat_dr_election++;

  /* pseudo neighbor "myself" */
  memset (&myself, 0, sizeof (myself));
  myself.state = NBS_TWOWAY;
  myself.dr = ospf6_interface->dr;
  myself.bdr = ospf6_interface->bdr;
  myself.priority = ospf6_interface->priority;
  myself.ifid = ospf6_interface->if_id;
  myself.router_id = ospf6_interface->area->ospf6->router_id;

/* step_one: */

  ospf6_interface->prevdr = prevdr = ospf6_interface->dr;
  ospf6_interface->prevbdr = prevbdr = ospf6_interface->bdr;

step_two:

  /* Calculate Backup Designated Router. */
  /* Make Candidate list */
  if (!list_isempty (candidate_list))
    list_delete_all_node (candidate_list);
  declare = 0;
  for (i = listhead (ospf6_interface->neighbor_list); i; nextnode (i))
    {
      nbpi = (struct ospf6_neighbor *)getdata (i);
      if (nbpi->priority == 0)
        continue;
      if (nbpi->state < NBS_TWOWAY)
        continue;
      if (nbpi->dr == nbpi->router_id)
        continue;
      if (nbpi->bdr == nbpi->router_id)
        declare++;
      listnode_add (candidate_list, nbpi);
    }

  if (myself.priority)
    {
      if (myself.dr != myself.router_id)
        {
          if (myself.bdr == myself.router_id)
            declare++;
          listnode_add (candidate_list, &myself);
        }
    }

  /* Elect BDR */
  for (i = listhead (candidate_list);
       candidate_list->count > 1;
       i = listhead (candidate_list))
    {
      j = i;
      nextnode(j);
      assert (j);
      nbpi = (struct ospf6_neighbor *)getdata (i);
      nbpj = (struct ospf6_neighbor *)getdata (j);
      if (declare)
        {
          int deleted = 0;
          if (nbpi->bdr != nbpi->router_id)
            {
              listnode_delete (candidate_list, nbpi);
              deleted++;
            }
          if (nbpj->bdr != nbpj->router_id)
            {
              listnode_delete (candidate_list, nbpj);
              deleted++;
            }
          if (deleted)
            continue;
        }
      if (nbpi->priority > nbpj->priority)
        {
          listnode_delete (candidate_list, nbpj);
          continue;
        }
      else if (nbpi->priority < nbpj->priority)
        {
          listnode_delete (candidate_list, nbpi);
          continue;
        }
      else /* equal, case of tie */
        {
          if (ntohl (nbpi->router_id) > ntohl (nbpj->router_id))
            {
              listnode_delete (candidate_list, nbpj);
              continue;
            }
          else if (ntohl (nbpi->router_id) < ntohl (nbpj->router_id))
            {
              listnode_delete (candidate_list, nbpi);
              continue;
            }
          else
            assert (0);
        }
    }

  if (!list_isempty (candidate_list))
    {
      assert (candidate_list->count == 1);
      n = listhead (candidate_list);
      nbr = (struct ospf6_neighbor *)getdata (n);
      bdr = nbr->router_id;
    }
  else
    bdr = 0;

/* step_three: */

  /* Calculate Designated Router. */
  /* Make Candidate list */
  if (!list_isempty (candidate_list))
    list_delete_all_node (candidate_list);
  declare = 0;
  for (i = listhead (ospf6_interface->neighbor_list); i; nextnode (i))
    {
      nbpi = (struct ospf6_neighbor *)getdata (i);
      if (nbpi->priority == 0)
        continue;
      if (nbpi->state < NBS_TWOWAY)
        continue;
      if (nbpi->dr == nbpi->router_id)
        {
          declare++;
          listnode_add (candidate_list, nbpi);
        }
    }
  if (myself.priority)
    {
      if (myself.dr == myself.router_id)
        {
          declare++;
          listnode_add (candidate_list, &myself);
        }
    }

  /* Elect DR */
  if (declare == 0)
    {
      assert (list_isempty (candidate_list));
      /* No one declare but candidate_list not empty */
      dr = bdr;
    }
  else
    {
      assert (!list_isempty (candidate_list));
      for (i = listhead (candidate_list);
           candidate_list->count > 1;
           i = listhead (candidate_list))
        {
          j = i;
          nextnode (j);
          assert (j);
          nbpi = (struct ospf6_neighbor *)getdata (i);
          nbpj = (struct ospf6_neighbor *)getdata (j);

          if (nbpi->dr != nbpi->router_id)
            {
              list_delete_node (candidate_list, i);
              continue;
            }
          if (nbpj->dr != nbpj->router_id)
            {
              list_delete_node (candidate_list, j);
              continue;
            }

          if (nbpi->priority > nbpj->priority)
            {
              list_delete_node (candidate_list, j);
              continue;
            }
          else if (nbpi->priority < nbpj->priority)
            {
              list_delete_node (candidate_list, i);
              continue;
            }
          else /* equal, case of tie */
            {
              if (ntohl (nbpi->router_id) > ntohl (nbpj->router_id))
                {
                  list_delete_node (candidate_list, j);
                  continue;
                }
              else if (ntohl (nbpi->router_id) < ntohl (nbpj->router_id))
                {
                  list_delete_node (candidate_list, i);
                  continue;
                }
              else
                {
                  zlog_warn ("!!!THE SAME ROUTER ID FOR DIFFERENT NEIGHBOR");
                  zlog_warn ("!!!MISCONFIGURATION?");
                  list_delete_node (candidate_list, i);
                  continue;
                }
            }
        }
      if (!list_isempty (candidate_list))
        {
          assert (candidate_list->count == 1);
          n = listhead (candidate_list);
          nbr = (struct ospf6_neighbor *)getdata (n);
          dr = nbr->router_id;
        }
      else
        assert (0);
    }

/* step_four: */

  if (gofive)
    goto step_five;

  if (dr != prevdr)
    {
      if ((dr == myself.router_id || prevdr == myself.router_id)
          && !(dr == myself.router_id && prevdr == myself.router_id))
        {
          myself.dr = dr;
          myself.bdr = bdr;
          gofive++;
          goto step_two;
        }
    }
  if (bdr != prevbdr)
    {
      if ((bdr == myself.router_id || prevbdr == myself.router_id)
          && !(bdr == myself.router_id && prevbdr == myself.router_id))
        {
          myself.dr = dr;
          myself.bdr = bdr;
          gofive++;
          goto step_two;
        }
    }

step_five:

  ospf6_interface->dr = dr;
  ospf6_interface->bdr = bdr;

  if (prevdr != dr || prevbdr != bdr)
    {
      for (i = listhead (ospf6_interface->neighbor_list); i; nextnode (i))
        {
          nbpi = getdata (i);
          if (nbpi->state < NBS_TWOWAY)
            continue;
          /* Schedule or Execute AdjOK. which does "invoke" mean? */
          thread_add_event (master, adj_ok, nbpi, 0);
        }
    }

  list_delete (candidate_list);

  if (dr == myself.router_id)
    {
      assert (bdr != myself.router_id);
      return IFS_DR;
    }
  else if (bdr == myself.router_id)
    {
      assert (dr != myself.router_id);
      return IFS_BDR;
    }
  else
    return IFS_DROTHER;
}


