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

#include "ospf6d.h"

#include "ospf6_interface.h"
#include "ospf6_asbr.h"

#include "ospf6_linklist.h"

/* information about zebra. */
struct zclient *zclient = NULL;

/* redistribute function */
void
ospf6_zebra_redistribute (int type)
{
  int top_change = 0;

  if (zclient->redist[type])
    return;

  if (! ospf6_is_asbr (ospf6))
    top_change = 1;

  zclient->redist[type] = 1;

  if (zclient->sock > 0)
    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient->sock, type);

  if (top_change)
    CALL_CHANGE_HOOK (&top_hook, ospf6);
}

void
ospf6_zebra_no_redistribute (int type)
{
  int top_change = 0;

  if (!zclient->redist[type])
    return;

  if (ospf6_is_asbr (ospf6))
    top_change = 1;

  zclient->redist[type] = 0;

  if (zclient->sock > 0)
    zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient->sock, type);

  if (top_change)
    CALL_CHANGE_HOOK (&top_hook, ospf6);
}

int
ospf6_zebra_is_redistribute (int type)
{
  return zclient->redist[type];
}


/* Inteface addition message from zebra. */
int
ospf6_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length)
{
  struct interface *ifp;

  ifp = zebra_interface_add_read (zclient->ibuf);

  /* log */
  if (IS_OSPF6_DUMP_ZEBRA)
    zlog_info ("ZEBRA: I/F add: %s index %d mtu %d",
               ifp->name, ifp->ifindex, ifp->mtu);

  ospf6_interface_if_add (ifp);

  return 0;
}

int
ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length)
{
#if 0
  struct interface *ifp = NULL;

  ifp = zebra_interface_delete_read (zclient->ibuf);

  /* log */
  if (IS_OSPF6_DUMP_ZEBRA)
    zlog_info ("ZEBRA: I/F delete: %s index %d mtu %d",
               ifp->name, ifp->ifindex, ifp->mtu);

  ospf6_interface_if_del (ifp);
#endif

  return 0;
}

int
ospf6_zebra_if_state_update (int command, struct zclient *zclient,
                             zebra_size_t length)
{
  struct interface *ifp;

  ifp = zebra_interface_state_read (zclient->ibuf);

  /* log */
  if (IS_OSPF6_DUMP_ZEBRA)
    zlog_info ("ZEBRA: I/F %s state change: index %d flags %ld metric %d mtu %d",
               ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu);

  ospf6_interface_state_update (ifp);
  return 0;
}

int
ospf6_zebra_if_address_update_add (int command, struct zclient *zclient,
                               zebra_size_t length)
{
  struct connected *c;
  char buf[128];

  c = zebra_interface_address_add_read (zclient->ibuf);
  if (c == NULL)
    return 0;

  if (IS_OSPF6_DUMP_ZEBRA)
    zlog_info ("ZEBRA: I/F %s address add: %5s %s/%d",
               c->ifp->name, prefix_family_str (c->address),
               inet_ntop (c->address->family, &c->address->u.prefix,
                          buf, sizeof (buf)), c->address->prefixlen);

  if (c->address->family == AF_INET6)
    ospf6_interface_address_update (c->ifp);

  return 0;
}

int
ospf6_zebra_if_address_update_delete (int command, struct zclient *zclient,
                               zebra_size_t length)
{
  struct connected *c;
  char buf[128];

  c = zebra_interface_address_delete_read (zclient->ibuf);
  if (c == NULL)
    return 0;

  if (IS_OSPF6_DUMP_ZEBRA)
    zlog_info ("ZEBRA: I/F %s address del: %5s %s/%d",
               c->ifp->name, prefix_family_str (c->address),
               inet_ntop (c->address->family, &c->address->u.prefix,
                          buf, sizeof (buf)), c->address->prefixlen);

  if (c->address->family == AF_INET6)
    ospf6_interface_address_update (c->ifp);

  return 0;
}



const char *zebra_route_name[ZEBRA_ROUTE_MAX] =
{
  "System",
  "Kernel",
  "Connect",
  "Static",
  "RIP",
  "RIPng",
  "OSPF",
  "OSPF6",
  "BGP",
};

const char *zebra_route_abname[ZEBRA_ROUTE_MAX] =
  { "X", "K", "C", "S", "r", "R", "o", "O", "B" };

