]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_asbr.c
zebra: fix redistribution of new protocols
[mirror_frr.git] / ospf6d / ospf6_asbr.c
CommitLineData
718e3744 1/*
508e53e2 2 * Copyright (C) 2003 Yasuhiro Ohara
718e3744 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"
508e53e2 33#include "linklist.h"
718e3744 34
508e53e2 35#include "ospf6_proto.h"
36#include "ospf6_lsa.h"
37#include "ospf6_lsdb.h"
38#include "ospf6_route.h"
718e3744 39#include "ospf6_zebra.h"
6452df09 40#include "ospf6_message.h"
41
718e3744 42#include "ospf6_top.h"
508e53e2 43#include "ospf6_area.h"
6452df09 44#include "ospf6_interface.h"
45#include "ospf6_neighbor.h"
508e53e2 46#include "ospf6_asbr.h"
47#include "ospf6_intra.h"
6452df09 48#include "ospf6_flood.h"
049207c3 49#include "ospf6d.h"
718e3744 50
508e53e2 51unsigned char conf_debug_ospf6_asbr = 0;
718e3744 52
f52d13cb 53#define ZROUTE_NAME(x) zebra_route_string(x)
508e53e2 54
55/* AS External LSA origination */
6ac29a51 56static void
6452df09 57ospf6_as_external_lsa_originate (struct ospf6_route *route)
718e3744 58{
508e53e2 59 char buffer[OSPF6_MAX_LSASIZE];
60 struct ospf6_lsa_header *lsa_header;
61 struct ospf6_lsa *old, *lsa;
0b26f81b 62 struct ospf6_external_info *info = route->route_option;
718e3744 63
508e53e2 64 struct ospf6_as_external_lsa *as_external_lsa;
65 char buf[64];
66 caddr_t p;
718e3744 67
508e53e2 68 /* find previous LSA */
69 old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
6452df09 70 route->path.origin.id, ospf6->router_id,
508e53e2 71 ospf6->lsdb);
718e3744 72
1e05838a 73 if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
508e53e2 74 {
75 prefix2str (&route->prefix, buf, sizeof (buf));
c6487d61 76 zlog_debug ("Originate AS-External-LSA for %s", buf);
508e53e2 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 */
0b26f81b 95 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
508e53e2 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);
718e3744 99
508e53e2 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 {
0b26f81b 124 memcpy (p, &info->forwarding, sizeof (struct in6_addr));
508e53e2 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);
6452df09 137 lsa_header->id = route->path.origin.id;
508e53e2 138 lsa_header->adv_router = ospf6->router_id;
139 lsa_header->seqnum =
049207c3 140 ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
141 lsa_header->adv_router, ospf6->lsdb);
508e53e2 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);
508e53e2 149
150 /* Originate */
6452df09 151 ospf6_lsa_originate_process (lsa, ospf6);
718e3744 152}
153
508e53e2 154\f
718e3744 155void
508e53e2 156ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
718e3744 157{
508e53e2 158 struct ospf6_as_external_lsa *external;
159 struct prefix asbr_id;
160 struct ospf6_route *asbr_entry, *route;
161 char buf[64];
718e3744 162 int i;
508e53e2 163
164 external = (struct ospf6_as_external_lsa *)
165 OSPF6_LSA_HEADER_END (lsa->header);
166
1e05838a 167 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
c6487d61 168 zlog_debug ("Calculate AS-External route for %s", lsa->name);
508e53e2 169
170 if (lsa->header->adv_router == ospf6->router_id)
718e3744 171 {
1e05838a 172 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
c6487d61 173 zlog_debug ("Ignore self-originated AS-External-LSA");
508e53e2 174 return;
718e3744 175 }
718e3744 176
508e53e2 177 if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
178 {
1e05838a 179 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
c6487d61 180 zlog_debug ("Ignore LSA with LSInfinity Metric");
508e53e2 181 return;
182 }
718e3744 183
ccb59b11 184 ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
6452df09 185 asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
63069ad6 186 if (asbr_entry == NULL ||
187 ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
508e53e2 188 {
1e05838a 189 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
508e53e2 190 {
191 prefix2str (&asbr_id, buf, sizeof (buf));
c6487d61 192 zlog_debug ("ASBR entry not found: %s", buf);
508e53e2 193 }
194 return;
195 }
718e3744 196
508e53e2 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);
718e3744 202
508e53e2 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;
718e3744 207
508e53e2 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
1e05838a 227 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
508e53e2 228 {
229 prefix2str (&route->prefix, buf, sizeof (buf));
c6487d61 230 zlog_debug ("AS-External route add: %s", buf);
508e53e2 231 }
232
233 ospf6_route_add (route, ospf6->route_table);
718e3744 234}
235
508e53e2 236void
237ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
718e3744 238{
508e53e2 239 struct ospf6_as_external_lsa *external;
240 struct prefix prefix;
241 struct ospf6_route *route;
242 char buf[64];
718e3744 243
508e53e2 244 external = (struct ospf6_as_external_lsa *)
245 OSPF6_LSA_HEADER_END (lsa->header);
718e3744 246
1e05838a 247 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
c6487d61 248 zlog_debug ("Withdraw AS-External route for %s", lsa->name);
718e3744 249
508e53e2 250 if (lsa->header->adv_router == ospf6->router_id)
718e3744 251 {
1e05838a 252 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
c6487d61 253 zlog_debug ("Ignore self-originated AS-External-LSA");
508e53e2 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 {
1e05838a 265 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
718e3744 266 {
508e53e2 267 prefix2str (&prefix, buf, sizeof (buf));
c6487d61 268 zlog_debug ("AS-External route %s not found", buf);
718e3744 269 }
508e53e2 270 return;
718e3744 271 }
272
508e53e2 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
1e05838a 286 if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
508e53e2 287 {
288 prefix2str (&route->prefix, buf, sizeof (buf));
c6487d61 289 zlog_debug ("AS-External route remove: %s", buf);
508e53e2 290 }
291 ospf6_route_remove (route, ospf6->route_table);
292 }
718e3744 293}
294
508e53e2 295void
296ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
297{
508e53e2 298 struct ospf6_lsa *lsa;
299 u_int16_t type;
300 u_int32_t router;
301
cb4b8845 302 if (! CHECK_FLAG (asbr_entry->flag, OSPF6_ROUTE_BEST))
508e53e2 303 {
cb4b8845
PJ
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;
508e53e2 309 }
718e3744 310
508e53e2 311 type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
312 router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
cb4b8845
PJ
313 for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb); lsa;
314 lsa = ospf6_lsdb_type_router_next (type, router, lsa))
508e53e2 315 {
316 if (! OSPF6_LSA_IS_MAXAGE (lsa))
317 ospf6_asbr_lsa_add (lsa);
318 }
508e53e2 319}
320
321void
322ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
718e3744 323{
508e53e2 324 struct ospf6_lsa *lsa;
325 u_int16_t type;
326 u_int32_t router;
718e3744 327
508e53e2 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);
508e53e2 333}
718e3744 334
508e53e2 335
336\f
337/* redistribute function */
338
6ac29a51 339static void
0c083ee9 340ospf6_asbr_routemap_set (int type, const char *mapname)
508e53e2 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);
718e3744 346}
347
6ac29a51 348static void
508e53e2 349ospf6_asbr_routemap_unset (int type)
718e3744 350{
508e53e2 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
6ac29a51 357static void
0c083ee9 358ospf6_asbr_routemap_update (const char *mapname)
508e53e2 359{
360 int type;
718e3744 361
508e53e2 362 if (ospf6 == NULL)
718e3744 363 return;
364
508e53e2 365 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
718e3744 366 {
508e53e2 367 if (ospf6->rmap[type].name)
368 ospf6->rmap[type].map =
369 route_map_lookup_by_name (ospf6->rmap[type].name);
718e3744 370 else
508e53e2 371 ospf6->rmap[type].map = NULL;
718e3744 372 }
373}
374
718e3744 375int
508e53e2 376ospf6_asbr_is_asbr (struct ospf6 *o)
377{
378 return o->external_table->count;
379}
380
6ac29a51 381static void
508e53e2 382ospf6_asbr_redistribute_set (int type)
718e3744 383{
508e53e2 384 ospf6_zebra_redistribute (type);
385}
386
6ac29a51 387static void
508e53e2 388ospf6_asbr_redistribute_unset (int type)
389{
390 struct ospf6_route *route;
718e3744 391 struct ospf6_external_info *info;
718e3744 392
508e53e2 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;
718e3744 401
508e53e2 402 ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
403 &route->prefix);
404 }
405}
718e3744 406
508e53e2 407void
408ospf6_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];
1eb8ef25 419 struct listnode *lnode, *lnnode;
508e53e2 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));
c6487d61 428 zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
508e53e2 429 }
430
431 /* if route-map was specified but not found, do not advertise */
432 if (ospf6->rmap[type].name)
718e3744 433 {
508e53e2 434 if (ospf6->rmap[type].map == NULL)
03d52f8d 435 ospf6_asbr_routemap_update (NULL);
508e53e2 436 if (ospf6->rmap[type].map == NULL)
718e3744 437 {
508e53e2 438 zlog_warn ("route-map \"%s\" not found, suppress redistributing",
439 ospf6->rmap[type].name);
440 return;
718e3744 441 }
718e3744 442 }
443
508e53e2 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;
42a7debf 450 tinfo.ifindex = ifindex;
718e3744 451
508e53e2 452 ret = route_map_apply (ospf6->rmap[type].map, prefix,
453 RMAP_OSPF6, &troute);
47828747 454 if (ret == RMAP_DENYMATCH)
508e53e2 455 {
456 if (IS_OSPF6_DEBUG_ASBR)
c6487d61 457 zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
508e53e2 458 return;
459 }
460 }
718e3744 461
508e53e2 462 match = ospf6_route_lookup (prefix, ospf6->external_table);
463 if (match)
464 {
465 info = match->route_option;
718e3744 466
508e53e2 467 /* copy result of route-map */
468 if (ospf6->rmap[type].map)
469 {
470 if (troute.path.metric_type)
471 match->path.metric_type = troute.path.metric_type;
472 if (troute.path.cost)
473 match->path.cost = troute.path.cost;
474 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
475 memcpy (&info->forwarding, &tinfo.forwarding,
476 sizeof (struct in6_addr));
477 }
718e3744 478
508e53e2 479 info->type = type;
480 match->nexthop[0].ifindex = ifindex;
481 if (nexthop_num && nexthop)
482 memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
718e3744 483
508e53e2 484 /* create/update binding in external_id_table */
485 prefix_id.family = AF_INET;
486 prefix_id.prefixlen = 32;
487 prefix_id.u.prefix4.s_addr = htonl (info->id);
488 node = route_node_get (ospf6->external_id_table, &prefix_id);
489 node->info = match;
718e3744 490
508e53e2 491 if (IS_OSPF6_DEBUG_ASBR)
492 {
493 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
c6487d61 494 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
508e53e2 495 }
718e3744 496
3b68735f 497 match->path.origin.id = htonl (info->id);
6452df09 498 ospf6_as_external_lsa_originate (match);
508e53e2 499 return;
500 }
718e3744 501
508e53e2 502 /* create new entry */
503 route = ospf6_route_create ();
504 route->type = OSPF6_DEST_TYPE_NETWORK;
505 memcpy (&route->prefix, prefix, sizeof (struct prefix));
718e3744 506
508e53e2 507 info = (struct ospf6_external_info *)
393deb9b 508 XCALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
508e53e2 509 route->route_option = info;
510 info->id = ospf6->external_id++;
511
512 /* copy result of route-map */
513 if (ospf6->rmap[type].map)
718e3744 514 {
508e53e2 515 if (troute.path.metric_type)
516 route->path.metric_type = troute.path.metric_type;
517 if (troute.path.cost)
518 route->path.cost = troute.path.cost;
519 if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
520 memcpy (&info->forwarding, &tinfo.forwarding,
521 sizeof (struct in6_addr));
718e3744 522 }
523
508e53e2 524 info->type = type;
525 route->nexthop[0].ifindex = ifindex;
526 if (nexthop_num && nexthop)
527 memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
528
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);
534 node->info = route;
535
536 route = ospf6_route_add (route, ospf6->external_table);
537 route->route_option = info;
538
539 if (IS_OSPF6_DEBUG_ASBR)
718e3744 540 {
508e53e2 541 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
c6487d61 542 zlog_debug ("Advertise as AS-External Id:%s", ibuf);
718e3744 543 }
544
3b68735f 545 route->path.origin.id = htonl (info->id);
6452df09 546 ospf6_as_external_lsa_originate (route);
508e53e2 547
548 /* Router-Bit (ASBR Flag) may have to be updated */
1eb8ef25 549 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
550 OSPF6_ROUTER_LSA_SCHEDULE (oa);
718e3744 551}
552
508e53e2 553void
554ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
718e3744 555{
508e53e2 556 struct ospf6_route *match;
557 struct ospf6_external_info *info = NULL;
558 struct route_node *node;
559 struct ospf6_lsa *lsa;
560 struct prefix prefix_id;
561 char pbuf[64], ibuf[16];
1eb8ef25 562 struct listnode *lnode, *lnnode;
508e53e2 563 struct ospf6_area *oa;
718e3744 564
508e53e2 565 match = ospf6_route_lookup (prefix, ospf6->external_table);
566 if (match == NULL)
718e3744 567 {
508e53e2 568 if (IS_OSPF6_DEBUG_ASBR)
718e3744 569 {
508e53e2 570 prefix2str (prefix, pbuf, sizeof (pbuf));
c6487d61 571 zlog_debug ("No such route %s to withdraw", pbuf);
718e3744 572 }
508e53e2 573 return;
718e3744 574 }
575
508e53e2 576 info = match->route_option;
577 assert (info);
718e3744 578
508e53e2 579 if (info->type != type)
718e3744 580 {
508e53e2 581 if (IS_OSPF6_DEBUG_ASBR)
582 {
583 prefix2str (prefix, pbuf, sizeof (pbuf));
c6487d61 584 zlog_debug ("Original protocol mismatch: %s", pbuf);
508e53e2 585 }
586 return;
718e3744 587 }
588
508e53e2 589 if (IS_OSPF6_DEBUG_ASBR)
590 {
591 prefix2str (prefix, pbuf, sizeof (pbuf));
592 inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
c6487d61 593 zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
508e53e2 594 }
718e3744 595
508e53e2 596 lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
597 htonl (info->id), ospf6->router_id, ospf6->lsdb);
718e3744 598 if (lsa)
6452df09 599 ospf6_lsa_purge (lsa);
508e53e2 600
601 /* remove binding in external_id_table */
602 prefix_id.family = AF_INET;
603 prefix_id.prefixlen = 32;
604 prefix_id.u.prefix4.s_addr = htonl (info->id);
605 node = route_node_lookup (ospf6->external_id_table, &prefix_id);
606 assert (node);
607 node->info = NULL;
608 route_unlock_node (node);
609
610 ospf6_route_remove (match, ospf6->external_table);
611 XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
612
613 /* Router-Bit (ASBR Flag) may have to be updated */
1eb8ef25 614 for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
615 OSPF6_ROUTER_LSA_SCHEDULE (oa);
718e3744 616}
617
508e53e2 618DEFUN (ospf6_redistribute,
619 ospf6_redistribute_cmd,
620 "redistribute (static|kernel|connected|ripng|bgp)",
621 "Redistribute\n"
622 "Static route\n"
623 "Kernel route\n"
624 "Connected route\n"
625 "RIPng route\n"
626 "BGP route\n"
627 )
718e3744 628{
508e53e2 629 int type = 0;
718e3744 630
508e53e2 631 if (strncmp (argv[0], "sta", 3) == 0)
632 type = ZEBRA_ROUTE_STATIC;
633 else if (strncmp (argv[0], "ker", 3) == 0)
634 type = ZEBRA_ROUTE_KERNEL;
635 else if (strncmp (argv[0], "con", 3) == 0)
636 type = ZEBRA_ROUTE_CONNECT;
637 else if (strncmp (argv[0], "rip", 3) == 0)
638 type = ZEBRA_ROUTE_RIPNG;
639 else if (strncmp (argv[0], "bgp", 3) == 0)
640 type = ZEBRA_ROUTE_BGP;
718e3744 641
508e53e2 642 ospf6_asbr_redistribute_unset (type);
643 ospf6_asbr_routemap_unset (type);
644 ospf6_asbr_redistribute_set (type);
645 return CMD_SUCCESS;
646}
718e3744 647
508e53e2 648DEFUN (ospf6_redistribute_routemap,
649 ospf6_redistribute_routemap_cmd,
650 "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
651 "Redistribute\n"
652 "Static routes\n"
653 "Kernel route\n"
654 "Connected route\n"
655 "RIPng route\n"
656 "BGP route\n"
657 "Route map reference\n"
658 "Route map name\n"
659 )
660{
661 int type = 0;
e26bbeba 662
508e53e2 663 if (strncmp (argv[0], "sta", 3) == 0)
664 type = ZEBRA_ROUTE_STATIC;
665 else if (strncmp (argv[0], "ker", 3) == 0)
666 type = ZEBRA_ROUTE_KERNEL;
667 else if (strncmp (argv[0], "con", 3) == 0)
668 type = ZEBRA_ROUTE_CONNECT;
669 else if (strncmp (argv[0], "rip", 3) == 0)
670 type = ZEBRA_ROUTE_RIPNG;
671 else if (strncmp (argv[0], "bgp", 3) == 0)
672 type = ZEBRA_ROUTE_BGP;
e26bbeba 673
508e53e2 674 ospf6_asbr_redistribute_unset (type);
675 ospf6_asbr_routemap_set (type, argv[1]);
676 ospf6_asbr_redistribute_set (type);
677 return CMD_SUCCESS;
678}
679
680DEFUN (no_ospf6_redistribute,
681 no_ospf6_redistribute_cmd,
682 "no redistribute (static|kernel|connected|ripng|bgp)",
683 NO_STR
684 "Redistribute\n"
685 "Static route\n"
686 "Kernel route\n"
687 "Connected route\n"
688 "RIPng route\n"
689 "BGP route\n"
690 )
691{
692 int type = 0;
693
694 if (strncmp (argv[0], "sta", 3) == 0)
695 type = ZEBRA_ROUTE_STATIC;
696 else if (strncmp (argv[0], "ker", 3) == 0)
697 type = ZEBRA_ROUTE_KERNEL;
698 else if (strncmp (argv[0], "con", 3) == 0)
699 type = ZEBRA_ROUTE_CONNECT;
700 else if (strncmp (argv[0], "rip", 3) == 0)
701 type = ZEBRA_ROUTE_RIPNG;
702 else if (strncmp (argv[0], "bgp", 3) == 0)
703 type = ZEBRA_ROUTE_BGP;
e26bbeba 704
508e53e2 705 ospf6_asbr_redistribute_unset (type);
706 ospf6_asbr_routemap_unset (type);
e26bbeba 707
508e53e2 708 return CMD_SUCCESS;
709}
718e3744 710
508e53e2 711int
712ospf6_redistribute_config_write (struct vty *vty)
713{
714 int type;
718e3744 715
508e53e2 716 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
718e3744 717 {
508e53e2 718 if (type == ZEBRA_ROUTE_OSPF6)
719 continue;
720 if (! ospf6_zebra_is_redistribute (type))
721 continue;
718e3744 722
508e53e2 723 if (ospf6->rmap[type].name)
724 vty_out (vty, " redistribute %s route-map %s%s",
049207c3 725 ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
508e53e2 726 else
727 vty_out (vty, " redistribute %s%s",
049207c3 728 ZROUTE_NAME (type), VNL);
508e53e2 729 }
718e3744 730
731 return 0;
732}
733
6ac29a51 734static void
508e53e2 735ospf6_redistribute_show_config (struct vty *vty)
718e3744 736{
508e53e2 737 int type;
738 int nroute[ZEBRA_ROUTE_MAX];
739 int total;
740 struct ospf6_route *route;
741 struct ospf6_external_info *info;
718e3744 742
508e53e2 743 total = 0;
744 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
745 nroute[type] = 0;
746 for (route = ospf6_route_head (ospf6->external_table); route;
747 route = ospf6_route_next (route))
718e3744 748 {
508e53e2 749 info = route->route_option;
750 nroute[info->type]++;
751 total++;
718e3744 752 }
753
049207c3 754 vty_out (vty, "Redistributing External Routes from:%s", VNL);
508e53e2 755 for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
718e3744 756 {
508e53e2 757 if (type == ZEBRA_ROUTE_OSPF6)
758 continue;
759 if (! ospf6_zebra_is_redistribute (type))
760 continue;
718e3744 761
508e53e2 762 if (ospf6->rmap[type].name)
763 vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
764 ZROUTE_NAME (type), ospf6->rmap[type].name,
765 (ospf6->rmap[type].map ? "" : " (not found !)"),
049207c3 766 VNL);
718e3744 767 else
508e53e2 768 vty_out (vty, " %d: %s%s", nroute[type],
049207c3 769 ZROUTE_NAME (type), VNL);
718e3744 770 }
049207c3 771 vty_out (vty, "Total %d routes%s", total, VNL);
508e53e2 772}
718e3744 773
718e3744 774
508e53e2 775\f
776/* Routemap Functions */
6ac29a51 777static route_map_result_t
508e53e2 778ospf6_routemap_rule_match_address_prefixlist (void *rule,
779 struct prefix *prefix,
780 route_map_object_t type,
781 void *object)
782{
783 struct prefix_list *plist;
718e3744 784
508e53e2 785 if (type != RMAP_OSPF6)
786 return RMAP_NOMATCH;
718e3744 787
508e53e2 788 plist = prefix_list_lookup (AFI_IP6, (char *) rule);
789 if (plist == NULL)
790 return RMAP_NOMATCH;
718e3744 791
508e53e2 792 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
793 RMAP_NOMATCH : RMAP_MATCH);
794}
718e3744 795
6ac29a51 796static void *
0c083ee9 797ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
508e53e2 798{
799 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 800}
801
6ac29a51 802static void
508e53e2 803ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
718e3744 804{
508e53e2 805 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
806}
718e3744 807
508e53e2 808struct route_map_rule_cmd
809ospf6_routemap_rule_match_address_prefixlist_cmd =
810{
811 "ipv6 address prefix-list",
812 ospf6_routemap_rule_match_address_prefixlist,
813 ospf6_routemap_rule_match_address_prefixlist_compile,
814 ospf6_routemap_rule_match_address_prefixlist_free,
815};
718e3744 816
42a7debf
VT
817/* `match interface IFNAME' */
818/* Match function should return 1 if match is success else return
819 zero. */
820static route_map_result_t
821ospf6_routemap_rule_match_interface (void *rule, struct prefix *prefix,
822 route_map_object_t type, void *object)
823{
824 struct interface *ifp;
825 struct ospf6_external_info *ei;
826
827 if (type == RMAP_OSPF6)
828 {
829 ei = ((struct ospf6_route *) object)->route_option;
830 ifp = if_lookup_by_name ((char *)rule);
831
832 if (ifp != NULL
833 && ei->ifindex == ifp->ifindex)
834 return RMAP_MATCH;
835 }
836
837 return RMAP_NOMATCH;
838}
839
840/* Route map `interface' match statement. `arg' should be
841 interface name. */
842static void *
843ospf6_routemap_rule_match_interface_compile (const char *arg)
844{
845 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
846}
847
848/* Free route map's compiled `interface' value. */
849static void
850ospf6_routemap_rule_match_interface_free (void *rule)
851{
852 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
853}
854
855/* Route map commands for interface matching. */
856struct route_map_rule_cmd
857ospf6_routemap_rule_match_interface_cmd =
858{
859 "interface",
860 ospf6_routemap_rule_match_interface,
861 ospf6_routemap_rule_match_interface_compile,
862 ospf6_routemap_rule_match_interface_free
863};
864
6ac29a51 865static route_map_result_t
508e53e2 866ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
867 route_map_object_t type, void *object)
868{
869 char *metric_type = rule;
870 struct ospf6_route *route = object;
718e3744 871
508e53e2 872 if (type != RMAP_OSPF6)
873 return RMAP_OKAY;
718e3744 874
508e53e2 875 if (strcmp (metric_type, "type-2") == 0)
876 route->path.metric_type = 2;
718e3744 877 else
508e53e2 878 route->path.metric_type = 1;
718e3744 879
508e53e2 880 return RMAP_OKAY;
881}
718e3744 882
6ac29a51 883static void *
0c083ee9 884ospf6_routemap_rule_set_metric_type_compile (const char *arg)
508e53e2 885{
886 if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
887 return NULL;
888 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 889}
890
6ac29a51 891static void
508e53e2 892ospf6_routemap_rule_set_metric_type_free (void *rule)
718e3744 893{
508e53e2 894 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
895}
718e3744 896
508e53e2 897struct route_map_rule_cmd
898ospf6_routemap_rule_set_metric_type_cmd =
899{
900 "metric-type",
901 ospf6_routemap_rule_set_metric_type,
902 ospf6_routemap_rule_set_metric_type_compile,
903 ospf6_routemap_rule_set_metric_type_free,
904};
718e3744 905
6ac29a51 906static route_map_result_t
508e53e2 907ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
908 route_map_object_t type, void *object)
909{
910 char *metric = rule;
911 struct ospf6_route *route = object;
718e3744 912
508e53e2 913 if (type != RMAP_OSPF6)
914 return RMAP_OKAY;
718e3744 915
508e53e2 916 route->path.cost = atoi (metric);
917 return RMAP_OKAY;
918}
718e3744 919
6ac29a51 920static void *
0c083ee9 921ospf6_routemap_rule_set_metric_compile (const char *arg)
508e53e2 922{
923 u_int32_t metric;
924 char *endp;
925 metric = strtoul (arg, &endp, 0);
926 if (metric > LS_INFINITY || *endp != '\0')
927 return NULL;
928 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 929}
930
6ac29a51 931static void
508e53e2 932ospf6_routemap_rule_set_metric_free (void *rule)
718e3744 933{
508e53e2 934 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
935}
718e3744 936
508e53e2 937struct route_map_rule_cmd
938ospf6_routemap_rule_set_metric_cmd =
939{
940 "metric",
941 ospf6_routemap_rule_set_metric,
942 ospf6_routemap_rule_set_metric_compile,
943 ospf6_routemap_rule_set_metric_free,
944};
718e3744 945
6ac29a51 946static route_map_result_t
508e53e2 947ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
948 route_map_object_t type, void *object)
949{
950 char *forwarding = rule;
951 struct ospf6_route *route = object;
952 struct ospf6_external_info *info = route->route_option;
718e3744 953
508e53e2 954 if (type != RMAP_OSPF6)
955 return RMAP_OKAY;
718e3744 956
508e53e2 957 if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
718e3744 958 {
508e53e2 959 memset (&info->forwarding, 0, sizeof (struct in6_addr));
960 return RMAP_ERROR;
718e3744 961 }
718e3744 962
508e53e2 963 return RMAP_OKAY;
718e3744 964}
965
6ac29a51 966static void *
0c083ee9 967ospf6_routemap_rule_set_forwarding_compile (const char *arg)
718e3744 968{
508e53e2 969 struct in6_addr a;
970 if (inet_pton (AF_INET6, arg, &a) != 1)
971 return NULL;
972 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
718e3744 973}
974
6ac29a51 975static void
508e53e2 976ospf6_routemap_rule_set_forwarding_free (void *rule)
718e3744 977{
508e53e2 978 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
979}
718e3744 980
508e53e2 981struct route_map_rule_cmd
982ospf6_routemap_rule_set_forwarding_cmd =
983{
984 "forwarding-address",
985 ospf6_routemap_rule_set_forwarding,
986 ospf6_routemap_rule_set_forwarding_compile,
987 ospf6_routemap_rule_set_forwarding_free,
988};
718e3744 989
6ac29a51 990static int
508e53e2 991route_map_command_status (struct vty *vty, int ret)
992{
993 if (! ret)
994 return CMD_SUCCESS;
718e3744 995
508e53e2 996 switch (ret)
718e3744 997 {
508e53e2 998 case RMAP_RULE_MISSING:
049207c3 999 vty_out (vty, "Can't find rule.%s", VNL);
508e53e2 1000 break;
1001 case RMAP_COMPILE_ERROR:
049207c3 1002 vty_out (vty, "Argument is malformed.%s", VNL);
508e53e2 1003 break;
1004 default:
049207c3 1005 vty_out (vty, "route-map add set failed.%s", VNL);
508e53e2 1006 break;
718e3744 1007 }
508e53e2 1008 return CMD_WARNING;
1009}
718e3744 1010
508e53e2 1011/* add "match address" */
1012DEFUN (ospf6_routemap_match_address_prefixlist,
1013 ospf6_routemap_match_address_prefixlist_cmd,
1014 "match ipv6 address prefix-list WORD",
1015 "Match values\n"
1016 IPV6_STR
1017 "Match address of route\n"
1018 "Match entries of prefix-lists\n"
1019 "IPv6 prefix-list name\n")
1020{
1021 int ret = route_map_add_match ((struct route_map_index *) vty->index,
1022 "ipv6 address prefix-list", argv[0]);
1023 return route_map_command_status (vty, ret);
1024}
1025
1026/* delete "match address" */
1027DEFUN (ospf6_routemap_no_match_address_prefixlist,
1028 ospf6_routemap_no_match_address_prefixlist_cmd,
1029 "no match ipv6 address prefix-list WORD",
1030 NO_STR
1031 "Match values\n"
1032 IPV6_STR
1033 "Match address of route\n"
1034 "Match entries of prefix-lists\n"
1035 "IPv6 prefix-list name\n")
1036{
1037 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1038 "ipv6 address prefix-list", argv[0]);
1039 return route_map_command_status (vty, ret);
1040}
718e3744 1041
42a7debf
VT
1042/* "match interface" */
1043DEFUN (ospf6_routemap_match_interface,
1044 ospf6_routemap_match_interface_cmd,
1045 "match interface WORD",
1046 MATCH_STR
1047 "Match first hop interface of route\n"
1048 "Interface name\n")
1049{
1050 return route_map_add_match ((struct route_map_index *) vty->index,
1051 "interface", argv[0]);
1052}
1053
1054/* "no match interface WORD" */
1055DEFUN (ospf6_routemap_no_match_interface,
1056 ospf6_routemap_no_match_interface_cmd,
1057 "no match interface",
1058 MATCH_STR
1059 NO_STR
1060 "Match first hop interface of route\n")
1061{
1062 int ret = route_map_delete_match ((struct route_map_index *) vty->index,
1063 "interface", (argc == 0) ? NULL : argv[0]);
1064 return route_map_command_status (vty, ret);
1065}
1066
1067ALIAS (ospf6_routemap_no_match_interface,
1068 ospf6_routemap_no_match_interface_val_cmd,
1069 "no match interface WORD",
1070 MATCH_STR
1071 NO_STR
1072 "Match first hop interface of route\n"
1073 "Interface name\n")
1074
508e53e2 1075/* add "set metric-type" */
1076DEFUN (ospf6_routemap_set_metric_type,
1077 ospf6_routemap_set_metric_type_cmd,
1078 "set metric-type (type-1|type-2)",
1079 "Set value\n"
1080 "Type of metric\n"
1081 "OSPF6 external type 1 metric\n"
1082 "OSPF6 external type 2 metric\n")
1083{
1084 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1085 "metric-type", argv[0]);
1086 return route_map_command_status (vty, ret);
718e3744 1087}
1088
508e53e2 1089/* delete "set metric-type" */
1090DEFUN (ospf6_routemap_no_set_metric_type,
1091 ospf6_routemap_no_set_metric_type_cmd,
1092 "no set metric-type (type-1|type-2)",
1093 NO_STR
1094 "Set value\n"
1095 "Type of metric\n"
1096 "OSPF6 external type 1 metric\n"
1097 "OSPF6 external type 2 metric\n")
718e3744 1098{
508e53e2 1099 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1100 "metric-type", argv[0]);
1101 return route_map_command_status (vty, ret);
1102}
718e3744 1103
508e53e2 1104/* add "set metric" */
1105DEFUN (set_metric,
1106 set_metric_cmd,
1107 "set metric <0-4294967295>",
1108 "Set value\n"
1109 "Metric value\n"
1110 "Metric value\n")
1111{
1112 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1113 "metric", argv[0]);
1114 return route_map_command_status (vty, ret);
1115}
718e3744 1116
508e53e2 1117/* delete "set metric" */
1118DEFUN (no_set_metric,
1119 no_set_metric_cmd,
1120 "no set metric <0-4294967295>",
1121 NO_STR
1122 "Set value\n"
1123 "Metric\n"
1124 "METRIC value\n")
1125{
1126 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1127 "metric", argv[0]);
1128 return route_map_command_status (vty, ret);
1129}
718e3744 1130
508e53e2 1131/* add "set forwarding-address" */
1132DEFUN (ospf6_routemap_set_forwarding,
1133 ospf6_routemap_set_forwarding_cmd,
1134 "set forwarding-address X:X::X:X",
1135 "Set value\n"
1136 "Forwarding Address\n"
1137 "IPv6 Address\n")
1138{
1139 int ret = route_map_add_set ((struct route_map_index *) vty->index,
1140 "forwarding-address", argv[0]);
1141 return route_map_command_status (vty, ret);
1142}
718e3744 1143
508e53e2 1144/* delete "set forwarding-address" */
1145DEFUN (ospf6_routemap_no_set_forwarding,
1146 ospf6_routemap_no_set_forwarding_cmd,
1147 "no set forwarding-address X:X::X:X",
1148 NO_STR
1149 "Set value\n"
1150 "Forwarding Address\n"
1151 "IPv6 Address\n")
1152{
1153 int ret = route_map_delete_set ((struct route_map_index *) vty->index,
1154 "forwarding-address", argv[0]);
1155 return route_map_command_status (vty, ret);
1156}
718e3744 1157
6ac29a51
PJ
1158static void
1159ospf6_routemap_init (void)
508e53e2 1160{
1161 route_map_init ();
1162 route_map_init_vty ();
1163 route_map_add_hook (ospf6_asbr_routemap_update);
1164 route_map_delete_hook (ospf6_asbr_routemap_update);
1165
1166 route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
42a7debf
VT
1167 route_map_install_match (&ospf6_routemap_rule_match_interface_cmd);
1168
508e53e2 1169 route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
1170 route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
1171 route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
1172
1173 /* Match address prefix-list */
1174 install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
1175 install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
1176
42a7debf
VT
1177 /* Match interface */
1178 install_element (RMAP_NODE, &ospf6_routemap_match_interface_cmd);
1179 install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_cmd);
1180 install_element (RMAP_NODE, &ospf6_routemap_no_match_interface_val_cmd);
1181
508e53e2 1182 /* ASE Metric Type (e.g. Type-1/Type-2) */
1183 install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
1184 install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
1185
1186 /* ASE Metric */
1187 install_element (RMAP_NODE, &set_metric_cmd);
1188 install_element (RMAP_NODE, &no_set_metric_cmd);
1189
1190 /* ASE Metric */
1191 install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
1192 install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
718e3744 1193}
1194
508e53e2 1195\f
1196/* Display functions */
6ac29a51 1197static int
508e53e2 1198ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
718e3744 1199{
508e53e2 1200 struct ospf6_as_external_lsa *external;
1201 char buf[64];
1202 struct in6_addr in6, *forwarding;
718e3744 1203
1204 assert (lsa->header);
508e53e2 1205 external = (struct ospf6_as_external_lsa *)
1206 OSPF6_LSA_HEADER_END (lsa->header);
718e3744 1207
1208 /* bits */
508e53e2 1209 snprintf (buf, sizeof (buf), "%c%c%c",
1210 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
1211 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
1212 (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
718e3744 1213
049207c3 1214 vty_out (vty, " Bits: %s%s", buf, VNL);
508e53e2 1215 vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
049207c3 1216 VNL);
718e3744 1217
508e53e2 1218 ospf6_prefix_options_printbuf (external->prefix.prefix_options,
1219 buf, sizeof (buf));
1220 vty_out (vty, " Prefix Options: %s%s", buf,
049207c3 1221 VNL);
718e3744 1222
1223 vty_out (vty, " Referenced LSType: %d%s",
508e53e2 1224 ntohs (external->prefix.prefix_refer_lstype),
049207c3 1225 VNL);
718e3744 1226
508e53e2 1227 ospf6_prefix_in6_addr (&in6, &external->prefix);
718e3744 1228 inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
508e53e2 1229 vty_out (vty, " Prefix: %s/%d%s", buf,
049207c3 1230 external->prefix.prefix_length, VNL);
718e3744 1231
1232 /* Forwarding-Address */
1233 if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
1234 {
508e53e2 1235 forwarding = (struct in6_addr *)
1236 ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
1237 OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
1238 inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
049207c3 1239 vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
718e3744 1240 }
1241
1242 return 0;
1243}
1244
6ac29a51 1245static void
508e53e2 1246ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
718e3744 1247{
508e53e2 1248 struct ospf6_external_info *info = route->route_option;
1249 char prefix[64], id[16], forwarding[64];
1250 u_int32_t tmp_id;
718e3744 1251
508e53e2 1252 prefix2str (&route->prefix, prefix, sizeof (prefix));
1253 tmp_id = ntohl (info->id);
1254 inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
1255 if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
1256 inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
1257 else
1258 snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
1259 route->nexthop[0].ifindex);
1260
f52d13cb 1261 vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
1262 zebra_route_char(info->type),
508e53e2 1263 prefix, id, route->path.metric_type,
1264 (u_long) (route->path.metric_type == 2 ?
1265 route->path.cost_e2 : route->path.cost),
049207c3 1266 forwarding, VNL);
718e3744 1267}
1268
508e53e2 1269DEFUN (show_ipv6_ospf6_redistribute,
1270 show_ipv6_ospf6_redistribute_cmd,
1271 "show ipv6 ospf6 redistribute",
1272 SHOW_STR
1273 IP6_STR
1274 OSPF6_STR
1275 "redistributing External information\n"
1276 )
718e3744 1277{
508e53e2 1278 struct ospf6_route *route;
718e3744 1279
508e53e2 1280 ospf6_redistribute_show_config (vty);
718e3744 1281
508e53e2 1282 for (route = ospf6_route_head (ospf6->external_table); route;
1283 route = ospf6_route_next (route))
1284 ospf6_asbr_external_route_show (vty, route);
1285
1286 return CMD_SUCCESS;
718e3744 1287}
1288
6452df09 1289struct ospf6_lsa_handler as_external_handler =
718e3744 1290{
6452df09 1291 OSPF6_LSTYPE_AS_EXTERNAL,
1292 "AS-External",
1293 ospf6_as_external_lsa_show
1294};
508e53e2 1295
718e3744 1296void
6ac29a51 1297ospf6_asbr_init (void)
718e3744 1298{
508e53e2 1299 ospf6_routemap_init ();
1300
6452df09 1301 ospf6_install_lsa_handler (&as_external_handler);
718e3744 1302
508e53e2 1303 install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
1304 install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
1305
718e3744 1306 install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
1307 install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
1308 install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
1309}
1310
ae2254aa
TG
1311void
1312ospf6_asbr_terminate (void)
1313{
1314 route_map_finish ();
1315}
718e3744 1316
508e53e2 1317DEFUN (debug_ospf6_asbr,
1318 debug_ospf6_asbr_cmd,
1319 "debug ospf6 asbr",
1320 DEBUG_STR
1321 OSPF6_STR
1322 "Debug OSPFv3 ASBR function\n"
1323 )
1324{
1325 OSPF6_DEBUG_ASBR_ON ();
1326 return CMD_SUCCESS;
1327}
1328
1329DEFUN (no_debug_ospf6_asbr,
1330 no_debug_ospf6_asbr_cmd,
1331 "no debug ospf6 asbr",
1332 NO_STR
1333 DEBUG_STR
1334 OSPF6_STR
1335 "Debug OSPFv3 ASBR function\n"
1336 )
1337{
1338 OSPF6_DEBUG_ASBR_OFF ();
1339 return CMD_SUCCESS;
1340}
1341
1342int
1343config_write_ospf6_debug_asbr (struct vty *vty)
1344{
1345 if (IS_OSPF6_DEBUG_ASBR)
049207c3 1346 vty_out (vty, "debug ospf6 asbr%s", VNL);
508e53e2 1347 return 0;
1348}
1349
1350void
1351install_element_ospf6_debug_asbr ()
1352{
1353 install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
1354 install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
1355 install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
1356 install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
1357}
1358
1359