/*
 * Copyright (C) 2001-2002 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 <zebra.h>

#include "log.h"
#include "memory.h"
#include "prefix.h"
#include "command.h"
#include "vty.h"
#include "routemap.h"
#include "table.h"
#include "plist.h"
#include "thread.h"

#include "ospf6_prefix.h"  /* xxx for ospf6_asbr.h */
#include "ospf6_lsa.h"     /* xxx for ospf6_asbr.h */
#include "ospf6_route.h"   /* xxx for ospf6_asbr.h, ospf6_zebra.h */
#include "ospf6_zebra.h"
#include "ospf6_asbr.h"
#include "ospf6_damp.h"
#include "ospf6_top.h"
#include "ospf6_lsdb.h"
#include "ospf6_proto.h"

extern struct thread_master *master;

struct route_table *external_table;
struct
{
  char *name;
  struct route_map *map;
} rmap [ZEBRA_ROUTE_MAX];

static u_int32_t link_state_id = 0;

char *
zroute_name[] =
{ 
  "system", "kernel", "connected", "static",
  "rip", "ripng", "ospf", "ospf6", "bgp", "unknown"
};
char *
zroute_abname[] =
{
  "X", "K", "C", "S", "R", "R", "O", "O", "B", "?"
};

#define ZROUTE_NAME(x) \
  (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? \
   zroute_name[(x)] : zroute_name[ZEBRA_ROUTE_MAX])

#define ZROUTE_ABNAME(x) \
  (0 < (x) && (x) < ZEBRA_ROUTE_MAX ? \
   zroute_abname[(x)] : zroute_abname[ZEBRA_ROUTE_MAX])

/* redistribute function */
void
ospf6_asbr_routemap_set (int type, char *mapname)
{
  if (rmap[type].name)
    free (rmap[type].name);

  rmap[type].name = strdup (mapname);
  rmap[type].map = route_map_lookup_by_name (mapname);
}

void
ospf6_asbr_routemap_unset (int type)
{
  if (rmap[type].name)
    free (rmap[type].name);
  rmap[type].name = NULL;
  rmap[type].map = NULL;
}

void
ospf6_asbr_routemap_update ()
{
  int i;
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    {
      if (rmap[i].name)
        rmap[i].map = route_map_lookup_by_name (rmap[i].name);
      else
        rmap[i].map = NULL;
    }
}

DEFUN (ospf6_redistribute,
       ospf6_redistribute_cmd,
       "redistribute (static|kernel|connected|ripng|bgp)",
       "Redistribute\n"
       "Static route\n"
       "Kernel route\n"
       "Connected route\n"
       "RIPng route\n"
       "BGP route\n"
      )
{
  int type = 0;

  if (strncmp (argv[0], "sta", 3) == 0)
    type = ZEBRA_ROUTE_STATIC;
  else if (strncmp (argv[0], "ker", 3) == 0)
    type = ZEBRA_ROUTE_KERNEL;
  else if (strncmp (argv[0], "con", 3) == 0)
    type = ZEBRA_ROUTE_CONNECT;
  else if (strncmp (argv[0], "rip", 3) == 0)
    type = ZEBRA_ROUTE_RIPNG;
  else if (strncmp (argv[0], "bgp", 3) == 0)
    type = ZEBRA_ROUTE_BGP;

  ospf6_zebra_no_redistribute (type);
  ospf6_asbr_routemap_unset (type);
  ospf6_zebra_redistribute (type);
  return CMD_SUCCESS;
}

DEFUN (ospf6_redistribute_routemap,
       ospf6_redistribute_routemap_cmd,
       "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
       "Redistribute\n"
       "Static routes\n"
       "Kernel route\n"
       "Connected route\n"
       "RIPng route\n"
       "BGP route\n"
       "Route map reference\n"
       "Route map name\n"
      )
{
  int type = 0;

  if (strncmp (argv[0], "sta", 3) == 0)
    type = ZEBRA_ROUTE_STATIC;
  else if (strncmp (argv[0], "ker", 3) == 0)
    type = ZEBRA_ROUTE_KERNEL;
  else if (strncmp (argv[0], "con", 3) == 0)
    type = ZEBRA_ROUTE_CONNECT;
  else if (strncmp (argv[0], "rip", 3) == 0)
    type = ZEBRA_ROUTE_RIPNG;
  else if (strncmp (argv[0], "bgp", 3) == 0)
    type = ZEBRA_ROUTE_BGP;

  ospf6_zebra_no_redistribute (type);
  ospf6_asbr_routemap_set (type, argv[1]);
  ospf6_zebra_redistribute (type);
  return CMD_SUCCESS;
}

