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