2  * Copyright (C) 2003 Yasuhiro Ohara
 
   4  * This file is part of GNU Zebra.
 
   6  * GNU Zebra is free software; you can redistribute it and/or modify it
 
   7  * under the terms of the GNU General Public License as published by the
 
   8  * Free Software Foundation; either version 2, or (at your option) any
 
  11  * GNU Zebra is distributed in the hope that it will be useful, but
 
  12  * WITHOUT ANY WARRANTY; without even the implied warranty of
 
  13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
  14  * General Public License for more details.
 
  16  * You should have received a copy of the GNU General Public License
 
  17  * along with GNU Zebra; see the file COPYING.  If not, write to the 
 
  18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
 
  19  * Boston, MA 02111-1307, USA.  
 
  35 #include "ospf6_proto.h"
 
  36 #include "ospf6_lsa.h"
 
  37 #include "ospf6_lsdb.h"
 
  38 #include "ospf6_route.h"
 
  39 #include "ospf6_zebra.h"
 
  40 #include "ospf6_message.h"
 
  42 #include "ospf6_top.h"
 
  43 #include "ospf6_area.h"
 
  44 #include "ospf6_interface.h"
 
  45 #include "ospf6_neighbor.h"
 
  46 #include "ospf6_asbr.h"
 
  47 #include "ospf6_intra.h"
 
  48 #include "ospf6_flood.h"
 
  51 unsigned char conf_debug_ospf6_asbr = 0;
 
  53 #define ZROUTE_NAME(x) zebra_route_string(x)
 
  55 /* AS External LSA origination */
 
  57 ospf6_as_external_lsa_originate (struct ospf6_route *route)
 
  59   char buffer[OSPF6_MAX_LSASIZE];
 
  60   struct ospf6_lsa_header *lsa_header;
 
  61   struct ospf6_lsa *lsa;
 
  62   struct ospf6_external_info *info = route->route_option;
 
  64   struct ospf6_as_external_lsa *as_external_lsa;
 
  68   if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
 
  70       prefix2str (&route->prefix, buf, sizeof (buf));
 
  71       zlog_debug ("Originate AS-External-LSA for %s", buf);
 
  75   memset (buffer, 0, sizeof (buffer));
 
  76   lsa_header = (struct ospf6_lsa_header *) buffer;
 
  77   as_external_lsa = (struct ospf6_as_external_lsa *)
 
  78     ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
 
  80     ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
 
  82   /* Fill AS-External-LSA */
 
  84   if (route->path.metric_type == 2)
 
  85     SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
 
  87     UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
 
  89   /* forwarding address */
 
  90   if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
 
  91     SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
 
  93     UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
 
  95   /* external route tag */
 
  97     SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
 
  99     UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
 
 102   OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
 
 105   as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
 
 108   as_external_lsa->prefix.prefix_options = route->path.prefix_options;
 
 110   /* don't use refer LS-type */
 
 111   as_external_lsa->prefix.prefix_refer_lstype = htons (0);
 
 114   memcpy (p, &route->prefix.u.prefix6,
 
 115           OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
 
 116   ospf6_prefix_apply_mask (&as_external_lsa->prefix);
 
 117   p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
 
 119   /* Forwarding address */
 
 120   if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
 
 122       memcpy (p, &info->forwarding, sizeof (struct in6_addr));
 
 123       p += sizeof (struct in6_addr);
 
 126   /* External Route Tag */
 
 127   if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
 
 129       route_tag_t network_order = htonl(info->tag);
 
 131       memcpy (p, &network_order, sizeof(network_order));
 
 132       p += sizeof(network_order);
 
 135   /* Fill LSA Header */
 
 137   lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
 
 138   lsa_header->id = route->path.origin.id;
 
 139   lsa_header->adv_router = ospf6->router_id;
 
 141     ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
 
 142                          lsa_header->adv_router, ospf6->lsdb);
 
 143   lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
 
 146   ospf6_lsa_checksum (lsa_header);
 
 149   lsa = ospf6_lsa_create (lsa_header);
 
 152   ospf6_lsa_originate_process (lsa, ospf6);
 
 156 ospf6_as_external_lsa_get_tag (struct ospf6_lsa *lsa)
 
 158   struct ospf6_as_external_lsa *external;
 
 159   ptrdiff_t tag_offset;
 
 160   route_tag_t network_order;
 
 165   external = (struct ospf6_as_external_lsa *)
 
 166     OSPF6_LSA_HEADER_END (lsa->header);
 
 168   if (!CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T))
 
 171   tag_offset = sizeof(*external) + OSPF6_PREFIX_SPACE(external->prefix.prefix_length);
 
 172   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
 
 173     tag_offset += sizeof(struct in6_addr);
 
 175   memcpy(&network_order, (caddr_t)external + tag_offset, sizeof(network_order));
 
 176   return ntohl(network_order);
 
 180 ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
 
 182   struct ospf6_as_external_lsa *external;
 
 183   struct prefix asbr_id;
 
 184   struct ospf6_route *asbr_entry, *route;
 
 188   external = (struct ospf6_as_external_lsa *)
 
 189     OSPF6_LSA_HEADER_END (lsa->header);
 
 191   if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 192     zlog_debug ("Calculate AS-External route for %s", lsa->name);
 
 194   if (lsa->header->adv_router == ospf6->router_id)
 
 196       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 197         zlog_debug ("Ignore self-originated AS-External-LSA");
 
 201   if (OSPF6_ASBR_METRIC (external) == OSPF_LS_INFINITY)
 
 203       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 204         zlog_debug ("Ignore LSA with LSInfinity Metric");
 
 208   if (CHECK_FLAG(external->prefix.prefix_options, OSPF6_PREFIX_OPTION_NU))
 
 210       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 211         zlog_debug ("Ignore LSA with NU bit set Metric");
 
 215   ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
 
 216   asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
 
 217   if (asbr_entry == NULL ||
 
 218       ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
 
 220       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 222           prefix2str (&asbr_id, buf, sizeof (buf));
 
 223           zlog_debug ("ASBR entry not found: %s", buf);
 
 228   route = ospf6_route_create ();
 
 229   route->type = OSPF6_DEST_TYPE_NETWORK;
 
 230   route->prefix.family = AF_INET6;
 
 231   route->prefix.prefixlen = external->prefix.prefix_length;
 
 232   ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
 
 234   route->path.area_id = asbr_entry->path.area_id;
 
 235   route->path.origin.type = lsa->header->type;
 
 236   route->path.origin.id = lsa->header->id;
 
 237   route->path.origin.adv_router = lsa->header->adv_router;
 
 239   route->path.prefix_options = external->prefix.prefix_options;
 
 240   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
 
 242       route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
 
 243       route->path.metric_type = 2;
 
 244       route->path.cost = asbr_entry->path.cost;
 
 245       route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
 
 249       route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
 
 250       route->path.metric_type = 1;
 
 251       route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
 
 252       route->path.cost_e2 = 0;
 
 255   route->path.tag = ospf6_as_external_lsa_get_tag (lsa);
 
 257   for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
 
 258     ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
 
 260   if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 262       prefix2str (&route->prefix, buf, sizeof (buf));
 
 263       zlog_debug ("AS-External route add: %s", buf);
 
 266   ospf6_route_add (route, ospf6->route_table);
 
 270 ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
 
 272   struct ospf6_as_external_lsa *external;
 
 273   struct prefix prefix;
 
 274   struct ospf6_route *route, *nroute;
 
 277   external = (struct ospf6_as_external_lsa *)
 
 278     OSPF6_LSA_HEADER_END (lsa->header);
 
 280   if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 281     zlog_debug ("Withdraw AS-External route for %s", lsa->name);
 
 283   if (lsa->header->adv_router == ospf6->router_id)
 
 285       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 286         zlog_debug ("Ignore self-originated AS-External-LSA");
 
 290   memset (&prefix, 0, sizeof (struct prefix));
 
 291   prefix.family = AF_INET6;
 
 292   prefix.prefixlen = external->prefix.prefix_length;
 
 293   ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
 
 295   route = ospf6_route_lookup (&prefix, ospf6->route_table);
 
 298       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 300           prefix2str (&prefix, buf, sizeof (buf));
 
 301           zlog_debug ("AS-External route %s not found", buf);
 
 306   for (ospf6_route_lock (route);
 
 307        route && ospf6_route_is_prefix (&prefix, route);
 
 310       nroute = ospf6_route_next (route);
 
 311       if (route->type != OSPF6_DEST_TYPE_NETWORK)
 
 313       if (route->path.origin.type != lsa->header->type)
 
 315       if (route->path.origin.id != lsa->header->id)
 
 317       if (route->path.origin.adv_router != lsa->header->adv_router)
 
 320       if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
 
 322           prefix2str (&route->prefix, buf, sizeof (buf));
 
 323           zlog_debug ("AS-External route remove: %s", buf);
 
 325       ospf6_route_remove (route, ospf6->route_table);
 
 328     ospf6_route_unlock (route);
 
 332 ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
 
 334   struct ospf6_lsa *lsa;
 
 338   if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST))
 
 341       inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&asbr_entry->prefix),
 
 343        zlog_info ("ignore non-best path: lsentry %s add", buf);
 
 347   type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
 
 348   router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
 
 349   for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa;
 
 350        lsa = ospf6_lsdb_type_router_next (type, router, lsa))
 
 352       if (! OSPF6_LSA_IS_MAXAGE (lsa))
 
 353         ospf6_asbr_lsa_add (lsa);
 
 358 ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
 
 360   struct ospf6_lsa *lsa;
 
 364   type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
 
 365   router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
 
 366   for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
 
 367        lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
 
 368     ospf6_asbr_lsa_remove (lsa);
 
 373 /* redistribute function */
 
 376 ospf6_asbr_routemap_set (int type, const char *mapname)
 
 378   if (ospf6->rmap[type].name)
 
 379     free (ospf6->rmap[type].name);
 
 380   ospf6->rmap[type].name = strdup (mapname);
 
 381   ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
 
 385 ospf6_asbr_routemap_unset (int type)
 
 387   if (ospf6->rmap[type].name)
 
 388     free (ospf6->rmap[type].name);
 
 389   ospf6->rmap[type].name = NULL;
 
 390   ospf6->rmap[type].map = NULL;
 
 394 ospf6_asbr_routemap_update (const char *mapname)
 
 401   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
 
 403       if (ospf6->rmap[type].name)
 
 404         ospf6->rmap[type].map =
 
 405           route_map_lookup_by_name (ospf6->rmap[type].name);
 
 407         ospf6->rmap[type].map = NULL;
 
 412 ospf6_asbr_is_asbr (struct ospf6 *o)
 
 414   return o->external_table->count;
 
 418 ospf6_asbr_redistribute_set (int type)
 
 420   ospf6_zebra_redistribute (type);
 
 424 ospf6_asbr_redistribute_unset (int type)
 
 426   struct ospf6_route *route;
 
 427   struct ospf6_external_info *info;
 
 429   ospf6_zebra_no_redistribute (type);
 
 431   for (route = ospf6_route_head (ospf6->external_table); route;
 
 432        route = ospf6_route_next (route))
 
 434       info = route->route_option;
 
 435       if (info->type != type)
 
 438       ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
 
 442   ospf6_asbr_routemap_unset (type);
 
 446 ospf6_asbr_redistribute_add (int type, ifindex_t ifindex, struct prefix *prefix,
 
 447                              u_int nexthop_num, struct in6_addr *nexthop, route_tag_t tag)
 
 450   struct ospf6_route troute;
 
 451   struct ospf6_external_info tinfo;
 
 452   struct ospf6_route *route, *match;
 
 453   struct ospf6_external_info *info;
 
 454   struct prefix prefix_id;
 
 455   struct route_node *node;
 
 456   char pbuf[64], ibuf[16];
 
 457   struct listnode *lnode, *lnnode;
 
 458   struct ospf6_area *oa;
 
 460   if (! ospf6_zebra_is_redistribute (type))
 
 463   if (IS_OSPF6_DEBUG_ASBR)
 
 465       prefix2str (prefix, pbuf, sizeof (pbuf));
 
 466       zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
 
 469   /* if route-map was specified but not found, do not advertise */
 
 470   if (ospf6->rmap[type].name)
 
 472       if (ospf6->rmap[type].map == NULL)
 
 473         ospf6_asbr_routemap_update (NULL);
 
 474       if (ospf6->rmap[type].map == NULL)
 
 476           zlog_warn ("route-map \"%s\" not found, suppress redistributing",
 
 477                      ospf6->rmap[type].name);
 
 482   /* apply route-map */
 
 483   if (ospf6->rmap[type].map)
 
 485       memset (&troute, 0, sizeof (troute));
 
 486       memset (&tinfo, 0, sizeof (tinfo));
 
 487       troute.route_option = &tinfo;
 
 488       tinfo.ifindex = ifindex;
 
 491       ret = route_map_apply (ospf6->rmap[type].map, prefix,
 
 492                              RMAP_OSPF6, &troute);
 
 493       if (ret == RMAP_DENYMATCH)
 
 495           if (IS_OSPF6_DEBUG_ASBR)
 
 496             zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
 
 501   match = ospf6_route_lookup (prefix, ospf6->external_table);
 
 504       info = match->route_option;
 
 506       /* copy result of route-map */
 
 507       if (ospf6->rmap[type].map)
 
 509           if (troute.path.metric_type)
 
 510             match->path.metric_type = troute.path.metric_type;
 
 511           if (troute.path.cost)
 
 512             match->path.cost = troute.path.cost;
 
 513           if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
 
 514             memcpy (&info->forwarding, &tinfo.forwarding,
 
 515                     sizeof (struct in6_addr));
 
 516           info->tag = tinfo.tag;
 
 520           /* If there is no route-map, simply update the tag */
 
 525       match->nexthop[0].ifindex = ifindex;
 
 526       if (nexthop_num && nexthop)
 
 527         memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
 
 529       /* create/update binding in external_id_table */
 
 530       prefix_id.family = AF_INET;
 
 531       prefix_id.prefixlen = 32;
 
 532       prefix_id.u.prefix4.s_addr = htonl (info->id);
 
 533       node = route_node_get (ospf6->external_id_table, &prefix_id);
 
 536       if (IS_OSPF6_DEBUG_ASBR)
 
 538           inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
 
 539           zlog_debug ("Advertise as AS-External Id:%s", ibuf);
 
 542       match->path.origin.id = htonl (info->id);
 
 543       ospf6_as_external_lsa_originate (match);
 
 547   /* create new entry */
 
 548   route = ospf6_route_create ();
 
 549   route->type = OSPF6_DEST_TYPE_NETWORK;
 
 550   memcpy (&route->prefix, prefix, sizeof (struct prefix));
 
 552   info = (struct ospf6_external_info *)
 
 553     XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
 
 554   route->route_option = info;
 
 555   info->id = ospf6->external_id++;
 
 557   /* copy result of route-map */
 
 558   if (ospf6->rmap[type].map)
 
 560       if (troute.path.metric_type)
 
 561         route->path.metric_type = troute.path.metric_type;
 
 562       if (troute.path.cost)
 
 563         route->path.cost = troute.path.cost;
 
 564       if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
 
 565         memcpy (&info->forwarding, &tinfo.forwarding,
 
 566                 sizeof (struct in6_addr));
 
 567       info->tag = tinfo.tag;
 
 571       /* If there is no route-map, simply set the tag */
 
 576   route->nexthop[0].ifindex = ifindex;
 
 577   if (nexthop_num && nexthop)
 
 578     memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
 
 580   /* create/update binding in external_id_table */
 
 581   prefix_id.family = AF_INET;
 
 582   prefix_id.prefixlen = 32;
 
 583   prefix_id.u.prefix4.s_addr = htonl (info->id);
 
 584   node = route_node_get (ospf6->external_id_table, &prefix_id);
 
 587   route = ospf6_route_add (route, ospf6->external_table);
 
 588   route->route_option = info;
 
 590   if (IS_OSPF6_DEBUG_ASBR)
 
 592       inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
 
 593       zlog_debug ("Advertise as AS-External Id:%s", ibuf);
 
 596   route->path.origin.id = htonl (info->id);
 
 597   ospf6_as_external_lsa_originate (route);
 
 599   /* Router-Bit (ASBR Flag) may have to be updated */
 
 600   for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
 
 601     OSPF6_ROUTER_LSA_SCHEDULE (oa);
 
 605 ospf6_asbr_redistribute_remove (int type, ifindex_t ifindex,
 
 606                                 struct prefix *prefix)
 
 608   struct ospf6_route *match;
 
 609   struct ospf6_external_info *info = NULL;
 
 610   struct route_node *node;
 
 611   struct ospf6_lsa *lsa;
 
 612   struct prefix prefix_id;
 
 613   char pbuf[64], ibuf[16];
 
 614   struct listnode *lnode, *lnnode;
 
 615   struct ospf6_area *oa;
 
 617   match = ospf6_route_lookup (prefix, ospf6->external_table);
 
 620       if (IS_OSPF6_DEBUG_ASBR)
 
 622           prefix2str (prefix, pbuf, sizeof (pbuf));
 
 623           zlog_debug ("No such route %s to withdraw", pbuf);
 
 628   info = match->route_option;
 
 631   if (info->type != type)
 
 633       if (IS_OSPF6_DEBUG_ASBR)
 
 635           prefix2str (prefix, pbuf, sizeof (pbuf));
 
 636           zlog_debug ("Original protocol mismatch: %s", pbuf);
 
 641   if (IS_OSPF6_DEBUG_ASBR)
 
 643       prefix2str (prefix, pbuf, sizeof (pbuf));
 
 644       inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
 
 645       zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
 
 648   lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
 
 649                            htonl (info->id), ospf6->router_id, ospf6->lsdb);
 
 651     ospf6_lsa_purge (lsa);
 
 653   /* remove binding in external_id_table */
 
 654   prefix_id.family = AF_INET;
 
 655   prefix_id.prefixlen = 32;
 
 656   prefix_id.u.prefix4.s_addr = htonl (info->id);
 
 657   node = route_node_lookup (ospf6->external_id_table, &prefix_id);
 
 660   route_unlock_node (node);
 
 662   ospf6_route_remove (match, ospf6->external_table);
 
 663   XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
 
 665   /* Router-Bit (ASBR Flag) may have to be updated */
 
 666   for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
 
 667     OSPF6_ROUTER_LSA_SCHEDULE (oa);
 
 670 DEFUN (ospf6_redistribute,
 
 671        ospf6_redistribute_cmd,
 
 672        "redistribute " QUAGGA_REDIST_STR_OSPF6D,
 
 674        QUAGGA_REDIST_HELP_STR_OSPF6D
 
 679   type = proto_redistnum(AFI_IP6, argv[0]);
 
 680   if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
 
 683   ospf6_asbr_redistribute_unset (type);
 
 684   ospf6_asbr_redistribute_set (type);
 
 688 DEFUN (ospf6_redistribute_routemap,
 
 689        ospf6_redistribute_routemap_cmd,
 
 690        "redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD",
 
 692        QUAGGA_REDIST_HELP_STR_OSPF6D
 
 693        "Route map reference\n"
 
 699   type = proto_redistnum(AFI_IP6, argv[0]);
 
 700   if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
 
 703   ospf6_asbr_redistribute_unset (type);
 
 704   ospf6_asbr_routemap_set (type, argv[1]);
 
 705   ospf6_asbr_redistribute_set (type);
 
 709 DEFUN (no_ospf6_redistribute,
 
 710        no_ospf6_redistribute_cmd,
 
 711        "no redistribute " QUAGGA_REDIST_STR_OSPF6D,
 
 714        QUAGGA_REDIST_HELP_STR_OSPF6D
 
 719   type = proto_redistnum(AFI_IP6, argv[0]);
 
 720   if (type < 0 || type == ZEBRA_ROUTE_OSPF6)
 
 723   ospf6_asbr_redistribute_unset (type);
 
 728 ALIAS (no_ospf6_redistribute,
 
 729        no_ospf6_redistribute_route_map_cmd,
 
 730        "no redistribute " QUAGGA_REDIST_STR_OSPF6D " route-map WORD",
 
 733        QUAGGA_REDIST_HELP_STR_OSPF6D
 
 734        "Route map reference\n"
 
 738 ospf6_redistribute_config_write (struct vty *vty)
 
 742   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
 
 744       if (type == ZEBRA_ROUTE_OSPF6)
 
 746       if (! ospf6_zebra_is_redistribute (type))
 
 749       if (ospf6->rmap[type].name)
 
 750         vty_out (vty, " redistribute %s route-map %s%s",
 
 751                  ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
 
 753         vty_out (vty, " redistribute %s%s",
 
 754                  ZROUTE_NAME (type), VNL);
 
 761 ospf6_redistribute_show_config (struct vty *vty)
 
 764   int nroute[ZEBRA_ROUTE_MAX];
 
 766   struct ospf6_route *route;
 
 767   struct ospf6_external_info *info;
 
 770   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
 
 772   for (route = ospf6_route_head (ospf6->external_table); route;
 
 773        route = ospf6_route_next (route))
 
 775       info = route->route_option;
 
 776       nroute[info->type]++;
 
 780   vty_out (vty, "Redistributing External Routes from:%s", VNL);
 
 781   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
 
 783       if (type == ZEBRA_ROUTE_OSPF6)
 
 785       if (! ospf6_zebra_is_redistribute (type))
 
 788       if (ospf6->rmap[type].name)
 
 789         vty_out (vty, "    %d: %s with route-map \"%s\"%s%s", nroute[type],
 
 790                  ZROUTE_NAME (type), ospf6->rmap[type].name,
 
 791                  (ospf6->rmap[type].map ? "" : " (not found !)"),
 
 794         vty_out (vty, "    %d: %s%s", nroute[type],
 
 795                  ZROUTE_NAME (type), VNL);
 
 797   vty_out (vty, "Total %d routes%s", total, VNL);
 
 802 /* Routemap Functions */
 
 803 static route_map_result_t
 
 804 ospf6_routemap_rule_match_address_prefixlist (void *rule,
 
 805                                               struct prefix *prefix,
 
 806                                               route_map_object_t type,
 
 809   struct prefix_list *plist;
 
 811   if (type != RMAP_OSPF6)
 
 814   plist = prefix_list_lookup (AFI_IP6, (char *) rule);
 
 818   return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
 
 819           RMAP_NOMATCH : RMAP_MATCH);
 
 823 ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
 
 825   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 829 ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
 
 831   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 834 struct route_map_rule_cmd
 
 835 ospf6_routemap_rule_match_address_prefixlist_cmd =
 
 837   "ipv6 address prefix-list",
 
 838   ospf6_routemap_rule_match_address_prefixlist,
 
 839   ospf6_routemap_rule_match_address_prefixlist_compile,
 
 840   ospf6_routemap_rule_match_address_prefixlist_free,
 
 843 /* `match interface IFNAME' */
 
 844 /* Match function should return 1 if match is success else return
 
 846 static route_map_result_t
 
 847 ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix,
 
 848                        route_map_object_t type, void *object)
 
 850   struct interface   *ifp;
 
 851   struct ospf6_external_info *ei;
 
 853   if (type == RMAP_OSPF6)
 
 855       ei = ((struct ospf6_route *) object)->route_option;
 
 856       ifp = if_lookup_by_name ((char *)rule);
 
 859       &&  ei->ifindex == ifp->ifindex)
 
 866 /* Route map `interface' match statement.  `arg' should be
 
 869 ospf6_routemap_rule_match_interface_compile (const char *arg)
 
 871   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 874 /* Free route map's compiled `interface' value. */
 
 876 ospf6_routemap_rule_match_interface_free (void *rule)
 
 878   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 881 /* Route map commands for interface matching. */
 
 882 struct route_map_rule_cmd
 
 883 ospf6_routemap_rule_match_interface_cmd =
 
 886   ospf6_routemap_rule_match_interface,
 
 887   ospf6_routemap_rule_match_interface_compile,
 
 888   ospf6_routemap_rule_match_interface_free
 
 891 /* Match function for matching route tags */
 
 892 static route_map_result_t
 
 893 ospf6_routemap_rule_match_tag (void *rule, struct prefix *prefix,
 
 894                                route_map_object_t type, void *object)
 
 896   route_tag_t *tag = rule;
 
 897   struct ospf6_route *route = object;
 
 898   struct ospf6_external_info *info = route->route_option;
 
 900   if (type == RMAP_OSPF6 && info->tag == *tag)
 
 906 static struct route_map_rule_cmd
 
 907 ospf6_routemap_rule_match_tag_cmd =
 
 910   ospf6_routemap_rule_match_tag,
 
 911   route_map_rule_tag_compile,
 
 912   route_map_rule_tag_free,
 
 915 static route_map_result_t
 
 916 ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
 
 917                                      route_map_object_t type, void *object)
 
 919   char *metric_type = rule;
 
 920   struct ospf6_route *route = object;
 
 922   if (type != RMAP_OSPF6)
 
 925   if (strcmp (metric_type, "type-2") == 0)
 
 926     route->path.metric_type = 2;
 
 928     route->path.metric_type = 1;
 
 934 ospf6_routemap_rule_set_metric_type_compile (const char *arg)
 
 936   if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
 
 938   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 942 ospf6_routemap_rule_set_metric_type_free (void *rule)
 
 944   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 947 struct route_map_rule_cmd
 
 948 ospf6_routemap_rule_set_metric_type_cmd =
 
 951   ospf6_routemap_rule_set_metric_type,
 
 952   ospf6_routemap_rule_set_metric_type_compile,
 
 953   ospf6_routemap_rule_set_metric_type_free,
 
 956 static route_map_result_t
 
 957 ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
 
 958                                 route_map_object_t type, void *object)
 
 961   struct ospf6_route *route = object;
 
 963   if (type != RMAP_OSPF6)
 
 966   route->path.cost = atoi (metric);
 
 971 ospf6_routemap_rule_set_metric_compile (const char *arg)
 
 975   metric = strtoul (arg, &endp, 0);
 
 976   if (metric > OSPF_LS_INFINITY || *endp != '\0')
 
 978   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
 982 ospf6_routemap_rule_set_metric_free (void *rule)
 
 984   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
 987 struct route_map_rule_cmd
 
 988 ospf6_routemap_rule_set_metric_cmd =
 
 991   ospf6_routemap_rule_set_metric,
 
 992   ospf6_routemap_rule_set_metric_compile,
 
 993   ospf6_routemap_rule_set_metric_free,
 
 996 static route_map_result_t
 
 997 ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
 
 998                                     route_map_object_t type, void *object)
 
1000   char *forwarding = rule;
 
1001   struct ospf6_route *route = object;
 
1002   struct ospf6_external_info *info = route->route_option;
 
1004   if (type != RMAP_OSPF6)
 
1007   if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
 
1009       memset (&info->forwarding, 0, sizeof (struct in6_addr));
 
1017 ospf6_routemap_rule_set_forwarding_compile (const char *arg)
 
1020   if (inet_pton (AF_INET6, arg, &a) != 1)
 
1022   return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
 
1026 ospf6_routemap_rule_set_forwarding_free (void *rule)
 
1028   XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
 
1031 struct route_map_rule_cmd
 
1032 ospf6_routemap_rule_set_forwarding_cmd =
 
1034   "forwarding-address",
 
1035   ospf6_routemap_rule_set_forwarding,
 
1036   ospf6_routemap_rule_set_forwarding_compile,
 
1037   ospf6_routemap_rule_set_forwarding_free,
 
1040 static route_map_result_t
 
1041 ospf6_routemap_rule_set_tag (void *rule, struct prefix *prefix,
 
1042                              route_map_object_t type, void *object)
 
1044   route_tag_t *tag = rule;
 
1045   struct ospf6_route *route = object;
 
1046   struct ospf6_external_info *info = route->route_option;
 
1048   if (type != RMAP_OSPF6)
 
1055 static struct route_map_rule_cmd
 
1056 ospf6_routemap_rule_set_tag_cmd =
 
1059   ospf6_routemap_rule_set_tag,
 
1060   route_map_rule_tag_compile,
 
1061   route_map_rule_tag_free,
 
1065 route_map_command_status (struct vty *vty, int ret)
 
1072     case RMAP_RULE_MISSING:
 
1073       vty_out (vty, "OSPF6 Can't find rule.%s", VNL);
 
1075     case RMAP_COMPILE_ERROR:
 
1076       vty_out (vty, "OSPF6 Argument is malformed.%s", VNL);
 
1079       vty_out (vty, "OSPF6 route-map add set failed.%s", VNL);
 
1085 /* add "match address" */
 
1086 DEFUN (ospf6_routemap_match_address_prefixlist,
 
1087        ospf6_routemap_match_address_prefixlist_cmd,
 
1088        "match ipv6 address prefix-list WORD",
 
1091        "Match address of route\n"
 
1092        "Match entries of prefix-lists\n"
 
1093        "IPv6 prefix-list name\n")
 
1095   int ret = route_map_add_match ((struct route_map_index *) vty->index,
 
1096                                  "ipv6 address prefix-list", argv[0]);
 
1097   return route_map_command_status (vty, ret);
 
1100 /* delete "match address" */
 
1101 DEFUN (ospf6_routemap_no_match_address_prefixlist,
 
1102        ospf6_routemap_no_match_address_prefixlist_cmd,
 
1103        "no match ipv6 address prefix-list WORD",
 
1107        "Match address of route\n"
 
1108        "Match entries of prefix-lists\n"
 
1109        "IPv6 prefix-list name\n")
 
1111   int ret = route_map_delete_match ((struct route_map_index *) vty->index,
 
1112                                     "ipv6 address prefix-list", argv[0]);
 
1113   return route_map_command_status (vty, ret);
 
1116 /* "match interface" */
 
1117 DEFUN (ospf6_routemap_match_interface,
 
1118        ospf6_routemap_match_interface_cmd,
 
1119        "match interface WORD",
 
1121        "Match first hop interface of route\n"
 
1124   return route_map_add_match ((struct route_map_index *) vty->index,
 
1125                               "interface", argv[0]);
 
1128 /* "no match interface WORD" */
 
1129 DEFUN (ospf6_routemap_no_match_interface,
 
1130        ospf6_routemap_no_match_interface_cmd,
 
1131        "no match interface",
 
1134        "Match first hop interface of route\n")
 
1136   int ret = route_map_delete_match ((struct route_map_index *) vty->index,
 
1137                                     "interface", (argc == 0) ? NULL : argv[0]);
 
1138   return route_map_command_status (vty, ret);
 
1141 ALIAS (ospf6_routemap_no_match_interface,
 
1142        ospf6_routemap_no_match_interface_val_cmd,
 
1143        "no match interface WORD",
 
1146        "Match first hop interface of route\n"
 
1149 /* add "match tag" */
 
1150 DEFUN (ospf6_routemap_match_tag,
 
1151        ospf6_routemap_match_tag_cmd,
 
1152        "match tag <1-4294967295>",
 
1154        "Tag value for routing protocol\n"
 
1157   int ret = route_map_add_match ((struct route_map_index *) vty->index,
 
1159   return route_map_command_status (vty, ret);
 
1162 /* delete "match tag" */
 
1163 DEFUN (ospf6_routemap_no_match_tag,
 
1164        ospf6_routemap_no_match_tag_cmd,
 
1168        "Tag value for routing protocol\n")
 
1170   int ret = route_map_delete_match ((struct route_map_index *) vty->index,
 
1171                                   "tag", argc ? argv[0] : NULL);
 
1172   return route_map_command_status (vty, ret);
 
1175 ALIAS (ospf6_routemap_no_match_tag,
 
1176        ospf6_routemap_no_match_tag_val_cmd,
 
1177        "no match tag <1-4294967295>",
 
1180        "Tag value for routing protocol\n"
 
1183 /* add "set metric-type" */
 
1184 DEFUN (ospf6_routemap_set_metric_type,
 
1185        ospf6_routemap_set_metric_type_cmd,
 
1186        "set metric-type (type-1|type-2)",
 
1189        "OSPF6 external type 1 metric\n"
 
1190        "OSPF6 external type 2 metric\n")
 
1192   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 
1193                                "metric-type", argv[0]);
 
1194   return route_map_command_status (vty, ret);
 
1197 /* delete "set metric-type" */
 
1198 DEFUN (ospf6_routemap_no_set_metric_type,
 
1199        ospf6_routemap_no_set_metric_type_cmd,
 
1200        "no set metric-type (type-1|type-2)",
 
1204        "OSPF6 external type 1 metric\n"
 
1205        "OSPF6 external type 2 metric\n")
 
1207   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 
1208                                   "metric-type", argv[0]);
 
1209   return route_map_command_status (vty, ret);
 
1212 /* add "set metric" */
 
1215        "set metric <0-4294967295>",
 
1220   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 
1222   return route_map_command_status (vty, ret);
 
1225 /* delete "set metric" */
 
1226 DEFUN (no_set_metric,
 
1231        "Metric value for destination routing protocol\n")
 
1236     ret = route_map_delete_set ((struct route_map_index *) vty->index,
 
1239     ret = route_map_delete_set ((struct route_map_index *) vty->index,
 
1241   return route_map_command_status (vty, ret);
 
1244 ALIAS (no_set_metric,
 
1245        no_set_metric_val_cmd,
 
1246        "no set metric <0-4294967295>",
 
1249        "Metric value for destination routing protocol\n"
 
1252 /* add "set forwarding-address" */
 
1253 DEFUN (ospf6_routemap_set_forwarding,
 
1254        ospf6_routemap_set_forwarding_cmd,
 
1255        "set forwarding-address X:X::X:X",
 
1257        "Forwarding Address\n"
 
1260   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 
1261                                "forwarding-address", argv[0]);
 
1262   return route_map_command_status (vty, ret);
 
1265 /* delete "set forwarding-address" */
 
1266 DEFUN (ospf6_routemap_no_set_forwarding,
 
1267        ospf6_routemap_no_set_forwarding_cmd,
 
1268        "no set forwarding-address X:X::X:X",
 
1271        "Forwarding Address\n"
 
1274   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 
1275                                   "forwarding-address", argv[0]);
 
1276   return route_map_command_status (vty, ret);
 
1280 DEFUN (ospf6_routemap_set_tag,
 
1281        ospf6_routemap_set_tag_cmd,
 
1282        "set tag <1-4294967295>",
 
1284        "Tag value for routing protocol\n"
 
1287   int ret = route_map_add_set ((struct route_map_index *) vty->index,
 
1289   return route_map_command_status (vty, ret);
 
1292 /* delete "set tag" */
 
1293 DEFUN (ospf6_routemap_no_set_tag,
 
1294        ospf6_routemap_no_set_tag_cmd,
 
1298        "Tag value for routing protocol\n")
 
1300   int ret = route_map_delete_set ((struct route_map_index *) vty->index,
 
1301                                   "tag", argc ? argv[0] : NULL);
 
1302   return route_map_command_status (vty, ret);
 
1305 ALIAS (ospf6_routemap_no_set_tag,
 
1306        ospf6_routemap_no_set_tag_val_cmd,
 
1307        "no set tag <1-4294967295>",
 
1310        "Tag value for routing protocol\n"
 
1314 ospf6_routemap_init (void)
 
1317   route_map_init_vty ();
 
1318   route_map_add_hook (ospf6_asbr_routemap_update);
 
1319   route_map_delete_hook (ospf6_asbr_routemap_update);
 
1321   route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
 
1322   route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
 
1323   route_map_install_match (&ospf6_routemap_rule_match_tag_cmd);
 
1325   route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
 
1326   route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
 
1327   route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
 
1328   route_map_install_set (&ospf6_routemap_rule_set_tag_cmd);
 
1330   /* Match address prefix-list */
 
1331   install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
 
1332   install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
 
1334   /* Match interface */
 
1335   install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd);
 
1336   install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd);
 
1337   install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd);
 
1340   install_element (RMAP_NODE, &ospf6_routemap_match_tag_cmd);
 
1341   install_element (RMAP_NODE, &ospf6_routemap_no_match_tag_cmd);
 
1342   install_element (RMAP_NODE, &ospf6_routemap_no_match_tag_val_cmd);
 
1344   /* ASE Metric Type (e.g. Type-1/Type-2) */
 
1345   install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
 
1346   install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
 
1349   install_element (RMAP_NODE, &set_metric_cmd);
 
1350   install_element (RMAP_NODE, &no_set_metric_cmd);
 
1351   install_element (RMAP_NODE, &no_set_metric_val_cmd);
 
1353   /* Forwarding address */
 
1354   install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
 
1355   install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
 
1358   install_element (RMAP_NODE, &ospf6_routemap_set_tag_cmd);
 
1359   install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_cmd);
 
1360   install_element (RMAP_NODE, &ospf6_routemap_no_set_tag_val_cmd);
 
1364 /* Display functions */
 
1366 ospf6_as_external_lsa_get_prefix_str (struct ospf6_lsa *lsa, char *buf,
 
1367                                       int buflen, int pos)
 
1369   struct ospf6_as_external_lsa *external;
 
1370   struct in6_addr in6;
 
1371   int prefix_length = 0;
 
1375         external = (struct ospf6_as_external_lsa *)
 
1376           OSPF6_LSA_HEADER_END (lsa->header);
 
1380             ospf6_prefix_in6_addr (&in6, &external->prefix);
 
1381             prefix_length = external->prefix.prefix_length;
 
1384           in6 = *((struct in6_addr *)
 
1385                   ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
 
1386                    OSPF6_PREFIX_SPACE (external->prefix.prefix_length)));
 
1390             inet_ntop (AF_INET6, &in6, buf, buflen);
 
1392               sprintf (&buf[strlen(buf)], "/%d", prefix_length);
 
1399 ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
 
1401   struct ospf6_as_external_lsa *external;
 
1404   assert (lsa->header);
 
1405   external = (struct ospf6_as_external_lsa *)
 
1406     OSPF6_LSA_HEADER_END (lsa->header);
 
1409   snprintf (buf, sizeof (buf), "%c%c%c",
 
1410     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
 
1411     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
 
1412     (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
 
1414   vty_out (vty, "     Bits: %s%s", buf, VNL);
 
1415   vty_out (vty, "     Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
 
1418   ospf6_prefix_options_printbuf (external->prefix.prefix_options,
 
1420   vty_out (vty, "     Prefix Options: %s%s", buf,
 
1423   vty_out (vty, "     Referenced LSType: %d%s",
 
1424            ntohs (external->prefix.prefix_refer_lstype),
 
1427   vty_out (vty, "     Prefix: %s%s",
 
1428            ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 0), VNL);
 
1430   /* Forwarding-Address */
 
1431   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
 
1433       vty_out (vty, "     Forwarding-Address: %s%s",
 
1434                ospf6_as_external_lsa_get_prefix_str (lsa, buf, sizeof(buf), 1),
 
1439   if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T))
 
1441       vty_out (vty, "     Tag: %u%s",
 
1442                ospf6_as_external_lsa_get_tag (lsa), VNL);
 
1449 ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
 
1451   struct ospf6_external_info *info = route->route_option;
 
1452   char prefix[64], id[16], forwarding[64];
 
1455   prefix2str (&route->prefix, prefix, sizeof (prefix));
 
1456   tmp_id = ntohl (info->id);
 
1457   inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
 
1458   if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
 
1459     inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
 
1461     snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
 
1462               route->nexthop[0].ifindex);
 
1464   vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
 
1465            zebra_route_char(info->type),
 
1466            prefix, id, route->path.metric_type,
 
1467            (u_long) (route->path.metric_type == 2 ?
 
1468                      route->path.cost_e2 : route->path.cost),
 
1472 DEFUN (show_ipv6_ospf6_redistribute,
 
1473        show_ipv6_ospf6_redistribute_cmd,
 
1474        "show ipv6 ospf6 redistribute",
 
1478        "redistributing External information\n"
 
1481   struct ospf6_route *route;
 
1483   OSPF6_CMD_CHECK_RUNNING ();
 
1485   ospf6_redistribute_show_config (vty);
 
1487   for (route = ospf6_route_head (ospf6->external_table); route;
 
1488        route = ospf6_route_next (route))
 
1489     ospf6_asbr_external_route_show (vty, route);
 
1494 struct ospf6_lsa_handler as_external_handler =
 
1496   OSPF6_LSTYPE_AS_EXTERNAL,
 
1499   ospf6_as_external_lsa_show,
 
1500   ospf6_as_external_lsa_get_prefix_str
 
1504 ospf6_asbr_init (void)
 
1506   ospf6_routemap_init ();
 
1508   ospf6_install_lsa_handler (&as_external_handler);
 
1510   install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
 
1512   install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
 
1513   install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
 
1514   install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
 
1515   install_element (OSPF6_NODE, &no_ospf6_redistribute_route_map_cmd);
 
1519 ospf6_asbr_redistribute_reset (void)
 
1523   for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
 
1525       if (type == ZEBRA_ROUTE_OSPF6)
 
1527       if (ospf6_zebra_is_redistribute (type))
 
1528         ospf6_asbr_redistribute_unset(type);
 
1533 ospf6_asbr_terminate (void)
 
1535   route_map_finish ();
 
1538 DEFUN (debug_ospf6_asbr,
 
1539        debug_ospf6_asbr_cmd,
 
1543        "Debug OSPFv3 ASBR function\n"
 
1546   OSPF6_DEBUG_ASBR_ON ();
 
1550 DEFUN (no_debug_ospf6_asbr,
 
1551        no_debug_ospf6_asbr_cmd,
 
1552        "no debug ospf6 asbr",
 
1556        "Debug OSPFv3 ASBR function\n"
 
1559   OSPF6_DEBUG_ASBR_OFF ();
 
1564 config_write_ospf6_debug_asbr (struct vty *vty)
 
1566   if (IS_OSPF6_DEBUG_ASBR)
 
1567     vty_out (vty, "debug ospf6 asbr%s", VNL);
 
1572 install_element_ospf6_debug_asbr ()
 
1574   install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
 
1575   install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
 
1576   install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
 
1577   install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);