]>
git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_ia.c
2 * OSPF inter-area routing.
3 * Copyright (C) 1999, 2000 Alex Zinin, Toshiaki Takada
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 Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
34 #include "ospfd/ospfd.h"
35 #include "ospfd/ospf_interface.h"
36 #include "ospfd/ospf_ism.h"
37 #include "ospfd/ospf_asbr.h"
38 #include "ospfd/ospf_lsa.h"
39 #include "ospfd/ospf_lsdb.h"
40 #include "ospfd/ospf_neighbor.h"
41 #include "ospfd/ospf_nsm.h"
42 #include "ospfd/ospf_spf.h"
43 #include "ospfd/ospf_route.h"
44 #include "ospfd/ospf_ase.h"
45 #include "ospfd/ospf_abr.h"
46 #include "ospfd/ospf_ia.h"
47 #include "ospfd/ospf_dump.h"
51 static struct ospf_route
*
52 ospf_find_abr_route (struct route_table
*rtrs
,
53 struct prefix_ipv4
*abr
,
54 struct ospf_area
*area
)
56 struct route_node
*rn
;
57 struct ospf_route
*or;
58 struct listnode
*node
;
60 if ((rn
= route_node_lookup (rtrs
, (struct prefix
*) abr
)) == NULL
)
63 route_unlock_node (rn
);
65 for (ALL_LIST_ELEMENTS_RO ((struct list
*) rn
->info
, node
, or))
66 if (IPV4_ADDR_SAME (&or->u
.std
.area_id
, &area
->area_id
)
67 && (or->u
.std
.flags
& ROUTER_LSA_BORDER
))
74 ospf_ia_network_route (struct ospf
*ospf
, struct route_table
*rt
,
75 struct prefix_ipv4
*p
, struct ospf_route
*new_or
,
76 struct ospf_route
*abr_or
)
78 struct route_node
*rn1
;
79 struct ospf_route
*or;
81 if (IS_DEBUG_OSPF_EVENT
)
82 zlog_debug ("ospf_ia_network_route(): processing summary route to %s/%d",
83 inet_ntoa (p
->prefix
), p
->prefixlen
);
85 /* Find a route to the same dest */
86 if ((rn1
= route_node_lookup (rt
, (struct prefix
*) p
)))
90 route_unlock_node (rn1
);
94 if (IS_DEBUG_OSPF_EVENT
)
95 zlog_debug ("ospf_ia_network_route(): "
96 "Found a route to the same network");
97 /* Check the existing route. */
98 if ((res
= ospf_route_cmp (ospf
, new_or
, or)) < 0)
100 /* New route is better, so replace old one. */
101 ospf_route_subst (rn1
, new_or
, abr_or
);
105 /* New and old route are equal, so next hops can be added. */
106 route_lock_node (rn1
);
107 ospf_route_copy_nexthops (or, abr_or
->paths
);
108 route_unlock_node (rn1
);
110 /* new route can be deleted, because existing route has been updated. */
111 ospf_route_free (new_or
);
115 /* New route is worse, so free it. */
116 ospf_route_free (new_or
);
123 if (IS_DEBUG_OSPF_EVENT
)
124 zlog_debug ("ospf_ia_network_route(): add new route to %s/%d",
125 inet_ntoa (p
->prefix
), p
->prefixlen
);
126 ospf_route_add (rt
, p
, new_or
, abr_or
);
131 ospf_ia_router_route (struct ospf
*ospf
, struct route_table
*rtrs
,
132 struct prefix_ipv4
*p
,
133 struct ospf_route
*new_or
, struct ospf_route
*abr_or
)
135 struct ospf_route
*or = NULL
;
136 struct route_node
*rn
;
139 if (IS_DEBUG_OSPF_EVENT
)
140 zlog_debug ("ospf_ia_router_route(): considering %s/%d",
141 inet_ntoa (p
->prefix
), p
->prefixlen
);
142 /* Find a route to the same dest */
143 rn
= route_node_get (rtrs
, (struct prefix
*) p
);
145 if (rn
->info
== NULL
)
146 /* This is a new route */
147 rn
->info
= list_new ();
150 struct ospf_area
*or_area
;
151 or_area
= ospf_area_lookup_by_area_id (ospf
, new_or
->u
.std
.area_id
);
153 /* This is an additional route */
154 route_unlock_node (rn
);
155 or = ospf_find_asbr_route_through_area (rtrs
, p
, or_area
);
160 if (IS_DEBUG_OSPF_EVENT
)
161 zlog_debug ("ospf_ia_router_route(): "
162 "a route to the same ABR through the same area exists");
163 /* New route is better */
164 if ((ret
= ospf_route_cmp (ospf
, new_or
, or)) < 0)
166 listnode_delete (rn
->info
, or);
167 ospf_route_free (or);
170 /* Routes are the same */
173 if (IS_DEBUG_OSPF_EVENT
)
174 zlog_debug ("ospf_ia_router_route(): merging the new route");
176 ospf_route_copy_nexthops (or, abr_or
->paths
);
177 ospf_route_free (new_or
);
180 /* New route is worse */
183 if (IS_DEBUG_OSPF_EVENT
)
184 zlog_debug ("ospf_ia_router_route(): skipping the new route");
185 ospf_route_free (new_or
);
190 ospf_route_copy_nexthops (new_or
, abr_or
->paths
);
192 if (IS_DEBUG_OSPF_EVENT
)
193 zlog_debug ("ospf_ia_router_route(): adding the new route");
195 listnode_add (rn
->info
, new_or
);
200 process_summary_lsa (struct ospf_area
*area
, struct route_table
*rt
,
201 struct route_table
*rtrs
, struct ospf_lsa
*lsa
)
203 struct ospf
*ospf
= area
->ospf
;
204 struct ospf_area_range
*range
;
205 struct ospf_route
*abr_or
, *new_or
;
206 struct summary_lsa
*sl
;
207 struct prefix_ipv4 p
, abr
;
213 sl
= (struct summary_lsa
*) lsa
->data
;
215 if (IS_DEBUG_OSPF_EVENT
)
216 zlog_debug ("process_summary_lsa(): LS ID: %s", inet_ntoa (sl
->header
.id
));
218 metric
= GET_METRIC (sl
->metric
);
220 if (metric
== OSPF_LS_INFINITY
)
223 if (IS_LSA_MAXAGE (lsa
))
226 if (ospf_lsa_is_self_originated (area
->ospf
, lsa
))
230 p
.prefix
= sl
->header
.id
;
232 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
233 p
.prefixlen
= ip_masklen (sl
->mask
);
235 p
.prefixlen
= IPV4_MAX_BITLEN
;
237 apply_mask_ipv4 (&p
);
239 if (sl
->header
.type
== OSPF_SUMMARY_LSA
&&
240 (range
= ospf_area_range_match_any (ospf
, &p
)) &&
241 ospf_area_range_active (range
))
244 /* XXX: This check seems dubious to me. If an ABR has already decided
245 * to consider summaries received in this area, then why would one wish
246 * to exclude default?
248 if (IS_OSPF_ABR(ospf
) &&
249 ospf
->abr_type
!= OSPF_ABR_STAND
&&
250 area
->external_routing
!= OSPF_AREA_DEFAULT
&&
251 p
.prefix
.s_addr
== OSPF_DEFAULT_DESTINATION
&&
253 return 0; /* Ignore summary default from a stub area */
255 abr
.family
= AF_INET
;
256 abr
.prefix
= sl
->header
.adv_router
;
257 abr
.prefixlen
= IPV4_MAX_BITLEN
;
258 apply_mask_ipv4 (&abr
);
260 abr_or
= ospf_find_abr_route (rtrs
, &abr
, area
);
265 new_or
= ospf_route_new ();
266 new_or
->type
= OSPF_DESTINATION_NETWORK
;
267 new_or
->id
= sl
->header
.id
;
268 new_or
->mask
= sl
->mask
;
269 new_or
->u
.std
.options
= sl
->header
.options
;
270 new_or
->u
.std
.origin
= (struct lsa_header
*) sl
;
271 new_or
->cost
= abr_or
->cost
+ metric
;
272 new_or
->u
.std
.area_id
= area
->area_id
;
273 new_or
->u
.std
.external_routing
= area
->external_routing
;
274 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
276 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
277 ospf_ia_network_route (ospf
, rt
, &p
, new_or
, abr_or
);
280 new_or
->type
= OSPF_DESTINATION_ROUTER
;
281 new_or
->u
.std
.flags
= ROUTER_LSA_EXTERNAL
;
282 ospf_ia_router_route (ospf
, rtrs
, &p
, new_or
, abr_or
);
289 ospf_examine_summaries (struct ospf_area
*area
,
290 struct route_table
*lsdb_rt
,
291 struct route_table
*rt
,
292 struct route_table
*rtrs
)
294 struct ospf_lsa
*lsa
;
295 struct route_node
*rn
;
297 LSDB_LOOP (lsdb_rt
, rn
, lsa
)
298 process_summary_lsa (area
, rt
, rtrs
, lsa
);
302 ospf_area_is_transit (struct ospf_area
*area
)
304 return (area
->transit
== OSPF_TRANSIT_TRUE
) ||
305 ospf_full_virtual_nbrs(area
); /* Cisco forgets to set the V-bit :( */
309 ospf_update_network_route (struct ospf
*ospf
,
310 struct route_table
*rt
,
311 struct route_table
*rtrs
,
312 struct summary_lsa
*lsa
,
313 struct prefix_ipv4
*p
,
314 struct ospf_area
*area
)
316 struct route_node
*rn
;
317 struct ospf_route
*or, *abr_or
, *new_or
;
318 struct prefix_ipv4 abr
;
321 abr
.family
= AF_INET
;
322 abr
.prefix
=lsa
->header
.adv_router
;
323 abr
.prefixlen
= IPV4_MAX_BITLEN
;
324 apply_mask_ipv4 (&abr
);
326 abr_or
= ospf_find_abr_route (rtrs
, &abr
, area
);
330 if (IS_DEBUG_OSPF_EVENT
)
331 zlog_debug ("ospf_update_network_route(): can't find a route to the ABR");
335 cost
= abr_or
->cost
+ GET_METRIC (lsa
->metric
);
337 rn
= route_node_lookup (rt
, (struct prefix
*) p
);
341 if (ospf
->abr_type
!= OSPF_ABR_SHORTCUT
)
342 return; /* Standard ABR can update only already installed
344 if (IS_DEBUG_OSPF_EVENT
)
345 zlog_debug ("ospf_update_network_route(): "
346 "Allowing Shortcut ABR to add new route");
347 new_or
= ospf_route_new ();
348 new_or
->type
= OSPF_DESTINATION_NETWORK
;
349 new_or
->id
= lsa
->header
.id
;
350 new_or
->mask
= lsa
->mask
;
351 new_or
->u
.std
.options
= lsa
->header
.options
;
352 new_or
->u
.std
.origin
= (struct lsa_header
*) lsa
;
354 new_or
->u
.std
.area_id
= area
->area_id
;
355 new_or
->u
.std
.external_routing
= area
->external_routing
;
356 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
357 ospf_route_add (rt
, p
, new_or
, abr_or
);
363 route_unlock_node (rn
);
364 if (rn
->info
== NULL
)
370 if (or->path_type
!= OSPF_PATH_INTRA_AREA
&&
371 or->path_type
!= OSPF_PATH_INTER_AREA
)
373 if (IS_DEBUG_OSPF_EVENT
)
374 zlog_debug ("ospf_update_network_route(): ERR: path type is wrong");
378 if (ospf
->abr_type
== OSPF_ABR_SHORTCUT
)
380 if (or->path_type
== OSPF_PATH_INTRA_AREA
&&
381 !OSPF_IS_AREA_ID_BACKBONE (or->u
.std
.area_id
))
383 if (IS_DEBUG_OSPF_EVENT
)
384 zlog_debug ("ospf_update_network_route(): Shortcut: "
385 "this intra-area path is not backbone");
389 else /* Not Shortcut ABR */
391 if (!OSPF_IS_AREA_ID_BACKBONE (or->u
.std
.area_id
))
393 if (IS_DEBUG_OSPF_EVENT
)
394 zlog_debug ("ospf_update_network_route(): "
395 "route is not BB-associated");
396 return; /* We can update only BB routes */
402 if (IS_DEBUG_OSPF_EVENT
)
403 zlog_debug ("ospf_update_network_route(): new route is worse");
407 if (or->cost
== cost
)
409 if (IS_DEBUG_OSPF_EVENT
)
410 zlog_debug ("ospf_update_network_route(): "
411 "new route is same distance, adding nexthops");
412 ospf_route_copy_nexthops (or, abr_or
->paths
);
417 if (IS_DEBUG_OSPF_EVENT
)
418 zlog_debug ("ospf_update_network_route(): "
419 "new route is better, overriding nexthops");
420 ospf_route_subst_nexthops (or, abr_or
->paths
);
423 if ((ospf
->abr_type
== OSPF_ABR_SHORTCUT
) &&
424 !OSPF_IS_AREA_ID_BACKBONE (or->u
.std
.area_id
))
426 or->path_type
= OSPF_PATH_INTER_AREA
;
427 or->u
.std
.area_id
= area
->area_id
;
428 or->u
.std
.external_routing
= area
->external_routing
;
429 /* Note that we can do this only in Shortcut ABR mode,
430 because standard ABR must leave the route type and area
438 ospf_update_router_route (struct ospf
*ospf
,
439 struct route_table
*rtrs
,
440 struct summary_lsa
*lsa
,
441 struct prefix_ipv4
*p
,
442 struct ospf_area
*area
)
444 struct ospf_route
*or, *abr_or
, *new_or
;
445 struct prefix_ipv4 abr
;
448 abr
.family
= AF_INET
;
449 abr
.prefix
= lsa
->header
.adv_router
;
450 abr
.prefixlen
= IPV4_MAX_BITLEN
;
451 apply_mask_ipv4 (&abr
);
453 abr_or
= ospf_find_abr_route (rtrs
, &abr
, area
);
457 if (IS_DEBUG_OSPF_EVENT
)
458 zlog_debug ("ospf_update_router_route(): can't find a route to the ABR");
462 cost
= abr_or
->cost
+ GET_METRIC (lsa
->metric
);
464 /* First try to find a backbone path,
465 because standard ABR can update only BB-associated paths */
467 if ((ospf
->backbone
== NULL
) &&
468 (ospf
->abr_type
!= OSPF_ABR_SHORTCUT
))
470 /* no BB area, not Shortcut ABR, exiting */
473 or = ospf_find_asbr_route_through_area (rtrs
, p
, ospf
->backbone
);
477 if (ospf
->abr_type
!= OSPF_ABR_SHORTCUT
)
479 /* route to ASBR through the BB not found
480 the router is not Shortcut ABR, exiting */
484 /* We're a Shortcut ABR*/
486 /* Let it either add a new router or update the route
487 through the same (non-BB) area. */
489 new_or
= ospf_route_new ();
490 new_or
->type
= OSPF_DESTINATION_ROUTER
;
491 new_or
->id
= lsa
->header
.id
;
492 new_or
->mask
= lsa
->mask
;
493 new_or
->u
.std
.options
= lsa
->header
.options
;
494 new_or
->u
.std
.origin
= (struct lsa_header
*)lsa
;
496 new_or
->u
.std
.area_id
= area
->area_id
;
497 new_or
->u
.std
.external_routing
= area
->external_routing
;
498 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
499 new_or
->u
.std
.flags
= ROUTER_LSA_EXTERNAL
;
500 ospf_ia_router_route (ospf
, rtrs
, p
, new_or
, abr_or
);
506 /* At this point the "or" is always bb-associated */
508 if (!(or->u
.std
.flags
& ROUTER_LSA_EXTERNAL
))
510 if (IS_DEBUG_OSPF_EVENT
)
511 zlog_debug ("ospf_upd_router_route(): the remote router is not an ASBR");
515 if (or->path_type
!= OSPF_PATH_INTRA_AREA
&&
516 or->path_type
!= OSPF_PATH_INTER_AREA
)
522 else if (or->cost
== cost
)
523 ospf_route_copy_nexthops (or, abr_or
->paths
);
525 else if (or->cost
> cost
)
527 ospf_route_subst_nexthops (or, abr_or
->paths
);
530 /* Even if the ABR runs in Shortcut mode, we can't change
531 the path type and area, because the "or" is always bb-associated
532 at this point and even Shortcut ABR can't change these attributes */
537 process_transit_summary_lsa (struct ospf_area
*area
, struct route_table
*rt
,
538 struct route_table
*rtrs
, struct ospf_lsa
*lsa
)
540 struct ospf
*ospf
= area
->ospf
;
541 struct summary_lsa
*sl
;
542 struct prefix_ipv4 p
;
548 sl
= (struct summary_lsa
*) lsa
->data
;
550 if (IS_DEBUG_OSPF_EVENT
)
551 zlog_debug ("process_transit_summaries(): LS ID: %s",
552 inet_ntoa (lsa
->data
->id
));
553 metric
= GET_METRIC (sl
->metric
);
555 if (metric
== OSPF_LS_INFINITY
)
557 if (IS_DEBUG_OSPF_EVENT
)
558 zlog_debug ("process_transit_summaries(): metric is infinity, skip");
562 if (IS_LSA_MAXAGE (lsa
))
564 if (IS_DEBUG_OSPF_EVENT
)
565 zlog_debug ("process_transit_summaries(): This LSA is too old");
569 if (ospf_lsa_is_self_originated (area
->ospf
, lsa
))
571 if (IS_DEBUG_OSPF_EVENT
)
572 zlog_debug ("process_transit_summaries(): This LSA is mine, skip");
577 p
.prefix
= sl
->header
.id
;
579 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
580 p
.prefixlen
= ip_masklen (sl
->mask
);
582 p
.prefixlen
= IPV4_MAX_BITLEN
;
584 apply_mask_ipv4 (&p
);
586 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
587 ospf_update_network_route (ospf
, rt
, rtrs
, sl
, &p
, area
);
589 ospf_update_router_route (ospf
, rtrs
, sl
, &p
, area
);
595 ospf_examine_transit_summaries (struct ospf_area
*area
,
596 struct route_table
*lsdb_rt
,
597 struct route_table
*rt
,
598 struct route_table
*rtrs
)
600 struct ospf_lsa
*lsa
;
601 struct route_node
*rn
;
603 LSDB_LOOP (lsdb_rt
, rn
, lsa
)
604 process_transit_summary_lsa (area
, rt
, rtrs
, lsa
);
608 ospf_ia_routing (struct ospf
*ospf
,
609 struct route_table
*rt
,
610 struct route_table
*rtrs
)
612 struct ospf_area
* area
;
614 if (IS_DEBUG_OSPF_EVENT
)
615 zlog_debug ("ospf_ia_routing():start");
617 if (IS_OSPF_ABR (ospf
))
619 struct listnode
*node
;
620 struct ospf_area
*area
;
622 switch (ospf
->abr_type
)
625 if (IS_DEBUG_OSPF_EVENT
)
626 zlog_debug ("ospf_ia_routing():Standard ABR");
628 if ((area
= ospf
->backbone
))
630 struct listnode
*node
;
632 if (IS_DEBUG_OSPF_EVENT
)
634 zlog_debug ("ospf_ia_routing():backbone area found");
635 zlog_debug ("ospf_ia_routing():examining summaries");
638 OSPF_EXAMINE_SUMMARIES_ALL (area
, rt
, rtrs
);
640 for (ALL_LIST_ELEMENTS_RO (ospf
->areas
, node
, area
))
641 if (area
!= ospf
->backbone
)
642 if (ospf_area_is_transit (area
))
643 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area
, rt
, rtrs
);
646 if (IS_DEBUG_OSPF_EVENT
)
647 zlog_debug ("ospf_ia_routing():backbone area NOT found");
651 if (IS_DEBUG_OSPF_EVENT
)
652 zlog_debug ("ospf_ia_routing():Alternative Cisco/IBM ABR");
653 area
= ospf
->backbone
; /* Find the BB */
655 /* If we have an active BB connection */
656 if (area
&& ospf_act_bb_connection (ospf
))
658 if (IS_DEBUG_OSPF_EVENT
)
660 zlog_debug ("ospf_ia_routing(): backbone area found");
661 zlog_debug ("ospf_ia_routing(): examining BB summaries");
664 OSPF_EXAMINE_SUMMARIES_ALL (area
, rt
, rtrs
);
666 for (ALL_LIST_ELEMENTS_RO (ospf
->areas
, node
, area
))
667 if (area
!= ospf
->backbone
)
668 if (ospf_area_is_transit (area
))
669 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area
, rt
, rtrs
);
672 { /* No active BB connection--consider all areas */
673 if (IS_DEBUG_OSPF_EVENT
)
674 zlog_debug ("ospf_ia_routing(): "
675 "Active BB connection not found");
676 for (ALL_LIST_ELEMENTS_RO (ospf
->areas
, node
, area
))
677 OSPF_EXAMINE_SUMMARIES_ALL (area
, rt
, rtrs
);
680 case OSPF_ABR_SHORTCUT
:
681 if (IS_DEBUG_OSPF_EVENT
)
682 zlog_debug ("ospf_ia_routing():Alternative Shortcut");
683 area
= ospf
->backbone
; /* Find the BB */
685 /* If we have an active BB connection */
686 if (area
&& ospf_act_bb_connection (ospf
))
688 if (IS_DEBUG_OSPF_EVENT
)
690 zlog_debug ("ospf_ia_routing(): backbone area found");
691 zlog_debug ("ospf_ia_routing(): examining BB summaries");
693 OSPF_EXAMINE_SUMMARIES_ALL (area
, rt
, rtrs
);
696 for (ALL_LIST_ELEMENTS_RO (ospf
->areas
, node
, area
))
697 if (area
!= ospf
->backbone
)
698 if (ospf_area_is_transit (area
) ||
699 ((area
->shortcut_configured
!= OSPF_SHORTCUT_DISABLE
) &&
700 ((ospf
->backbone
== NULL
) ||
701 ((area
->shortcut_configured
== OSPF_SHORTCUT_ENABLE
) &&
702 area
->shortcut_capability
))))
703 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL (area
, rt
, rtrs
);
711 struct listnode
*node
;
713 if (IS_DEBUG_OSPF_EVENT
)
714 zlog_debug ("ospf_ia_routing():not ABR, considering all areas");
716 for (ALL_LIST_ELEMENTS_RO (ospf
->areas
, node
, area
))
717 OSPF_EXAMINE_SUMMARIES_ALL (area
, rt
, rtrs
);