int
ospf6_zebra_read_ipv6 (int command, struct zclient *zclient,
                       zebra_size_t length)
{
  struct stream *s;
  struct zapi_ipv6 api;
  unsigned long ifindex;
  struct prefix_ipv6 p;
  struct in6_addr *nexthop;
  char prefixstr[128], nexthopstr[128];

  s = zclient->ibuf;
  ifindex = 0;
  nexthop = NULL;
  memset (&api, 0, sizeof (api));

  /* Type, flags, message. */
  api.type = stream_getc (s);
  api.flags = stream_getc (s);
  api.message = stream_getc (s);

  /* IPv6 prefix. */
  memset (&p, 0, sizeof (struct prefix_ipv6));
  p.family = AF_INET6;
  p.prefixlen = stream_getc (s);
  stream_get (&p.prefix, s, PSIZE (p.prefixlen));

  /* Nexthop, ifindex, distance, metric. */
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    {
      api.nexthop_num = stream_getc (s);
      nexthop = (struct in6_addr *)
        malloc (api.nexthop_num * sizeof (struct in6_addr));
      stream_get (nexthop, s, api.nexthop_num * sizeof (struct in6_addr));
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_IFINDEX))
    {
      api.ifindex_num = stream_getc (s);
      ifindex = stream_getl (s);
    }
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_DISTANCE))
    api.distance = stream_getc (s);
  else
    api.distance = 0;
  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_METRIC))
    api.metric = stream_getl (s);
  else
    api.metric = 0;

  /* log */
  if (IS_OSPF6_DUMP_ZEBRA)
    {
      prefix2str ((struct prefix *)&p, prefixstr, sizeof (prefixstr));
      inet_ntop (AF_INET6, &nexthop, nexthopstr, sizeof (nexthopstr));

      if (command == ZEBRA_IPV6_ROUTE_ADD)
	zlog_info ("ZEBRA: Receive add %s route: %s nexthop:%s ifindex:%ld",
		   zebra_route_name [api.type], prefixstr,
		   nexthopstr, ifindex);
      else
	zlog_info ("ZEBRA: Receive remove %s route: %s nexthop:%s ifindex:%ld",
		   zebra_route_name [api.type], prefixstr,
		   nexthopstr, ifindex);
    }
 
  if (command == ZEBRA_IPV6_ROUTE_ADD)
    ospf6_asbr_route_add (api.type, ifindex, (struct prefix *) &p,
                          api.nexthop_num, nexthop);
  else
    ospf6_asbr_route_remove (api.type, ifindex, (struct prefix *) &p);

  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP))
    free (nexthop);

  return 0;
}


DEFUN (show_zebra,
       show_zebra_cmd,
       "show zebra",
       SHOW_STR
       "Zebra information\n")
{
  int i;
  if (!zclient)
    vty_out (vty, "Not connected to zebra%s", VTY_NEWLINE);

  vty_out (vty, "Zebra Infomation%s", VTY_NEWLINE);
  vty_out (vty, "  enable: %d%s", zclient->enable, VTY_NEWLINE);
  vty_out (vty, "  fail: %d%s", zclient->fail, VTY_NEWLINE);
  vty_out (vty, "  redistribute default: %d%s", zclient->redist_default,
           VTY_NEWLINE);
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    vty_out (vty, "    RouteType: %s - %s%s", zebra_route_name[i],
             zclient->redist[i] ? "redistributed" : "not redistributed",
             VTY_NEWLINE);
  return CMD_SUCCESS;
}

DEFUN (router_zebra,
       router_zebra_cmd,
       "router zebra",
       "Enable a routing process\n"
       "Make connection to zebra daemon\n")
{
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("Config: router zebra");

  vty->node = ZEBRA_NODE;
  zclient->enable = 1;
  zclient_start (zclient);
  return CMD_SUCCESS;
}

DEFUN (no_router_zebra,
       no_router_zebra_cmd,
       "no router zebra",
       NO_STR
       "Configure routing process\n"
       "Disable connection to zebra daemon\n")
{
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("no router zebra");

  zclient->enable = 0;
  zclient_stop (zclient);
  return CMD_SUCCESS;
}

/* Zebra configuration write function. */
int
ospf6_zebra_config_write (struct vty *vty)
{
  if (! zclient->enable)
    {
      vty_out (vty, "no router zebra%s", VTY_NEWLINE);
      return 1;
    }
  else if (! zclient->redist[ZEBRA_ROUTE_OSPF6])
    {
      vty_out (vty, "router zebra%s", VTY_NEWLINE);
      vty_out (vty, " no redistribute ospf6%s", VTY_NEWLINE);
      return 1;
    }
  return 0;
}