DEFUN (no_ospf6_redistribute,
       no_ospf6_redistribute_cmd,
       "no redistribute (static|kernel|connected|ripng|bgp)",
       NO_STR
       "Redistribute\n"
       "Static route\n"
       "Kernel route\n"
       "Connected route\n"
       "RIPng route\n"
       "BGP route\n"
      )
{
  int type = 0;
  struct route_node *node;
  struct ospf6_external_route *route;
  struct ospf6_external_info *info, *info_next = NULL;

  if (strncmp (argv[0], "sta", 3) == 0)
    type = ZEBRA_ROUTE_STATIC;
  else if (strncmp (argv[0], "ker", 3) == 0)
    type = ZEBRA_ROUTE_KERNEL;
  else if (strncmp (argv[0], "con", 3) == 0)
    type = ZEBRA_ROUTE_CONNECT;
  else if (strncmp (argv[0], "rip", 3) == 0)
    type = ZEBRA_ROUTE_RIPNG;
  else if (strncmp (argv[0], "bgp", 3) == 0)
    type = ZEBRA_ROUTE_BGP;

  ospf6_zebra_no_redistribute (type);
  ospf6_asbr_routemap_unset (type);

  /* remove redistributed route */
  for (node = route_top (external_table); node; node = route_next (node))
    {
      route = node->info;
      if (! route)
        continue;
      for (info = route->info_head; info; info = info_next)
        {
          info_next = info->next;
          if (info->type != type)
            continue;
          ospf6_asbr_route_remove (info->type, info->ifindex,
                                   &route->prefix);
        }
    }

  return CMD_SUCCESS;
}


int
ospf6_redistribute_config_write (struct vty *vty)
{
  int i;

  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    {
      if (i == ZEBRA_ROUTE_OSPF6)
        continue;

      if (! ospf6_zebra_is_redistribute (i))
        continue;

      if (rmap[i].map)
        vty_out (vty, " redistribute %s route-map %s%s",
                 ZROUTE_NAME(i), rmap[i].name, VTY_NEWLINE);
      else
        vty_out (vty, " redistribute %s%s",
                 ZROUTE_NAME(i), VTY_NEWLINE);
    }

  return 0;
}

void
ospf6_redistribute_show_config (struct vty *vty)
{
  int i;

  if (! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_SYSTEM) &&
      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_KERNEL) &&
      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_STATIC) &&
      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_RIPNG) &&
      ! ospf6_zebra_is_redistribute(ZEBRA_ROUTE_BGP))
    return;

  vty_out (vty, " Redistributing External Routes from,%s", VTY_NEWLINE);
  for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
    {
      if (i == ZEBRA_ROUTE_OSPF6)
        continue;
      if (! ospf6_zebra_is_redistribute (i))
        continue;

      if (rmap[i].map)
        vty_out (vty, "    %s with route-map %s%s",
                 ZROUTE_NAME(i), rmap[i].name, VTY_NEWLINE);
      else
        vty_out (vty, "    %s%s", ZROUTE_NAME(i), VTY_NEWLINE);
    }
}

