/*
 * Router ID for zebra daemon.
 *
 * Copyright (C) 2004 James R. Leu 
 *
 * This file is part of Quagga routing suite.
 *
 * Quagga 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.
 *
 * Quagga 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 "if.h"
#include "vty.h"
#include "sockunion.h"
#include "prefix.h"
#include "stream.h"
#include "command.h"
#include "memory.h"
#include "ioctl.h"
#include "connected.h"
#include "network.h"
#include "log.h"
#include "table.h"
#include "rib.h"

#include "zebra/zserv.h"
#include "zebra/router-id.h"
#include "zebra/redistribute.h"

static struct list rid_all_sorted_list;
static struct list rid_lo_sorted_list;
static struct prefix rid_user_assigned;

/* master zebra server structure */
extern struct zebra_t zebrad;

static struct connected *
router_id_find_node (struct list *l, struct connected *ifc)
{
  struct listnode *node;
  struct connected *c;

  for (ALL_LIST_ELEMENTS_RO (l, node, c))
    if (prefix_same (ifc->address, c->address))
      return c;

  return NULL;
}

static int
router_id_bad_address (struct connected *ifc)
{
  if (ifc->address->family != AF_INET)
    return 1;
  
  /* non-redistributable addresses shouldn't be used for RIDs either */
  if (!zebra_check_addr (ifc->address))
    return 1;
  
  return 0;
}

void
router_id_get (struct prefix *p)
{
  struct listnode *node;
  struct connected *c;

  p->u.prefix4.s_addr = 0;
  p->family = AF_INET;
  p->prefixlen = 32;

  if (rid_user_assigned.u.prefix4.s_addr)
    p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
  else if (!list_isempty (&rid_lo_sorted_list))
    {
      node = listtail (&rid_lo_sorted_list);
      c = listgetdata (node);
      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
    }
  else if (!list_isempty (&rid_all_sorted_list))
    {
      node = listtail (&rid_all_sorted_list);
      c = listgetdata (node);
      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
    }
}

static void
router_id_set (struct prefix *p)
{
  struct prefix p2;
  struct listnode *node;
  struct zserv *client;

  rid_user_assigned.u.prefix4.s_addr = p->u.prefix4.s_addr;

  router_id_get (&p2);

  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
    zsend_router_id_update (client, &p2);
}

void
router_id_add_address (struct connected *ifc)
{
  struct list *l = NULL;
  struct listnode *node;
  struct prefix before;
  struct prefix after;
  struct zserv *client;

  if (router_id_bad_address (ifc))
    return;

  router_id_get (&before);

  if (!strncmp (ifc->ifp->name, "lo", 2)
      || !strncmp (ifc->ifp->name, "dummy", 5))
    l = &rid_lo_sorted_list;
  else
    l = &rid_all_sorted_list;
  
  if (!router_id_find_node (l, ifc))
    listnode_add_sort (l, ifc);

  router_id_get (&after);

  if (prefix_same (&before, &after))
    return;

  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
    zsend_router_id_update (client, &after);
}

void
router_id_del_address (struct connected *ifc)
{
  struct connected *c;
  struct list *l;
  struct prefix after;
  struct prefix before;
  struct listnode *node;
  struct zserv *client;

  if (router_id_bad_address (ifc))
    return;

  router_id_get (&before);

  if (!strncmp (ifc->ifp->name, "lo", 2)
      || !strncmp (ifc->ifp->name, "dummy", 5))
    l = &rid_lo_sorted_list;
  else
    l = &rid_all_sorted_list;

  if ((c = router_id_find_node (l, ifc)))
    listnode_delete (l, c);

  router_id_get (&after);

  if (prefix_same (&before, &after))
    return;

  for (ALL_LIST_ELEMENTS_RO (zebrad.client_list, node, client))
    zsend_router_id_update (client, &after);
}

void
router_id_write (struct vty *vty)
{
  if (rid_user_assigned.u.prefix4.s_addr)
    vty_out (vty, "router-id %s%s", inet_ntoa (rid_user_assigned.u.prefix4),
	     VTY_NEWLINE);
}

DEFUN (router_id,
       router_id_cmd,
       "router-id A.B.C.D",
       "Manually set the router-id\n"
       "IP address to use for router-id\n")
{
  struct prefix rid;

  rid.u.prefix4.s_addr = inet_addr (argv[0]);
  if (!rid.u.prefix4.s_addr)
    return CMD_WARNING;

  rid.prefixlen = 32;
  rid.family = AF_INET;

  router_id_set (&rid);

  return CMD_SUCCESS;
}

DEFUN (no_router_id,
       no_router_id_cmd,
       "no router-id",
       NO_STR
       "Remove the manually configured router-id\n")
{
  struct prefix rid;

  rid.u.prefix4.s_addr = 0;
  rid.prefixlen = 0;
  rid.family = AF_INET;

  router_id_set (&rid);

  return CMD_SUCCESS;
}

static int
router_id_cmp (void *a, void *b)
{
  const struct connected *ifa = (const struct connected *)a;
  const struct connected *ifb = (const struct connected *)b;
  unsigned int A = ntohl(ifa->address->u.prefix4.s_addr);
  unsigned int B = ntohl(ifb->address->u.prefix4.s_addr);

  return (int) (A - B);
}

void
router_id_init (void)
{
  install_element (CONFIG_NODE, &router_id_cmd);
  install_element (CONFIG_NODE, &no_router_id_cmd);

  memset (&rid_all_sorted_list, 0, sizeof (rid_all_sorted_list));
  memset (&rid_lo_sorted_list, 0, sizeof (rid_lo_sorted_list));
  memset (&rid_user_assigned, 0, sizeof (rid_user_assigned));

  rid_all_sorted_list.cmp = router_id_cmp;
  rid_lo_sorted_list.cmp = router_id_cmp;

  rid_user_assigned.family = AF_INET;
  rid_user_assigned.prefixlen = 32;
}
