]>
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 along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 #include "ospfd/ospfd.h"
34 #include "ospfd/ospf_interface.h"
35 #include "ospfd/ospf_ism.h"
36 #include "ospfd/ospf_asbr.h"
37 #include "ospfd/ospf_lsa.h"
38 #include "ospfd/ospf_lsdb.h"
39 #include "ospfd/ospf_neighbor.h"
40 #include "ospfd/ospf_nsm.h"
41 #include "ospfd/ospf_spf.h"
42 #include "ospfd/ospf_route.h"
43 #include "ospfd/ospf_ase.h"
44 #include "ospfd/ospf_abr.h"
45 #include "ospfd/ospf_ia.h"
46 #include "ospfd/ospf_dump.h"
48 static struct ospf_route
*ospf_find_abr_route(struct route_table
*rtrs
,
49 struct prefix_ipv4
*abr
,
50 struct ospf_area
*area
)
52 struct route_node
*rn
;
53 struct ospf_route
* or ;
54 struct listnode
*node
;
56 if ((rn
= route_node_lookup(rtrs
, (struct prefix
*)abr
)) == NULL
)
59 route_unlock_node(rn
);
61 for (ALL_LIST_ELEMENTS_RO((struct list
*)rn
->info
, node
, or))
62 if (IPV4_ADDR_SAME(& or->u
.std
.area_id
, &area
->area_id
)
63 && (or->u
.std
.flags
& ROUTER_LSA_BORDER
))
69 static void ospf_ia_network_route(struct ospf
*ospf
, struct route_table
*rt
,
70 struct prefix_ipv4
*p
,
71 struct ospf_route
*new_or
,
72 struct ospf_route
*abr_or
)
74 struct route_node
*rn1
;
75 struct ospf_route
* or ;
77 if (IS_DEBUG_OSPF_EVENT
)
79 "ospf_ia_network_route(): processing summary route to %pFX",
82 /* Find a route to the same dest */
83 if ((rn1
= route_node_lookup(rt
, (struct prefix
*)p
))) {
86 route_unlock_node(rn1
);
88 if ((or = rn1
->info
)) {
89 if (IS_DEBUG_OSPF_EVENT
)
91 "ospf_ia_network_route(): Found a route to the same network");
92 /* Check the existing route. */
93 if ((res
= ospf_route_cmp(ospf
, new_or
, or)) < 0) {
94 /* New route is better, so replace old one. */
95 ospf_route_subst(rn1
, new_or
, abr_or
);
96 } else if (res
== 0) {
97 /* New and old route are equal, so next hops can
100 ospf_route_copy_nexthops(or, abr_or
->paths
);
101 route_unlock_node(rn1
);
103 /* new route can be deleted, because existing
104 * route has been updated. */
105 ospf_route_free(new_or
);
107 /* New route is worse, so free it. */
108 ospf_route_free(new_or
);
113 else { /* no route */
114 if (IS_DEBUG_OSPF_EVENT
)
116 "ospf_ia_network_route(): add new route to %pFX",
118 ospf_route_add(rt
, p
, new_or
, abr_or
);
122 static void ospf_ia_router_route(struct ospf
*ospf
, struct route_table
*rtrs
,
123 struct prefix_ipv4
*p
,
124 struct ospf_route
*new_or
,
125 struct ospf_route
*abr_or
)
127 struct ospf_route
* or = NULL
;
128 struct route_node
*rn
;
131 if (IS_DEBUG_OSPF_EVENT
)
132 zlog_debug("ospf_ia_router_route(): considering %pFX", p
);
133 /* Find a route to the same dest */
134 rn
= route_node_get(rtrs
, (struct prefix
*)p
);
136 if (rn
->info
== NULL
)
137 /* This is a new route */
138 rn
->info
= list_new();
140 struct ospf_area
*or_area
;
141 or_area
= ospf_area_lookup_by_area_id(ospf
,
142 new_or
->u
.std
.area_id
);
144 /* This is an additional route */
145 route_unlock_node(rn
);
146 or = ospf_find_asbr_route_through_area(rtrs
, p
, or_area
);
150 if (IS_DEBUG_OSPF_EVENT
)
152 "ospf_ia_router_route(): a route to the same ABR through the same area exists");
153 /* New route is better */
154 if ((ret
= ospf_route_cmp(ospf
, new_or
, or)) < 0) {
155 listnode_delete(rn
->info
, or);
159 /* Routes are the same */
161 if (IS_DEBUG_OSPF_EVENT
)
163 "ospf_ia_router_route(): merging the new route");
165 ospf_route_copy_nexthops(or, abr_or
->paths
);
166 ospf_route_free(new_or
);
169 /* New route is worse */
171 if (IS_DEBUG_OSPF_EVENT
)
173 "ospf_ia_router_route(): skipping the new route");
174 ospf_route_free(new_or
);
179 ospf_route_copy_nexthops(new_or
, abr_or
->paths
);
181 if (IS_DEBUG_OSPF_EVENT
)
182 zlog_debug("ospf_ia_router_route(): adding the new route");
184 listnode_add(rn
->info
, new_or
);
188 static int process_summary_lsa(struct ospf_area
*area
, struct route_table
*rt
,
189 struct route_table
*rtrs
, struct ospf_lsa
*lsa
)
191 struct ospf
*ospf
= area
->ospf
;
192 struct ospf_area_range
*range
;
193 struct ospf_route
*abr_or
, *new_or
;
194 struct summary_lsa
*sl
;
195 struct prefix_ipv4 p
, abr
;
201 sl
= (struct summary_lsa
*)lsa
->data
;
203 if (IS_DEBUG_OSPF_EVENT
)
204 zlog_debug("process_summary_lsa(): LS ID: %s",
205 inet_ntoa(sl
->header
.id
));
207 metric
= GET_METRIC(sl
->metric
);
209 if (metric
== OSPF_LS_INFINITY
)
212 if (IS_LSA_MAXAGE(lsa
))
215 if (ospf_lsa_is_self_originated(area
->ospf
, lsa
))
219 p
.prefix
= sl
->header
.id
;
221 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
222 p
.prefixlen
= ip_masklen(sl
->mask
);
224 p
.prefixlen
= IPV4_MAX_BITLEN
;
228 if (sl
->header
.type
== OSPF_SUMMARY_LSA
229 && (range
= ospf_area_range_match_any(ospf
, &p
))
230 && ospf_area_range_active(range
))
233 /* XXX: This check seems dubious to me. If an ABR has already decided
234 * to consider summaries received in this area, then why would one wish
235 * to exclude default?
237 if (IS_OSPF_ABR(ospf
) && ospf
->abr_type
!= OSPF_ABR_STAND
238 && area
->external_routing
!= OSPF_AREA_DEFAULT
239 && p
.prefix
.s_addr
== OSPF_DEFAULT_DESTINATION
&& p
.prefixlen
== 0)
240 return 0; /* Ignore summary default from a stub area */
242 abr
.family
= AF_INET
;
243 abr
.prefix
= sl
->header
.adv_router
;
244 abr
.prefixlen
= IPV4_MAX_BITLEN
;
245 apply_mask_ipv4(&abr
);
247 abr_or
= ospf_find_abr_route(rtrs
, &abr
, area
);
252 new_or
= ospf_route_new();
253 new_or
->type
= OSPF_DESTINATION_NETWORK
;
254 new_or
->id
= sl
->header
.id
;
255 new_or
->mask
= sl
->mask
;
256 new_or
->u
.std
.options
= sl
->header
.options
;
257 new_or
->u
.std
.origin
= (struct lsa_header
*)sl
;
258 new_or
->cost
= abr_or
->cost
+ metric
;
259 new_or
->u
.std
.area_id
= area
->area_id
;
260 new_or
->u
.std
.external_routing
= area
->external_routing
;
261 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
263 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
264 ospf_ia_network_route(ospf
, rt
, &p
, new_or
, abr_or
);
266 new_or
->type
= OSPF_DESTINATION_ROUTER
;
267 new_or
->u
.std
.flags
= ROUTER_LSA_EXTERNAL
;
268 ospf_ia_router_route(ospf
, rtrs
, &p
, new_or
, abr_or
);
274 static void ospf_examine_summaries(struct ospf_area
*area
,
275 struct route_table
*lsdb_rt
,
276 struct route_table
*rt
,
277 struct route_table
*rtrs
)
279 struct ospf_lsa
*lsa
;
280 struct route_node
*rn
;
282 LSDB_LOOP (lsdb_rt
, rn
, lsa
)
283 process_summary_lsa(area
, rt
, rtrs
, lsa
);
286 int ospf_area_is_transit(struct ospf_area
*area
)
288 return (area
->transit
== OSPF_TRANSIT_TRUE
)
289 || ospf_full_virtual_nbrs(
290 area
); /* Cisco forgets to set the V-bit :( */
293 static void ospf_update_network_route(struct ospf
*ospf
, struct route_table
*rt
,
294 struct route_table
*rtrs
,
295 struct summary_lsa
*lsa
,
296 struct prefix_ipv4
*p
,
297 struct ospf_area
*area
)
299 struct route_node
*rn
;
300 struct ospf_route
* or, *abr_or
, *new_or
;
301 struct prefix_ipv4 abr
;
304 abr
.family
= AF_INET
;
305 abr
.prefix
= lsa
->header
.adv_router
;
306 abr
.prefixlen
= IPV4_MAX_BITLEN
;
307 apply_mask_ipv4(&abr
);
309 abr_or
= ospf_find_abr_route(rtrs
, &abr
, area
);
311 if (abr_or
== NULL
) {
312 if (IS_DEBUG_OSPF_EVENT
)
314 "ospf_update_network_route(): can't find a route to the ABR");
318 cost
= abr_or
->cost
+ GET_METRIC(lsa
->metric
);
320 rn
= route_node_lookup(rt
, (struct prefix
*)p
);
323 if (ospf
->abr_type
!= OSPF_ABR_SHORTCUT
)
324 return; /* Standard ABR can update only already
327 if (IS_DEBUG_OSPF_EVENT
)
329 "ospf_update_network_route(): Allowing Shortcut ABR to add new route");
330 new_or
= ospf_route_new();
331 new_or
->type
= OSPF_DESTINATION_NETWORK
;
332 new_or
->id
= lsa
->header
.id
;
333 new_or
->mask
= lsa
->mask
;
334 new_or
->u
.std
.options
= lsa
->header
.options
;
335 new_or
->u
.std
.origin
= (struct lsa_header
*)lsa
;
337 new_or
->u
.std
.area_id
= area
->area_id
;
338 new_or
->u
.std
.external_routing
= area
->external_routing
;
339 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
340 ospf_route_add(rt
, p
, new_or
, abr_or
);
344 route_unlock_node(rn
);
345 if (rn
->info
== NULL
)
351 if (or->path_type
!= OSPF_PATH_INTRA_AREA
&&
352 or->path_type
!= OSPF_PATH_INTER_AREA
) {
353 if (IS_DEBUG_OSPF_EVENT
)
355 "ospf_update_network_route(): ERR: path type is wrong");
359 if (ospf
->abr_type
== OSPF_ABR_SHORTCUT
) {
361 or->path_type
== OSPF_PATH_INTRA_AREA
362 && !OSPF_IS_AREA_ID_BACKBONE(
363 or->u
.std
.area_id
)) {
364 if (IS_DEBUG_OSPF_EVENT
)
366 "ospf_update_network_route(): Shortcut: this intra-area path is not backbone");
369 } else /* Not Shortcut ABR */
371 if (!OSPF_IS_AREA_ID_BACKBONE(or->u
.std
.area_id
)) {
372 if (IS_DEBUG_OSPF_EVENT
)
374 "ospf_update_network_route(): route is not BB-associated");
375 return; /* We can update only BB routes */
379 if (or->cost
< cost
) {
380 if (IS_DEBUG_OSPF_EVENT
)
382 "ospf_update_network_route(): new route is worse");
386 if (or->cost
== cost
) {
387 if (IS_DEBUG_OSPF_EVENT
)
389 "ospf_update_network_route(): new route is same distance, adding nexthops");
390 ospf_route_copy_nexthops(or, abr_or
->paths
);
393 if (or->cost
> cost
) {
394 if (IS_DEBUG_OSPF_EVENT
)
396 "ospf_update_network_route(): new route is better, overriding nexthops");
397 ospf_route_subst_nexthops(or, abr_or
->paths
);
400 if ((ospf
->abr_type
== OSPF_ABR_SHORTCUT
)
401 && !OSPF_IS_AREA_ID_BACKBONE(or->u
.std
.area_id
)) {
402 or->path_type
= OSPF_PATH_INTER_AREA
;
403 or->u
.std
.area_id
= area
->area_id
;
404 or->u
.std
.external_routing
= area
->external_routing
;
405 /* Note that we can do this only in Shortcut ABR mode,
406 because standard ABR must leave the route type and
414 static void ospf_update_router_route(struct ospf
*ospf
,
415 struct route_table
*rtrs
,
416 struct summary_lsa
*lsa
,
417 struct prefix_ipv4
*p
,
418 struct ospf_area
*area
)
420 struct ospf_route
* or, *abr_or
, *new_or
;
421 struct prefix_ipv4 abr
;
424 abr
.family
= AF_INET
;
425 abr
.prefix
= lsa
->header
.adv_router
;
426 abr
.prefixlen
= IPV4_MAX_BITLEN
;
427 apply_mask_ipv4(&abr
);
429 abr_or
= ospf_find_abr_route(rtrs
, &abr
, area
);
431 if (abr_or
== NULL
) {
432 if (IS_DEBUG_OSPF_EVENT
)
434 "ospf_update_router_route(): can't find a route to the ABR");
438 cost
= abr_or
->cost
+ GET_METRIC(lsa
->metric
);
440 /* First try to find a backbone path,
441 because standard ABR can update only BB-associated paths */
443 if ((ospf
->backbone
== NULL
) && (ospf
->abr_type
!= OSPF_ABR_SHORTCUT
))
444 return; /* no BB area, not Shortcut ABR, exiting */
446 /* find the backbone route, if possible */
447 if ((ospf
->backbone
== NULL
)
448 || !(or = ospf_find_asbr_route_through_area(rtrs
, p
,
450 if (ospf
->abr_type
!= OSPF_ABR_SHORTCUT
)
452 /* route to ASBR through the BB not found
453 the router is not Shortcut ABR, exiting */
457 /* We're a Shortcut ABR*/
459 /* Let it either add a new router or update the route
460 through the same (non-BB) area. */
462 new_or
= ospf_route_new();
463 new_or
->type
= OSPF_DESTINATION_ROUTER
;
464 new_or
->id
= lsa
->header
.id
;
465 new_or
->mask
= lsa
->mask
;
466 new_or
->u
.std
.options
= lsa
->header
.options
;
467 new_or
->u
.std
.origin
= (struct lsa_header
*)lsa
;
469 new_or
->u
.std
.area_id
= area
->area_id
;
470 new_or
->u
.std
.external_routing
= area
->external_routing
;
471 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
472 new_or
->u
.std
.flags
= ROUTER_LSA_EXTERNAL
;
473 ospf_ia_router_route(ospf
, rtrs
, p
, new_or
, abr_or
);
479 /* At this point the "or" is always bb-associated */
481 if (!(or->u
.std
.flags
& ROUTER_LSA_EXTERNAL
)) {
482 if (IS_DEBUG_OSPF_EVENT
)
484 "ospf_upd_router_route(): the remote router is not an ASBR");
488 if (or->path_type
!= OSPF_PATH_INTRA_AREA
&&
489 or->path_type
!= OSPF_PATH_INTER_AREA
)
495 else if (or->cost
== cost
)
496 ospf_route_copy_nexthops(or, abr_or
->paths
);
498 else if (or->cost
> cost
) {
499 ospf_route_subst_nexthops(or, abr_or
->paths
);
502 /* Even if the ABR runs in Shortcut mode, we can't change
503 the path type and area, because the "or" is always
505 at this point and even Shortcut ABR can't change these
510 static int process_transit_summary_lsa(struct ospf_area
*area
,
511 struct route_table
*rt
,
512 struct route_table
*rtrs
,
513 struct ospf_lsa
*lsa
)
515 struct ospf
*ospf
= area
->ospf
;
516 struct summary_lsa
*sl
;
517 struct prefix_ipv4 p
;
523 sl
= (struct summary_lsa
*)lsa
->data
;
525 if (IS_DEBUG_OSPF_EVENT
)
526 zlog_debug("process_transit_summaries(): LS ID: %s",
527 inet_ntoa(lsa
->data
->id
));
528 metric
= GET_METRIC(sl
->metric
);
530 if (metric
== OSPF_LS_INFINITY
) {
531 if (IS_DEBUG_OSPF_EVENT
)
533 "process_transit_summaries(): metric is infinity, skip");
537 if (IS_LSA_MAXAGE(lsa
)) {
538 if (IS_DEBUG_OSPF_EVENT
)
540 "process_transit_summaries(): This LSA is too old");
544 if (ospf_lsa_is_self_originated(area
->ospf
, lsa
)) {
545 if (IS_DEBUG_OSPF_EVENT
)
547 "process_transit_summaries(): This LSA is mine, skip");
552 p
.prefix
= sl
->header
.id
;
554 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
555 p
.prefixlen
= ip_masklen(sl
->mask
);
557 p
.prefixlen
= IPV4_MAX_BITLEN
;
561 if (sl
->header
.type
== OSPF_SUMMARY_LSA
)
562 ospf_update_network_route(ospf
, rt
, rtrs
, sl
, &p
, area
);
564 ospf_update_router_route(ospf
, rtrs
, sl
, &p
, area
);
569 static void ospf_examine_transit_summaries(struct ospf_area
*area
,
570 struct route_table
*lsdb_rt
,
571 struct route_table
*rt
,
572 struct route_table
*rtrs
)
574 struct ospf_lsa
*lsa
;
575 struct route_node
*rn
;
577 LSDB_LOOP (lsdb_rt
, rn
, lsa
)
578 process_transit_summary_lsa(area
, rt
, rtrs
, lsa
);
581 void ospf_ia_routing(struct ospf
*ospf
, struct route_table
*rt
,
582 struct route_table
*rtrs
)
584 struct listnode
*node
;
585 struct ospf_area
*area
;
587 if (IS_DEBUG_OSPF_EVENT
)
588 zlog_debug("ospf_ia_routing():start");
590 if (IS_OSPF_ABR(ospf
)) {
591 switch (ospf
->abr_type
) {
593 if (IS_DEBUG_OSPF_EVENT
)
594 zlog_debug("ospf_ia_routing():Standard ABR");
596 if ((area
= ospf
->backbone
)) {
597 if (IS_DEBUG_OSPF_EVENT
) {
599 "ospf_ia_routing():backbone area found");
601 "ospf_ia_routing():examining summaries");
604 OSPF_EXAMINE_SUMMARIES_ALL(area
, rt
, rtrs
);
606 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
,
608 if (area
!= ospf
->backbone
)
609 if (ospf_area_is_transit(area
))
610 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
612 } else if (IS_DEBUG_OSPF_EVENT
)
614 "ospf_ia_routing():backbone area NOT found");
618 if (IS_DEBUG_OSPF_EVENT
)
620 "ospf_ia_routing():Alternative Cisco/IBM ABR");
621 area
= ospf
->backbone
; /* Find the BB */
623 /* If we have an active BB connection */
624 if (area
&& ospf_act_bb_connection(ospf
)) {
625 if (IS_DEBUG_OSPF_EVENT
) {
627 "ospf_ia_routing(): backbone area found");
629 "ospf_ia_routing(): examining BB summaries");
632 OSPF_EXAMINE_SUMMARIES_ALL(area
, rt
, rtrs
);
634 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
,
636 if (area
!= ospf
->backbone
)
637 if (ospf_area_is_transit(area
))
638 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
640 } else { /* No active BB connection--consider all areas
642 if (IS_DEBUG_OSPF_EVENT
)
644 "ospf_ia_routing(): Active BB connection not found");
645 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
,
647 OSPF_EXAMINE_SUMMARIES_ALL(area
, rt
,
651 case OSPF_ABR_SHORTCUT
:
652 if (IS_DEBUG_OSPF_EVENT
)
654 "ospf_ia_routing():Alternative Shortcut");
655 area
= ospf
->backbone
; /* Find the BB */
657 /* If we have an active BB connection */
658 if (area
&& ospf_act_bb_connection(ospf
)) {
659 if (IS_DEBUG_OSPF_EVENT
) {
661 "ospf_ia_routing(): backbone area found");
663 "ospf_ia_routing(): examining BB summaries");
665 OSPF_EXAMINE_SUMMARIES_ALL(area
, rt
, rtrs
);
668 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
))
669 if (area
!= ospf
->backbone
)
670 if (ospf_area_is_transit(area
)
671 || ((area
->shortcut_configured
672 != OSPF_SHORTCUT_DISABLE
)
673 && ((ospf
->backbone
== NULL
)
674 || ((area
->shortcut_configured
675 == OSPF_SHORTCUT_ENABLE
)
676 && area
->shortcut_capability
))))
677 OSPF_EXAMINE_TRANSIT_SUMMARIES_ALL(
684 if (IS_DEBUG_OSPF_EVENT
)
686 "ospf_ia_routing():not ABR, considering all areas");
688 for (ALL_LIST_ELEMENTS_RO(ospf
->areas
, node
, area
))
689 OSPF_EXAMINE_SUMMARIES_ALL(area
, rt
, rtrs
);