]>
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 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
31 #include "sockunion.h"
33 #include "ospfd/ospfd.h"
34 #include "ospfd/ospf_interface.h"
35 #include "ospfd/ospf_asbr.h"
36 #include "ospfd/ospf_lsa.h"
37 #include "ospfd/ospf_route.h"
38 #include "ospfd/ospf_spf.h"
39 #include "ospfd/ospf_zebra.h"
40 #include "ospfd/ospf_dump.h"
45 struct ospf_route
*new;
47 new = XCALLOC (MTYPE_OSPF_ROUTE
, sizeof (struct ospf_route
));
49 new->paths
= list_new ();
50 new->paths
->del
= (void (*) (void *))ospf_path_free
;
56 ospf_route_free (struct ospf_route
*or)
59 list_delete (or->paths
);
61 XFREE (MTYPE_OSPF_ROUTE
, or);
67 struct ospf_path
*new;
69 new = XCALLOC (MTYPE_OSPF_PATH
, sizeof (struct ospf_path
));
74 static struct ospf_path
*
75 ospf_path_dup (struct ospf_path
*path
)
77 struct ospf_path
*new;
79 new = ospf_path_new ();
80 memcpy (new, path
, sizeof (struct ospf_path
));
86 ospf_path_free (struct ospf_path
*op
)
88 XFREE (MTYPE_OSPF_PATH
, op
);
92 ospf_route_delete (struct route_table
*rt
)
94 struct route_node
*rn
;
95 struct ospf_route
*or;
97 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
98 if ((or = rn
->info
) != NULL
)
100 if (or->type
== OSPF_DESTINATION_NETWORK
)
101 ospf_zebra_delete ((struct prefix_ipv4
*) &rn
->p
,
103 else if (or->type
== OSPF_DESTINATION_DISCARD
)
104 ospf_zebra_delete_discard ((struct prefix_ipv4
*) &rn
->p
);
109 ospf_route_table_free (struct route_table
*rt
)
111 struct route_node
*rn
;
112 struct ospf_route
*or;
114 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
115 if ((or = rn
->info
) != NULL
)
117 ospf_route_free (or);
120 route_unlock_node (rn
);
123 route_table_finish (rt
);
126 /* If a prefix exists in the new routing table, then return 1,
127 otherwise return 0. Since the ZEBRA-RIB does an implicit
128 withdraw, it is not necessary to send a delete, an add later
129 will act like an implicit delete. */
131 ospf_route_exist_new_table (struct route_table
*rt
, struct prefix_ipv4
*prefix
)
133 struct route_node
*rn
;
138 rn
= route_node_lookup (rt
, (struct prefix
*) prefix
);
142 route_unlock_node (rn
);
151 /* If a prefix and a nexthop match any route in the routing table,
152 then return 1, otherwise return 0. */
154 ospf_route_match_same (struct route_table
*rt
, struct prefix_ipv4
*prefix
,
155 struct ospf_route
*newor
)
157 struct route_node
*rn
;
158 struct ospf_route
*or;
159 struct ospf_path
*op
;
160 struct ospf_path
*newop
;
164 if (! rt
|| ! prefix
)
167 rn
= route_node_lookup (rt
, (struct prefix
*) prefix
);
168 if (! rn
|| ! rn
->info
)
171 route_unlock_node (rn
);
174 if (or->type
== newor
->type
&& or->cost
== newor
->cost
)
176 if (or->type
== OSPF_DESTINATION_NETWORK
)
178 if (or->paths
->count
!= newor
->paths
->count
)
181 /* Check each path. */
182 for (n1
= listhead (or->paths
), n2
= listhead (newor
->paths
);
183 n1
&& n2
; n1
= listnextnode (n1
), n2
= listnextnode (n2
))
185 op
= listgetdata (n1
);
186 newop
= listgetdata (n2
);
188 if (! IPV4_ADDR_SAME (&op
->nexthop
, &newop
->nexthop
))
190 if (op
->ifindex
!= newop
->ifindex
)
195 else if (prefix_same (&rn
->p
, (struct prefix
*) prefix
))
201 /* delete routes generated from AS-External routes if there is a inter/intra
205 ospf_route_delete_same_ext(struct route_table
*external_routes
,
206 struct route_table
*routes
)
208 struct route_node
*rn
,
211 if ( (external_routes
== NULL
) || (routes
== NULL
) )
214 /* Remove deleted routes */
215 for ( rn
= route_top (routes
); rn
; rn
= route_next (rn
) )
219 struct prefix_ipv4
*p
= (struct prefix_ipv4
*)(&rn
->p
);
220 if ( (ext_rn
= route_node_lookup (external_routes
, (struct prefix
*)p
)) )
224 ospf_zebra_delete (p
, ext_rn
->info
);
225 ospf_route_free( ext_rn
->info
);
228 route_unlock_node (ext_rn
);
234 /* rt: Old, cmprt: New */
236 ospf_route_delete_uniq (struct route_table
*rt
, struct route_table
*cmprt
)
238 struct route_node
*rn
;
239 struct ospf_route
*or;
241 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
242 if ((or = rn
->info
) != NULL
)
243 if (or->path_type
== OSPF_PATH_INTRA_AREA
||
244 or->path_type
== OSPF_PATH_INTER_AREA
)
246 if (or->type
== OSPF_DESTINATION_NETWORK
)
248 if (! ospf_route_exist_new_table (cmprt
,
249 (struct prefix_ipv4
*) &rn
->p
))
250 ospf_zebra_delete ((struct prefix_ipv4
*) &rn
->p
, or);
252 else if (or->type
== OSPF_DESTINATION_DISCARD
)
253 if (! ospf_route_exist_new_table (cmprt
,
254 (struct prefix_ipv4
*) &rn
->p
))
255 ospf_zebra_delete_discard ((struct prefix_ipv4
*) &rn
->p
);
259 /* Install routes to table. */
261 ospf_route_install (struct ospf
*ospf
, struct route_table
*rt
)
263 struct route_node
*rn
;
264 struct ospf_route
*or;
266 /* rt contains new routing table, new_table contains an old one.
269 ospf_route_table_free (ospf
->old_table
);
271 ospf
->old_table
= ospf
->new_table
;
272 ospf
->new_table
= rt
;
274 /* Delete old routes. */
276 ospf_route_delete_uniq (ospf
->old_table
, rt
);
277 if (ospf
->old_external_route
)
278 ospf_route_delete_same_ext (ospf
->old_external_route
, rt
);
280 /* Install new routes. */
281 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
282 if ((or = rn
->info
) != NULL
)
284 if (or->type
== OSPF_DESTINATION_NETWORK
)
286 if (! ospf_route_match_same (ospf
->old_table
,
287 (struct prefix_ipv4
*)&rn
->p
, or))
288 ospf_zebra_add ((struct prefix_ipv4
*) &rn
->p
, or);
290 else if (or->type
== OSPF_DESTINATION_DISCARD
)
291 if (! ospf_route_match_same (ospf
->old_table
,
292 (struct prefix_ipv4
*) &rn
->p
, or))
293 ospf_zebra_add_discard ((struct prefix_ipv4
*) &rn
->p
);
297 /* RFC2328 16.1. (4). For "router". */
299 ospf_intra_add_router (struct route_table
*rt
, struct vertex
*v
,
300 struct ospf_area
*area
)
302 struct route_node
*rn
;
303 struct ospf_route
*or;
304 struct prefix_ipv4 p
;
305 struct router_lsa
*lsa
;
307 if (IS_DEBUG_OSPF_EVENT
)
308 zlog_debug ("ospf_intra_add_router: Start");
310 lsa
= (struct router_lsa
*) v
->lsa
;
312 if (IS_DEBUG_OSPF_EVENT
)
313 zlog_debug ("ospf_intra_add_router: LS ID: %s",
314 inet_ntoa (lsa
->header
.id
));
316 if (!OSPF_IS_AREA_BACKBONE(area
))
317 ospf_vl_up_check (area
, lsa
->header
.id
, v
);
319 if (!CHECK_FLAG (lsa
->flags
, ROUTER_LSA_SHORTCUT
))
320 area
->shortcut_capability
= 0;
322 /* If the newly added vertex is an area border router or AS boundary
323 router, a routing table entry is added whose destination type is
325 if (! IS_ROUTER_LSA_BORDER (lsa
) && ! IS_ROUTER_LSA_EXTERNAL (lsa
))
327 if (IS_DEBUG_OSPF_EVENT
)
328 zlog_debug ("ospf_intra_add_router: "
329 "this router is neither ASBR nor ABR, skipping it");
333 /* Update ABR and ASBR count in this area. */
334 if (IS_ROUTER_LSA_BORDER (lsa
))
336 if (IS_ROUTER_LSA_EXTERNAL (lsa
))
339 /* The Options field found in the associated router-LSA is copied
340 into the routing table entry's Optional capabilities field. Call
341 the newly added vertex Router X. */
342 or = ospf_route_new ();
345 or->u
.std
.area_id
= area
->area_id
;
346 or->u
.std
.external_routing
= area
->external_routing
;
347 or->path_type
= OSPF_PATH_INTRA_AREA
;
348 or->cost
= v
->distance
;
349 or->type
= OSPF_DESTINATION_ROUTER
;
350 or->u
.std
.origin
= (struct lsa_header
*) lsa
;
351 or->u
.std
.options
= lsa
->header
.options
;
352 or->u
.std
.flags
= lsa
->flags
;
354 /* If Router X is the endpoint of one of the calculating router's
355 virtual links, and the virtual link uses Area A as Transit area:
356 the virtual link is declared up, the IP address of the virtual
357 interface is set to the IP address of the outgoing interface
358 calculated above for Router X, and the virtual neighbor's IP
359 address is set to Router X's interface address (contained in
360 Router X's router-LSA) that points back to the root of the
361 shortest- path tree; equivalently, this is the interface that
362 points back to Router X's parent vertex on the shortest-path tree
363 (similar to the calculation in Section 16.1.1). */
367 p
.prefixlen
= IPV4_MAX_BITLEN
;
369 if (IS_DEBUG_OSPF_EVENT
)
370 zlog_debug ("ospf_intra_add_router: talking about %s/%d",
371 inet_ntoa (p
.prefix
), p
.prefixlen
);
373 rn
= route_node_get (rt
, (struct prefix
*) &p
);
375 /* Note that we keep all routes to ABRs and ASBRs, not only the best */
376 if (rn
->info
== NULL
)
377 rn
->info
= list_new ();
379 route_unlock_node (rn
);
381 ospf_route_copy_nexthops_from_vertex (or, v
);
383 listnode_add (rn
->info
, or);
385 if (IS_DEBUG_OSPF_EVENT
)
386 zlog_debug ("ospf_intra_add_router: Stop");
389 /* RFC2328 16.1. (4). For transit network. */
391 ospf_intra_add_transit (struct route_table
*rt
, struct vertex
*v
,
392 struct ospf_area
*area
)
394 struct route_node
*rn
;
395 struct ospf_route
*or;
396 struct prefix_ipv4 p
;
397 struct network_lsa
*lsa
;
399 lsa
= (struct network_lsa
*) v
->lsa
;
401 /* If the newly added vertex is a transit network, the routing table
402 entry for the network is located. The entry's Destination ID is
403 the IP network number, which can be obtained by masking the
404 Vertex ID (Link State ID) with its associated subnet mask (found
405 in the body of the associated network-LSA). */
408 p
.prefixlen
= ip_masklen (lsa
->mask
);
409 apply_mask_ipv4 (&p
);
411 rn
= route_node_get (rt
, (struct prefix
*) &p
);
413 /* If the routing table entry already exists (i.e., there is already
414 an intra-area route to the destination installed in the routing
415 table), multiple vertices have mapped to the same IP network.
416 For example, this can occur when a new Designated Router is being
417 established. In this case, the current routing table entry
418 should be overwritten if and only if the newly found path is just
419 as short and the current routing table entry's Link State Origin
420 has a smaller Link State ID than the newly added vertex' LSA. */
423 struct ospf_route
*cur_or
;
425 route_unlock_node (rn
);
428 if (v
->distance
> cur_or
->cost
||
429 IPV4_ADDR_CMP (&cur_or
->u
.std
.origin
->id
, &lsa
->header
.id
) > 0)
432 ospf_route_free (rn
->info
);
435 or = ospf_route_new ();
438 or->u
.std
.area_id
= area
->area_id
;
439 or->u
.std
.external_routing
= area
->external_routing
;
440 or->path_type
= OSPF_PATH_INTRA_AREA
;
441 or->cost
= v
->distance
;
442 or->type
= OSPF_DESTINATION_NETWORK
;
443 or->u
.std
.origin
= (struct lsa_header
*) lsa
;
445 ospf_route_copy_nexthops_from_vertex (or, v
);
450 /* RFC2328 16.1. second stage. */
452 ospf_intra_add_stub (struct route_table
*rt
, struct router_lsa_link
*link
,
453 struct vertex
*v
, struct ospf_area
*area
,
454 int parent_is_root
, int lsa_pos
)
457 struct route_node
*rn
;
458 struct ospf_route
*or;
459 struct prefix_ipv4 p
;
460 struct router_lsa
*lsa
;
461 struct ospf_interface
*oi
;
462 struct ospf_path
*path
;
464 if (IS_DEBUG_OSPF_EVENT
)
465 zlog_debug ("ospf_intra_add_stub(): Start");
467 lsa
= (struct router_lsa
*) v
->lsa
;
470 p
.prefix
= link
->link_id
;
471 p
.prefixlen
= ip_masklen (link
->link_data
);
472 apply_mask_ipv4 (&p
);
474 if (IS_DEBUG_OSPF_EVENT
)
475 zlog_debug ("ospf_intra_add_stub(): processing route to %s/%d",
476 inet_ntoa (p
.prefix
), p
.prefixlen
);
478 /* (1) Calculate the distance D of stub network from the root. D is
479 equal to the distance from the root to the router vertex
480 (calculated in stage 1), plus the stub network link's advertised
482 cost
= v
->distance
+ ntohs (link
->m
[0].metric
);
484 if (IS_DEBUG_OSPF_EVENT
)
485 zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d",
486 v
->distance
, ntohs(link
->m
[0].metric
), cost
);
488 /* PtP links with /32 masks adds host routes to remote, directly
489 * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
490 * Such routes can just be ignored for the sake of tidyness.
492 if (parent_is_root
&& link
->link_data
.s_addr
== 0xffffffff &&
493 ospf_if_lookup_by_local_addr (area
->ospf
, NULL
, link
->link_id
))
495 if (IS_DEBUG_OSPF_EVENT
)
496 zlog_debug ("%s: ignoring host route %s/32 to self.",
497 __func__
, inet_ntoa (link
->link_id
));
501 rn
= route_node_get (rt
, (struct prefix
*) &p
);
503 /* Lookup current routing table. */
506 struct ospf_route
*cur_or
;
508 route_unlock_node (rn
);
512 if (IS_DEBUG_OSPF_EVENT
)
513 zlog_debug ("ospf_intra_add_stub(): "
514 "another route to the same prefix found with cost %u",
517 /* Compare this distance to the current best cost to the stub
518 network. This is done by looking up the stub network's
519 current routing table entry. If the calculated distance D is
520 larger, go on to examine the next stub network link in the
522 if (cost
> cur_or
->cost
)
524 if (IS_DEBUG_OSPF_EVENT
)
525 zlog_debug ("ospf_intra_add_stub(): old route is better, exit");
529 /* (2) If this step is reached, the stub network's routing table
530 entry must be updated. Calculate the set of next hops that
531 would result from using the stub network link. This
532 calculation is shown in Section 16.1.1; input to this
533 calculation is the destination (the stub network) and the
534 parent vertex (the router vertex). If the distance D is the
535 same as the current routing table cost, simply add this set
536 of next hops to the routing table entry's list of next hops.
537 In this case, the routing table already has a Link State
538 Origin. If this Link State Origin is a router-LSA whose Link
539 State ID is smaller than V's Router ID, reset the Link State
540 Origin to V's router-LSA. */
542 if (cost
== cur_or
->cost
)
544 if (IS_DEBUG_OSPF_EVENT
)
545 zlog_debug ("ospf_intra_add_stub(): routes are equal, merge");
547 ospf_route_copy_nexthops_from_vertex (cur_or
, v
);
549 if (IPV4_ADDR_CMP (&cur_or
->u
.std
.origin
->id
, &lsa
->header
.id
) < 0)
550 cur_or
->u
.std
.origin
= (struct lsa_header
*) lsa
;
554 /* Otherwise D is smaller than the routing table cost.
555 Overwrite the current routing table entry by setting the
556 routing table entry's cost to D, and by setting the entry's
557 list of next hops to the newly calculated set. Set the
558 routing table entry's Link State Origin to V's router-LSA.
559 Then go on to examine the next stub network link. */
561 if (cost
< cur_or
->cost
)
563 if (IS_DEBUG_OSPF_EVENT
)
564 zlog_debug ("ospf_intra_add_stub(): new route is better, set it");
568 list_delete_all_node (cur_or
->paths
);
570 ospf_route_copy_nexthops_from_vertex (cur_or
, v
);
572 cur_or
->u
.std
.origin
= (struct lsa_header
*) lsa
;
577 if (IS_DEBUG_OSPF_EVENT
)
578 zlog_debug ("ospf_intra_add_stub(): installing new route");
580 or = ospf_route_new ();
583 or->u
.std
.area_id
= area
->area_id
;
584 or->u
.std
.external_routing
= area
->external_routing
;
585 or->path_type
= OSPF_PATH_INTRA_AREA
;
587 or->type
= OSPF_DESTINATION_NETWORK
;
588 or->u
.std
.origin
= (struct lsa_header
*) lsa
;
590 /* Nexthop is depend on connection type. */
593 if (IS_DEBUG_OSPF_EVENT
)
594 zlog_debug ("ospf_intra_add_stub(): this network is on remote router");
595 ospf_route_copy_nexthops_from_vertex (or, v
);
599 if (IS_DEBUG_OSPF_EVENT
)
600 zlog_debug ("ospf_intra_add_stub(): this network is on this router");
602 if ((oi
= ospf_if_lookup_by_lsa_pos (area
, lsa_pos
)))
604 if (IS_DEBUG_OSPF_EVENT
)
605 zlog_debug ("ospf_intra_add_stub(): the interface is %s",
608 path
= ospf_path_new ();
609 path
->nexthop
.s_addr
= 0;
610 path
->ifindex
= oi
->ifp
->ifindex
;
611 if (CHECK_FLAG(oi
->connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
612 path
->unnumbered
= 1;
613 listnode_add (or->paths
, path
);
617 if (IS_DEBUG_OSPF_EVENT
)
618 zlog_debug ("ospf_intra_add_stub(): where's the interface ?");
624 if (IS_DEBUG_OSPF_EVENT
)
625 zlog_debug("ospf_intra_add_stub(): Stop");
628 const char *ospf_path_type_str
[] =
638 ospf_route_table_dump (struct route_table
*rt
)
640 struct route_node
*rn
;
641 struct ospf_route
*or;
644 struct listnode
*pnode
;
645 struct ospf_path
*path
;
648 zlog_debug ("Type Dest Area Path Type Cost Next Adv.");
649 zlog_debug (" Hop(s) Router(s)");
652 zlog_debug ("========== OSPF routing table ==========");
653 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
654 if ((or = rn
->info
) != NULL
)
656 if (or->type
== OSPF_DESTINATION_NETWORK
)
658 zlog_debug ("N %s/%d\t%s\t%s\t%d",
659 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf1
, BUFSIZ
),
661 inet_ntop (AF_INET
, &or->u
.std
.area_id
, buf2
,
663 ospf_path_type_str
[or->path_type
],
665 for (ALL_LIST_ELEMENTS_RO (or->paths
, pnode
, path
))
666 zlog_debug (" -> %s", inet_ntoa (path
->nexthop
));
669 zlog_debug ("R %s\t%s\t%s\t%d",
670 inet_ntop (AF_INET
, &rn
->p
.u
.prefix4
, buf1
, BUFSIZ
),
671 inet_ntop (AF_INET
, &or->u
.std
.area_id
, buf2
,
673 ospf_path_type_str
[or->path_type
],
676 zlog_debug ("========================================");
679 /* This is 16.4.1 implementation.
680 o Intra-area paths using non-backbone areas are always the most preferred.
681 o The other paths, intra-area backbone paths and inter-area paths,
682 are of equal preference. */
684 ospf_asbr_route_cmp (struct ospf
*ospf
, struct ospf_route
*r1
,
685 struct ospf_route
*r2
)
687 u_char r1_type
, r2_type
;
689 r1_type
= r1
->path_type
;
690 r2_type
= r2
->path_type
;
692 /* r1/r2 itself is backbone, and it's Inter-area path. */
693 if (OSPF_IS_AREA_ID_BACKBONE (r1
->u
.std
.area_id
))
694 r1_type
= OSPF_PATH_INTER_AREA
;
695 if (OSPF_IS_AREA_ID_BACKBONE (r2
->u
.std
.area_id
))
696 r2_type
= OSPF_PATH_INTER_AREA
;
698 return (r1_type
- r2_type
);
701 /* Compare two routes.
702 ret < 0 -- r1 is better.
703 ret == 0 -- r1 and r2 are the same.
704 ret > 0 -- r2 is better. */
706 ospf_route_cmp (struct ospf
*ospf
, struct ospf_route
*r1
,
707 struct ospf_route
*r2
)
711 /* Path types of r1 and r2 are not the same. */
712 if ((ret
= (r1
->path_type
- r2
->path_type
)))
715 if (IS_DEBUG_OSPF_EVENT
)
716 zlog_debug ("Route[Compare]: Path types are the same.");
717 /* Path types are the same, compare any cost. */
718 switch (r1
->path_type
)
720 case OSPF_PATH_INTRA_AREA
:
721 case OSPF_PATH_INTER_AREA
:
723 case OSPF_PATH_TYPE1_EXTERNAL
:
724 if (!CHECK_FLAG (ospf
->config
, OSPF_RFC1583_COMPATIBLE
))
726 ret
= ospf_asbr_route_cmp (ospf
, r1
->u
.ext
.asbr
, r2
->u
.ext
.asbr
);
731 case OSPF_PATH_TYPE2_EXTERNAL
:
732 if ((ret
= (r1
->u
.ext
.type2_cost
- r2
->u
.ext
.type2_cost
)))
735 if (!CHECK_FLAG (ospf
->config
, OSPF_RFC1583_COMPATIBLE
))
737 ret
= ospf_asbr_route_cmp (ospf
, r1
->u
.ext
.asbr
, r2
->u
.ext
.asbr
);
744 /* Anyway, compare the costs. */
745 return (r1
->cost
- r2
->cost
);
749 ospf_path_exist (struct list
*plist
, struct in_addr nexthop
,
750 struct ospf_interface
*oi
)
752 struct listnode
*node
, *nnode
;
753 struct ospf_path
*path
;
755 for (ALL_LIST_ELEMENTS (plist
, node
, nnode
, path
))
756 if (IPV4_ADDR_SAME (&path
->nexthop
, &nexthop
) &&
757 path
->ifindex
== oi
->ifp
->ifindex
)
764 ospf_route_copy_nexthops_from_vertex (struct ospf_route
*to
,
767 struct listnode
*node
;
768 struct ospf_path
*path
;
769 struct vertex_nexthop
*nexthop
;
770 struct vertex_parent
*vp
;
774 for (ALL_LIST_ELEMENTS_RO (v
->parents
, node
, vp
))
776 nexthop
= vp
->nexthop
;
778 if (nexthop
->oi
!= NULL
)
780 if (! ospf_path_exist (to
->paths
, nexthop
->router
, nexthop
->oi
))
782 path
= ospf_path_new ();
783 path
->nexthop
= nexthop
->router
;
784 path
->ifindex
= nexthop
->oi
->ifp
->ifindex
;
785 if (CHECK_FLAG(nexthop
->oi
->connected
->flags
, ZEBRA_IFA_UNNUMBERED
))
786 path
->unnumbered
= 1;
787 listnode_add (to
->paths
, path
);
794 ospf_path_lookup (struct list
*plist
, struct ospf_path
*path
)
796 struct listnode
*node
;
797 struct ospf_path
*op
;
799 for (ALL_LIST_ELEMENTS_RO (plist
, node
, op
))
801 if (!IPV4_ADDR_SAME (&op
->nexthop
, &path
->nexthop
))
803 if (!IPV4_ADDR_SAME (&op
->adv_router
, &path
->adv_router
))
805 if (op
->ifindex
!= path
->ifindex
)
813 ospf_route_copy_nexthops (struct ospf_route
*to
, struct list
*from
)
815 struct listnode
*node
, *nnode
;
816 struct ospf_path
*path
;
820 for (ALL_LIST_ELEMENTS (from
, node
, nnode
, path
))
821 /* The same routes are just discarded. */
822 if (!ospf_path_lookup (to
->paths
, path
))
823 listnode_add (to
->paths
, ospf_path_dup (path
));
827 ospf_route_subst_nexthops (struct ospf_route
*to
, struct list
*from
)
830 list_delete_all_node (to
->paths
);
831 ospf_route_copy_nexthops (to
, from
);
835 ospf_route_subst (struct route_node
*rn
, struct ospf_route
*new_or
,
836 struct ospf_route
*over
)
838 route_lock_node (rn
);
839 ospf_route_free (rn
->info
);
841 ospf_route_copy_nexthops (new_or
, over
->paths
);
843 route_unlock_node (rn
);
847 ospf_route_add (struct route_table
*rt
, struct prefix_ipv4
*p
,
848 struct ospf_route
*new_or
, struct ospf_route
*over
)
850 struct route_node
*rn
;
852 rn
= route_node_get (rt
, (struct prefix
*) p
);
854 ospf_route_copy_nexthops (new_or
, over
->paths
);
858 if (IS_DEBUG_OSPF_EVENT
)
859 zlog_debug ("ospf_route_add(): something's wrong !");
860 route_unlock_node (rn
);
868 ospf_prune_unreachable_networks (struct route_table
*rt
)
870 struct route_node
*rn
, *next
;
871 struct ospf_route
*or;
873 if (IS_DEBUG_OSPF_EVENT
)
874 zlog_debug ("Pruning unreachable networks");
876 for (rn
= route_top (rt
); rn
; rn
= next
)
878 next
= route_next (rn
);
879 if (rn
->info
!= NULL
)
882 if (listcount (or->paths
) == 0)
884 if (IS_DEBUG_OSPF_EVENT
)
885 zlog_debug ("Pruning route to %s/%d",
886 inet_ntoa (rn
->p
.u
.prefix4
), rn
->p
.prefixlen
);
888 ospf_route_free (or);
890 route_unlock_node (rn
);
897 ospf_prune_unreachable_routers (struct route_table
*rtrs
)
899 struct route_node
*rn
, *next
;
900 struct ospf_route
*or;
901 struct listnode
*node
, *nnode
;
904 if (IS_DEBUG_OSPF_EVENT
)
905 zlog_debug ("Pruning unreachable routers");
907 for (rn
= route_top (rtrs
); rn
; rn
= next
)
909 next
= route_next (rn
);
910 if ((paths
= rn
->info
) == NULL
)
913 for (ALL_LIST_ELEMENTS (paths
, node
, nnode
, or))
915 if (listcount (or->paths
) == 0)
917 if (IS_DEBUG_OSPF_EVENT
)
919 zlog_debug ("Pruning route to rtr %s",
920 inet_ntoa (rn
->p
.u
.prefix4
));
921 zlog_debug (" via area %s",
922 inet_ntoa (or->u
.std
.area_id
));
925 listnode_delete (paths
, or);
926 ospf_route_free (or);
930 if (listcount (paths
) == 0)
932 if (IS_DEBUG_OSPF_EVENT
)
933 zlog_debug ("Pruning router node %s", inet_ntoa (rn
->p
.u
.prefix4
));
937 route_unlock_node (rn
);
943 ospf_add_discard_route (struct route_table
*rt
, struct ospf_area
*area
,
944 struct prefix_ipv4
*p
)
946 struct route_node
*rn
;
947 struct ospf_route
*or, *new_or
;
949 rn
= route_node_get (rt
, (struct prefix
*) p
);
953 if (IS_DEBUG_OSPF_EVENT
)
954 zlog_debug ("ospf_add_discard_route(): router installation error");
958 if (rn
->info
) /* If the route to the same destination is found */
960 route_unlock_node (rn
);
964 if (or->path_type
== OSPF_PATH_INTRA_AREA
)
966 if (IS_DEBUG_OSPF_EVENT
)
967 zlog_debug ("ospf_add_discard_route(): "
968 "an intra-area route exists");
972 if (or->type
== OSPF_DESTINATION_DISCARD
)
974 if (IS_DEBUG_OSPF_EVENT
)
975 zlog_debug ("ospf_add_discard_route(): "
976 "discard entry already installed");
980 ospf_route_free (rn
->info
);
983 if (IS_DEBUG_OSPF_EVENT
)
984 zlog_debug ("ospf_add_discard_route(): "
985 "adding %s/%d", inet_ntoa (p
->prefix
), p
->prefixlen
);
987 new_or
= ospf_route_new ();
988 new_or
->type
= OSPF_DESTINATION_DISCARD
;
989 new_or
->id
.s_addr
= 0;
991 new_or
->u
.std
.area_id
= area
->area_id
;
992 new_or
->u
.std
.external_routing
= area
->external_routing
;
993 new_or
->path_type
= OSPF_PATH_INTER_AREA
;
996 ospf_zebra_add_discard (p
);
1002 ospf_delete_discard_route (struct route_table
*rt
, struct prefix_ipv4
*p
)
1004 struct route_node
*rn
;
1005 struct ospf_route
*or;
1007 if (IS_DEBUG_OSPF_EVENT
)
1008 zlog_debug ("ospf_delete_discard_route(): "
1009 "deleting %s/%d", inet_ntoa (p
->prefix
), p
->prefixlen
);
1011 rn
= route_node_lookup (rt
, (struct prefix
*)p
);
1015 if (IS_DEBUG_OSPF_EVENT
)
1016 zlog_debug("ospf_delete_discard_route(): no route found");
1022 if (or->path_type
== OSPF_PATH_INTRA_AREA
)
1024 if (IS_DEBUG_OSPF_EVENT
)
1025 zlog_debug ("ospf_delete_discard_route(): "
1026 "an intra-area route exists");
1030 if (or->type
!= OSPF_DESTINATION_DISCARD
)
1032 if (IS_DEBUG_OSPF_EVENT
)
1033 zlog_debug ("ospf_delete_discard_route(): "
1034 "not a discard entry");
1038 /* free the route entry and the route node */
1039 ospf_route_free (rn
->info
);
1042 route_unlock_node (rn
);
1043 route_unlock_node (rn
);
1045 /* remove the discard entry from the rib */
1046 ospf_zebra_delete_discard(p
);