/*
 * 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;
  struct ospf6_external_info *info;

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

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

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 (! 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;

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