/* AS External LSA origination */
int
ospf6_asbr_external_lsa_originate (struct thread *thread)
{
  struct ospf6_external_info *info;
  char buffer [MAXLSASIZE];
  struct ospf6_lsa_as_external *e;
  char *p;

  info = THREAD_ARG (thread);

  /* clear thread */
  info->thread_originate = NULL;

  if (info->is_removed)
    {
      if (IS_OSPF6_DUMP_ASBR)
        {
          char pbuf[64];
          prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));
          zlog_info ("ASBR: quit redistribution %s: state is down",
                     pbuf);
        }
      return 0;
    }

  /* prepare buffer */
  memset (buffer, 0, sizeof (buffer));
  e = (struct ospf6_lsa_as_external *) buffer;
  p = (char *) (e + 1);

  if (info->metric_type == 2)
    SET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_E);   /* type2 */
  else
    UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_E); /* type1, default */

  /* forwarding address */
  if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
    SET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F);
  else
    UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F);

  /* external route tag */
  UNSET_FLAG (e->bits_metric, OSPF6_ASBR_BIT_T);

  /* set metric. note: related to E bit */
  OSPF6_ASBR_METRIC_SET (e, info->metric);

  /* prefixlen */
  e->prefix.prefix_length = info->route->prefix.prefixlen;

  /* PrefixOptions */
  e->prefix.prefix_options = info->prefix_options;

  /* don't use refer LS-type */
  e->prefix.prefix_refer_lstype = htons (0);

  /* set Prefix */
  memcpy (p, &info->route->prefix.u.prefix6,
          OSPF6_PREFIX_SPACE (info->route->prefix.prefixlen));
  ospf6_prefix_apply_mask (&e->prefix);
  p += OSPF6_PREFIX_SPACE (info->route->prefix.prefixlen);

  /* Forwarding address */
  if (CHECK_FLAG (e->bits_metric, OSPF6_ASBR_BIT_F))
    {
      memcpy (p, &info->forwarding, sizeof (struct in6_addr));
      p += sizeof (struct in6_addr);
    }

  /* External Route Tag */
  if (CHECK_FLAG (e->bits_metric, OSPF6_ASBR_BIT_T))
    {
      /* xxx */
    }

  ospf6_lsa_originate (htons (OSPF6_LSA_TYPE_AS_EXTERNAL),
                       htonl (info->id), ospf6->router_id,
                       (char *) buffer, p - buffer, ospf6);
  return 0;
}

int
ospf6_asbr_schedule_external (void *data)
{
  struct ospf6_external_info *info = data;
  u_long elasped_time, time = 0;

  if (info->thread_originate)
    {
      if (IS_OSPF6_DUMP_ASBR)
        {
          char pbuf[64];
          prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));
          zlog_info ("ASBR: schedule redistribution %s: another thread",
                     pbuf);
        }
      return 0;
    }

  elasped_time =
    ospf6_lsa_has_elasped (htons (OSPF6_LSA_TYPE_AS_EXTERNAL),
                           htonl (info->id), ospf6->router_id, ospf6);
  if (elasped_time < OSPF6_MIN_LS_INTERVAL)
    time = OSPF6_MIN_LS_INTERVAL - elasped_time;
  else
    time = 0;

  //if (IS_OSPF6_DUMP_ASBR)
    {
      char pbuf[64];
      prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));
      zlog_info ("ASBR: schedule redistribution %s as LS-ID %ld after %lu sec",
                 pbuf, (u_long) info->id, time);
    }

  if (time)
    info->thread_originate =
      thread_add_timer (master, ospf6_asbr_external_lsa_originate, info, time);
  else
    info->thread_originate =
      thread_add_timer (master, ospf6_asbr_external_lsa_originate, info, 0);

  return 0;
}

int
ospf6_asbr_external_lsa_flush (void *data)
{
  struct ospf6_lsa *lsa = data;
  if (lsa)
    ospf6_lsa_premature_aging (lsa);
  return 0;
}

int
ospf6_asbr_external_lsa_refresh (void *data)
{
  struct ospf6_lsa *lsa = data;
  struct ospf6_lsa_as_external *e;
  struct prefix prefix;
  struct route_node *node;
  struct ospf6_external_route *route = NULL;
  struct ospf6_external_info *info = NULL;
  struct ospf6_external_info *match = NULL;

  if (IS_OSPF6_DUMP_ASBR)
    zlog_info ("ASBR: refresh %s", lsa->str);

  e = (struct ospf6_lsa_as_external *) (lsa->header + 1);
  ospf6_prefix_in6_addr (&e->prefix, &prefix.u.prefix6);
  prefix.prefixlen = e->prefix.prefix_length;
  prefix.family = AF_INET6;
  apply_mask_ipv6 ((struct prefix_ipv6 *) &prefix);

  for (node = route_top (external_table); node; node = route_next (node))
    {
      route = node->info;
      if (route == NULL)
        continue;

      for (info = route->info_head; info; info = info->next)
        {
          if (lsa->header->id == htonl (info->id))
            match = info;
        }
    }

  if (match == NULL)
    {
      ospf6_lsa_premature_aging (lsa);
      return 0;
    }

  ospf6_asbr_schedule_external (match);
  return 0;

#if 0
  node = route_node_lookup (external_table, &prefix);
  if (! node || ! node->info)
    {
      char pname[64];

      prefix2str (&prefix, pname, sizeof (pname));
      if (IS_OSPF6_DUMP_ASBR)
        zlog_info ("ASBR: could not find %s: premature age", pname);
      ospf6_lsa_premature_aging (lsa);
      return 0;
    }

  /* find external_info */
  route = node->info;
  for (info = route->info_head; info; info = info->next)
    {
      if (lsa->header->id == htonl (info->id))
        break;
    }

  if (info)
    ospf6_asbr_schedule_external (info);
  else
    ospf6_lsa_premature_aging (lsa);

  return 0;
#endif
}

