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
);
559 prefix2str (&prefix
, buf
, sizeof (buf
));
560 table
= oa
->ospf6
->route_table
;
561 type
= OSPF6_DEST_TYPE_NETWORK
;
562 prefix_options
= prefix_lsa
->prefix
.prefix_options
;
563 cost
= OSPF6_ABR_SUMMARY_METRIC (prefix_lsa
);
565 else if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_ROUTER
))
567 struct ospf6_inter_router_lsa
*router_lsa
;
569 if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER
))
572 zlog_debug ("Examin %s in area %s", lsa
->name
, oa
->name
);
575 router_lsa
= (struct ospf6_inter_router_lsa
*)
576 OSPF6_LSA_HEADER_END (lsa
->header
);
577 ospf6_linkstate_prefix (router_lsa
->router_id
, htonl (0), &prefix
);
579 inet_ntop (AF_INET
, &router_lsa
->router_id
, buf
, sizeof (buf
));
580 table
= oa
->ospf6
->brouter_table
;
581 type
= OSPF6_DEST_TYPE_ROUTER
;
582 options
[0] = router_lsa
->options
[0];
583 options
[1] = router_lsa
->options
[1];
584 options
[2] = router_lsa
->options
[2];
585 cost
= OSPF6_ABR_SUMMARY_METRIC (router_lsa
);
586 SET_FLAG (router_bits
, OSPF6_ROUTER_BIT_E
);
591 /* Find existing route */
592 route
= ospf6_route_lookup (&prefix
, table
);
594 ospf6_route_lock (route
);
595 while (route
&& ospf6_route_is_prefix (&prefix
, route
))
597 if (route
->path
.area_id
== oa
->area_id
&&
598 route
->path
.origin
.type
== lsa
->header
->type
&&
599 route
->path
.origin
.id
== lsa
->header
->id
&&
600 route
->path
.origin
.adv_router
== lsa
->header
->adv_router
&&
601 ! CHECK_FLAG (route
->flag
, OSPF6_ROUTE_WAS_REMOVED
))
603 route
= ospf6_route_next (route
);
606 /* (1) if cost == LSInfinity or if the LSA is MaxAge */
607 if (cost
== LS_INFINITY
)
610 zlog_debug ("cost is LS_INFINITY, ignore");
612 ospf6_route_remove (old
, table
);
615 if (OSPF6_LSA_IS_MAXAGE (lsa
))
618 zlog_debug ("LSA is MaxAge, ignore");
620 ospf6_route_remove (old
, table
);
624 /* (2) if the LSA is self-originated, ignore */
625 if (lsa
->header
->adv_router
== oa
->ospf6
->router_id
)
628 zlog_debug ("LSA is self-originated, ignore");
630 ospf6_route_remove (old
, table
);
634 /* (3) if the prefix is equal to an active configured address range */
635 if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_PREFIX
))
637 range
= ospf6_route_lookup (&prefix
, oa
->range_table
);
641 zlog_debug ("Prefix is equal to address range, ignore");
643 ospf6_route_remove (old
, table
);
648 /* (4) if the routing table entry for the ABR does not exist */
649 ospf6_linkstate_prefix (lsa
->header
->adv_router
, htonl (0), &abr_prefix
);
650 abr_entry
= ospf6_route_lookup (&abr_prefix
, oa
->ospf6
->brouter_table
);
651 if (abr_entry
== NULL
|| abr_entry
->path
.area_id
!= oa
->area_id
||
652 CHECK_FLAG (abr_entry
->flag
, OSPF6_ROUTE_REMOVE
) ||
653 ! CHECK_FLAG (abr_entry
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
656 zlog_debug ("ABR router entry does not exist, ignore");
658 ospf6_route_remove (old
, table
);
662 /* Check import list */
663 if (IMPORT_NAME (oa
))
665 if (IMPORT_LIST (oa
) == NULL
)
666 IMPORT_LIST (oa
) = access_list_lookup (AFI_IP6
, IMPORT_NAME (oa
));
668 if (IMPORT_LIST (oa
))
669 if (access_list_apply (IMPORT_LIST (oa
), &prefix
) == FILTER_DENY
)
672 zlog_debug ("Prefix was denied by import-list");
674 ospf6_route_remove (old
, table
);
679 /* Check input prefix-list */
680 if (PREFIX_NAME_IN (oa
))
682 if (PREFIX_LIST_IN (oa
) == NULL
)
683 PREFIX_LIST_IN (oa
) = prefix_list_lookup (AFI_IP6
, PREFIX_NAME_IN (oa
));
685 if (PREFIX_LIST_IN (oa
))
686 if (prefix_list_apply (PREFIX_LIST_IN (oa
), &prefix
) != PREFIX_PERMIT
)
689 zlog_debug ("Prefix was denied by prefix-list");
691 ospf6_route_remove (old
, table
);
696 /* (5),(6),(7) the path preference is handled by the sorting
697 in the routing table. Always install the path by substituting
698 old route (if any). */
700 route
= ospf6_route_copy (old
);
702 route
= ospf6_route_create ();
705 route
->prefix
= prefix
;
706 route
->path
.origin
.type
= lsa
->header
->type
;
707 route
->path
.origin
.id
= lsa
->header
->id
;
708 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
709 route
->path
.router_bits
= router_bits
;
710 route
->path
.options
[0] = options
[0];
711 route
->path
.options
[1] = options
[1];
712 route
->path
.options
[2] = options
[2];
713 route
->path
.prefix_options
= prefix_options
;
714 route
->path
.area_id
= oa
->area_id
;
715 route
->path
.type
= OSPF6_PATH_TYPE_INTER
;
716 route
->path
.cost
= abr_entry
->path
.cost
+ cost
;
717 for (i
= 0; i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
718 route
->nexthop
[i
] = abr_entry
->nexthop
[i
];
721 zlog_debug ("Install route: %s", buf
);
722 ospf6_route_add (route
, table
);
726 ospf6_abr_examin_brouter (u_int32_t router_id
)
728 struct ospf6_lsa
*lsa
;
729 struct ospf6_area
*oa
;
730 struct listnode
*node
, *nnode
;
733 for (ALL_LIST_ELEMENTS (ospf6
->area_list
, node
, nnode
, oa
))
735 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
736 for (lsa
= ospf6_lsdb_type_router_head (type
, router_id
, oa
->lsdb
); lsa
;
737 lsa
= ospf6_lsdb_type_router_next (type
, router_id
, lsa
))
738 ospf6_abr_examin_summary (lsa
, oa
);
740 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
741 for (lsa
= ospf6_lsdb_type_router_head (type
, router_id
, oa
->lsdb
); lsa
;
742 lsa
= ospf6_lsdb_type_router_next (type
, router_id
, lsa
))
743 ospf6_abr_examin_summary (lsa
, oa
);
748 ospf6_abr_reimport (struct ospf6_area
*oa
)
750 struct ospf6_lsa
*lsa
;
753 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
754 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
755 lsa
= ospf6_lsdb_type_next (type
, lsa
))
756 ospf6_abr_examin_summary (lsa
, oa
);
758 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
759 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
760 lsa
= ospf6_lsdb_type_next (type
, lsa
))
761 ospf6_abr_examin_summary (lsa
, oa
);
766 /* Display functions */
768 ospf6_inter_area_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
770 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
774 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
775 OSPF6_LSA_HEADER_END (lsa
->header
);
777 vty_out (vty
, " Metric: %lu%s",
778 (u_long
) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa
), VNL
);
780 ospf6_prefix_options_printbuf (prefix_lsa
->prefix
.prefix_options
,
782 vty_out (vty
, " Prefix Options: %s%s", buf
, VNL
);
784 ospf6_prefix_in6_addr (&in6
, &prefix_lsa
->prefix
);
785 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
786 vty_out (vty
, " Prefix: %s/%d%s", buf
,
787 prefix_lsa
->prefix
.prefix_length
, VNL
);
793 ospf6_inter_area_router_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
795 struct ospf6_inter_router_lsa
*router_lsa
;
798 router_lsa
= (struct ospf6_inter_router_lsa
*)
799 OSPF6_LSA_HEADER_END (lsa
->header
);
801 ospf6_options_printbuf (router_lsa
->options
, buf
, sizeof (buf
));
802 vty_out (vty
, " Options: %s%s", buf
, VNL
);
803 vty_out (vty
, " Metric: %lu%s",
804 (u_long
) OSPF6_ABR_SUMMARY_METRIC (router_lsa
), VNL
);
805 inet_ntop (AF_INET
, &router_lsa
->router_id
, buf
, sizeof (buf
));
806 vty_out (vty
, " Destination Router ID: %s%s", buf
, VNL
);
812 DEFUN (debug_ospf6_abr
,
817 "Debug OSPFv3 ABR function\n"
820 OSPF6_DEBUG_ABR_ON ();
824 DEFUN (no_debug_ospf6_abr
,
825 no_debug_ospf6_abr_cmd
,
826 "no debug ospf6 abr",
830 "Debug OSPFv3 ABR function\n"
833 OSPF6_DEBUG_ABR_OFF ();
838 config_write_ospf6_debug_abr (struct vty
*vty
)
840 if (IS_OSPF6_DEBUG_ABR
)
841 vty_out (vty
, "debug ospf6 abr%s", VNL
);
846 install_element_ospf6_debug_abr (void)
848 install_element (ENABLE_NODE
, &debug_ospf6_abr_cmd
);
849 install_element (ENABLE_NODE
, &no_debug_ospf6_abr_cmd
);
850 install_element (CONFIG_NODE
, &debug_ospf6_abr_cmd
);
851 install_element (CONFIG_NODE
, &no_debug_ospf6_abr_cmd
);
854 struct ospf6_lsa_handler inter_prefix_handler
=
856 OSPF6_LSTYPE_INTER_PREFIX
,
858 ospf6_inter_area_prefix_lsa_show
861 struct ospf6_lsa_handler inter_router_handler
=
863 OSPF6_LSTYPE_INTER_ROUTER
,
865 ospf6_inter_area_router_lsa_show
869 ospf6_abr_init (void)
871 ospf6_install_lsa_handler (&inter_prefix_handler
);
872 ospf6_install_lsa_handler (&inter_router_handler
);