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