void
ospf6_asbr_route_add (int type, int ifindex, struct prefix *prefix,
                      u_int nexthop_num, struct in6_addr *nexthop)
{
  int ret;
  struct route_node *node;
  struct ospf6_external_route *route;
  struct ospf6_external_info *info, tinfo;

#if defined (MUSICA) || defined (LINUX)
  /* XXX As long as the OSPFv3 redistribution is applied to all the connected
   *     routes, one needs to filter the ::/96 prefixes.
   *     However it could be a wanted case, it will be removed soon.
   */
  struct prefix_ipv6 *p = (prefix_ipv6 *)prefix;

  if ((IN6_IS_ADDR_V4COMPAT(&p->prefix)) ||
      (IN6_IS_ADDR_UNSPECIFIED (&p->prefix) && (p->prefixlen == 96))) 
    return;
#endif /* MUSICA or LINUX */

  if (! ospf6_zebra_is_redistribute (type))
    return;

  /* apply route-map */
  memset (&tinfo, 0, sizeof (struct ospf6_external_info));
  if (rmap[type].map)
    {
      ret = route_map_apply (rmap[type].map, prefix, RMAP_OSPF6, &tinfo);
      if (ret == RMAP_DENYMATCH)
        {
          if (IS_OSPF6_DUMP_ASBR)
            zlog_info ("ASBR: denied by route-map %s", rmap[type].name);
          return;
        }
    }

  node = route_node_get (external_table, prefix);
  route = node->info;

  if (! route)
    {
      route = XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO,
                       sizeof (struct ospf6_external_route));
      memset (route, 0, sizeof (struct ospf6_external_route));

      memcpy (&route->prefix, prefix, sizeof (struct prefix));

      node->info = route;
      route->node = node;
    }

  for (info = route->info_head; info; info = info->next)
    {
      if (info->type == type && info->ifindex == ifindex)
        break;
    }

  if (! info)
    {
      info = XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO,
                      sizeof (struct ospf6_external_info));
      memset (info, 0, sizeof (struct ospf6_external_info));

      info->route = route;
      /* add tail */
      info->prev = route->info_tail;
      if (route->info_tail)
        route->info_tail->next = info;
      else
        route->info_head = info;
      route->info_tail = info;

      info->id = link_state_id++;
    }

  /* copy result of route-map */
  info->metric_type = tinfo.metric_type;
  info->metric = tinfo.metric;
  memcpy (&info->forwarding, &tinfo.forwarding,
          sizeof (struct in6_addr));

  info->type = type;
  info->ifindex = ifindex;

  if (nexthop_num && nexthop)
    {
      info->nexthop_num = nexthop_num;

      if (info->nexthop)
        XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info->nexthop);

      info->nexthop = (struct in6_addr *)
        XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO,
                 nexthop_num * sizeof (struct in6_addr));
      memcpy (info->nexthop, nexthop,
              nexthop_num * sizeof (struct in6_addr));
    }

  info->is_removed = 0;

  //if (IS_OSPF6_DUMP_ASBR)
    {
      char pbuf[64];
      struct timeval now;
      prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));
      gettimeofday (&now, NULL);
      zlog_info ("ASBR: start redistributing %s as LS-ID %ld: %ld.%06ld",
                 pbuf, (u_long) info->id, now.tv_sec, now.tv_usec);
    }

#ifdef HAVE_OSPF6_DAMP
  ospf6_damp_event_up (OSPF6_DAMP_TYPE_ROUTE, prefix,
                       ospf6_asbr_schedule_external, info);
#else /*HAVE_OSPF6_DAMP*/
  ospf6_asbr_schedule_external (info);
#endif /*HAVE_OSPF6_DAMP*/
}

