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
)
58 struct ospf6_area
*oa
;
61 for (node
= listhead (o
->area_list
); node
; nextnode (node
))
63 oa
= OSPF6_AREA (getdata (node
));
64 if (IS_AREA_ENABLED (oa
))
74 ospf6_abr_enable_area (struct ospf6_area
*area
)
76 struct ospf6_area
*oa
;
77 struct ospf6_route
*ro
;
80 for (node
= listhead (area
->ospf6
->area_list
); node
; nextnode (node
))
82 oa
= OSPF6_AREA (getdata (node
));
84 /* update B bit for each area */
85 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
87 /* install other area's configured address range */
90 for (ro
= ospf6_route_head (oa
->range_table
); ro
;
91 ro
= ospf6_route_next (ro
))
93 if (CHECK_FLAG (ro
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
))
94 ospf6_abr_originate_summary_to_area (ro
, area
);
99 /* install calculated routes to border routers */
100 for (ro
= ospf6_route_head (area
->ospf6
->brouter_table
); ro
;
101 ro
= ospf6_route_next (ro
))
102 ospf6_abr_originate_summary_to_area (ro
, area
);
104 /* install calculated routes to network (may be rejected by ranges) */
105 for (ro
= ospf6_route_head (area
->ospf6
->route_table
); ro
;
106 ro
= ospf6_route_next (ro
))
107 ospf6_abr_originate_summary_to_area (ro
, area
);
111 ospf6_abr_disable_area (struct ospf6_area
*area
)
113 struct ospf6_area
*oa
;
114 struct ospf6_route
*ro
;
115 struct ospf6_lsa
*old
;
118 /* Withdraw all summary prefixes previously originated */
119 for (ro
= ospf6_route_head (area
->summary_prefix
); ro
;
120 ro
= ospf6_route_next (ro
))
122 old
= ospf6_lsdb_lookup (ro
->path
.origin
.type
, ro
->path
.origin
.id
,
123 area
->ospf6
->router_id
, area
->lsdb
);
125 ospf6_lsa_purge (old
);
126 ospf6_route_remove (ro
, area
->summary_prefix
);
129 /* Withdraw all summary router-routes previously originated */
130 for (ro
= ospf6_route_head (area
->summary_router
); ro
;
131 ro
= ospf6_route_next (ro
))
133 old
= ospf6_lsdb_lookup (ro
->path
.origin
.type
, ro
->path
.origin
.id
,
134 area
->ospf6
->router_id
, area
->lsdb
);
136 ospf6_lsa_purge (old
);
137 ospf6_route_remove (ro
, area
->summary_router
);
140 /* Schedule Router-LSA for each area (ABR status may change) */
141 for (node
= listhead (area
->ospf6
->area_list
); node
; nextnode (node
))
143 oa
= OSPF6_AREA (getdata (node
));
145 /* update B bit for each area */
146 OSPF6_ROUTER_LSA_SCHEDULE (oa
);
150 /* RFC 2328 12.4.3. Summary-LSAs */
152 ospf6_abr_originate_summary_to_area (struct ospf6_route
*route
,
153 struct ospf6_area
*area
)
155 struct ospf6_lsa
*lsa
, *old
= NULL
;
156 struct ospf6_interface
*oi
;
157 struct ospf6_route
*summary
, *range
= NULL
;
158 struct ospf6_area
*route_area
;
159 char buffer
[OSPF6_MAX_LSASIZE
];
160 struct ospf6_lsa_header
*lsa_header
;
162 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
163 struct ospf6_inter_router_lsa
*router_lsa
;
164 struct ospf6_route_table
*summary_table
= NULL
;
169 if (route
->type
== OSPF6_DEST_TYPE_ROUTER
)
171 if (IS_OSPF6_DEBUG_ABR
|| IS_OSPF6_DEBUG_ORIGINATE (INTER_ROUTER
))
174 inet_ntop (AF_INET
, &(ADV_ROUTER_IN_PREFIX (&route
->prefix
)),
176 zlog_info ("Originating summary in area %s for ASBR %s",
179 summary_table
= area
->summary_router
;
183 if (IS_OSPF6_DEBUG_ABR
|| IS_OSPF6_DEBUG_ORIGINATE (INTER_PREFIX
))
186 prefix2str (&route
->prefix
, buf
, sizeof (buf
));
187 zlog_info ("Originating summary in area %s for %s",
190 summary_table
= area
->summary_prefix
;
193 summary
= ospf6_route_lookup (&route
->prefix
, summary_table
);
195 old
= ospf6_lsdb_lookup (summary
->path
.origin
.type
,
196 summary
->path
.origin
.id
,
197 area
->ospf6
->router_id
, area
->lsdb
);
199 /* if this route has just removed, remove corresponding LSA */
200 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_REMOVE
))
203 zlog_info ("The route has just removed, purge previous LSA");
205 ospf6_route_remove (summary
, summary_table
);
207 ospf6_lsa_purge (old
);
211 /* Only destination type network, range or ASBR are considered */
212 if (route
->type
!= OSPF6_DEST_TYPE_NETWORK
&&
213 route
->type
!= OSPF6_DEST_TYPE_RANGE
&&
214 (route
->type
!= OSPF6_DEST_TYPE_ROUTER
||
215 ! CHECK_FLAG (route
->path
.router_bits
, OSPF6_ROUTER_BIT_E
)))
218 zlog_info ("Route type is none of network, range nor ASBR, withdraw");
220 ospf6_route_remove (summary
, summary_table
);
222 ospf6_lsa_purge (old
);
226 /* AS External routes are never considered */
227 if (route
->path
.type
== OSPF6_PATH_TYPE_EXTERNAL1
||
228 route
->path
.type
== OSPF6_PATH_TYPE_EXTERNAL2
)
231 zlog_info ("Path type is external, withdraw");
233 ospf6_route_remove (summary
, summary_table
);
235 ospf6_lsa_purge (old
);
239 /* do not generate if the path's area is the same as target area */
240 if (route
->path
.area_id
== area
->area_id
)
243 zlog_info ("The route is in the area itself, ignore");
245 ospf6_route_remove (summary
, summary_table
);
247 ospf6_lsa_purge (old
);
251 /* do not generate if the nexthops belongs to the target area */
252 oi
= ospf6_interface_lookup_by_ifindex (route
->nexthop
[0].ifindex
);
253 if (oi
&& oi
->area
&& oi
->area
== area
)
256 zlog_info ("The route's nexthop is in the same area, ignore");
258 ospf6_route_remove (summary
, summary_table
);
260 ospf6_lsa_purge (old
);
264 /* do not generate if the route cost is greater or equal to LSInfinity */
265 if (route
->path
.cost
>= LS_INFINITY
)
268 zlog_info ("The cost exceeds LSInfinity, withdraw");
270 ospf6_route_remove (summary
, summary_table
);
272 ospf6_lsa_purge (old
);
276 /* if this is a route to ASBR */
277 if (route
->type
== OSPF6_DEST_TYPE_ROUTER
)
279 /* Only the prefered best path is considered */
280 if (! CHECK_FLAG (route
->flag
, OSPF6_ROUTE_BEST
))
283 zlog_info ("This is the secondary path to the ASBR, ignore");
285 ospf6_route_remove (summary
, summary_table
);
287 ospf6_lsa_purge (old
);
291 /* Do not generate if the area is stub */
295 /* if this is an intra-area route, this may be suppressed by aggregation */
296 if (route
->type
== OSPF6_DEST_TYPE_NETWORK
&&
297 route
->path
.type
== OSPF6_PATH_TYPE_INTRA
)
299 /* search for configured address range for the route's area */
300 route_area
= ospf6_area_lookup (route
->path
.area_id
, area
->ospf6
);
302 range
= ospf6_route_lookup_bestmatch (&route
->prefix
,
303 route_area
->range_table
);
305 /* ranges are ignored when originate backbone routes to transit area.
306 Otherwise, if ranges are configured, the route is suppressed. */
307 if (range
&& ! CHECK_FLAG (range
->flag
, OSPF6_ROUTE_REMOVE
) &&
308 (route
->path
.area_id
!= BACKBONE_AREA_ID
||
309 ! IS_AREA_TRANSIT (area
)))
313 prefix2str (&range
->prefix
, buf
, sizeof (buf
));
314 zlog_info ("Suppressed by range %s of area %s",
315 buf
, route_area
->name
);
319 ospf6_route_remove (summary
, summary_table
);
321 ospf6_lsa_purge (old
);
326 /* If this is a configured address range */
327 if (route
->type
== OSPF6_DEST_TYPE_RANGE
)
329 /* If DoNotAdvertise is set */
330 if (CHECK_FLAG (route
->flag
, OSPF6_ROUTE_DO_NOT_ADVERTISE
))
333 zlog_info ("This is the range with DoNotAdvertise set. ignore");
335 ospf6_route_remove (summary
, summary_table
);
337 ospf6_lsa_purge (old
);
341 /* Whether the route have active longer prefix */
342 if (! CHECK_FLAG (route
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
))
345 zlog_info ("The range is not active. withdraw");
347 ospf6_route_remove (summary
, summary_table
);
349 ospf6_lsa_purge (old
);
354 /* Check export list */
355 if (EXPORT_NAME (area
))
357 if (EXPORT_LIST (area
) == NULL
)
359 access_list_lookup (AFI_IP6
, EXPORT_NAME (area
));
361 if (EXPORT_LIST (area
))
362 if (access_list_apply (EXPORT_LIST (area
),
363 &route
->prefix
) == FILTER_DENY
)
367 inet_ntop (AF_INET
, &(ADV_ROUTER_IN_PREFIX (&route
->prefix
)),
369 zlog_debug ("prefix %s was denied by export list", buf
);
375 /* Check filter-list */
376 if (PREFIX_NAME_OUT (area
))
378 if (PREFIX_LIST_OUT (area
) == NULL
)
379 PREFIX_LIST_OUT (area
) =
380 prefix_list_lookup(AFI_IP6
, PREFIX_NAME_OUT (area
));
382 if (PREFIX_LIST_OUT (area
))
383 if (prefix_list_apply (PREFIX_LIST_OUT (area
),
384 &route
->prefix
) != PREFIX_PERMIT
)
388 inet_ntop (AF_INET
, &(ADV_ROUTER_IN_PREFIX (&route
->prefix
)),
390 zlog_debug ("prefix %s was denied by filter-list out", buf
);
396 /* the route is going to be originated. store it in area's summary_table */
399 summary
= ospf6_route_copy (route
);
400 if (route
->type
== OSPF6_DEST_TYPE_NETWORK
||
401 route
->type
== OSPF6_DEST_TYPE_RANGE
)
402 summary
->path
.origin
.type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
404 summary
->path
.origin
.type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
405 summary
->path
.origin
.adv_router
= area
->ospf6
->router_id
;
406 summary
->path
.origin
.id
=
407 ospf6_new_ls_id (summary
->path
.origin
.type
,
408 summary
->path
.origin
.adv_router
, area
->lsdb
);
409 summary
= ospf6_route_add (summary
, summary_table
);
413 summary
->type
= route
->type
;
414 gettimeofday (&summary
->changed
, NULL
);
417 summary
->path
.router_bits
= route
->path
.router_bits
;
418 summary
->path
.options
[0] = route
->path
.options
[0];
419 summary
->path
.options
[1] = route
->path
.options
[1];
420 summary
->path
.options
[2] = route
->path
.options
[2];
421 summary
->path
.prefix_options
= route
->path
.prefix_options
;
422 summary
->path
.area_id
= area
->area_id
;
423 summary
->path
.type
= OSPF6_PATH_TYPE_INTER
;
424 summary
->path
.cost
= route
->path
.cost
;
425 summary
->nexthop
[0] = route
->nexthop
[0];
428 memset (buffer
, 0, sizeof (buffer
));
429 lsa_header
= (struct ospf6_lsa_header
*) buffer
;
431 if (route
->type
== OSPF6_DEST_TYPE_ROUTER
)
433 router_lsa
= (struct ospf6_inter_router_lsa
*)
434 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
435 p
= (caddr_t
) router_lsa
+ sizeof (struct ospf6_inter_router_lsa
);
437 /* Fill Inter-Area-Router-LSA */
438 router_lsa
->options
[0] = route
->path
.options
[0];
439 router_lsa
->options
[1] = route
->path
.options
[1];
440 router_lsa
->options
[2] = route
->path
.options
[2];
441 OSPF6_ABR_SUMMARY_METRIC_SET (router_lsa
, route
->path
.cost
);
442 router_lsa
->router_id
= ADV_ROUTER_IN_PREFIX (&route
->prefix
);
443 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
447 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
448 ((caddr_t
) lsa_header
+ sizeof (struct ospf6_lsa_header
));
449 p
= (caddr_t
) prefix_lsa
+ sizeof (struct ospf6_inter_prefix_lsa
);
451 /* Fill Inter-Area-Prefix-LSA */
452 OSPF6_ABR_SUMMARY_METRIC_SET (prefix_lsa
, route
->path
.cost
);
453 prefix_lsa
->prefix
.prefix_length
= route
->prefix
.prefixlen
;
454 prefix_lsa
->prefix
.prefix_options
= route
->path
.prefix_options
;
457 memcpy (p
, &route
->prefix
.u
.prefix6
,
458 OSPF6_PREFIX_SPACE (route
->prefix
.prefixlen
));
459 ospf6_prefix_apply_mask (&prefix_lsa
->prefix
);
460 p
+= OSPF6_PREFIX_SPACE (route
->prefix
.prefixlen
);
461 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
464 /* Fill LSA Header */
466 lsa_header
->type
= type
;
467 lsa_header
->id
= summary
->path
.origin
.id
;
468 lsa_header
->adv_router
= area
->ospf6
->router_id
;
470 ospf6_new_ls_seqnum (lsa_header
->type
, lsa_header
->id
,
471 lsa_header
->adv_router
, area
->lsdb
);
472 lsa_header
->length
= htons ((caddr_t
) p
- (caddr_t
) lsa_header
);
475 ospf6_lsa_checksum (lsa_header
);
478 lsa
= ospf6_lsa_create (lsa_header
);
481 ospf6_lsa_originate_area (lsa
, area
);
485 ospf6_abr_range_update (struct ospf6_route
*range
)
488 struct ospf6_route
*ro
;
490 assert (range
->type
== OSPF6_DEST_TYPE_RANGE
);
492 /* update range's cost and active flag */
493 for (ro
= ospf6_route_match_head (&range
->prefix
, ospf6
->route_table
);
494 ro
; ro
= ospf6_route_match_next (&range
->prefix
, ro
))
496 if (ro
->path
.area_id
== range
->path
.area_id
&&
497 ! CHECK_FLAG (ro
->flag
, OSPF6_ROUTE_REMOVE
))
498 cost
= MAX (cost
, ro
->path
.cost
);
501 if (range
->path
.cost
!= cost
)
503 range
->path
.cost
= cost
;
505 if (range
->path
.cost
)
506 SET_FLAG (range
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
);
508 UNSET_FLAG (range
->flag
, OSPF6_ROUTE_ACTIVE_SUMMARY
);
510 ospf6_abr_originate_summary (range
);
515 ospf6_abr_originate_summary (struct ospf6_route
*route
)
518 struct ospf6_area
*oa
;
519 struct ospf6_route
*range
= NULL
;
521 if (route
->type
== OSPF6_DEST_TYPE_NETWORK
)
523 oa
= ospf6_area_lookup (route
->path
.area_id
, ospf6
);
524 range
= ospf6_route_lookup_bestmatch (&route
->prefix
, oa
->range_table
);
526 ospf6_abr_range_update (range
);
529 for (node
= listhead (ospf6
->area_list
); node
; nextnode (node
))
531 oa
= (struct ospf6_area
*) getdata (node
);
532 ospf6_abr_originate_summary_to_area (route
, oa
);
536 /* RFC 2328 16.2. Calculating the inter-area routes */
538 ospf6_abr_examin_summary (struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
540 struct prefix prefix
, abr_prefix
;
541 struct ospf6_route_table
*table
= NULL
;
542 struct ospf6_route
*range
, *route
, *old
= NULL
;
543 struct ospf6_route
*abr_entry
;
545 char options
[3] = {0, 0, 0};
546 u_int8_t prefix_options
= 0;
548 u_char router_bits
= 0;
553 if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_PREFIX
))
555 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
557 if (IS_OSPF6_DEBUG_EXAMIN (INTER_PREFIX
))
560 zlog_info ("Examin %s in area %s", lsa
->name
, oa
->name
);
563 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
564 OSPF6_LSA_HEADER_END (lsa
->header
);
565 prefix
.family
= AF_INET6
;
566 prefix
.prefixlen
= prefix_lsa
->prefix
.prefix_length
;
567 ospf6_prefix_in6_addr (&prefix
.u
.prefix6
, &prefix_lsa
->prefix
);
568 prefix2str (&prefix
, buf
, sizeof (buf
));
569 table
= oa
->ospf6
->route_table
;
570 type
= OSPF6_DEST_TYPE_NETWORK
;
571 prefix_options
= prefix_lsa
->prefix
.prefix_options
;
572 cost
= OSPF6_ABR_SUMMARY_METRIC (prefix_lsa
);
574 else if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_ROUTER
))
576 struct ospf6_inter_router_lsa
*router_lsa
;
578 if (IS_OSPF6_DEBUG_EXAMIN (INTER_ROUTER
))
581 zlog_info ("Examin %s in area %s", lsa
->name
, oa
->name
);
584 router_lsa
= (struct ospf6_inter_router_lsa
*)
585 OSPF6_LSA_HEADER_END (lsa
->header
);
586 ospf6_linkstate_prefix (router_lsa
->router_id
, htonl (0), &prefix
);
587 inet_ntop (AF_INET
, &router_lsa
->router_id
, buf
, sizeof (buf
));
588 table
= oa
->ospf6
->brouter_table
;
589 type
= OSPF6_DEST_TYPE_ROUTER
;
590 options
[0] = router_lsa
->options
[0];
591 options
[1] = router_lsa
->options
[1];
592 options
[2] = router_lsa
->options
[2];
593 cost
= OSPF6_ABR_SUMMARY_METRIC (router_lsa
);
594 SET_FLAG (router_bits
, OSPF6_ROUTER_BIT_E
);
599 /* Find existing route */
600 route
= ospf6_route_lookup (&prefix
, table
);
602 ospf6_route_lock (route
);
603 while (route
&& ospf6_route_is_prefix (&prefix
, route
))
605 if (route
->path
.area_id
== oa
->area_id
&&
606 route
->path
.origin
.type
== lsa
->header
->type
&&
607 route
->path
.origin
.id
== lsa
->header
->id
&&
608 route
->path
.origin
.adv_router
== lsa
->header
->adv_router
)
610 route
= ospf6_route_next (route
);
613 /* (1) if cost == LSInfinity or if the LSA is MaxAge */
614 if (cost
== LS_INFINITY
)
617 zlog_info ("cost is LS_INFINITY, ignore");
619 ospf6_route_remove (old
, table
);
622 if (OSPF6_LSA_IS_MAXAGE (lsa
))
625 zlog_info ("LSA is MaxAge, ignore");
627 ospf6_route_remove (old
, table
);
631 /* (2) if the LSA is self-originated, ignore */
632 if (lsa
->header
->adv_router
== oa
->ospf6
->router_id
)
635 zlog_info ("LSA is self-originated, ignore");
637 ospf6_route_remove (old
, table
);
641 /* (3) if the prefix is equal to an active configured address range */
642 if (lsa
->header
->type
== htons (OSPF6_LSTYPE_INTER_PREFIX
))
644 range
= ospf6_route_lookup (&prefix
, oa
->range_table
);
648 zlog_info ("Prefix is equal to address range, ignore");
650 ospf6_route_remove (old
, table
);
655 /* (4) if the routing table entry for the ABR does not exist */
656 ospf6_linkstate_prefix (lsa
->header
->adv_router
, htonl (0), &abr_prefix
);
657 abr_entry
= ospf6_route_lookup (&abr_prefix
, oa
->ospf6
->brouter_table
);
658 if (abr_entry
== NULL
|| abr_entry
->path
.area_id
!= oa
->area_id
||
659 CHECK_FLAG (abr_entry
->flag
, OSPF6_ROUTE_REMOVE
) ||
660 ! CHECK_FLAG (abr_entry
->path
.router_bits
, OSPF6_ROUTER_BIT_B
))
663 zlog_info ("ABR router entry does not exist, ignore");
665 ospf6_route_remove (old
, table
);
669 /* Check import list */
670 if (IMPORT_NAME (oa
))
672 if (IMPORT_LIST (oa
) == NULL
)
673 IMPORT_LIST (oa
) = access_list_lookup (AFI_IP6
, IMPORT_NAME (oa
));
675 if (IMPORT_LIST (oa
))
676 if (access_list_apply (IMPORT_LIST (oa
), &prefix
) == FILTER_DENY
)
679 zlog_debug ("Prefix was denied by import-list");
681 ospf6_route_remove (old
, table
);
686 /* Check input prefix-list */
687 if (PREFIX_NAME_IN (oa
))
689 if (PREFIX_LIST_IN (oa
) == NULL
)
690 PREFIX_LIST_IN (oa
) = prefix_list_lookup (AFI_IP6
, PREFIX_NAME_IN (oa
));
692 if (PREFIX_LIST_IN (oa
))
693 if (prefix_list_apply (PREFIX_LIST_IN (oa
), &prefix
) != PREFIX_PERMIT
)
696 zlog_debug ("Prefix was denied by prefix-list");
698 ospf6_route_remove (old
, table
);
703 /* (5),(6),(7) the path preference is handled by the sorting
704 in the routing table. Always install the path by substituting
705 old route (if any). */
707 route
= ospf6_route_copy (old
);
709 route
= ospf6_route_create ();
712 route
->prefix
= prefix
;
713 route
->path
.origin
.type
= lsa
->header
->type
;
714 route
->path
.origin
.id
= lsa
->header
->id
;
715 route
->path
.origin
.adv_router
= lsa
->header
->adv_router
;
716 route
->path
.router_bits
= router_bits
;
717 route
->path
.options
[0] = options
[0];
718 route
->path
.options
[1] = options
[1];
719 route
->path
.options
[2] = options
[2];
720 route
->path
.prefix_options
= prefix_options
;
721 route
->path
.area_id
= oa
->area_id
;
722 route
->path
.type
= OSPF6_PATH_TYPE_INTER
;
723 route
->path
.cost
= abr_entry
->path
.cost
+ cost
;
724 for (i
= 0; i
< OSPF6_MULTI_PATH_LIMIT
; i
++)
725 route
->nexthop
[i
] = abr_entry
->nexthop
[i
];
728 zlog_info ("Install route: %s", buf
);
729 ospf6_route_add (route
, table
);
733 ospf6_abr_examin_brouter (u_int32_t router_id
)
735 struct ospf6_lsa
*lsa
;
736 struct ospf6_area
*oa
;
740 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
741 for (node
= listhead (ospf6
->area_list
); node
; nextnode (node
))
743 oa
= OSPF6_AREA (getdata (node
));
744 for (lsa
= ospf6_lsdb_type_router_head (type
, router_id
, oa
->lsdb
); lsa
;
745 lsa
= ospf6_lsdb_type_router_next (type
, router_id
, lsa
))
746 ospf6_abr_examin_summary (lsa
, oa
);
749 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
750 for (node
= listhead (ospf6
->area_list
); node
; nextnode (node
))
752 oa
= OSPF6_AREA (getdata (node
));
753 for (lsa
= ospf6_lsdb_type_router_head (type
, router_id
, oa
->lsdb
); lsa
;
754 lsa
= ospf6_lsdb_type_router_next (type
, router_id
, lsa
))
755 ospf6_abr_examin_summary (lsa
, oa
);
760 ospf6_abr_reimport (struct ospf6_area
*oa
)
762 struct ospf6_lsa
*lsa
;
765 type
= htons (OSPF6_LSTYPE_INTER_ROUTER
);
766 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
767 lsa
= ospf6_lsdb_type_next (type
, lsa
))
768 ospf6_abr_examin_summary (lsa
, oa
);
770 type
= htons (OSPF6_LSTYPE_INTER_PREFIX
);
771 for (lsa
= ospf6_lsdb_type_head (type
, oa
->lsdb
); lsa
;
772 lsa
= ospf6_lsdb_type_next (type
, lsa
))
773 ospf6_abr_examin_summary (lsa
, oa
);
778 /* Display functions */
780 ospf6_inter_area_prefix_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
782 struct ospf6_inter_prefix_lsa
*prefix_lsa
;
786 prefix_lsa
= (struct ospf6_inter_prefix_lsa
*)
787 OSPF6_LSA_HEADER_END (lsa
->header
);
789 vty_out (vty
, " Metric: %lu%s",
790 (u_long
) OSPF6_ABR_SUMMARY_METRIC (prefix_lsa
), VNL
);
792 ospf6_prefix_options_printbuf (prefix_lsa
->prefix
.prefix_options
,
794 vty_out (vty
, " Prefix Options: %s%s", buf
, VNL
);
796 ospf6_prefix_in6_addr (&in6
, &prefix_lsa
->prefix
);
797 inet_ntop (AF_INET6
, &in6
, buf
, sizeof (buf
));
798 vty_out (vty
, " Prefix: %s/%d%s", buf
,
799 prefix_lsa
->prefix
.prefix_length
, VNL
);
805 ospf6_inter_area_router_lsa_show (struct vty
*vty
, struct ospf6_lsa
*lsa
)
807 struct ospf6_inter_router_lsa
*router_lsa
;
810 router_lsa
= (struct ospf6_inter_router_lsa
*)
811 OSPF6_LSA_HEADER_END (lsa
->header
);
813 ospf6_options_printbuf (router_lsa
->options
, buf
, sizeof (buf
));
814 vty_out (vty
, " Options: %s%s", buf
, VNL
);
815 vty_out (vty
, " Metric: %lu%s",
816 (u_long
) OSPF6_ABR_SUMMARY_METRIC (router_lsa
), VNL
);
817 inet_ntop (AF_INET
, &router_lsa
->router_id
, buf
, sizeof (buf
));
818 vty_out (vty
, " Destination Router ID: %s%s", buf
, VNL
);
824 DEFUN (debug_ospf6_abr
,
829 "Debug OSPFv3 ABR function\n"
832 OSPF6_DEBUG_ABR_ON ();
836 DEFUN (no_debug_ospf6_abr
,
837 no_debug_ospf6_abr_cmd
,
838 "no debug ospf6 abr",
842 "Debug OSPFv3 ABR function\n"
845 OSPF6_DEBUG_ABR_OFF ();
850 config_write_ospf6_debug_abr (struct vty
*vty
)
852 if (IS_OSPF6_DEBUG_ABR
)
853 vty_out (vty
, "debug ospf6 abr%s", VNL
);
858 install_element_ospf6_debug_abr ()
860 install_element (ENABLE_NODE
, &debug_ospf6_abr_cmd
);
861 install_element (ENABLE_NODE
, &no_debug_ospf6_abr_cmd
);
862 install_element (CONFIG_NODE
, &debug_ospf6_abr_cmd
);
863 install_element (CONFIG_NODE
, &no_debug_ospf6_abr_cmd
);
866 struct ospf6_lsa_handler inter_prefix_handler
=
868 OSPF6_LSTYPE_INTER_PREFIX
,
870 ospf6_inter_area_prefix_lsa_show
873 struct ospf6_lsa_handler inter_router_handler
=
875 OSPF6_LSTYPE_INTER_ROUTER
,
877 ospf6_inter_area_router_lsa_show
883 ospf6_install_lsa_handler (&inter_prefix_handler
);
884 ospf6_install_lsa_handler (&inter_router_handler
);