2 * Area Border Router function.
3 * Copyright (C) 2004 Yasuhiro Ohara
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
35 #include "ospf6_proto.h"
36 #include "ospf6_route.h"
37 #include "ospf6_lsa.h"
38 #include "ospf6_route.h"
39 #include "ospf6_lsdb.h"
40 #include "ospf6_message.h"
42 #include "ospf6_top.h"
43 #include "ospf6_area.h"
44 #include "ospf6_interface.h"
45 #include "ospf6_neighbor.h"
47 #include "ospf6_flood.h"
48 #include "ospf6_intra.h"
49 #include "ospf6_abr.h"
52 unsigned char conf_debug_ospf6_abr
;
55 ospf6_is_router_abr (struct ospf6
*o
)
57 struct listnode
*node
;
58 struct ospf6_area
*oa
;
61 for (ALL_LIST_ELEMENTS_RO (o
->area_list
, node
, oa
))
62 if (IS_AREA_ENABLED (oa
))
71 ospf6_abr_enable_area (struct ospf6_area
*area
)
73 struct ospf6_area
*oa
;
74 struct ospf6_route
*ro
;
75 struct listnode
*node
, *nnode
;
77 for (ALL_LIST_ELEMENTS (area
->ospf6
->area_list
, node
, nnode
, oa
))
79 /* update B bit for each area */
80 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
82 /* install other area's configured address range */
85 for (ro
= ospf6_route_head (oa
->range_table
); ro
;
86 ro
= ospf6_route_next (ro
))
88 if (CHECK_FLAG (ro
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
))
89 ospf6_abr_originate_summary_to_area (ro
, area
);
94 /* install calculated routes to border routers */
95 for (ro
= ospf6_route_head (area
->ospf6
->brouter_table
); ro
;
96 ro
= ospf6_route_next (ro
))
97 ospf6_abr_originate_summary_to_area (ro
, area
);
99 /* install calculated routes to network (may be rejected by ranges) */
100 for (ro
= ospf6_route_head (area
->ospf6
->route_table
); ro
;
101 ro
= ospf6_route_next (ro
))
102 ospf6_abr_originate_summary_to_area (ro
, area
);
106 ospf6_abr_disable_area (struct ospf6_area
*area
)
108 struct ospf6_area
*oa
;
109 struct ospf6_route
*ro
;
110 struct ospf6_lsa
*old
;
111 struct listnode
*node
, *nnode
;
113 /* Withdraw all summary prefixes previously originated */
114 for (ro
= ospf6_route_head (area
->summary_prefix
); ro
;
115 ro
= ospf6_route_next (ro
))
117 old
= ospf6_lsdb_lookup (ro
->path
.origin
.type
, ro
->path
.origin
.id
,
118 area
->ospf6
->router_id
, area
->lsdb
);
120 ospf6_lsa_purge (old
);
121 ospf6_route_remove (ro
, area
->summary_prefix
);
124 /* Withdraw all summary router-routes previously originated */
125 for (ro
= ospf6_route_head (area
->summary_router
); ro
;
126 ro
= ospf6_route_next (ro
))
128 old
= ospf6_lsdb_lookup (ro
->path
.origin
.type
, ro
->path
.origin
.id
,
129 area
->ospf6
->router_id
, area
->lsdb
);
131 ospf6_lsa_purge (old
);
132 ospf6_route_remove (ro
, area
->summary_router
);
135 /* Schedule Router-LSA for each area (ABR status may change) */
136 for (ALL_LIST_ELEMENTS (area
->ospf6
->area_list
, node
, nnode
, oa
))
137 /* update B bit for each area */
138 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
141 /* RFC 2328 12.4.3. Summary-LSAs */
143 ospf6_abr_originate_summary_to_area (struct ospf6_route
*route
,
144 struct ospf6_area
*area
)
146 struct ospf6_lsa
*lsa
, *old
= NULL
;
147 struct ospf6_interface
*oi
;
148 struct ospf6_route
*summary
, *range
= NULL
;
149 struct ospf6_area
*route_area
;
150 char buffer
[OSPF6_MAX_LSASIZE
];
151 struct ospf6_lsa_header
*lsa_header
;
153 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
154 struct ospf6_inter_router_lsa
*router_lsa
;
155 struct ospf6_route_table
*summary_table
= NULL
;
160 if (route
->type
== OSPF6_DEST_TYPE_ROUTER
)
162 if (IS_OSPF6_DEBUG_ABR
|| IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER
))
165 inet_ntop (AF_INET
, &(ADV_ROUTER_IN_PREFIX (&route
->prefix
)),
167 zlog_debug ("Originating summary in area %s for ASBR %s",
170 summary_table
= area
->summary_router
;
174 if (IS_OSPF6_DEBUG_ABR
|| IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX
))
177 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
178 zlog_debug ("Originating summary in area %s for %s",
181 summary_table
= area
->summary_prefix
;
184 summary
= ospf6_route_lookup (&route
->prefix
, summary_table
);
186 old
= ospf6_lsdb_lookup (summary
->path
.origin
.type
,
187 summary
->path
.origin
.id
,
188 area
->ospf6
->router_id
, area
->lsdb
);
190 /* if this route has just removed, remove corresponding LSA */
191 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
))
194 zlog_debug ("The route has just removed, purge previous LSA");
196 ospf6_route_remove (summary
, summary_table
);
198 ospf6_lsa_purge (old
);
202 /* Only destination type network, range or ASBR are considered */
203 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
&&
204 route
->type
!= OSPF6_DEST_TYPE_RANGE
&&
205 (route
->type
!= OSPF6_DEST_TYPE_ROUTER
||
206 ! CHECK_FLAG (route
->path
.router_bits
, OSPF6_ROUTER_BIT_E
)))
209 zlog_debug ("Route type is none of network, range nor ASBR, withdraw");
211 ospf6_route_remove (summary
, summary_table
);
213 ospf6_lsa_purge (old
);
217 /* AS External routes are never considered */
218 if (route
->path
.type
== OSPF6_PATH_TYPE_EXTERNAL1
||
219 route
->path
.type
== OSPF6_PATH_TYPE_EXTERNAL2
)
222 zlog_debug ("Path type is external, withdraw");
224 ospf6_route_remove (summary
, summary_table
);
226 ospf6_lsa_purge (old
);
230 /* do not generate if the path's area is the same as target area */
231 if (route
->path
.area_id
== area
->area_id
)
234 zlog_debug ("The route is in the area itself, ignore");
236 ospf6_route_remove (summary
, summary_table
);
238 ospf6_lsa_purge (old
);
242 /* do not generate if the nexthops belongs to the target area */
243 oi
= ospf6_interface_lookup_by_ifindex (route
->nexthop
[0].ifindex
);
244 if (oi
&& oi
->area
&& oi
->area
== area
)
247 zlog_debug ("The route's nexthop is in the same area, ignore");
249 ospf6_route_remove (summary
, summary_table
);
251 ospf6_lsa_purge (old
);
255 /* do not generate if the route cost is greater or equal to LSInfinity */
256 if (route
->path
.cost
>= LS_INFINITY
)
259 zlog_debug ("The cost exceeds LSInfinity, withdraw");
261 ospf6_route_remove (summary
, summary_table
);
263 ospf6_lsa_purge (old
);
267 /* if this is a route to ASBR */
268 if (route
->type
== OSPF6_DEST_TYPE_ROUTER
)
270 /* Only the prefered best path is considered */
271 if (! CHECK_FLAG (route
->flag
, OSPF6_ROUTE_BEST
))
274 zlog_debug ("This is the secondary path to the ASBR, ignore");
276 ospf6_route_remove (summary
, summary_table
);
278 ospf6_lsa_purge (old
);
282 /* Do not generate if the area is stub */
286 /* if this is an intra-area route, this may be suppressed by aggregation */
287 if (route
->type
== OSPF6_DEST_TYPE_NETWORK
&&
288 route
->path
.type
== OSPF6_PATH_TYPE_INTRA
)
290 /* search for configured address range for the route's area */
291 route_area
= ospf6_area_lookup (route
->path
.area_id
, area
->ospf6
);
293 range
= ospf6_route_lookup_bestmatch (&route
->prefix
,
294 route_area
->range_table
);
296 /* ranges are ignored when originate backbone routes to transit area.
297 Otherwise, if ranges are configured, the route is suppressed. */
298 if (range
&& ! CHECK_FLAG (range
->flag
, OSPF6_ROUTE_REMOVE
) &&
299 (route
->path
.area_id
!= BACKBONE_AREA_ID
||
300 ! IS_AREA_TRANSIT (area
)))
304 prefix2str (&range
->prefix
, buf
, sizeof (buf
));
305 zlog_debug ("Suppressed by range %s of area %s",
306 buf
, route_area
->name
);
310 ospf6_route_remove (summary
, summary_table
);
312 ospf6_lsa_purge (old
);
317 /* If this is a configured address range */
318 if (route
->type
== OSPF6_DEST_TYPE_RANGE
)
320 /* If DoNotAdvertise is set */
321 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
))
324 zlog_debug ("This is the range with DoNotAdvertise set. ignore");
326 ospf6_route_remove (summary
, summary_table
);
328 ospf6_lsa_purge (old
);
332 /* Whether the route have active longer prefix */
333 if (! CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
))
336 zlog_debug ("The range is not active. withdraw");
338 ospf6_route_remove (summary
, summary_table
);
340 ospf6_lsa_purge (old
);
345 /* Check export list */
346 if (EXPORT_NAME (area
))
348 if (EXPORT_LIST (area
) == NULL
)
350 access_list_lookup (AFI_IP6
, EXPORT_NAME (area
));
352 if (EXPORT_LIST (area
))
353 if (access_list_apply (EXPORT_LIST (area
),
354 &route
->prefix
) == FILTER_DENY
)
358 inet_ntop (AF_INET
, &(ADV_ROUTER_IN_PREFIX (&route
->prefix
)),
360 zlog_debug ("prefix %s was denied by export list", buf
);
366 /* Check filter-list */
367 if (PREFIX_NAME_OUT (area
))
369 if (PREFIX_LIST_OUT (area
) == NULL
)
370 PREFIX_LIST_OUT (area
) =
371 prefix_list_lookup(AFI_IP6
, PREFIX_NAME_OUT (area
));
373 if (PREFIX_LIST_OUT (area
))
374 if (prefix_list_apply (PREFIX_LIST_OUT (area
),
375 &route
->prefix
) != PREFIX_PERMIT
)
379 inet_ntop (AF_INET
, &(ADV_ROUTER_IN_PREFIX (&route
->prefix
)),
381 zlog_debug ("prefix %s was denied by filter-list out", buf
);
387 /* the route is going to be originated. store it in area's summary_table */
390 summary
= ospf6_route_copy (route
);
391 if (route
->type
== OSPF6_DEST_TYPE_NETWORK
||
392 route
->type
== OSPF6_DEST_TYPE_RANGE
)
393 summary
->path
.origin
.type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
395 summary
->path
.origin
.type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
396 summary
->path
.origin
.adv_router
= area
->ospf6
->router_id
;
397 summary
->path
.origin
.id
=
398 ospf6_new_ls_id (summary
->path
.origin
.type
,
399 summary
->path
.origin
.adv_router
, area
->lsdb
);
400 summary
= ospf6_route_add (summary
, summary_table
);
404 summary
->type
= route
->type
;
405 quagga_gettime (QUAGGA_CLK_MONOTONIC
, &summary
->changed
);
408 summary
->path
.router_bits
= route
->path
.router_bits
;
409 summary
->path
.options
[0] = route
->path
.options
[0];
410 summary
->path
.options
[1] = route
->path
.options
[1];
411 summary
->path
.options
[2] = route
->path
.options
[2];
412 summary
->path
.prefix_options
= route
->path
.prefix_options
;
413 summary
->path
.area_id
= area
->area_id
;
414 summary
->path
.type
= OSPF6_PATH_TYPE_INTER
;
415 summary
->path
.cost
= route
->path
.cost
;
416 summary
->nexthop
[0] = route
->nexthop
[0];
419 memset (buffer
, 0, sizeof (buffer
));
420 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
422 if (route
->type
== OSPF6_DEST_TYPE_ROUTER
)
424 router_lsa
= (struct ospf6_inter_router_lsa
*)
425 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
426 p
= (caddr_t
) router_lsa
+ sizeof (struct ospf6_inter_router_lsa
);
428 /* Fill Inter-Area-Router-LSA */
429 router_lsa
->options
[0] = route
->path
.options
[0];
430 router_lsa
->options
[1] = route
->path
.options
[1];
431 router_lsa
->options
[2] = route
->path
.options
[2];
432 OSPF6_ABR_SUMMARY_METRIC_SET (router_lsa
, route
->path
.cost
);
433 router_lsa
->router_id
= ADV_ROUTER_IN_PREFIX (&route
->prefix
);
434 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
438 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
439 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
440 p
= (caddr_t
) prefix_lsa
+ sizeof (struct ospf6_inter_prefix_lsa
);
442 /* Fill Inter-Area-Prefix-LSA */
443 OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa
, route
->path
.cost
);
444 prefix_lsa
->prefix
.prefix_length
= route
->prefix
.prefixlen
;
445 prefix_lsa
->prefix
.prefix_options
= route
->path
.prefix_options
;
448 memcpy (p
, &route
->prefix
.u
.prefix6
,
449 OSPF6_PREFIX_SPACE (route
->prefix
.prefixlen
));
450 ospf6_prefix_apply_mask (&prefix_lsa
->prefix
);
451 p
+= OSPF6_PREFIX_SPACE (route
->prefix
.prefixlen
);
452 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
455 /* Fill LSA Header */
457 lsa_header
->type
= type
;
458 lsa_header
->id
= summary
->path
.origin
.id
;
459 lsa_header
->adv_router
= area
->ospf6
->router_id
;
461 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
462 lsa_header
->adv_router
, area
->lsdb
);
463 lsa_header
->length
= htons ((caddr_t
) p
- (caddr_t
) lsa_header
);
466 ospf6_lsa_checksum (lsa_header
);
469 lsa
= ospf6_lsa_create (lsa_header
);
472 ospf6_lsa_originate_area (lsa
, area
);
476 ospf6_abr_range_update (struct ospf6_route
*range
)
479 struct ospf6_route
*ro
;
481 assert (range
->type
== OSPF6_DEST_TYPE_RANGE
);
483 /* update range's cost and active flag */
484 for (ro
= ospf6_route_match_head (&range
->prefix
, ospf6
->route_table
);
485 ro
; ro
= ospf6_route_match_next (&range
->prefix
, ro
))
487 if (ro
->path
.area_id
== range
->path
.area_id
&&
488 ! CHECK_FLAG (ro
->flag
, OSPF6_ROUTE_REMOVE
))
489 cost
= MAX (cost
, ro
->path
.cost
);
492 if (range
->path
.cost
!= cost
)
494 range
->path
.cost
= cost
;
496 if (range
->path
.cost
)
497 SET_FLAG (range
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
);
499 UNSET_FLAG (range
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
);
501 ospf6_abr_originate_summary (range
);
506 ospf6_abr_originate_summary (struct ospf6_route
*route
)
508 struct listnode
*node
, *nnode
;
509 struct ospf6_area
*oa
;
510 struct ospf6_route
*range
= NULL
;
512 if (route
->type
== OSPF6_DEST_TYPE_NETWORK
)
514 oa
= ospf6_area_lookup (route
->path
.area_id
, ospf6
);
515 range
= ospf6_route_lookup_bestmatch (&route
->prefix
, oa
->range_table
);
517 ospf6_abr_range_update (range
);
520 for (ALL_LIST_ELEMENTS (ospf6
->area_list
, node
, nnode
, oa
))
521 ospf6_abr_originate_summary_to_area (route
, oa
);
524 /* RFC 2328 16.2. Calculating the inter-area routes */
526 ospf6_abr_examin_summary (struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
528 struct prefix prefix
, abr_prefix
;
529 struct ospf6_route_table
*table
= NULL
;
530 struct ospf6_route
*range
, *route
, *old
= NULL
;
531 struct ospf6_route
*abr_entry
;
533 char options
[3] = {0, 0, 0};
534 u_int8_t prefix_options
= 0;
536 u_char router_bits
= 0;
541 memset (&prefix
, 0, sizeof (prefix
));
543 if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_PREFIX
))
545 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
547 if (IS_OSPF6_DEBUG_EXAMIN (INTER_PREFIX
))
550 zlog_debug ("Examin %s in area %s", lsa
->name
, oa
->name
);
553 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
554 OSPF6_LSA_HEADER_END (lsa
->header
);
555 prefix
.family
= AF_INET6
;
556 prefix
.prefixlen
= prefix_lsa
->prefix
.prefix_length
;
557 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, &prefix_lsa
->prefix
);
558 prefix2str (&prefix
, buf
, sizeof (buf
));
559 table
= oa
->ospf6
->route_table
;
560 type
= OSPF6_DEST_TYPE_NETWORK
;
561 prefix_options
= prefix_lsa
->prefix
.prefix_options
;
562 cost
= OSPF6_ABR_SUMMARY_METRIC (prefix_lsa
);
564 else if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_ROUTER
))
566 struct ospf6_inter_router_lsa
*router_lsa
;
568 if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER
))
571 zlog_debug ("Examin %s in area %s", lsa
->name
, oa
->name
);
574 router_lsa
= (struct ospf6_inter_router_lsa
*)
575 OSPF6_LSA_HEADER_END (lsa
->header
);
576 ospf6_linkstate_prefix (router_lsa
->router_id
, htonl (0), &prefix
);
577 inet_ntop (AF_INET
, &router_lsa
->router_id
, buf
, sizeof (buf
));
578 table
= oa
->ospf6
->brouter_table
;
579 type
= OSPF6_DEST_TYPE_ROUTER
;
580 options
[0] = router_lsa
->options
[0];
581 options
[1] = router_lsa
->options
[1];
582 options
[2] = router_lsa
->options
[2];
583 cost
= OSPF6_ABR_SUMMARY_METRIC (router_lsa
);
584 SET_FLAG (router_bits
, OSPF6_ROUTER_BIT_E
);
589 /* Find existing route */
590 route
= ospf6_route_lookup (&prefix
, table
);
592 ospf6_route_lock (route
);
593 while (route
&& ospf6_route_is_prefix (&prefix
, route
))
595 if (route
->path
.area_id
== oa
->area_id
&&
596 route
->path
.origin
.type
== lsa
->header
->type
&&
597 route
->path
.origin
.id
== lsa
->header
->id
&&
598 route
->path
.origin
.adv_router
== lsa
->header
->adv_router
&&
599 ! CHECK_FLAG (route
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
601 route
= ospf6_route_next (route
);
604 /* (1) if cost == LSInfinity or if the LSA is MaxAge */
605 if (cost
== LS_INFINITY
)
608 zlog_debug ("cost is LS_INFINITY, ignore");
610 ospf6_route_remove (old
, table
);
613 if (OSPF6_LSA_IS_MAXAGE (lsa
))
616 zlog_debug ("LSA is MaxAge, ignore");
618 ospf6_route_remove (old
, table
);
622 /* (2) if the LSA is self-originated, ignore */
623 if (lsa
->header
->adv_router
== oa
->ospf6
->router_id
)
626 zlog_debug ("LSA is self-originated, ignore");
628 ospf6_route_remove (old
, table
);
632 /* (3) if the prefix is equal to an active configured address range */
633 if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_PREFIX
))
635 range
= ospf6_route_lookup (&prefix
, oa
->range_table
);
639 zlog_debug ("Prefix is equal to address range, ignore");
641 ospf6_route_remove (old
, table
);
646 /* (4) if the routing table entry for the ABR does not exist */
647 ospf6_linkstate_prefix (lsa
->header
->adv_router
, htonl (0), &abr_prefix
);
648 abr_entry
= ospf6_route_lookup (&abr_prefix
, oa
->ospf6
->brouter_table
);
649 if (abr_entry
== NULL
|| abr_entry
->path
.area_id
!= oa
->area_id
||
650 CHECK_FLAG (abr_entry
->flag
, OSPF6_ROUTE_REMOVE
) ||
651 ! CHECK_FLAG (abr_entry
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
654 zlog_debug ("ABR router entry does not exist, ignore");
656 ospf6_route_remove (old
, table
);
660 /* Check import list */
661 if (IMPORT_NAME (oa
))
663 if (IMPORT_LIST (oa
) == NULL
)
664 IMPORT_LIST (oa
) = access_list_lookup (AFI_IP6
, IMPORT_NAME (oa
));
666 if (IMPORT_LIST (oa
))
667 if (access_list_apply (IMPORT_LIST (oa
), &prefix
) == FILTER_DENY
)
670 zlog_debug ("Prefix was denied by import-list");
672 ospf6_route_remove (old
, table
);
677 /* Check input prefix-list */
678 if (PREFIX_NAME_IN (oa
))
680 if (PREFIX_LIST_IN (oa
) == NULL
)
681 PREFIX_LIST_IN (oa
) = prefix_list_lookup (AFI_IP6
, PREFIX_NAME_IN (oa
));
683 if (PREFIX_LIST_IN (oa
))
684 if (prefix_list_apply (PREFIX_LIST_IN (oa
), &prefix
) != PREFIX_PERMIT
)
687 zlog_debug ("Prefix was denied by prefix-list");
689 ospf6_route_remove (old
, table
);
694 /* (5),(6),(7) the path preference is handled by the sorting
695 in the routing table. Always install the path by substituting
696 old route (if any). */
698 route
= ospf6_route_copy (old
);
700 route
= ospf6_route_create ();
703 route
->prefix
= prefix
;
704 route
->path
.origin
.type
= lsa
->header
->type
;
705 route
->path
.origin
.id
= lsa
->header
->id
;
706 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
707 route
->path
.router_bits
= router_bits
;
708 route
->path
.options
[0] = options
[0];
709 route
->path
.options
[1] = options
[1];
710 route
->path
.options
[2] = options
[2];
711 route
->path
.prefix_options
= prefix_options
;
712 route
->path
.area_id
= oa
->area_id
;
713 route
->path
.type
= OSPF6_PATH_TYPE_INTER
;
714 route
->path
.cost
= abr_entry
->path
.cost
+ cost
;
715 for (i
= 0; i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
716 route
->nexthop
[i
] = abr_entry
->nexthop
[i
];
719 zlog_debug ("Install route: %s", buf
);
720 ospf6_route_add (route
, table
);
724 ospf6_abr_examin_brouter (u_int32_t router_id
)
726 struct ospf6_lsa
*lsa
;
727 struct ospf6_area
*oa
;
728 struct listnode
*node
, *nnode
;
731 for (ALL_LIST_ELEMENTS (ospf6
->area_list
, node
, nnode
, oa
))
733 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
734 for (lsa
= ospf6_lsdb_type_router_head (type
, router_id
, oa
->lsdb
); lsa
;
735 lsa
= ospf6_lsdb_type_router_next (type
, router_id
, lsa
))
736 ospf6_abr_examin_summary (lsa
, oa
);
738 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
739 for (lsa
= ospf6_lsdb_type_router_head (type
, router_id
, oa
->lsdb
); lsa
;
740 lsa
= ospf6_lsdb_type_router_next (type
, router_id
, lsa
))
741 ospf6_abr_examin_summary (lsa
, oa
);
746 ospf6_abr_reimport (struct ospf6_area
*oa
)
748 struct ospf6_lsa
*lsa
;
751 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
752 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
753 lsa
= ospf6_lsdb_type_next (type
, lsa
))
754 ospf6_abr_examin_summary (lsa
, oa
);
756 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
757 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
758 lsa
= ospf6_lsdb_type_next (type
, lsa
))
759 ospf6_abr_examin_summary (lsa
, oa
);
764 /* Display functions */
766 ospf6_inter_area_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
768 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
772 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
773 OSPF6_LSA_HEADER_END (lsa
->header
);
775 vty_out (vty
, " Metric: %lu%s",
776 (u_long
) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa
), VNL
);
778 ospf6_prefix_options_printbuf (prefix_lsa
->prefix
.prefix_options
,
780 vty_out (vty
, " Prefix Options: %s%s", buf
, VNL
);
782 ospf6_prefix_in6_addr (&in6
, &prefix_lsa
->prefix
);
783 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
784 vty_out (vty
, " Prefix: %s/%d%s", buf
,
785 prefix_lsa
->prefix
.prefix_length
, VNL
);
791 ospf6_inter_area_router_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
793 struct ospf6_inter_router_lsa
*router_lsa
;
796 router_lsa
= (struct ospf6_inter_router_lsa
*)
797 OSPF6_LSA_HEADER_END (lsa
->header
);
799 ospf6_options_printbuf (router_lsa
->options
, buf
, sizeof (buf
));
800 vty_out (vty
, " Options: %s%s", buf
, VNL
);
801 vty_out (vty
, " Metric: %lu%s",
802 (u_long
) OSPF6_ABR_SUMMARY_METRIC (router_lsa
), VNL
);
803 inet_ntop (AF_INET
, &router_lsa
->router_id
, buf
, sizeof (buf
));
804 vty_out (vty
, " Destination Router ID: %s%s", buf
, VNL
);
810 DEFUN (debug_ospf6_abr
,
815 "Debug OSPFv3 ABR function\n"
818 OSPF6_DEBUG_ABR_ON ();
822 DEFUN (no_debug_ospf6_abr
,
823 no_debug_ospf6_abr_cmd
,
824 "no debug ospf6 abr",
828 "Debug OSPFv3 ABR function\n"
831 OSPF6_DEBUG_ABR_OFF ();
836 config_write_ospf6_debug_abr (struct vty
*vty
)
838 if (IS_OSPF6_DEBUG_ABR
)
839 vty_out (vty
, "debug ospf6 abr%s", VNL
);
844 install_element_ospf6_debug_abr (void)
846 install_element (ENABLE_NODE
, &debug_ospf6_abr_cmd
);
847 install_element (ENABLE_NODE
, &no_debug_ospf6_abr_cmd
);
848 install_element (CONFIG_NODE
, &debug_ospf6_abr_cmd
);
849 install_element (CONFIG_NODE
, &no_debug_ospf6_abr_cmd
);
852 struct ospf6_lsa_handler inter_prefix_handler
=
854 OSPF6_LSTYPE_INTER_PREFIX
,
856 ospf6_inter_area_prefix_lsa_show
859 struct ospf6_lsa_handler inter_router_handler
=
861 OSPF6_LSTYPE_INTER_ROUTER
,
863 ospf6_inter_area_router_lsa_show
867 ospf6_abr_init (void)
869 ospf6_install_lsa_handler (&inter_prefix_handler
);
870 ospf6_install_lsa_handler (&inter_router_handler
);