void
ospf6_asbr_route_remove (int type, int ifindex, struct prefix *prefix)
{
  struct route_node *node;
  struct ospf6_external_route *route;
  struct ospf6_external_info *info;
  struct ospf6_lsa *lsa;

#if defined (MUSICA) || defined (LINUX)
  /* XXX As long as the OSPFv3 redistribution is applied to all the connected
   *     routes, one needs to filter the ::/96 prefixes.
   *     However it could be a wanted case, it will be removed soon.
   */
  struct prefix_ipv6 *p = (prefix_ipv6 *)prefix;

  if ((IN6_IS_ADDR_V4COMPAT(&p->prefix)) ||
      (IN6_IS_ADDR_UNSPECIFIED (&p->prefix) && (p->prefixlen == 96))) 
    return;
#endif /* MUSICA or LINUX */

  node = route_node_get (external_table, prefix);
  route = node->info;

  if (! route)
    return;

  for (info = route->info_head; info; info = info->next)
    {
      if (info->type == type && info->ifindex == ifindex)
        break;
    }

  if (! info)
    return;

  //if (IS_OSPF6_DUMP_ASBR)
    {
      char pbuf[64];
      struct timeval now;
      prefix2str (&info->route->prefix, pbuf, sizeof (pbuf));
      gettimeofday (&now, NULL);
      zlog_info ("ASBR: quit redistributing %s as LS-ID %ld: %ld.%06ld",
                 pbuf, (u_long) info->id, now.tv_sec, now.tv_usec);
    }

  if (info->thread_originate)
    thread_cancel (info->thread_originate);
  info->thread_originate = NULL;

  lsa = ospf6_lsdb_lookup (htons (OSPF6_LSA_TYPE_AS_EXTERNAL),
                           htonl (info->id), ospf6->router_id, ospf6);
#ifdef HAVE_OSPF6_DAMP
  ospf6_damp_event_down (OSPF6_DAMP_TYPE_ROUTE, &info->route->prefix,
                         ospf6_asbr_external_lsa_flush, lsa);
#else /*HAVE_OSPF6_DAMP*/
  ospf6_asbr_external_lsa_flush (lsa);
#endif /*HAVE_OSPF6_DAMP*/

#if 1
  info->is_removed = 1;
#else
  /* remove from route */
  if (info->prev)
    info->prev->next = info->next;
  else
    info->route->info_head = info->next;
  if (info->next)
    info->next->prev = info->prev;
  else
    info->route->info_tail = info->prev;

  /* if no info, free route */
  if (! info->route->info_head && ! info->route->info_tail)
    {
      info->route->node->info = NULL;
      free (info->route);
    }

  if (info->nexthop)
    free (info->nexthop);
  free (info);
#endif /*0*/
}