/* Zebra node structure. */
struct cmd_node zebra_node =
{
  ZEBRA_NODE,
  "%s(config-zebra)# ",
  vtysh: 0
};

#define ADD    0
#define CHANGE 1
#define REMOVE 2

static void
ospf6_zebra_route_update (int type, struct ospf6_route_req *request)
{
  char buf[96], ifname[IFNAMSIZ];

  struct zapi_ipv6 api;
  struct ospf6_route_req route;
  struct linklist *nexthop_list;
  struct linklist_node node;
  struct ospf6_nexthop *nexthop = NULL;
  struct in6_addr **nexthops;
  unsigned int *ifindexes;
  struct prefix_ipv6 *p;
  int i, ret = 0;

  if (IS_OSPF6_DUMP_ZEBRA)
    {
      prefix2str (&request->route.prefix, buf, sizeof (buf));
      if (type == REMOVE)
        zlog_info ("ZEBRA: Send remove route: %s", buf);
      else
        zlog_info ("ZEBRA: Send add route: %s", buf);
    }

  if (zclient->sock < 0)
    {
      if (IS_OSPF6_DUMP_ZEBRA)
        zlog_info ("ZEBRA:   failed: not connected to zebra");
      return;
    }

  if (request->path.origin.adv_router == ospf6->router_id &&
      (request->path.type == OSPF6_PATH_TYPE_EXTERNAL1 ||
       request->path.type == OSPF6_PATH_TYPE_EXTERNAL2))
    {
      if (IS_OSPF6_DUMP_ZEBRA)
        zlog_info ("ZEBRA:   self originated external route, ignore");
      return;
    }

  /* Only the best path (i.e. the first path of the path-list
     in 'struct ospf6_route') will be sent to zebra. */
  ospf6_route_lookup (&route, &request->route.prefix, request->table);
  if (memcmp (&route.path, &request->path, sizeof (route.path)))
    {
      /* this is not preferred best route, ignore */
      if (IS_OSPF6_DUMP_ZEBRA)
        zlog_info ("ZEBRA:   not best path, ignore");
      return;
    }

  nexthop_list = linklist_create ();

  /* for each nexthop */
  for (ospf6_route_lookup (&route, &request->route.prefix, request->table);
       ! ospf6_route_end (&route); ospf6_route_next (&route))
    {
      if (memcmp (&route.path, &request->path, sizeof (route.path)))
        break;

      #define IN6_IS_ILLEGAL_NEXTHOP(a)\
        ((*(u_int32_t *)(void *)(&(a)->s6_addr[0]) == 0xffffffff) &&\
        (*(u_int32_t *)(void *)(&(a)->s6_addr[4]) == 0xffffffff) &&\
        (*(u_int32_t *)(void *)(&(a)->s6_addr[8]) == 0xffffffff) &&\
        (*(u_int32_t *)(void *)(&(a)->s6_addr[12]) == 0xffffffff))
      if (IN6_IS_ILLEGAL_NEXTHOP (&route.nexthop.address))
        {
          zlog_warn ("ZEBRA: Illegal nexthop");
          continue;
        }

      if (type == REMOVE && ! memcmp (&route.nexthop, &request->nexthop,
                                      sizeof (struct ospf6_nexthop)))
        continue;

      nexthop = XCALLOC (MTYPE_OSPF6_OTHER, sizeof (struct ospf6_nexthop));
      if (! nexthop)
        {
          zlog_warn ("ZEBRA: Can't update nexthop: malloc failed");
          continue;
        }

      memcpy (nexthop, &route.nexthop, sizeof (struct ospf6_nexthop));
      linklist_add (nexthop, nexthop_list);
    }

  if (type == REMOVE && nexthop_list->count != 0)
    type = ADD;
  else if (type == REMOVE && nexthop_list->count == 0)
    {
      if (IS_OSPF6_DUMP_ZEBRA)
        zlog_info ("ZEBRA:   all nexthop with the selected path has gone");

      if (! memcmp (&request->route, &route.route,
                    sizeof (struct ospf6_route)))
        {
          /* send 'add' of alternative route */
          struct ospf6_path seconde_path;

          if (IS_OSPF6_DUMP_ZEBRA)
            zlog_info ("ZEBRA:   found alternative path to add");

          memcpy (&seconde_path, &route.path, sizeof (struct ospf6_path));
          type = ADD;

          while (! memcmp (&seconde_path, &route.path,
                           sizeof (struct ospf6_path)))
            {
              nexthop = XCALLOC (MTYPE_OSPF6_OTHER,
                                 sizeof (struct ospf6_nexthop));
              if (! nexthop)
                zlog_warn ("ZEBRA:   Can't update nexthop: malloc failed");
              else
                {
                  memcpy (nexthop, &route.nexthop,
                          sizeof (struct ospf6_nexthop));
                  linklist_add (nexthop, nexthop_list);
                }

              ospf6_route_next (&route);
            }
        }
      else
        {
          /* there is no alternative route. send 'remove' to zebra for
             requested route */
          if (IS_OSPF6_DUMP_ZEBRA)
            zlog_info ("ZEBRA:   can't find alternative path, remove");

          if (IS_OSPF6_DUMP_ZEBRA)
            {
              zlog_info ("ZEBRA:   Debug: walk over the route ?");
              ospf6_route_log_request ("Debug route", "***", &route);
              ospf6_route_log_request ("Debug request", "***", request);
            }

          nexthop = XCALLOC (MTYPE_OSPF6_OTHER,
                             sizeof (struct ospf6_nexthop));
          if (! nexthop)
            zlog_warn ("ZEBRA:   Can't update nexthop: malloc failed");
          else
            {
              memcpy (nexthop, &request->nexthop,
                      sizeof (struct ospf6_nexthop));
              linklist_add (nexthop, nexthop_list);
            }
        }
    }

  if (nexthop_list->count == 0)
    {
      if (IS_OSPF6_DUMP_ZEBRA)
        zlog_info ("ZEBRA:   no nexthop, ignore");
      linklist_delete (nexthop_list);
      return;
    }

  /* allocate memory for nexthop_list */
  nexthops = XCALLOC (MTYPE_OSPF6_OTHER,
                      nexthop_list->count * sizeof (struct in6_addr *));
  if (! nexthops)
    {
      zlog_warn ("ZEBRA:   Can't update zebra route: malloc failed");
      for (linklist_head (nexthop_list, &node); !linklist_end (&node);
           linklist_next (&node))
        XFREE (MTYPE_OSPF6_OTHER, node.data);
      linklist_delete (nexthop_list);
      return;
    }

  /* allocate memory for ifindex_list */
  ifindexes = XCALLOC (MTYPE_OSPF6_OTHER,
                       nexthop_list->count * sizeof (unsigned int));
  if (! ifindexes)
    {
      zlog_warn ("ZEBRA: Can't update zebra route: malloc failed");
      for (linklist_head (nexthop_list, &node); !linklist_end (&node);
           linklist_next (&node))
        XFREE (MTYPE_OSPF6_OTHER, node.data);
      linklist_delete (nexthop_list);
      XFREE (MTYPE_OSPF6_OTHER, nexthops);
      return;
    }

  i = 0;
  for (linklist_head (nexthop_list, &node); ! linklist_end (&node);
       linklist_next (&node))
    {
      nexthop = node.data;
      if (IS_OSPF6_DUMP_ZEBRA)
        {
          inet_ntop (AF_INET6, &nexthop->address, buf, sizeof (buf));
          if_indextoname (nexthop->ifindex, ifname);
          zlog_info ("ZEBRA:   nexthop: %s%%%s(%d)",
                     buf, ifname, nexthop->ifindex);
        }
      nexthops[i] = &nexthop->address;
      ifindexes[i] = nexthop->ifindex;
      i++;
    }

  api.type = ZEBRA_ROUTE_OSPF6;
  api.flags = 0;
  api.message = 0;
  SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
  SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
  api.nexthop_num = nexthop_list->count;
  api.nexthop = nexthops;
  api.ifindex_num = nexthop_list->count;
  api.ifindex = ifindexes;

  p = (struct prefix_ipv6 *) &request->route.prefix;
  if (type == REMOVE && nexthop_list->count == 1)
    ret = zapi_ipv6_delete (zclient, p, &api);
  else
    ret = zapi_ipv6_add (zclient, p, &api);

  if (ret < 0)
    zlog_err ("ZEBRA: zapi_ipv6_add () failed: %s", strerror (errno));

  for (linklist_head (nexthop_list, &node); !linklist_end (&node);
       linklist_next (&node))
    XFREE (MTYPE_OSPF6_OTHER, node.data);
  linklist_delete (nexthop_list);
  XFREE (MTYPE_OSPF6_OTHER, nexthops);
  XFREE (MTYPE_OSPF6_OTHER, ifindexes);

  return;
}

