/*
 * 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_read (ZEBRA_INTERFACE_ADDRESS_ADD, 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_read (ZEBRA_INTERFACE_ADDRESS_DELETE, 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_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, p, &api);
  else
    ret = zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, p, &api);

  if (ret < 0)
    zlog_err ("ZEBRA: zapi_ipv6_route () 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;
}