void
ospf6_asbr_external_lsa_add (struct ospf6_lsa *lsa)
{
  struct ospf6_lsa_as_external *external;
  struct prefix_ls asbr_id;
  struct ospf6_route_req asbr_entry;
  struct ospf6_route_req request;

  external = OSPF6_LSA_HEADER_END (lsa->header);

  if (IS_LSA_MAXAGE (lsa))
    {
      if (IS_OSPF6_DUMP_ASBR)
        zlog_info ("ASBR: maxage external lsa: %s seq: %lx",
                   lsa->str, (u_long)ntohl (lsa->header->seqnum));
      ospf6_asbr_external_lsa_remove (lsa);
      return;
    }

  if (IS_OSPF6_DUMP_ASBR)
    zlog_info ("ASBR: new external lsa: %s seq: %lx",
               lsa->str, (u_long)ntohl (lsa->header->seqnum));

  if (lsa->header->adv_router == ospf6->router_id)
    {
      if (IS_OSPF6_DUMP_ASBR)
        zlog_info ("ASBR: my external LSA, ignore");
      return;
    }

  if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
    {
      if (IS_OSPF6_DUMP_ASBR)
        zlog_info ("ASBR: metric is infinity, ignore");
      return;
    }

  memset (&asbr_id, 0, sizeof (asbr_id));
  asbr_id.family = AF_UNSPEC;
  asbr_id.prefixlen = 64; /* xxx */
  asbr_id.adv_router.s_addr = lsa->header->adv_router;

  ospf6_route_lookup (&asbr_entry, (struct prefix *) &asbr_id,
                      ospf6->topology_table);

  if (ospf6_route_end (&asbr_entry))
    {
      if (IS_OSPF6_DUMP_ASBR)
        {
          char buf[64];
          inet_ntop (AF_INET, &asbr_id.adv_router, buf, sizeof (buf));
          zlog_info ("ASBR: router %s not found, ignore", buf);
        }
      return;
    }

  memset (&request, 0, sizeof (request));
  request.route.type = OSPF6_DEST_TYPE_NETWORK;
  request.route.prefix.family = AF_INET6;
  request.route.prefix.prefixlen = external->prefix.prefix_length;
  memcpy (&request.route.prefix.u.prefix6, (char *)(external + 1),
          OSPF6_PREFIX_SPACE (request.route.prefix.prefixlen));

  request.path.area_id = asbr_entry.path.area_id;
  request.path.origin.type = htons (OSPF6_LSA_TYPE_AS_EXTERNAL);
  request.path.origin.id = lsa->header->id;
  request.path.origin.adv_router = lsa->header->adv_router;
  if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
    {
      request.path.type = OSPF6_PATH_TYPE_EXTERNAL2;
      request.path.metric_type = 2;
      request.path.cost = asbr_entry.path.cost;
      request.path.cost_e2 = OSPF6_ASBR_METRIC (external);
    }
  else
    {
      request.path.type = OSPF6_PATH_TYPE_EXTERNAL1;
      request.path.metric_type = 1;
      request.path.cost = asbr_entry.path.cost
                          + OSPF6_ASBR_METRIC (external);
      request.path.cost_e2 = 0;
    }
  request.path.prefix_options = external->prefix.prefix_options;

  while (((struct prefix_ls *)&asbr_entry.route.prefix)->adv_router.s_addr ==
         asbr_id.adv_router.s_addr &&
         asbr_entry.route.type == OSPF6_DEST_TYPE_ROUTER)
    {
      memcpy (&request.nexthop, &asbr_entry.nexthop,
              sizeof (struct ospf6_nexthop));
      if (IS_OSPF6_DUMP_ASBR)
        {
          char buf[64], nhop[64], ifname[IFNAMSIZ];
          prefix2str (&request.route.prefix, buf, sizeof (buf));
          inet_ntop (AF_INET6, &request.nexthop.address, nhop, sizeof (nhop));
          if_indextoname (request.nexthop.ifindex, ifname);
          zlog_info ("ASBR: add route: %s %s%%%s", buf, nhop, ifname);
        }
      ospf6_route_add (&request, ospf6->route_table);
      ospf6_route_next (&asbr_entry);
    }
}

void
ospf6_asbr_external_lsa_remove (struct ospf6_lsa *lsa)
{
  struct ospf6_lsa_as_external *external;
  struct prefix dest;
  char buf[64];
  struct ospf6_route_req request;

  if (IS_OSPF6_DUMP_ASBR)
    zlog_info ("ASBR: withdraw external lsa: %s seq: %lx",
               lsa->str, (u_long)ntohl (lsa->header->seqnum));

  if (lsa->header->adv_router == ospf6->router_id)
    {
      if (IS_OSPF6_DUMP_ASBR)
        zlog_info ("ASBR: my external LSA, ignore");
      return;
    }

  external = OSPF6_LSA_HEADER_END (lsa->header);
  memset (&dest, 0, sizeof (dest));
  dest.family = AF_INET6;
  dest.prefixlen = external->prefix.prefix_length;
  memcpy (&dest.u.prefix6, (char *)(external + 1),
          OSPF6_PREFIX_SPACE (dest.prefixlen));

  ospf6_route_lookup (&request, &dest, ospf6->route_table);
  if (ospf6_route_end (&request))
    {
      if (IS_OSPF6_DUMP_ASBR)
        {
          prefix2str (&dest, buf, sizeof (buf));
          zlog_info ("ASBR: %s not found", buf);
        }
      return;
    }

  while (request.path.origin.id != lsa->header->id ||
         request.path.origin.adv_router != lsa->header->adv_router)
    {
      if (prefix_same (&request.route.prefix, &dest) != 1)
        {
          if (IS_OSPF6_DUMP_ASBR)
            zlog_info ("ASBR:   Can't find the entry matches the origin");
          return;
        }
      ospf6_route_next (&request);
    }
  assert (request.path.origin.id == lsa->header->id);
  assert (request.path.origin.adv_router == request.path.origin.adv_router);

  while (request.path.origin.id == lsa->header->id &&
         request.path.origin.adv_router == lsa->header->adv_router &&
         prefix_same (&request.route.prefix, &dest) == 1)
    {
      if (IS_OSPF6_DUMP_ASBR)
        {
          char nhop[64], ifname[IFNAMSIZ];
          prefix2str (&dest, buf, sizeof (buf));
          inet_ntop (AF_INET6, &request.nexthop.address, nhop, sizeof (nhop));
          if_indextoname (request.nexthop.ifindex, ifname);
          zlog_info ("ASBR: remove route: %s %s%%%s", buf, nhop, ifname);
        }

      ospf6_route_remove (&request, ospf6->route_table);
      ospf6_route_next (&request);
    }
}