void
ospf6_zebra_route_update_add (struct ospf6_route_req *request)
{
  ospf6_zebra_route_update (ADD, request);
}

void
ospf6_zebra_route_update_remove (struct ospf6_route_req *request)
{
  ospf6_zebra_route_update (REMOVE, request);
}

static void
ospf6_zebra_redistribute_ospf6 ()
{
  struct route_node *node;

  for (node = route_top (ospf6->route_table->table); node;
       node = route_next (node))
    {
      if (! node || ! node->info)
        continue;
      ospf6_zebra_route_update_add (node->info);
    }
}

static void
ospf6_zebra_no_redistribute_ospf6 ()
{
  struct route_node *node;

  if (! ospf6)
    return;

  for (node = route_top (ospf6->route_table->table); node;
       node = route_next (node))
    {
      if (! node || ! node->info)
        continue;

      ospf6_zebra_route_update_remove (node->info);
    }
}


DEFUN (redistribute_ospf6,
       redistribute_ospf6_cmd,
       "redistribute ospf6",
       "Redistribute control\n"
       "OSPF6 route\n")
{
  /* log */
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("Config: redistribute ospf6");

  zclient->redist[ZEBRA_ROUTE_OSPF6] = 1;

  /* set zebra route table */
  ospf6_zebra_redistribute_ospf6 ();

  return CMD_SUCCESS;
}

