]>
git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_route.c
3 * Copyright (C) 1999, 2000 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
32 #include "sockunion.h"
34 #include "ospfd/ospfd.h"
35 #include "ospfd/ospf_interface.h"
36 #include "ospfd/ospf_asbr.h"
37 #include "ospfd/ospf_lsa.h"
38 #include "ospfd/ospf_route.h"
39 #include "ospfd/ospf_spf.h"
40 #include "ospfd/ospf_zebra.h"
41 #include "ospfd/ospf_dump.h"
46 struct ospf_route
*new;
48 new = XCALLOC (MTYPE_OSPF_ROUTE
, sizeof (struct ospf_route
));
50 new->paths
= list_new ();
51 new->paths
->del
= (void (*) (void *))ospf_path_free
;
57 ospf_route_free (struct ospf_route
*or)
60 list_delete (or->paths
);
62 XFREE (MTYPE_OSPF_ROUTE
, or);
68 struct ospf_path
*new;
70 new = XCALLOC (MTYPE_OSPF_PATH
, sizeof (struct ospf_path
));
75 static struct ospf_path
*
76 ospf_path_dup (struct ospf_path
*path
)
78 struct ospf_path
*new;
80 new = ospf_path_new ();
81 memcpy (new, path
, sizeof (struct ospf_path
));
87 ospf_path_free (struct ospf_path
*op
)
89 XFREE (MTYPE_OSPF_PATH
, op
);
93 ospf_route_delete (struct route_table
*rt
)
95 struct route_node
*rn
;
96 struct ospf_route
*or;
98 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
99 if ((or = rn
->info
) != NULL
)
101 if (or->type
== OSPF_DESTINATION_NETWORK
)
102 ospf_zebra_delete ((struct prefix_ipv4
*) &rn
->p
,
104 else if (or->type
== OSPF_DESTINATION_DISCARD
)
105 ospf_zebra_delete_discard ((struct prefix_ipv4
*) &rn
->p
);
110 ospf_route_table_free (struct route_table
*rt
)
112 struct route_node
*rn
;
113 struct ospf_route
*or;
115 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
116 if ((or = rn
->info
) != NULL
)
118 ospf_route_free (or);
121 route_unlock_node (rn
);
124 route_table_finish (rt
);
127 /* If a prefix exists in the new routing table, then return 1,
128 otherwise return 0. Since the ZEBRA-RIB does an implicit
129 withdraw, it is not necessary to send a delete, an add later
130 will act like an implicit delete. */
132 ospf_route_exist_new_table (struct route_table
*rt
, struct prefix_ipv4
*prefix
)
134 struct route_node
*rn
;
139 rn
= route_node_lookup (rt
, (struct prefix
*) prefix
);
143 route_unlock_node (rn
);
152 /* If a prefix and a nexthop match any route in the routing table,
153 then return 1, otherwise return 0. */
155 ospf_route_match_same (struct route_table
*rt
, struct prefix_ipv4
*prefix
,
156 struct ospf_route
*newor
)
158 struct route_node
*rn
;
159 struct ospf_route
*or;
160 struct ospf_path
*op
;
161 struct ospf_path
*newop
;
165 if (! rt
|| ! prefix
)
168 rn
= route_node_lookup (rt
, (struct prefix
*) prefix
);
169 if (! rn
|| ! rn
->info
)
172 route_unlock_node (rn
);
175 if (or->type
== newor
->type
&& or->cost
== newor
->cost
)
177 if (or->type
== OSPF_DESTINATION_NETWORK
)
179 if (or->paths
->count
!= newor
->paths
->count
)
182 /* Check each path. */
183 for (n1
= listhead (or->paths
), n2
= listhead (newor
->paths
);
184 n1
&& n2
; n1
= listnextnode (n1
), n2
= listnextnode (n2
))
186 op
= listgetdata (n1
);
187 newop
= listgetdata (n2
);
189 if (! IPV4_ADDR_SAME (&op
->nexthop
, &newop
->nexthop
))
191 if (op
->ifindex
!= newop
->ifindex
)
196 else if (prefix_same (&rn
->p
, (struct prefix
*) prefix
))
202 /* delete routes generated from AS-External routes if there is a inter/intra
206 ospf_route_delete_same_ext(struct route_table
*external_routes
,
207 struct route_table
*routes
)
209 struct route_node
*rn
,
212 if ( (external_routes
== NULL
) || (routes
== NULL
) )
215 /* Remove deleted routes */
216 for ( rn
= route_top (routes
); rn
; rn
= route_next (rn
) )
220 struct prefix_ipv4
*p
= (struct prefix_ipv4
*)(&rn
->p
);
221 if ( (ext_rn
= route_node_lookup (external_routes
, (struct prefix
*)p
)) )
225 ospf_zebra_delete (p
, ext_rn
->info
);
226 ospf_route_free( ext_rn
->info
);
229 route_unlock_node (ext_rn
);
235 /* rt: Old, cmprt: New */
237 ospf_route_delete_uniq (struct route_table
*rt
, struct route_table
*cmprt
)
239 struct route_node
*rn
;
240 struct ospf_route
*or;
242 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
243 if ((or = rn
->info
) != NULL
)
244 if (or->path_type
== OSPF_PATH_INTRA_AREA
||
245 or->path_type
== OSPF_PATH_INTER_AREA
)
247 if (or->type
== OSPF_DESTINATION_NETWORK
)
249 if (! ospf_route_exist_new_table (cmprt
,
250 (struct prefix_ipv4
*) &rn
->p
))
251 ospf_zebra_delete ((struct prefix_ipv4
*) &rn
->p
, or);
253 else if (or->type
== OSPF_DESTINATION_DISCARD
)
254 if (! ospf_route_exist_new_table (cmprt
,
255 (struct prefix_ipv4
*) &rn
->p
))
256 ospf_zebra_delete_discard ((struct prefix_ipv4
*) &rn
->p
);
260 /* Install routes to table. */
262 ospf_route_install (struct ospf
*ospf
, struct route_table
*rt
)
264 struct route_node
*rn
;
265 struct ospf_route
*or;
267 /* rt contains new routing table, new_table contains an old one.
270 ospf_route_table_free (ospf
->old_table
);
272 ospf
->old_table
= ospf
->new_table
;
273 ospf
->new_table
= rt
;
275 /* Delete old routes. */
277 ospf_route_delete_uniq (ospf
->old_table
, rt
);
278 if (ospf
->old_external_route
)
279 ospf_route_delete_same_ext (ospf
->old_external_route
, rt
);
281 /* Install new routes. */
282 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
283 if ((or = rn
->info
) != NULL
)
285 if (or->type
== OSPF_DESTINATION_NETWORK
)
287 if (! ospf_route_match_same (ospf
->old_table
,
288 (struct prefix_ipv4
*)&rn
->p
, or))
289 ospf_zebra_add ((struct prefix_ipv4
*) &rn
->p
, or);
291 else if (or->type
== OSPF_DESTINATION_DISCARD
)
292 if (! ospf_route_match_same (ospf
->old_table
,
293 (struct prefix_ipv4
*) &rn
->p
, or))
294 ospf_zebra_add_discard ((struct prefix_ipv4
*) &rn
->p
);
298 /* RFC2328 16.1. (4). For "router". */
300 ospf_intra_add_router (struct route_table
*rt
, struct vertex
*v
,
301 struct ospf_area
*area
)
303 struct route_node
*rn
;
304 struct ospf_route
*or;
305 struct prefix_ipv4 p
;
306 struct router_lsa
*lsa
;
308 if (IS_DEBUG_OSPF_EVENT
)
309 zlog_debug ("ospf_intra_add_router: Start");
311 lsa
= (struct router_lsa
*) v
->lsa
;
313 if (IS_DEBUG_OSPF_EVENT
)
314 zlog_debug ("ospf_intra_add_router: LS ID: %s",
315 inet_ntoa (lsa
->header
.id
));
317 if (!OSPF_IS_AREA_BACKBONE(area
))
318 ospf_vl_up_check (area
, lsa
->header
.id
, v
);
320 if (!CHECK_FLAG (lsa
->flags
, ROUTER_LSA_SHORTCUT
))
321 area
->shortcut_capability
= 0;
323 /* If the newly added vertex is an area border router or AS boundary
324 router, a routing table entry is added whose destination type is
326 if (! IS_ROUTER_LSA_BORDER (lsa
) && ! IS_ROUTER_LSA_EXTERNAL (lsa
))
328 if (IS_DEBUG_OSPF_EVENT
)
329 zlog_debug ("ospf_intra_add_router: "
330 "this router is neither ASBR nor ABR, skipping it");
334 /* Update ABR and ASBR count in this area. */
335 if (IS_ROUTER_LSA_BORDER (lsa
))
337 if (IS_ROUTER_LSA_EXTERNAL (lsa
))
340 /* The Options field found in the associated router-LSA is copied
341 into the routing table entry's Optional capabilities field. Call
342 the newly added vertex Router X. */
343 or = ospf_route_new ();
346 or->u
.std
.area_id
= area
->area_id
;
347 or->u
.std
.external_routing
= area
->external_routing
;
348 or->path_type
= OSPF_PATH_INTRA_AREA
;
349 or->cost
= v
->distance
;
350 or->type
= OSPF_DESTINATION_ROUTER
;
351 or->u
.std
.origin
= (struct lsa_header
*) lsa
;
352 or->u
.std
.options
= lsa
->header
.options
;
353 or->u
.std
.flags
= lsa
->flags
;
355 /* If Router X is the endpoint of one of the calculating router's
356 virtual links, and the virtual link uses Area A as Transit area:
357 the virtual link is declared up, the IP address of the virtual
358 interface is set to the IP address of the outgoing interface
359 calculated above for Router X, and the virtual neighbor's IP
360 address is set to Router X's interface address (contained in
361 Router X's router-LSA) that points back to the root of the
362 shortest- path tree; equivalently, this is the interface that
363 points back to Router X's parent vertex on the shortest-path tree
364 (similar to the calculation in Section 16.1.1). */
368 p
.prefixlen
= IPV4_MAX_BITLEN
;
370 if (IS_DEBUG_OSPF_EVENT
)
371 zlog_debug ("ospf_intra_add_router: talking about %s/%d",
372 inet_ntoa (p
.prefix
), p
.prefixlen
);
374 rn
= route_node_get (rt
, (struct prefix
*) &p
);
376 /* Note that we keep all routes to ABRs and ASBRs, not only the best */
377 if (rn
->info
== NULL
)
378 rn
->info
= list_new ();
380 route_unlock_node (rn
);
382 ospf_route_copy_nexthops_from_vertex (or, v
);
384 listnode_add (rn
->info
, or);
386 if (IS_DEBUG_OSPF_EVENT
)
387 zlog_debug ("ospf_intra_add_router: Stop");
390 /* RFC2328 16.1. (4). For transit network. */
392 ospf_intra_add_transit (struct route_table
*rt
, struct vertex
*v
,
393 struct ospf_area
*area
)
395 struct route_node
*rn
;
396 struct ospf_route
*or;
397 struct prefix_ipv4 p
;
398 struct network_lsa
*lsa
;
400 lsa
= (struct network_lsa
*) v
->lsa
;
402 /* If the newly added vertex is a transit network, the routing table
403 entry for the network is located. The entry's Destination ID is
404 the IP network number, which can be obtained by masking the
405 Vertex ID (Link State ID) with its associated subnet mask (found
406 in the body of the associated network-LSA). */
409 p
.prefixlen
= ip_masklen (lsa
->mask
);
410 apply_mask_ipv4 (&p
);
412 rn
= route_node_get (rt
, (struct prefix
*) &p
);
414 /* If the routing table entry already exists (i.e., there is already
415 an intra-area route to the destination installed in the routing
416 table), multiple vertices have mapped to the same IP network.
417 For example, this can occur when a new Designated Router is being
418 established. In this case, the current routing table entry
419 should be overwritten if and only if the newly found path is just
420 as short and the current routing table entry's Link State Origin
421 has a smaller Link State ID than the newly added vertex' LSA. */
424 struct ospf_route
*cur_or
;
426 route_unlock_node (rn
);
429 if (v
->distance
> cur_or
->cost
||
430 IPV4_ADDR_CMP (&cur_or
->u
.std
.origin
->id
, &lsa
->header
.id
) > 0)
433 ospf_route_free (rn
->info
);
436 or = ospf_route_new ();
439 or->u
.std
.area_id
= area
->area_id
;
440 or->u
.std
.external_routing
= area
->external_routing
;
441 or->path_type
= OSPF_PATH_INTRA_AREA
;
442 or->cost
= v
->distance
;
443 or->type
= OSPF_DESTINATION_NETWORK
;
444 or->u
.std
.origin
= (struct lsa_header
*) lsa
;
446 ospf_route_copy_nexthops_from_vertex (or, v
);
451 /* RFC2328 16.1. second stage. */
453 ospf_intra_add_stub (struct route_table
*rt
, struct router_lsa_link
*link
,
454 struct vertex
*v
, struct ospf_area
*area
,
455 int parent_is_root
, int lsa_pos
)
458 struct route_node
*rn
;
459 struct ospf_route
*or;
460 struct prefix_ipv4 p
;
461 struct router_lsa
*lsa
;
462 struct ospf_interface
*oi
;
463 struct ospf_path
*path
;
465 if (IS_DEBUG_OSPF_EVENT
)
466 zlog_debug ("ospf_intra_add_stub(): Start");
468 lsa
= (struct router_lsa
*) v
->lsa
;
471 p
.prefix
= link
->link_id
;
472 p
.prefixlen
= ip_masklen (link
->link_data
);
473 apply_mask_ipv4 (&p
);
475 if (IS_DEBUG_OSPF_EVENT
)
476 zlog_debug ("ospf_intra_add_stub(): processing route to %s/%d",
477 inet_ntoa (p
.prefix
), p
.prefixlen
);
479 /* (1) Calculate the distance D of stub network from the root. D is
480 equal to the distance from the root to the router vertex
481 (calculated in stage 1), plus the stub network link's advertised
483 cost
= v
->distance
+ ntohs (link
->m
[0].metric
);
485 if (IS_DEBUG_OSPF_EVENT
)
486 zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d",
487 v
->distance
, ntohs(link
->m
[0].metric
), cost
);
489 /* PtP links with /32 masks adds host routes to remote, directly
490 * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
491 * Such routes can just be ignored for the sake of tidyness.
493 if (parent_is_root
&& link
->link_data
.s_addr
== 0xffffffff &&
494 ospf_if_lookup_by_local_addr (area
->ospf
, NULL
, link
->link_id
))
496 if (IS_DEBUG_OSPF_EVENT
)
497 zlog_debug ("%s: ignoring host route %s/32 to self.",
498 __func__
, inet_ntoa (link
->link_id
));
502 rn
= route_node_get (rt
, (struct prefix
*) &p
);
504 /* Lookup current routing table. */
507 struct ospf_route
*cur_or
;
509 route_unlock_node (rn
);
513 if (IS_DEBUG_OSPF_EVENT
)
514 zlog_debug ("ospf_intra_add_stub(): "
515 "another route to the same prefix found with cost %u",
518 /* Compare this distance to the current best cost to the stub
519 network. This is done by looking up the stub network's
520 current routing table entry. If the calculated distance D is
521 larger, go on to examine the next stub network link in the
523 if (cost
> cur_or
->cost
)
525 if (IS_DEBUG_OSPF_EVENT
)
526 zlog_debug ("ospf_intra_add_stub(): old route is better, exit");
530 /* (2) If this step is reached, the stub network's routing table
531 entry must be updated. Calculate the set of next hops that
532 would result from using the stub network link. This
533 calculation is shown in Section 16.1.1; input to this
534 calculation is the destination (the stub network) and the
535 parent vertex (the router vertex). If the distance D is the
536 same as the current routing table cost, simply add this set
537 of next hops to the routing table entry's list of next hops.
538 In this case, the routing table already has a Link State
539 Origin. If this Link State Origin is a router-LSA whose Link
540 State ID is smaller than V's Router ID, reset the Link State
541 Origin to V's router-LSA. */
543 if (cost
== cur_or
->cost
)
545 if (IS_DEBUG_OSPF_EVENT
)
546 zlog_debug ("ospf_intra_add_stub(): routes are equal, merge");
548 ospf_route_copy_nexthops_from_vertex (cur_or
, v
);
550 if (IPV4_ADDR_CMP (&cur_or
->u
.std
.origin
->id
, &lsa
->header
.id
) < 0)
551 cur_or
->u
.std
.origin
= (struct lsa_header
*) lsa
;
555 /* Otherwise D is smaller than the routing table cost.
556 Overwrite the current routing table entry by setting the
557 routing table entry's cost to D, and by setting the entry's
558 list of next hops to the newly calculated set. Set the
559 routing table entry's Link State Origin to V's router-LSA.
560 Then go on to examine the next stub network link. */
562 if (cost
< cur_or
->cost
)
564 if (IS_DEBUG_OSPF_EVENT
)
565 zlog_debug ("ospf_intra_add_stub(): new route is better, set it");
569 list_delete_all_node (cur_or
->paths
);
571 ospf_route_copy_nexthops_from_vertex (cur_or
, v
);
573 cur_or
->u
.std
.origin
= (struct lsa_header
*) lsa
;
578 if (IS_DEBUG_OSPF_EVENT
)
579 zlog_debug ("ospf_intra_add_stub(): installing new route");
581 or = ospf_route_new ();
584 or->u
.std
.area_id
= area
->area_id
;
585 or->u
.std
.external_routing
= area
->external_routing
;
586 or->path_type
= OSPF_PATH_INTRA_AREA
;
588 or->type
= OSPF_DESTINATION_NETWORK
;
589 or->u
.std
.origin
= (struct lsa_header
*) lsa
;
591 /* Nexthop is depend on connection type. */
594 if (IS_DEBUG_OSPF_EVENT
)
595 zlog_debug ("ospf_intra_add_stub(): this network is on remote router");
596 ospf_route_copy_nexthops_from_vertex (or, v
);
600 if (IS_DEBUG_OSPF_EVENT
)
601 zlog_debug ("ospf_intra_add_stub(): this network is on this router");
603 if ((oi
= ospf_if_lookup_by_lsa_pos (area
, lsa_pos
)))
605 if (IS_DEBUG_OSPF_EVENT
)
606 zlog_debug ("ospf_intra_add_stub(): the interface is %s",
609 path
= ospf_path_new ();
610 path
->nexthop
.s_addr
= 0;
611 path
->ifindex
= oi
->ifp
->ifindex
;
612 if (CHECK_FLAG(oi
->connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
613 path
->unnumbered
= 1;
614 listnode_add (or->paths
, path
);
618 if (IS_DEBUG_OSPF_EVENT
)
619 zlog_debug ("ospf_intra_add_stub(): where's the interface ?");
625 if (IS_DEBUG_OSPF_EVENT
)
626 zlog_debug("ospf_intra_add_stub(): Stop");
629 const char *ospf_path_type_str
[] =
639 ospf_route_table_dump (struct route_table
*rt
)
641 struct route_node
*rn
;
642 struct ospf_route
*or;
645 struct listnode
*pnode
;
646 struct ospf_path
*path
;
649 zlog_debug ("Type Dest Area Path Type Cost Next Adv.");
650 zlog_debug (" Hop(s) Router(s)");
653 zlog_debug ("========== OSPF routing table ==========");
654 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
655 if ((or = rn
->info
) != NULL
)
657 if (or->type
== OSPF_DESTINATION_NETWORK
)
659 zlog_debug ("N %s/%d\t%s\t%s\t%d",
660 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf1
, BUFSIZ
),
662 inet_ntop (AF_INET
, &or->u
.std
.area_id
, buf2
,
664 ospf_path_type_str
[or->path_type
],
666 for (ALL_LIST_ELEMENTS_RO (or->paths
, pnode
, path
))
667 zlog_debug (" -> %s", inet_ntoa (path
->nexthop
));
670 zlog_debug ("R %s\t%s\t%s\t%d",
671 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf1
, BUFSIZ
),
672 inet_ntop (AF_INET
, &or->u
.std
.area_id
, buf2
,
674 ospf_path_type_str
[or->path_type
],
677 zlog_debug ("========================================");
680 /* This is 16.4.1 implementation.
681 o Intra-area paths using non-backbone areas are always the most preferred.
682 o The other paths, intra-area backbone paths and inter-area paths,
683 are of equal preference. */
685 ospf_asbr_route_cmp (struct ospf
*ospf
, struct ospf_route
*r1
,
686 struct ospf_route
*r2
)
688 u_char r1_type
, r2_type
;
690 r1_type
= r1
->path_type
;
691 r2_type
= r2
->path_type
;
693 /* r1/r2 itself is backbone, and it's Inter-area path. */
694 if (OSPF_IS_AREA_ID_BACKBONE (r1
->u
.std
.area_id
))
695 r1_type
= OSPF_PATH_INTER_AREA
;
696 if (OSPF_IS_AREA_ID_BACKBONE (r2
->u
.std
.area_id
))
697 r2_type
= OSPF_PATH_INTER_AREA
;
699 return (r1_type
- r2_type
);
702 /* Compare two routes.
703 ret < 0 -- r1 is better.
704 ret == 0 -- r1 and r2 are the same.
705 ret > 0 -- r2 is better. */
707 ospf_route_cmp (struct ospf
*ospf
, struct ospf_route
*r1
,
708 struct ospf_route
*r2
)
712 /* Path types of r1 and r2 are not the same. */
713 if ((ret
= (r1
->path_type
- r2
->path_type
)))
716 if (IS_DEBUG_OSPF_EVENT
)
717 zlog_debug ("Route[Compare]: Path types are the same.");
718 /* Path types are the same, compare any cost. */
719 switch (r1
->path_type
)
721 case OSPF_PATH_INTRA_AREA
:
722 case OSPF_PATH_INTER_AREA
:
724 case OSPF_PATH_TYPE1_EXTERNAL
:
725 if (!CHECK_FLAG (ospf
->config
, OSPF_RFC1583_COMPATIBLE
))
727 ret
= ospf_asbr_route_cmp (ospf
, r1
->u
.ext
.asbr
, r2
->u
.ext
.asbr
);
732 case OSPF_PATH_TYPE2_EXTERNAL
:
733 if ((ret
= (r1
->u
.ext
.type2_cost
- r2
->u
.ext
.type2_cost
)))
736 if (!CHECK_FLAG (ospf
->config
, OSPF_RFC1583_COMPATIBLE
))
738 ret
= ospf_asbr_route_cmp (ospf
, r1
->u
.ext
.asbr
, r2
->u
.ext
.asbr
);
745 /* Anyway, compare the costs. */
746 return (r1
->cost
- r2
->cost
);
750 ospf_path_exist (struct list
*plist
, struct in_addr nexthop
,
751 struct ospf_interface
*oi
)
753 struct listnode
*node
, *nnode
;
754 struct ospf_path
*path
;
756 for (ALL_LIST_ELEMENTS (plist
, node
, nnode
, path
))
757 if (IPV4_ADDR_SAME (&path
->nexthop
, &nexthop
) &&
758 path
->ifindex
== oi
->ifp
->ifindex
)
765 ospf_route_copy_nexthops_from_vertex (struct ospf_route
*to
,
768 struct listnode
*node
;
769 struct ospf_path
*path
;
770 struct vertex_nexthop
*nexthop
;
771 struct vertex_parent
*vp
;
775 for (ALL_LIST_ELEMENTS_RO (v
->parents
, node
, vp
))
777 nexthop
= vp
->nexthop
;
779 if (nexthop
->oi
!= NULL
)
781 if (! ospf_path_exist (to
->paths
, nexthop
->router
, nexthop
->oi
))
783 path
= ospf_path_new ();
784 path
->nexthop
= nexthop
->router
;
785 path
->ifindex
= nexthop
->oi
->ifp
->ifindex
;
786 if (CHECK_FLAG(nexthop
->oi
->connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
787 path
->unnumbered
= 1;
788 listnode_add (to
->paths
, path
);
795 ospf_path_lookup (struct list
*plist
, struct ospf_path
*path
)
797 struct listnode
*node
;
798 struct ospf_path
*op
;
800 for (ALL_LIST_ELEMENTS_RO (plist
, node
, op
))
802 if (!IPV4_ADDR_SAME (&op
->nexthop
, &path
->nexthop
))
804 if (!IPV4_ADDR_SAME (&op
->adv_router
, &path
->adv_router
))
806 if (op
->ifindex
!= path
->ifindex
)
814 ospf_route_copy_nexthops (struct ospf_route
*to
, struct list
*from
)
816 struct listnode
*node
, *nnode
;
817 struct ospf_path
*path
;
821 for (ALL_LIST_ELEMENTS (from
, node
, nnode
, path
))
822 /* The same routes are just discarded. */
823 if (!ospf_path_lookup (to
->paths
, path
))
824 listnode_add (to
->paths
, ospf_path_dup (path
));
828 ospf_route_subst_nexthops (struct ospf_route
*to
, struct list
*from
)
831 list_delete_all_node (to
->paths
);
832 ospf_route_copy_nexthops (to
, from
);
836 ospf_route_subst (struct route_node
*rn
, struct ospf_route
*new_or
,
837 struct ospf_route
*over
)
839 route_lock_node (rn
);
840 ospf_route_free (rn
->info
);
842 ospf_route_copy_nexthops (new_or
, over
->paths
);
844 route_unlock_node (rn
);
848 ospf_route_add (struct route_table
*rt
, struct prefix_ipv4
*p
,
849 struct ospf_route
*new_or
, struct ospf_route
*over
)
851 struct route_node
*rn
;
853 rn
= route_node_get (rt
, (struct prefix
*) p
);
855 ospf_route_copy_nexthops (new_or
, over
->paths
);
859 if (IS_DEBUG_OSPF_EVENT
)
860 zlog_debug ("ospf_route_add(): something's wrong !");
861 route_unlock_node (rn
);
869 ospf_prune_unreachable_networks (struct route_table
*rt
)
871 struct route_node
*rn
, *next
;
872 struct ospf_route
*or;
874 if (IS_DEBUG_OSPF_EVENT
)
875 zlog_debug ("Pruning unreachable networks");
877 for (rn
= route_top (rt
); rn
; rn
= next
)
879 next
= route_next (rn
);
880 if (rn
->info
!= NULL
)
883 if (listcount (or->paths
) == 0)
885 if (IS_DEBUG_OSPF_EVENT
)
886 zlog_debug ("Pruning route to %s/%d",
887 inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
);
889 ospf_route_free (or);
891 route_unlock_node (rn
);
898 ospf_prune_unreachable_routers (struct route_table
*rtrs
)
900 struct route_node
*rn
, *next
;
901 struct ospf_route
*or;
902 struct listnode
*node
, *nnode
;
905 if (IS_DEBUG_OSPF_EVENT
)
906 zlog_debug ("Pruning unreachable routers");
908 for (rn
= route_top (rtrs
); rn
; rn
= next
)
910 next
= route_next (rn
);
911 if ((paths
= rn
->info
) == NULL
)
914 for (ALL_LIST_ELEMENTS (paths
, node
, nnode
, or))
916 if (listcount (or->paths
) == 0)
918 if (IS_DEBUG_OSPF_EVENT
)
920 zlog_debug ("Pruning route to rtr %s",
921 inet_ntoa (rn
->p
.u
.prefix4
));
922 zlog_debug (" via area %s",
923 inet_ntoa (or->u
.std
.area_id
));
926 listnode_delete (paths
, or);
927 ospf_route_free (or);
931 if (listcount (paths
) == 0)
933 if (IS_DEBUG_OSPF_EVENT
)
934 zlog_debug ("Pruning router node %s", inet_ntoa (rn
->p
.u
.prefix4
));
938 route_unlock_node (rn
);
944 ospf_add_discard_route (struct route_table
*rt
, struct ospf_area
*area
,
945 struct prefix_ipv4
*p
)
947 struct route_node
*rn
;
948 struct ospf_route
*or, *new_or
;
950 rn
= route_node_get (rt
, (struct prefix
*) p
);
954 if (IS_DEBUG_OSPF_EVENT
)
955 zlog_debug ("ospf_add_discard_route(): router installation error");
959 if (rn
->info
) /* If the route to the same destination is found */
961 route_unlock_node (rn
);
965 if (or->path_type
== OSPF_PATH_INTRA_AREA
)
967 if (IS_DEBUG_OSPF_EVENT
)
968 zlog_debug ("ospf_add_discard_route(): "
969 "an intra-area route exists");
973 if (or->type
== OSPF_DESTINATION_DISCARD
)
975 if (IS_DEBUG_OSPF_EVENT
)
976 zlog_debug ("ospf_add_discard_route(): "
977 "discard entry already installed");
981 ospf_route_free (rn
->info
);
984 if (IS_DEBUG_OSPF_EVENT
)
985 zlog_debug ("ospf_add_discard_route(): "
986 "adding %s/%d", inet_ntoa (p
->prefix
), p
->prefixlen
);
988 new_or
= ospf_route_new ();
989 new_or
->type
= OSPF_DESTINATION_DISCARD
;
990 new_or
->id
.s_addr
= 0;
992 new_or
->u
.std
.area_id
= area
->area_id
;
993 new_or
->u
.std
.external_routing
= area
->external_routing
;
994 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
997 ospf_zebra_add_discard (p
);
1003 ospf_delete_discard_route (struct route_table
*rt
, struct prefix_ipv4
*p
)
1005 struct route_node
*rn
;
1006 struct ospf_route
*or;
1008 if (IS_DEBUG_OSPF_EVENT
)
1009 zlog_debug ("ospf_delete_discard_route(): "
1010 "deleting %s/%d", inet_ntoa (p
->prefix
), p
->prefixlen
);
1012 rn
= route_node_lookup (rt
, (struct prefix
*)p
);
1016 if (IS_DEBUG_OSPF_EVENT
)
1017 zlog_debug("ospf_delete_discard_route(): no route found");
1023 if (or->path_type
== OSPF_PATH_INTRA_AREA
)
1025 if (IS_DEBUG_OSPF_EVENT
)
1026 zlog_debug ("ospf_delete_discard_route(): "
1027 "an intra-area route exists");
1031 if (or->type
!= OSPF_DESTINATION_DISCARD
)
1033 if (IS_DEBUG_OSPF_EVENT
)
1034 zlog_debug ("ospf_delete_discard_route(): "
1035 "not a discard entry");
1039 /* free the route entry and the route node */
1040 ospf_route_free (rn
->info
);
1043 route_unlock_node (rn
);
1044 route_unlock_node (rn
);
1046 /* remove the discard entry from the rib */
1047 ospf_zebra_delete_discard(p
);