void
ospf6_asbr_external_lsa_change (struct ospf6_lsa *old, struct ospf6_lsa *new)
{
  assert (old || new);

  if (old == NULL)
    ospf6_asbr_external_lsa_add (new);
  else if (new == NULL)
    ospf6_asbr_external_lsa_remove (old);
  else
    {
      ospf6_route_table_freeze (ospf6->route_table);
      ospf6_asbr_external_lsa_remove (old);
      ospf6_asbr_external_lsa_add (new);
      ospf6_route_table_thaw (ospf6->route_table);
    }
}

void
ospf6_asbr_asbr_entry_add (struct ospf6_route_req *topo_entry)
{
  struct ospf6_lsdb_node node;

  struct prefix_ls *inter_router;
  u_int32_t id, adv_router;

  inter_router = (struct prefix_ls *) &topo_entry->route.prefix;
  id = inter_router->id.s_addr;
  adv_router = inter_router->adv_router.s_addr;

  if (IS_OSPF6_DUMP_ASBR)
    {
      char buf[64];
      inet_ntop (AF_INET, &inter_router->adv_router, buf, sizeof (buf));
      zlog_info ("ASBR: new router found: %s", buf);
    }

  if (ntohl (id) != 0 ||
      ! OSPF6_OPT_ISSET (topo_entry->path.capability, OSPF6_OPT_E))
    {
      zlog_warn ("ASBR: Inter topology table malformed");
      return;
    }

  for (ospf6_lsdb_type_router (&node, htons (OSPF6_LSA_TYPE_AS_EXTERNAL),
                               adv_router, ospf6->lsdb);
       ! ospf6_lsdb_is_end (&node);
       ospf6_lsdb_next (&node))
    ospf6_asbr_external_lsa_add (node.lsa);
}

void
ospf6_asbr_asbr_entry_remove (struct ospf6_route_req *topo_entry)
{
  struct prefix_ls *inter_router;
  u_int32_t id, adv_router;
  struct ospf6_route_req request;

  inter_router = (struct prefix_ls *) &topo_entry->route.prefix;
  id = inter_router->id.s_addr;
  adv_router = inter_router->adv_router.s_addr;

  if (IS_OSPF6_DUMP_ASBR)
    {
      char buf[64];
      inet_ntop (AF_INET, &inter_router->adv_router, buf, sizeof (buf));
      zlog_info ("ASBR: router disappearing: %s", buf);
    }

  if (ntohl (id) != 0 ||
      ! OSPF6_OPT_ISSET (topo_entry->path.capability, OSPF6_OPT_E))
    {
      zlog_warn ("ASBR: Inter topology table malformed");
    }

  for (ospf6_route_head (&request, ospf6->route_table);
       ! ospf6_route_end (&request);
       ospf6_route_next (&request))
    {
      if (request.path.type != OSPF6_PATH_TYPE_EXTERNAL1 &&
          request.path.type != OSPF6_PATH_TYPE_EXTERNAL2)
        continue;
      if (request.path.area_id != topo_entry->path.area_id)
        continue;
      if (request.path.origin.adv_router != topo_entry->path.origin.adv_router)
        continue;
      if (memcmp (&topo_entry->nexthop, &request.nexthop,
                  sizeof (struct ospf6_nexthop)))
        continue;

      ospf6_route_remove (&request, ospf6->route_table);
    }
}