DEFUN (no_redistribute_ospf6,
       no_redistribute_ospf6_cmd,
       "no redistribute ospf6",
       NO_STR
       "Redistribute control\n"
       "OSPF6 route\n")
{
  /* log */
  if (IS_OSPF6_DUMP_CONFIG)
    zlog_info ("Config: no redistribute ospf6");

  zclient->redist[ZEBRA_ROUTE_OSPF6] = 0;

  if (! ospf6)
    return CMD_SUCCESS;

  /* clean up zebra route table */
  ospf6_zebra_no_redistribute_ospf6 ();

  ospf6_route_hook_unregister (ospf6_zebra_route_update_add,
                               ospf6_zebra_route_update_add,
                               ospf6_zebra_route_update_remove,
                               ospf6->route_table);

  return CMD_SUCCESS;
}

void
ospf6_zebra_init ()
{
  /* Allocate zebra structure. */
  zclient = zclient_new ();
  zclient_init (zclient, ZEBRA_ROUTE_OSPF6);
  zclient->interface_add = ospf6_zebra_if_add;
  zclient->interface_delete = ospf6_zebra_if_del;
  zclient->interface_up = ospf6_zebra_if_state_update;
  zclient->interface_down = ospf6_zebra_if_state_update;
  zclient->interface_address_add = ospf6_zebra_if_address_update_add;
  zclient->interface_address_delete = ospf6_zebra_if_address_update_delete;
  zclient->ipv4_route_add = NULL;
  zclient->ipv4_route_delete = NULL;
  zclient->ipv6_route_add = ospf6_zebra_read_ipv6;
  zclient->ipv6_route_delete = ospf6_zebra_read_ipv6;

  /* redistribute connected route by default */
  /* ospf6_zebra_redistribute (ZEBRA_ROUTE_CONNECT); */

  /* Install zebra node. */
  install_node (&zebra_node, ospf6_zebra_config_write);

  /* Install command element for zebra node. */
  install_element (VIEW_NODE, &show_zebra_cmd);
  install_element (ENABLE_NODE, &show_zebra_cmd);
  install_element (CONFIG_NODE, &router_zebra_cmd);
  install_element (CONFIG_NODE, &no_router_zebra_cmd);
  install_default (ZEBRA_NODE);
  install_element (ZEBRA_NODE, &redistribute_ospf6_cmd);
  install_element (ZEBRA_NODE, &no_redistribute_ospf6_cmd);

#if 0
  hook.name = "ZebraRouteUpdate";
  hook.hook_add = ospf6_zebra_route_update_add;
  hook.hook_change = ospf6_zebra_route_update_add;
  hook.hook_remove = ospf6_zebra_route_update_remove;
  ospf6_hook_register (&hook, &route_hook);
#endif

  return;
}

void
ospf6_zebra_finish ()
{
  zclient_stop (zclient);
  zclient_free (zclient);
  zclient = (struct zclient *) NULL;
}

