Annotation of embedaddon/quagga/ospf6d/ospf6_asbr.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2003 Yasuhiro Ohara
! 3: *
! 4: * This file is part of GNU Zebra.
! 5: *
! 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
! 9: * later version.
! 10: *
! 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.
! 15: *
! 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.
! 20: */
! 21:
! 22: #include <zebra.h>
! 23:
! 24: #include "log.h"
! 25: #include "memory.h"
! 26: #include "prefix.h"
! 27: #include "command.h"
! 28: #include "vty.h"
! 29: #include "routemap.h"
! 30: #include "table.h"
! 31: #include "plist.h"
! 32: #include "thread.h"
! 33: #include "linklist.h"
! 34:
! 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"
! 41:
! 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"
! 49: #include "ospf6d.h"
! 50:
! 51: unsigned char conf_debug_ospf6_asbr = 0;
! 52:
! 53: #define ZROUTE_NAME(x) zebra_route_string(x)
! 54:
! 55: /* AS External LSA origination */
! 56: static void
! 57: ospf6_as_external_lsa_originate (struct ospf6_route *route)
! 58: {
! 59: char buffer[OSPF6_MAX_LSASIZE];
! 60: struct ospf6_lsa_header *lsa_header;
! 61: struct ospf6_lsa *old, *lsa;
! 62: struct ospf6_external_info *info = route->route_option;
! 63:
! 64: struct ospf6_as_external_lsa *as_external_lsa;
! 65: char buf[64];
! 66: caddr_t p;
! 67:
! 68: /* find previous LSA */
! 69: old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
! 70: route->path.origin.id, ospf6->router_id,
! 71: ospf6->lsdb);
! 72:
! 73: if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
! 74: {
! 75: prefix2str (&route->prefix, buf, sizeof (buf));
! 76: zlog_debug ("Originate AS-External-LSA for %s", buf);
! 77: }
! 78:
! 79: /* prepare buffer */
! 80: memset (buffer, 0, sizeof (buffer));
! 81: lsa_header = (struct ospf6_lsa_header *) buffer;
! 82: as_external_lsa = (struct ospf6_as_external_lsa *)
! 83: ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
! 84: p = (caddr_t)
! 85: ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
! 86:
! 87: /* Fill AS-External-LSA */
! 88: /* Metric type */
! 89: if (route->path.metric_type == 2)
! 90: SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
! 91: else
! 92: UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
! 93:
! 94: /* forwarding address */
! 95: if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
! 96: SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
! 97: else
! 98: UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
! 99:
! 100: /* external route tag */
! 101: UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
! 102:
! 103: /* Set metric */
! 104: OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
! 105:
! 106: /* prefixlen */
! 107: as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
! 108:
! 109: /* PrefixOptions */
! 110: as_external_lsa->prefix.prefix_options = route->path.prefix_options;
! 111:
! 112: /* don't use refer LS-type */
! 113: as_external_lsa->prefix.prefix_refer_lstype = htons (0);
! 114:
! 115: /* set Prefix */
! 116: memcpy (p, &route->prefix.u.prefix6,
! 117: OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
! 118: ospf6_prefix_apply_mask (&as_external_lsa->prefix);
! 119: p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
! 120:
! 121: /* Forwarding address */
! 122: if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
! 123: {
! 124: memcpy (p, &info->forwarding, sizeof (struct in6_addr));
! 125: p += sizeof (struct in6_addr);
! 126: }
! 127:
! 128: /* External Route Tag */
! 129: if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
! 130: {
! 131: /* xxx */
! 132: }
! 133:
! 134: /* Fill LSA Header */
! 135: lsa_header->age = 0;
! 136: lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
! 137: lsa_header->id = route->path.origin.id;
! 138: lsa_header->adv_router = ospf6->router_id;
! 139: lsa_header->seqnum =
! 140: ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
! 141: lsa_header->adv_router, ospf6->lsdb);
! 142: lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
! 143:
! 144: /* LSA checksum */
! 145: ospf6_lsa_checksum (lsa_header);
! 146:
! 147: /* create LSA */
! 148: lsa = ospf6_lsa_create (lsa_header);
! 149:
! 150: /* Originate */
! 151: ospf6_lsa_originate_process (lsa, ospf6);
! 152: }
! 153:
! 154:
! 155: void
! 156: ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
! 157: {
! 158: struct ospf6_as_external_lsa *external;
! 159: struct prefix asbr_id;
! 160: struct ospf6_route *asbr_entry, *route;
! 161: char buf[64];
! 162: int i;
! 163:
! 164: external = (struct ospf6_as_external_lsa *)
! 165: OSPF6_LSA_HEADER_END (lsa->header);
! 166:
! 167: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 168: zlog_debug ("Calculate AS-External route for %s", lsa->name);
! 169:
! 170: if (lsa->header->adv_router == ospf6->router_id)
! 171: {
! 172: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 173: zlog_debug ("Ignore self-originated AS-External-LSA");
! 174: return;
! 175: }
! 176:
! 177: if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
! 178: {
! 179: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 180: zlog_debug ("Ignore LSA with LSInfinity Metric");
! 181: return;
! 182: }
! 183:
! 184: ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
! 185: asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
! 186: if (asbr_entry == NULL ||
! 187: ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
! 188: {
! 189: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 190: {
! 191: prefix2str (&asbr_id, buf, sizeof (buf));
! 192: zlog_debug ("ASBR entry not found: %s", buf);
! 193: }
! 194: return;
! 195: }
! 196:
! 197: route = ospf6_route_create ();
! 198: route->type = OSPF6_DEST_TYPE_NETWORK;
! 199: route->prefix.family = AF_INET6;
! 200: route->prefix.prefixlen = external->prefix.prefix_length;
! 201: ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
! 202:
! 203: route->path.area_id = asbr_entry->path.area_id;
! 204: route->path.origin.type = lsa->header->type;
! 205: route->path.origin.id = lsa->header->id;
! 206: route->path.origin.adv_router = lsa->header->adv_router;
! 207:
! 208: route->path.prefix_options = external->prefix.prefix_options;
! 209: if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
! 210: {
! 211: route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
! 212: route->path.metric_type = 2;
! 213: route->path.cost = asbr_entry->path.cost;
! 214: route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
! 215: }
! 216: else
! 217: {
! 218: route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
! 219: route->path.metric_type = 1;
! 220: route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
! 221: route->path.cost_e2 = 0;
! 222: }
! 223:
! 224: for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
! 225: ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
! 226:
! 227: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 228: {
! 229: prefix2str (&route->prefix, buf, sizeof (buf));
! 230: zlog_debug ("AS-External route add: %s", buf);
! 231: }
! 232:
! 233: ospf6_route_add (route, ospf6->route_table);
! 234: }
! 235:
! 236: void
! 237: ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
! 238: {
! 239: struct ospf6_as_external_lsa *external;
! 240: struct prefix prefix;
! 241: struct ospf6_route *route;
! 242: char buf[64];
! 243:
! 244: external = (struct ospf6_as_external_lsa *)
! 245: OSPF6_LSA_HEADER_END (lsa->header);
! 246:
! 247: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 248: zlog_debug ("Withdraw AS-External route for %s", lsa->name);
! 249:
! 250: if (lsa->header->adv_router == ospf6->router_id)
! 251: {
! 252: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 253: zlog_debug ("Ignore self-originated AS-External-LSA");
! 254: return;
! 255: }
! 256:
! 257: memset (&prefix, 0, sizeof (struct prefix));
! 258: prefix.family = AF_INET6;
! 259: prefix.prefixlen = external->prefix.prefix_length;
! 260: ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
! 261:
! 262: route = ospf6_route_lookup (&prefix, ospf6->route_table);
! 263: if (route == NULL)
! 264: {
! 265: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 266: {
! 267: prefix2str (&prefix, buf, sizeof (buf));
! 268: zlog_debug ("AS-External route %s not found", buf);
! 269: }
! 270: return;
! 271: }
! 272:
! 273: for (ospf6_route_lock (route);
! 274: route && ospf6_route_is_prefix (&prefix, route);
! 275: route = ospf6_route_next (route))
! 276: {
! 277: if (route->type != OSPF6_DEST_TYPE_NETWORK)
! 278: continue;
! 279: if (route->path.origin.type != lsa->header->type)
! 280: continue;
! 281: if (route->path.origin.id != lsa->header->id)
! 282: continue;
! 283: if (route->path.origin.adv_router != lsa->header->adv_router)
! 284: continue;
! 285:
! 286: if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
! 287: {
! 288: prefix2str (&route->prefix, buf, sizeof (buf));
! 289: zlog_debug ("AS-External route remove: %s", buf);
! 290: }
! 291: ospf6_route_remove (route, ospf6->route_table);
! 292: }
! 293: }
! 294:
! 295: void
! 296: ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
! 297: {
! 298: struct ospf6_lsa *lsa;
! 299: u_int16_t type;
! 300: u_int32_t router;
! 301:
! 302: if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST))
! 303: {
! 304: char buf[16];
! 305: inet_ntop (AF_INET, &ADV_ROUTER_IN_PREFIX (&asbr_entry->prefix),
! 306: buf, sizeof (buf));
! 307: zlog_info ("ignore non-best path: lsentry %s add", buf);
! 308: return;
! 309: }
! 310:
! 311: type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
! 312: router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
! 313: for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa;
! 314: lsa = ospf6_lsdb_type_router_next (type, router, lsa))
! 315: {
! 316: if (! OSPF6_LSA_IS_MAXAGE (lsa))
! 317: ospf6_asbr_lsa_add (lsa);
! 318: }
! 319: }
! 320:
! 321: void
! 322: ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
! 323: {
! 324: struct ospf6_lsa *lsa;
! 325: u_int16_t type;
! 326: u_int32_t router;
! 327:
! 328: type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
! 329: router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
! 330: for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
! 331: lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
! 332: ospf6_asbr_lsa_remove (lsa);
! 333: }
! 334:
! 335:
! 336:
! 337: /* redistribute function */
! 338:
! 339: static void
! 340: ospf6_asbr_routemap_set (int type, const char *mapname)
! 341: {
! 342: if (ospf6->rmap[type].name)
! 343: free (ospf6->rmap[type].name);
! 344: ospf6->rmap[type].name = strdup (mapname);
! 345: ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
! 346: }
! 347:
! 348: static void
! 349: ospf6_asbr_routemap_unset (int type)
! 350: {
! 351: if (ospf6->rmap[type].name)
! 352: free (ospf6->rmap[type].name);
! 353: ospf6->rmap[type].name = NULL;
! 354: ospf6->rmap[type].map = NULL;
! 355: }
! 356:
! 357: static void
! 358: ospf6_asbr_routemap_update (const char *mapname)
! 359: {
! 360: int type;
! 361:
! 362: if (ospf6 == NULL)
! 363: return;
! 364:
! 365: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
! 366: {
! 367: if (ospf6->rmap[type].name)
! 368: ospf6->rmap[type].map =
! 369: route_map_lookup_by_name (ospf6->rmap[type].name);
! 370: else
! 371: ospf6->rmap[type].map = NULL;
! 372: }
! 373: }
! 374:
! 375: int
! 376: ospf6_asbr_is_asbr (struct ospf6 *o)
! 377: {
! 378: return o->external_table->count;
! 379: }
! 380:
! 381: static void
! 382: ospf6_asbr_redistribute_set (int type)
! 383: {
! 384: ospf6_zebra_redistribute (type);
! 385: }
! 386:
! 387: static void
! 388: ospf6_asbr_redistribute_unset (int type)
! 389: {
! 390: struct ospf6_route *route;
! 391: struct ospf6_external_info *info;
! 392:
! 393: ospf6_zebra_no_redistribute (type);
! 394:
! 395: for (route = ospf6_route_head (ospf6->external_table); route;
! 396: route = ospf6_route_next (route))
! 397: {
! 398: info = route->route_option;
! 399: if (info->type != type)
! 400: continue;
! 401:
! 402: ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
! 403: &route->prefix);
! 404: }
! 405: }
! 406:
! 407: void
! 408: ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
! 409: u_int nexthop_num, struct in6_addr *nexthop)
! 410: {
! 411: int ret;
! 412: struct ospf6_route troute;
! 413: struct ospf6_external_info tinfo;
! 414: struct ospf6_route *route, *match;
! 415: struct ospf6_external_info *info;
! 416: struct prefix prefix_id;
! 417: struct route_node *node;
! 418: char pbuf[64], ibuf[16];
! 419: struct listnode *lnode, *lnnode;
! 420: struct ospf6_area *oa;
! 421:
! 422: if (! ospf6_zebra_is_redistribute (type))
! 423: return;
! 424:
! 425: if (IS_OSPF6_DEBUG_ASBR)
! 426: {
! 427: prefix2str (prefix, pbuf, sizeof (pbuf));
! 428: zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
! 429: }
! 430:
! 431: /* if route-map was specified but not found, do not advertise */
! 432: if (ospf6->rmap[type].name)
! 433: {
! 434: if (ospf6->rmap[type].map == NULL)
! 435: ospf6_asbr_routemap_update (NULL);
! 436: if (ospf6->rmap[type].map == NULL)
! 437: {
! 438: zlog_warn ("route-map \"%s\" not found, suppress redistributing",
! 439: ospf6->rmap[type].name);
! 440: return;
! 441: }
! 442: }
! 443:
! 444: /* apply route-map */
! 445: if (ospf6->rmap[type].map)
! 446: {
! 447: memset (&troute, 0, sizeof (troute));
! 448: memset (&tinfo, 0, sizeof (tinfo));
! 449: troute.route_option = &tinfo;
! 450:
! 451: ret = route_map_apply (ospf6->rmap[type].map, prefix,
! 452: RMAP_OSPF6, &troute);
! 453: if (ret == RMAP_DENYMATCH)
! 454: {
! 455: if (IS_OSPF6_DEBUG_ASBR)
! 456: zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
! 457: return;
! 458: }
! 459: }
! 460:
! 461: match = ospf6_route_lookup (prefix, ospf6->external_table);
! 462: if (match)
! 463: {
! 464: info = match->route_option;
! 465:
! 466: /* copy result of route-map */
! 467: if (ospf6->rmap[type].map)
! 468: {
! 469: if (troute.path.metric_type)
! 470: match->path.metric_type = troute.path.metric_type;
! 471: if (troute.path.cost)
! 472: match->path.cost = troute.path.cost;
! 473: if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
! 474: memcpy (&info->forwarding, &tinfo.forwarding,
! 475: sizeof (struct in6_addr));
! 476: }
! 477:
! 478: info->type = type;
! 479: match->nexthop[0].ifindex = ifindex;
! 480: if (nexthop_num && nexthop)
! 481: memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
! 482:
! 483: /* create/update binding in external_id_table */
! 484: prefix_id.family = AF_INET;
! 485: prefix_id.prefixlen = 32;
! 486: prefix_id.u.prefix4.s_addr = htonl (info->id);
! 487: node = route_node_get (ospf6->external_id_table, &prefix_id);
! 488: node->info = match;
! 489:
! 490: if (IS_OSPF6_DEBUG_ASBR)
! 491: {
! 492: inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
! 493: zlog_debug ("Advertise as AS-External Id:%s", ibuf);
! 494: }
! 495:
! 496: match->path.origin.id = htonl (info->id);
! 497: ospf6_as_external_lsa_originate (match);
! 498: return;
! 499: }
! 500:
! 501: /* create new entry */
! 502: route = ospf6_route_create ();
! 503: route->type = OSPF6_DEST_TYPE_NETWORK;
! 504: memcpy (&route->prefix, prefix, sizeof (struct prefix));
! 505:
! 506: info = (struct ospf6_external_info *)
! 507: XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
! 508: route->route_option = info;
! 509: info->id = ospf6->external_id++;
! 510:
! 511: /* copy result of route-map */
! 512: if (ospf6->rmap[type].map)
! 513: {
! 514: if (troute.path.metric_type)
! 515: route->path.metric_type = troute.path.metric_type;
! 516: if (troute.path.cost)
! 517: route->path.cost = troute.path.cost;
! 518: if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
! 519: memcpy (&info->forwarding, &tinfo.forwarding,
! 520: sizeof (struct in6_addr));
! 521: }
! 522:
! 523: info->type = type;
! 524: route->nexthop[0].ifindex = ifindex;
! 525: if (nexthop_num && nexthop)
! 526: memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
! 527:
! 528: /* create/update binding in external_id_table */
! 529: prefix_id.family = AF_INET;
! 530: prefix_id.prefixlen = 32;
! 531: prefix_id.u.prefix4.s_addr = htonl (info->id);
! 532: node = route_node_get (ospf6->external_id_table, &prefix_id);
! 533: node->info = route;
! 534:
! 535: route = ospf6_route_add (route, ospf6->external_table);
! 536: route->route_option = info;
! 537:
! 538: if (IS_OSPF6_DEBUG_ASBR)
! 539: {
! 540: inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
! 541: zlog_debug ("Advertise as AS-External Id:%s", ibuf);
! 542: }
! 543:
! 544: route->path.origin.id = htonl (info->id);
! 545: ospf6_as_external_lsa_originate (route);
! 546:
! 547: /* Router-Bit (ASBR Flag) may have to be updated */
! 548: for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
! 549: OSPF6_ROUTER_LSA_SCHEDULE (oa);
! 550: }
! 551:
! 552: void
! 553: ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
! 554: {
! 555: struct ospf6_route *match;
! 556: struct ospf6_external_info *info = NULL;
! 557: struct route_node *node;
! 558: struct ospf6_lsa *lsa;
! 559: struct prefix prefix_id;
! 560: char pbuf[64], ibuf[16];
! 561: struct listnode *lnode, *lnnode;
! 562: struct ospf6_area *oa;
! 563:
! 564: match = ospf6_route_lookup (prefix, ospf6->external_table);
! 565: if (match == NULL)
! 566: {
! 567: if (IS_OSPF6_DEBUG_ASBR)
! 568: {
! 569: prefix2str (prefix, pbuf, sizeof (pbuf));
! 570: zlog_debug ("No such route %s to withdraw", pbuf);
! 571: }
! 572: return;
! 573: }
! 574:
! 575: info = match->route_option;
! 576: assert (info);
! 577:
! 578: if (info->type != type)
! 579: {
! 580: if (IS_OSPF6_DEBUG_ASBR)
! 581: {
! 582: prefix2str (prefix, pbuf, sizeof (pbuf));
! 583: zlog_debug ("Original protocol mismatch: %s", pbuf);
! 584: }
! 585: return;
! 586: }
! 587:
! 588: if (IS_OSPF6_DEBUG_ASBR)
! 589: {
! 590: prefix2str (prefix, pbuf, sizeof (pbuf));
! 591: inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
! 592: zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
! 593: }
! 594:
! 595: lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
! 596: htonl (info->id), ospf6->router_id, ospf6->lsdb);
! 597: if (lsa)
! 598: ospf6_lsa_purge (lsa);
! 599:
! 600: /* remove binding in external_id_table */
! 601: prefix_id.family = AF_INET;
! 602: prefix_id.prefixlen = 32;
! 603: prefix_id.u.prefix4.s_addr = htonl (info->id);
! 604: node = route_node_lookup (ospf6->external_id_table, &prefix_id);
! 605: assert (node);
! 606: node->info = NULL;
! 607: route_unlock_node (node);
! 608:
! 609: ospf6_route_remove (match, ospf6->external_table);
! 610: XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
! 611:
! 612: /* Router-Bit (ASBR Flag) may have to be updated */
! 613: for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
! 614: OSPF6_ROUTER_LSA_SCHEDULE (oa);
! 615: }
! 616:
! 617: DEFUN (ospf6_redistribute,
! 618: ospf6_redistribute_cmd,
! 619: "redistribute (static|kernel|connected|ripng|bgp)",
! 620: "Redistribute\n"
! 621: "Static route\n"
! 622: "Kernel route\n"
! 623: "Connected route\n"
! 624: "RIPng route\n"
! 625: "BGP route\n"
! 626: )
! 627: {
! 628: int type = 0;
! 629:
! 630: if (strncmp (argv[0], "sta", 3) == 0)
! 631: type = ZEBRA_ROUTE_STATIC;
! 632: else if (strncmp (argv[0], "ker", 3) == 0)
! 633: type = ZEBRA_ROUTE_KERNEL;
! 634: else if (strncmp (argv[0], "con", 3) == 0)
! 635: type = ZEBRA_ROUTE_CONNECT;
! 636: else if (strncmp (argv[0], "rip", 3) == 0)
! 637: type = ZEBRA_ROUTE_RIPNG;
! 638: else if (strncmp (argv[0], "bgp", 3) == 0)
! 639: type = ZEBRA_ROUTE_BGP;
! 640:
! 641: ospf6_asbr_redistribute_unset (type);
! 642: ospf6_asbr_routemap_unset (type);
! 643: ospf6_asbr_redistribute_set (type);
! 644: return CMD_SUCCESS;
! 645: }
! 646:
! 647: DEFUN (ospf6_redistribute_routemap,
! 648: ospf6_redistribute_routemap_cmd,
! 649: "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
! 650: "Redistribute\n"
! 651: "Static routes\n"
! 652: "Kernel route\n"
! 653: "Connected route\n"
! 654: "RIPng route\n"
! 655: "BGP route\n"
! 656: "Route map reference\n"
! 657: "Route map name\n"
! 658: )
! 659: {
! 660: int type = 0;
! 661:
! 662: if (strncmp (argv[0], "sta", 3) == 0)
! 663: type = ZEBRA_ROUTE_STATIC;
! 664: else if (strncmp (argv[0], "ker", 3) == 0)
! 665: type = ZEBRA_ROUTE_KERNEL;
! 666: else if (strncmp (argv[0], "con", 3) == 0)
! 667: type = ZEBRA_ROUTE_CONNECT;
! 668: else if (strncmp (argv[0], "rip", 3) == 0)
! 669: type = ZEBRA_ROUTE_RIPNG;
! 670: else if (strncmp (argv[0], "bgp", 3) == 0)
! 671: type = ZEBRA_ROUTE_BGP;
! 672:
! 673: ospf6_asbr_redistribute_unset (type);
! 674: ospf6_asbr_routemap_set (type, argv[1]);
! 675: ospf6_asbr_redistribute_set (type);
! 676: return CMD_SUCCESS;
! 677: }
! 678:
! 679: DEFUN (no_ospf6_redistribute,
! 680: no_ospf6_redistribute_cmd,
! 681: "no redistribute (static|kernel|connected|ripng|bgp)",
! 682: NO_STR
! 683: "Redistribute\n"
! 684: "Static route\n"
! 685: "Kernel route\n"
! 686: "Connected route\n"
! 687: "RIPng route\n"
! 688: "BGP route\n"
! 689: )
! 690: {
! 691: int type = 0;
! 692:
! 693: if (strncmp (argv[0], "sta", 3) == 0)
! 694: type = ZEBRA_ROUTE_STATIC;
! 695: else if (strncmp (argv[0], "ker", 3) == 0)
! 696: type = ZEBRA_ROUTE_KERNEL;
! 697: else if (strncmp (argv[0], "con", 3) == 0)
! 698: type = ZEBRA_ROUTE_CONNECT;
! 699: else if (strncmp (argv[0], "rip", 3) == 0)
! 700: type = ZEBRA_ROUTE_RIPNG;
! 701: else if (strncmp (argv[0], "bgp", 3) == 0)
! 702: type = ZEBRA_ROUTE_BGP;
! 703:
! 704: ospf6_asbr_redistribute_unset (type);
! 705: ospf6_asbr_routemap_unset (type);
! 706:
! 707: return CMD_SUCCESS;
! 708: }
! 709:
! 710: int
! 711: ospf6_redistribute_config_write (struct vty *vty)
! 712: {
! 713: int type;
! 714:
! 715: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
! 716: {
! 717: if (type == ZEBRA_ROUTE_OSPF6)
! 718: continue;
! 719: if (! ospf6_zebra_is_redistribute (type))
! 720: continue;
! 721:
! 722: if (ospf6->rmap[type].name)
! 723: vty_out (vty, " redistribute %s route-map %s%s",
! 724: ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
! 725: else
! 726: vty_out (vty, " redistribute %s%s",
! 727: ZROUTE_NAME (type), VNL);
! 728: }
! 729:
! 730: return 0;
! 731: }
! 732:
! 733: static void
! 734: ospf6_redistribute_show_config (struct vty *vty)
! 735: {
! 736: int type;
! 737: int nroute[ZEBRA_ROUTE_MAX];
! 738: int total;
! 739: struct ospf6_route *route;
! 740: struct ospf6_external_info *info;
! 741:
! 742: total = 0;
! 743: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
! 744: nroute[type] = 0;
! 745: for (route = ospf6_route_head (ospf6->external_table); route;
! 746: route = ospf6_route_next (route))
! 747: {
! 748: info = route->route_option;
! 749: nroute[info->type]++;
! 750: total++;
! 751: }
! 752:
! 753: vty_out (vty, "Redistributing External Routes from:%s", VNL);
! 754: for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
! 755: {
! 756: if (type == ZEBRA_ROUTE_OSPF6)
! 757: continue;
! 758: if (! ospf6_zebra_is_redistribute (type))
! 759: continue;
! 760:
! 761: if (ospf6->rmap[type].name)
! 762: vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
! 763: ZROUTE_NAME (type), ospf6->rmap[type].name,
! 764: (ospf6->rmap[type].map ? "" : " (not found !)"),
! 765: VNL);
! 766: else
! 767: vty_out (vty, " %d: %s%s", nroute[type],
! 768: ZROUTE_NAME (type), VNL);
! 769: }
! 770: vty_out (vty, "Total %d routes%s", total, VNL);
! 771: }
! 772:
! 773:
! 774:
! 775: /* Routemap Functions */
! 776: static route_map_result_t
! 777: ospf6_routemap_rule_match_address_prefixlist (void *rule,
! 778: struct prefix *prefix,
! 779: route_map_object_t type,
! 780: void *object)
! 781: {
! 782: struct prefix_list *plist;
! 783:
! 784: if (type != RMAP_OSPF6)
! 785: return RMAP_NOMATCH;
! 786:
! 787: plist = prefix_list_lookup (AFI_IP6, (char *) rule);
! 788: if (plist == NULL)
! 789: return RMAP_NOMATCH;
! 790:
! 791: return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
! 792: RMAP_NOMATCH : RMAP_MATCH);
! 793: }
! 794:
! 795: static void *
! 796: ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
! 797: {
! 798: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 799: }
! 800:
! 801: static void
! 802: ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
! 803: {
! 804: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 805: }
! 806:
! 807: struct route_map_rule_cmd
! 808: ospf6_routemap_rule_match_address_prefixlist_cmd =
! 809: {
! 810: "ipv6 address prefix-list",
! 811: ospf6_routemap_rule_match_address_prefixlist,
! 812: ospf6_routemap_rule_match_address_prefixlist_compile,
! 813: ospf6_routemap_rule_match_address_prefixlist_free,
! 814: };
! 815:
! 816: static route_map_result_t
! 817: ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
! 818: route_map_object_t type, void *object)
! 819: {
! 820: char *metric_type = rule;
! 821: struct ospf6_route *route = object;
! 822:
! 823: if (type != RMAP_OSPF6)
! 824: return RMAP_OKAY;
! 825:
! 826: if (strcmp (metric_type, "type-2") == 0)
! 827: route->path.metric_type = 2;
! 828: else
! 829: route->path.metric_type = 1;
! 830:
! 831: return RMAP_OKAY;
! 832: }
! 833:
! 834: static void *
! 835: ospf6_routemap_rule_set_metric_type_compile (const char *arg)
! 836: {
! 837: if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
! 838: return NULL;
! 839: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 840: }
! 841:
! 842: static void
! 843: ospf6_routemap_rule_set_metric_type_free (void *rule)
! 844: {
! 845: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 846: }
! 847:
! 848: struct route_map_rule_cmd
! 849: ospf6_routemap_rule_set_metric_type_cmd =
! 850: {
! 851: "metric-type",
! 852: ospf6_routemap_rule_set_metric_type,
! 853: ospf6_routemap_rule_set_metric_type_compile,
! 854: ospf6_routemap_rule_set_metric_type_free,
! 855: };
! 856:
! 857: static route_map_result_t
! 858: ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
! 859: route_map_object_t type, void *object)
! 860: {
! 861: char *metric = rule;
! 862: struct ospf6_route *route = object;
! 863:
! 864: if (type != RMAP_OSPF6)
! 865: return RMAP_OKAY;
! 866:
! 867: route->path.cost = atoi (metric);
! 868: return RMAP_OKAY;
! 869: }
! 870:
! 871: static void *
! 872: ospf6_routemap_rule_set_metric_compile (const char *arg)
! 873: {
! 874: u_int32_t metric;
! 875: char *endp;
! 876: metric = strtoul (arg, &endp, 0);
! 877: if (metric > LS_INFINITY || *endp != '\0')
! 878: return NULL;
! 879: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 880: }
! 881:
! 882: static void
! 883: ospf6_routemap_rule_set_metric_free (void *rule)
! 884: {
! 885: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 886: }
! 887:
! 888: struct route_map_rule_cmd
! 889: ospf6_routemap_rule_set_metric_cmd =
! 890: {
! 891: "metric",
! 892: ospf6_routemap_rule_set_metric,
! 893: ospf6_routemap_rule_set_metric_compile,
! 894: ospf6_routemap_rule_set_metric_free,
! 895: };
! 896:
! 897: static route_map_result_t
! 898: ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
! 899: route_map_object_t type, void *object)
! 900: {
! 901: char *forwarding = rule;
! 902: struct ospf6_route *route = object;
! 903: struct ospf6_external_info *info = route->route_option;
! 904:
! 905: if (type != RMAP_OSPF6)
! 906: return RMAP_OKAY;
! 907:
! 908: if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
! 909: {
! 910: memset (&info->forwarding, 0, sizeof (struct in6_addr));
! 911: return RMAP_ERROR;
! 912: }
! 913:
! 914: return RMAP_OKAY;
! 915: }
! 916:
! 917: static void *
! 918: ospf6_routemap_rule_set_forwarding_compile (const char *arg)
! 919: {
! 920: struct in6_addr a;
! 921: if (inet_pton (AF_INET6, arg, &a) != 1)
! 922: return NULL;
! 923: return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
! 924: }
! 925:
! 926: static void
! 927: ospf6_routemap_rule_set_forwarding_free (void *rule)
! 928: {
! 929: XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
! 930: }
! 931:
! 932: struct route_map_rule_cmd
! 933: ospf6_routemap_rule_set_forwarding_cmd =
! 934: {
! 935: "forwarding-address",
! 936: ospf6_routemap_rule_set_forwarding,
! 937: ospf6_routemap_rule_set_forwarding_compile,
! 938: ospf6_routemap_rule_set_forwarding_free,
! 939: };
! 940:
! 941: static int
! 942: route_map_command_status (struct vty *vty, int ret)
! 943: {
! 944: if (! ret)
! 945: return CMD_SUCCESS;
! 946:
! 947: switch (ret)
! 948: {
! 949: case RMAP_RULE_MISSING:
! 950: vty_out (vty, "Can't find rule.%s", VNL);
! 951: break;
! 952: case RMAP_COMPILE_ERROR:
! 953: vty_out (vty, "Argument is malformed.%s", VNL);
! 954: break;
! 955: default:
! 956: vty_out (vty, "route-map add set failed.%s", VNL);
! 957: break;
! 958: }
! 959: return CMD_WARNING;
! 960: }
! 961:
! 962: /* add "match address" */
! 963: DEFUN (ospf6_routemap_match_address_prefixlist,
! 964: ospf6_routemap_match_address_prefixlist_cmd,
! 965: "match ipv6 address prefix-list WORD",
! 966: "Match values\n"
! 967: IPV6_STR
! 968: "Match address of route\n"
! 969: "Match entries of prefix-lists\n"
! 970: "IPv6 prefix-list name\n")
! 971: {
! 972: int ret = route_map_add_match ((struct route_map_index *) vty->index,
! 973: "ipv6 address prefix-list", argv[0]);
! 974: return route_map_command_status (vty, ret);
! 975: }
! 976:
! 977: /* delete "match address" */
! 978: DEFUN (ospf6_routemap_no_match_address_prefixlist,
! 979: ospf6_routemap_no_match_address_prefixlist_cmd,
! 980: "no match ipv6 address prefix-list WORD",
! 981: NO_STR
! 982: "Match values\n"
! 983: IPV6_STR
! 984: "Match address of route\n"
! 985: "Match entries of prefix-lists\n"
! 986: "IPv6 prefix-list name\n")
! 987: {
! 988: int ret = route_map_delete_match ((struct route_map_index *) vty->index,
! 989: "ipv6 address prefix-list", argv[0]);
! 990: return route_map_command_status (vty, ret);
! 991: }
! 992:
! 993: /* add "set metric-type" */
! 994: DEFUN (ospf6_routemap_set_metric_type,
! 995: ospf6_routemap_set_metric_type_cmd,
! 996: "set metric-type (type-1|type-2)",
! 997: "Set value\n"
! 998: "Type of metric\n"
! 999: "OSPF6 external type 1 metric\n"
! 1000: "OSPF6 external type 2 metric\n")
! 1001: {
! 1002: int ret = route_map_add_set ((struct route_map_index *) vty->index,
! 1003: "metric-type", argv[0]);
! 1004: return route_map_command_status (vty, ret);
! 1005: }
! 1006:
! 1007: /* delete "set metric-type" */
! 1008: DEFUN (ospf6_routemap_no_set_metric_type,
! 1009: ospf6_routemap_no_set_metric_type_cmd,
! 1010: "no set metric-type (type-1|type-2)",
! 1011: NO_STR
! 1012: "Set value\n"
! 1013: "Type of metric\n"
! 1014: "OSPF6 external type 1 metric\n"
! 1015: "OSPF6 external type 2 metric\n")
! 1016: {
! 1017: int ret = route_map_delete_set ((struct route_map_index *) vty->index,
! 1018: "metric-type", argv[0]);
! 1019: return route_map_command_status (vty, ret);
! 1020: }
! 1021:
! 1022: /* add "set metric" */
! 1023: DEFUN (set_metric,
! 1024: set_metric_cmd,
! 1025: "set metric <0-4294967295>",
! 1026: "Set value\n"
! 1027: "Metric value\n"
! 1028: "Metric value\n")
! 1029: {
! 1030: int ret = route_map_add_set ((struct route_map_index *) vty->index,
! 1031: "metric", argv[0]);
! 1032: return route_map_command_status (vty, ret);
! 1033: }
! 1034:
! 1035: /* delete "set metric" */
! 1036: DEFUN (no_set_metric,
! 1037: no_set_metric_cmd,
! 1038: "no set metric <0-4294967295>",
! 1039: NO_STR
! 1040: "Set value\n"
! 1041: "Metric\n"
! 1042: "METRIC value\n")
! 1043: {
! 1044: int ret = route_map_delete_set ((struct route_map_index *) vty->index,
! 1045: "metric", argv[0]);
! 1046: return route_map_command_status (vty, ret);
! 1047: }
! 1048:
! 1049: /* add "set forwarding-address" */
! 1050: DEFUN (ospf6_routemap_set_forwarding,
! 1051: ospf6_routemap_set_forwarding_cmd,
! 1052: "set forwarding-address X:X::X:X",
! 1053: "Set value\n"
! 1054: "Forwarding Address\n"
! 1055: "IPv6 Address\n")
! 1056: {
! 1057: int ret = route_map_add_set ((struct route_map_index *) vty->index,
! 1058: "forwarding-address", argv[0]);
! 1059: return route_map_command_status (vty, ret);
! 1060: }
! 1061:
! 1062: /* delete "set forwarding-address" */
! 1063: DEFUN (ospf6_routemap_no_set_forwarding,
! 1064: ospf6_routemap_no_set_forwarding_cmd,
! 1065: "no set forwarding-address X:X::X:X",
! 1066: NO_STR
! 1067: "Set value\n"
! 1068: "Forwarding Address\n"
! 1069: "IPv6 Address\n")
! 1070: {
! 1071: int ret = route_map_delete_set ((struct route_map_index *) vty->index,
! 1072: "forwarding-address", argv[0]);
! 1073: return route_map_command_status (vty, ret);
! 1074: }
! 1075:
! 1076: static void
! 1077: ospf6_routemap_init (void)
! 1078: {
! 1079: route_map_init ();
! 1080: route_map_init_vty ();
! 1081: route_map_add_hook (ospf6_asbr_routemap_update);
! 1082: route_map_delete_hook (ospf6_asbr_routemap_update);
! 1083:
! 1084: route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
! 1085: route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
! 1086: route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
! 1087: route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
! 1088:
! 1089: /* Match address prefix-list */
! 1090: install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
! 1091: install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
! 1092:
! 1093: /* ASE Metric Type (e.g. Type-1/Type-2) */
! 1094: install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
! 1095: install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
! 1096:
! 1097: /* ASE Metric */
! 1098: install_element (RMAP_NODE, &set_metric_cmd);
! 1099: install_element (RMAP_NODE, &no_set_metric_cmd);
! 1100:
! 1101: /* ASE Metric */
! 1102: install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
! 1103: install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
! 1104: }
! 1105:
! 1106:
! 1107: /* Display functions */
! 1108: static int
! 1109: ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
! 1110: {
! 1111: struct ospf6_as_external_lsa *external;
! 1112: char buf[64];
! 1113: struct in6_addr in6, *forwarding;
! 1114:
! 1115: assert (lsa->header);
! 1116: external = (struct ospf6_as_external_lsa *)
! 1117: OSPF6_LSA_HEADER_END (lsa->header);
! 1118:
! 1119: /* bits */
! 1120: snprintf (buf, sizeof (buf), "%c%c%c",
! 1121: (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
! 1122: (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
! 1123: (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
! 1124:
! 1125: vty_out (vty, " Bits: %s%s", buf, VNL);
! 1126: vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
! 1127: VNL);
! 1128:
! 1129: ospf6_prefix_options_printbuf (external->prefix.prefix_options,
! 1130: buf, sizeof (buf));
! 1131: vty_out (vty, " Prefix Options: %s%s", buf,
! 1132: VNL);
! 1133:
! 1134: vty_out (vty, " Referenced LSType: %d%s",
! 1135: ntohs (external->prefix.prefix_refer_lstype),
! 1136: VNL);
! 1137:
! 1138: ospf6_prefix_in6_addr (&in6, &external->prefix);
! 1139: inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
! 1140: vty_out (vty, " Prefix: %s/%d%s", buf,
! 1141: external->prefix.prefix_length, VNL);
! 1142:
! 1143: /* Forwarding-Address */
! 1144: if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
! 1145: {
! 1146: forwarding = (struct in6_addr *)
! 1147: ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
! 1148: OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
! 1149: inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
! 1150: vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
! 1151: }
! 1152:
! 1153: return 0;
! 1154: }
! 1155:
! 1156: static void
! 1157: ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
! 1158: {
! 1159: struct ospf6_external_info *info = route->route_option;
! 1160: char prefix[64], id[16], forwarding[64];
! 1161: u_int32_t tmp_id;
! 1162:
! 1163: prefix2str (&route->prefix, prefix, sizeof (prefix));
! 1164: tmp_id = ntohl (info->id);
! 1165: inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
! 1166: if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
! 1167: inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
! 1168: else
! 1169: snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
! 1170: route->nexthop[0].ifindex);
! 1171:
! 1172: vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
! 1173: zebra_route_char(info->type),
! 1174: prefix, id, route->path.metric_type,
! 1175: (u_long) (route->path.metric_type == 2 ?
! 1176: route->path.cost_e2 : route->path.cost),
! 1177: forwarding, VNL);
! 1178: }
! 1179:
! 1180: DEFUN (show_ipv6_ospf6_redistribute,
! 1181: show_ipv6_ospf6_redistribute_cmd,
! 1182: "show ipv6 ospf6 redistribute",
! 1183: SHOW_STR
! 1184: IP6_STR
! 1185: OSPF6_STR
! 1186: "redistributing External information\n"
! 1187: )
! 1188: {
! 1189: struct ospf6_route *route;
! 1190:
! 1191: ospf6_redistribute_show_config (vty);
! 1192:
! 1193: for (route = ospf6_route_head (ospf6->external_table); route;
! 1194: route = ospf6_route_next (route))
! 1195: ospf6_asbr_external_route_show (vty, route);
! 1196:
! 1197: return CMD_SUCCESS;
! 1198: }
! 1199:
! 1200: struct ospf6_lsa_handler as_external_handler =
! 1201: {
! 1202: OSPF6_LSTYPE_AS_EXTERNAL,
! 1203: "AS-External",
! 1204: ospf6_as_external_lsa_show
! 1205: };
! 1206:
! 1207: void
! 1208: ospf6_asbr_init (void)
! 1209: {
! 1210: ospf6_routemap_init ();
! 1211:
! 1212: ospf6_install_lsa_handler (&as_external_handler);
! 1213:
! 1214: install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
! 1215: install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
! 1216:
! 1217: install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
! 1218: install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
! 1219: install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
! 1220: }
! 1221:
! 1222: void
! 1223: ospf6_asbr_terminate (void)
! 1224: {
! 1225: route_map_finish ();
! 1226: }
! 1227:
! 1228: DEFUN (debug_ospf6_asbr,
! 1229: debug_ospf6_asbr_cmd,
! 1230: "debug ospf6 asbr",
! 1231: DEBUG_STR
! 1232: OSPF6_STR
! 1233: "Debug OSPFv3 ASBR function\n"
! 1234: )
! 1235: {
! 1236: OSPF6_DEBUG_ASBR_ON ();
! 1237: return CMD_SUCCESS;
! 1238: }
! 1239:
! 1240: DEFUN (no_debug_ospf6_asbr,
! 1241: no_debug_ospf6_asbr_cmd,
! 1242: "no debug ospf6 asbr",
! 1243: NO_STR
! 1244: DEBUG_STR
! 1245: OSPF6_STR
! 1246: "Debug OSPFv3 ASBR function\n"
! 1247: )
! 1248: {
! 1249: OSPF6_DEBUG_ASBR_OFF ();
! 1250: return CMD_SUCCESS;
! 1251: }
! 1252:
! 1253: int
! 1254: config_write_ospf6_debug_asbr (struct vty *vty)
! 1255: {
! 1256: if (IS_OSPF6_DEBUG_ASBR)
! 1257: vty_out (vty, "debug ospf6 asbr%s", VNL);
! 1258: return 0;
! 1259: }
! 1260:
! 1261: void
! 1262: install_element_ospf6_debug_asbr ()
! 1263: {
! 1264: install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
! 1265: install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
! 1266: install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
! 1267: install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
! 1268: }
! 1269:
! 1270:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>