int
ospf6_asbr_external_show (struct vty *vty, struct ospf6_lsa *lsa)
{
  struct ospf6_lsa_as_external *external;
  char buf[128], *ptr;
  struct in6_addr in6;

  assert (lsa->header);
  external = (struct ospf6_lsa_as_external *)(lsa->header + 1);
  
  /* bits */
  snprintf (buf, sizeof (buf), "%s%s%s",
            (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ?
             "E" : "-"),
            (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ?
             "F" : "-"),
            (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ?
             "T" : "-"));

  vty_out (vty, "     Bits: %s%s", buf, VTY_NEWLINE);
  vty_out (vty, "     Metric: %5lu%s", (u_long)OSPF6_ASBR_METRIC (external),
           VTY_NEWLINE);

  ospf6_prefix_options_str (external->prefix.prefix_options,
                            buf, sizeof (buf));
  vty_out (vty, "     Prefix Options: %s%s", buf, VTY_NEWLINE);

  vty_out (vty, "     Referenced LSType: %d%s",
           ntohs (external->prefix.prefix_refer_lstype), VTY_NEWLINE);

  ospf6_prefix_in6_addr (&external->prefix, &in6);
  inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
  vty_out (vty, "     Prefix: %s/%d%s",
           buf, external->prefix.prefix_length, VTY_NEWLINE);

  /* Forwarding-Address */
  if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
    {
      ptr = ((char *)(external + 1))
            + OSPF6_PREFIX_SPACE (external->prefix.prefix_length);
      inet_ntop (AF_INET6, (struct in6_addr *) ptr, buf, sizeof (buf));
      vty_out (vty, "     Forwarding-Address: %s%s", buf, VTY_NEWLINE);
    }

  return 0;
}

void
ospf6_asbr_database_hook (struct ospf6_lsa *old, struct ospf6_lsa *new)
{
  if (old)
    ospf6_asbr_external_lsa_remove (old);
  if (new && ! IS_LSA_MAXAGE (new))
    ospf6_asbr_external_lsa_add (new);
}

void
ospf6_asbr_register_as_external ()
{
  struct ospf6_lsa_slot slot;

  memset (&slot, 0, sizeof (slot));
  slot.type              = htons (OSPF6_LSA_TYPE_AS_EXTERNAL);
  slot.name              = "AS-External";
  slot.func_show         = ospf6_asbr_external_show;
  slot.func_refresh      = ospf6_asbr_external_lsa_refresh;
  ospf6_lsa_slot_register (&slot);

  ospf6_lsdb_hook[OSPF6_LSA_TYPE_AS_EXTERNAL & OSPF6_LSTYPE_CODE_MASK].hook = 
    ospf6_asbr_database_hook;
}

void
ospf6_asbr_external_info_show (struct vty *vty,
                               struct ospf6_external_info *info)
{
  char prefix_buf[64], id_buf[16];
  struct in_addr id;

  if (info->is_removed)
    return;

  id.s_addr = ntohl (info->id);
  inet_ntop (AF_INET, &id, id_buf, sizeof (id_buf));
  prefix2str (&info->route->prefix, prefix_buf, sizeof (prefix_buf));
  vty_out (vty, "%s %-32s %3d %-15s %3d %lu(type-%d)%s",
           ZROUTE_ABNAME(info->type), prefix_buf, info->ifindex, id_buf,
           info->nexthop_num, (u_long) info->metric, info->metric_type,
           VTY_NEWLINE);
}

void
ospf6_asbr_external_route_show (struct vty *vty,
                                struct ospf6_external_route *route)
{
  struct ospf6_external_info *info;
  for (info = route->info_head; info; info = info->next)
    ospf6_asbr_external_info_show (vty, info);
}

DEFUN (show_ipv6_route_ospf6_external,
       show_ipv6_route_ospf6_external_cmd,
       "show ipv6 ospf6 route redistribute",
       SHOW_STR
       IP6_STR
       ROUTE_STR
       OSPF6_STR
       "redistributing External information\n"
       )
{
  struct route_node *node;
  struct ospf6_external_route *route;

  vty_out (vty, "%s %-32s %3s %-15s %3s %s%s",
           " ", "Prefix", "I/F", "LS-Id", "#NH", "Metric",
           VTY_NEWLINE);
  for (node = route_top (external_table); node; node = route_next (node))
    {
      route = node->info;
      if (route)
        ospf6_asbr_external_route_show (vty, route);
    }
  return CMD_SUCCESS;
}

void
ospf6_asbr_init ()
{
  external_table = route_table_init ();
  link_state_id = 0;

  ospf6_asbr_register_as_external ();

  install_element (VIEW_NODE, &show_ipv6_route_ospf6_external_cmd);
  install_element (ENABLE_NODE, &show_ipv6_route_ospf6_external_cmd);
  install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
  install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
  install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
}


