/*
 * 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"

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 (node = l->head; node; node = node->next)
    {
      c = (struct connected *) getdata (node);
      if (prefix_same (ifc->address, c->address))
	return c;
    }
  return NULL;
}

static int
router_id_bad_address (struct connected *ifc)
{
  struct prefix n;

  if (ifc->address->family != AF_INET)
    return 1;

  n.u.prefix4.s_addr = htonl (INADDR_LOOPBACK);
  n.prefixlen = 8;
  n.family = AF_INET;

  if (prefix_match (&n, 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 = getdata (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 = getdata (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 (node = listhead (zebrad.client_list); node; nextnode (node))
    if ((client = getdata (node)) != NULL)
      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 (l, ifc);

  router_id_get (&after);

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

  for (node = listhead (zebrad.client_list); node; nextnode (node))
    if ((client = getdata (node)) != NULL)
      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 (node = listhead (zebrad.client_list); node; nextnode (node))
    if ((client = getdata (node)) != NULL)
      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;
}

int
router_id_cmp (void *a, void *b)
{
  unsigned int A, B;

  A = ((struct connected *) a)->address->u.prefix4.s_addr;
  B = ((struct connected *) b)->address->u.prefix4.s_addr;

  if (A > B)
    return 1;
  else if (A < B)
    return -1;
  return 0;
}

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;
}
