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->ctime = quagga_time (NULL);
51 new->mtime = new->ctime;
52 new->paths = list_new ();
53 new->paths->del = (void (*) (void *))ospf_path_free;
59 ospf_route_free (struct ospf_route *or)
62 list_delete (or->paths);
64 XFREE (MTYPE_OSPF_ROUTE, or);
70 struct ospf_path *new;
72 new = XCALLOC (MTYPE_OSPF_PATH, sizeof (struct ospf_path));
77 static struct ospf_path *
78 ospf_path_dup (struct ospf_path *path)
80 struct ospf_path *new;
82 new = ospf_path_new ();
83 memcpy (new, path, sizeof (struct ospf_path));
89 ospf_path_free (struct ospf_path *op)
91 XFREE (MTYPE_OSPF_PATH, op);
95 ospf_route_delete (struct route_table *rt)
97 struct route_node *rn;
98 struct ospf_route *or;
100 for (rn = route_top (rt); rn; rn = route_next (rn))
101 if ((or = rn->info) != NULL)
103 if (or->type == OSPF_DESTINATION_NETWORK)
104 ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p,
106 else if (or->type == OSPF_DESTINATION_DISCARD)
107 ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p);
112 ospf_route_table_free (struct route_table *rt)
114 struct route_node *rn;
115 struct ospf_route *or;
117 for (rn = route_top (rt); rn; rn = route_next (rn))
118 if ((or = rn->info) != NULL)
120 ospf_route_free (or);
123 route_unlock_node (rn);
126 route_table_finish (rt);
129 /* If a prefix exists in the new routing table, then return 1,
130 otherwise return 0. Since the ZEBRA-RIB does an implicit
131 withdraw, it is not necessary to send a delete, an add later
132 will act like an implicit delete. */
134 ospf_route_exist_new_table (struct route_table *rt, struct prefix_ipv4 *prefix)
136 struct route_node *rn;
141 rn = route_node_lookup (rt, (struct prefix *) prefix);
145 route_unlock_node (rn);
154 /* If a prefix and a nexthop match any route in the routing table,
155 then return 1, otherwise return 0. */
157 ospf_route_match_same (struct route_table *rt, struct prefix_ipv4 *prefix,
158 struct ospf_route *newor)
160 struct route_node *rn;
161 struct ospf_route *or;
162 struct ospf_path *op;
163 struct ospf_path *newop;
167 if (! rt || ! prefix)
170 rn = route_node_lookup (rt, (struct prefix *) prefix);
171 if (! rn || ! rn->info)
174 route_unlock_node (rn);
177 if (or->type == newor->type && or->cost == newor->cost)
179 if (or->type == OSPF_DESTINATION_NETWORK)
181 if (or->paths->count != newor->paths->count)
184 /* Check each path. */
185 for (n1 = listhead (or->paths), n2 = listhead (newor->paths);
186 n1 && n2; n1 = listnextnode (n1), n2 = listnextnode (n2))
188 op = listgetdata (n1);
189 newop = listgetdata (n2);
191 if (! IPV4_ADDR_SAME (&op->nexthop, &newop->nexthop))
193 if (op->ifindex != newop->ifindex)
198 else if (prefix_same (&rn->p, (struct prefix *) prefix))
204 /* delete routes generated from AS-External routes if there is a inter/intra
208 ospf_route_delete_same_ext(struct route_table *external_routes,
209 struct route_table *routes)
211 struct route_node *rn,
214 if ( (external_routes == NULL) || (routes == NULL) )
217 /* Remove deleted routes */
218 for ( rn = route_top (routes); rn; rn = route_next (rn) )
222 struct prefix_ipv4 *p = (struct prefix_ipv4 *)(&rn->p);
223 if ( (ext_rn = route_node_lookup (external_routes, (struct prefix *)p)) )
227 ospf_zebra_delete (p, ext_rn->info);
228 ospf_route_free( ext_rn->info);
231 route_unlock_node (ext_rn);
237 /* rt: Old, cmprt: New */
239 ospf_route_delete_uniq (struct route_table *rt, struct route_table *cmprt)
241 struct route_node *rn;
242 struct ospf_route *or;
244 for (rn = route_top (rt); rn; rn = route_next (rn))
245 if ((or = rn->info) != NULL)
246 if (or->path_type == OSPF_PATH_INTRA_AREA ||
247 or->path_type == OSPF_PATH_INTER_AREA)
249 if (or->type == OSPF_DESTINATION_NETWORK)
251 if (! ospf_route_exist_new_table (cmprt,
252 (struct prefix_ipv4 *) &rn->p))
253 ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or);
255 else if (or->type == OSPF_DESTINATION_DISCARD)
256 if (! ospf_route_exist_new_table (cmprt,
257 (struct prefix_ipv4 *) &rn->p))
258 ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p);
262 /* Install routes to table. */
264 ospf_route_install (struct ospf *ospf, struct route_table *rt)
266 struct route_node *rn;
267 struct ospf_route *or;
269 /* rt contains new routing table, new_table contains an old one.
272 ospf_route_table_free (ospf->old_table);
274 ospf->old_table = ospf->new_table;
275 ospf->new_table = rt;
277 /* Delete old routes. */
279 ospf_route_delete_uniq (ospf->old_table, rt);
280 if (ospf->old_external_route)
281 ospf_route_delete_same_ext (ospf->old_external_route, rt);
283 /* Install new routes. */
284 for (rn = route_top (rt); rn; rn = route_next (rn))
285 if ((or = rn->info) != NULL)
287 if (or->type == OSPF_DESTINATION_NETWORK)
289 if (! ospf_route_match_same (ospf->old_table,
290 (struct prefix_ipv4 *)&rn->p, or))
291 ospf_zebra_add ((struct prefix_ipv4 *) &rn->p, or);
293 else if (or->type == OSPF_DESTINATION_DISCARD)
294 if (! ospf_route_match_same (ospf->old_table,
295 (struct prefix_ipv4 *) &rn->p, or))
296 ospf_zebra_add_discard ((struct prefix_ipv4 *) &rn->p);
300 /* RFC2328 16.1. (4). For "router". */
302 ospf_intra_add_router (struct route_table *rt, struct vertex *v,
303 struct ospf_area *area)
305 struct route_node *rn;
306 struct ospf_route *or;
307 struct prefix_ipv4 p;
308 struct router_lsa *lsa;
310 if (IS_DEBUG_OSPF_EVENT)
311 zlog_debug ("ospf_intra_add_router: Start");
313 lsa = (struct router_lsa *) v->lsa;
315 if (IS_DEBUG_OSPF_EVENT)
316 zlog_debug ("ospf_intra_add_router: LS ID: %s",
317 inet_ntoa (lsa->header.id));
319 if (!OSPF_IS_AREA_BACKBONE(area))
320 ospf_vl_up_check (area, lsa->header.id, v);
322 if (!CHECK_FLAG (lsa->flags, ROUTER_LSA_SHORTCUT))
323 area->shortcut_capability = 0;
325 /* If the newly added vertex is an area border router or AS boundary
326 router, a routing table entry is added whose destination type is
328 if (! IS_ROUTER_LSA_BORDER (lsa) && ! IS_ROUTER_LSA_EXTERNAL (lsa))
330 if (IS_DEBUG_OSPF_EVENT)
331 zlog_debug ("ospf_intra_add_router: "
332 "this router is neither ASBR nor ABR, skipping it");
336 /* Update ABR and ASBR count in this area. */
337 if (IS_ROUTER_LSA_BORDER (lsa))
339 if (IS_ROUTER_LSA_EXTERNAL (lsa))
342 /* The Options field found in the associated router-LSA is copied
343 into the routing table entry's Optional capabilities field. Call
344 the newly added vertex Router X. */
345 or = ospf_route_new ();
348 or->u.std.area_id = area->area_id;
349 or->u.std.external_routing = area->external_routing;
350 or->path_type = OSPF_PATH_INTRA_AREA;
351 or->cost = v->distance;
352 or->type = OSPF_DESTINATION_ROUTER;
353 or->u.std.origin = (struct lsa_header *) lsa;
354 or->u.std.options = lsa->header.options;
355 or->u.std.flags = lsa->flags;
357 /* If Router X is the endpoint of one of the calculating router's
358 virtual links, and the virtual link uses Area A as Transit area:
359 the virtual link is declared up, the IP address of the virtual
360 interface is set to the IP address of the outgoing interface
361 calculated above for Router X, and the virtual neighbor's IP
362 address is set to Router X's interface address (contained in
363 Router X's router-LSA) that points back to the root of the
364 shortest- path tree; equivalently, this is the interface that
365 points back to Router X's parent vertex on the shortest-path tree
366 (similar to the calculation in Section 16.1.1). */
370 p.prefixlen = IPV4_MAX_BITLEN;
372 if (IS_DEBUG_OSPF_EVENT)
373 zlog_debug ("ospf_intra_add_router: talking about %s/%d",
374 inet_ntoa (p.prefix), p.prefixlen);
376 rn = route_node_get (rt, (struct prefix *) &p);
378 /* Note that we keep all routes to ABRs and ASBRs, not only the best */
379 if (rn->info == NULL)
380 rn->info = list_new ();
382 route_unlock_node (rn);
384 ospf_route_copy_nexthops_from_vertex (or, v);
386 listnode_add (rn->info, or);
388 if (IS_DEBUG_OSPF_EVENT)
389 zlog_debug ("ospf_intra_add_router: Stop");
392 /* RFC2328 16.1. (4). For transit network. */
394 ospf_intra_add_transit (struct route_table *rt, struct vertex *v,
395 struct ospf_area *area)
397 struct route_node *rn;
398 struct ospf_route *or;
399 struct prefix_ipv4 p;
400 struct network_lsa *lsa;
402 lsa = (struct network_lsa*) v->lsa;
404 /* If the newly added vertex is a transit network, the routing table
405 entry for the network is located. The entry's Destination ID is
406 the IP network number, which can be obtained by masking the
407 Vertex ID (Link State ID) with its associated subnet mask (found
408 in the body of the associated network-LSA). */
411 p.prefixlen = ip_masklen (lsa->mask);
412 apply_mask_ipv4 (&p);
414 rn = route_node_get (rt, (struct prefix *) &p);
416 /* If the routing table entry already exists (i.e., there is already
417 an intra-area route to the destination installed in the routing
418 table), multiple vertices have mapped to the same IP network.
419 For example, this can occur when a new Designated Router is being
420 established. In this case, the current routing table entry
421 should be overwritten if and only if the newly found path is just
422 as short and the current routing table entry's Link State Origin
423 has a smaller Link State ID than the newly added vertex' LSA. */
426 struct ospf_route *cur_or;
428 route_unlock_node (rn);
431 if (v->distance > cur_or->cost ||
432 IPV4_ADDR_CMP (&cur_or->u.std.origin->id, &lsa->header.id) > 0)
435 ospf_route_free (rn->info);
438 or = ospf_route_new ();
441 or->u.std.area_id = area->area_id;
442 or->u.std.external_routing = area->external_routing;
443 or->path_type = OSPF_PATH_INTRA_AREA;
444 or->cost = v->distance;
445 or->type = OSPF_DESTINATION_NETWORK;
446 or->u.std.origin = (struct lsa_header *) lsa;
448 ospf_route_copy_nexthops_from_vertex (or, v);
453 /* RFC2328 16.1. second stage. */
455 ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link,
456 struct vertex *v, struct ospf_area *area,
457 int parent_is_root, int lsa_pos)
460 struct route_node *rn;
461 struct ospf_route *or;
462 struct prefix_ipv4 p;
463 struct router_lsa *lsa;
464 struct ospf_interface *oi;
465 struct ospf_path *path;
467 if (IS_DEBUG_OSPF_EVENT)
468 zlog_debug ("ospf_intra_add_stub(): Start");
470 lsa = (struct router_lsa *) v->lsa;
473 p.prefix = link->link_id;
474 p.prefixlen = ip_masklen (link->link_data);
475 apply_mask_ipv4 (&p);
477 if (IS_DEBUG_OSPF_EVENT)
478 zlog_debug ("ospf_intra_add_stub(): processing route to %s/%d",
479 inet_ntoa (p.prefix), p.prefixlen);
481 /* (1) Calculate the distance D of stub network from the root. D is
482 equal to the distance from the root to the router vertex
483 (calculated in stage 1), plus the stub network link's advertised
485 cost = v->distance + ntohs (link->m[0].metric);
487 if (IS_DEBUG_OSPF_EVENT)
488 zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d",
489 v->distance, ntohs(link->m[0].metric), cost);
491 /* PtP links with /32 masks adds host routes to remote, directly
492 * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
493 * Such routes can just be ignored for the sake of tidyness.
495 if (parent_is_root && link->link_data.s_addr == 0xffffffff &&
496 ospf_if_lookup_by_local_addr (area->ospf, NULL, link->link_id))
498 if (IS_DEBUG_OSPF_EVENT)
499 zlog_debug ("%s: ignoring host route %s/32 to self.",
500 __func__, inet_ntoa (link->link_id));
504 rn = route_node_get (rt, (struct prefix *) &p);
506 /* Lookup current routing table. */
509 struct ospf_route *cur_or;
511 route_unlock_node (rn);
515 if (IS_DEBUG_OSPF_EVENT)
516 zlog_debug ("ospf_intra_add_stub(): "
517 "another route to the same prefix found with cost %u",
520 /* Compare this distance to the current best cost to the stub
521 network. This is done by looking up the stub network's
522 current routing table entry. If the calculated distance D is
523 larger, go on to examine the next stub network link in the
525 if (cost > cur_or->cost)
527 if (IS_DEBUG_OSPF_EVENT)
528 zlog_debug ("ospf_intra_add_stub(): old route is better, exit");
532 /* (2) If this step is reached, the stub network's routing table
533 entry must be updated. Calculate the set of next hops that
534 would result from using the stub network link. This
535 calculation is shown in Section 16.1.1; input to this
536 calculation is the destination (the stub network) and the
537 parent vertex (the router vertex). If the distance D is the
538 same as the current routing table cost, simply add this set
539 of next hops to the routing table entry's list of next hops.
540 In this case, the routing table already has a Link State
541 Origin. If this Link State Origin is a router-LSA whose Link
542 State ID is smaller than V's Router ID, reset the Link State
543 Origin to V's router-LSA. */
545 if (cost == cur_or->cost)
547 if (IS_DEBUG_OSPF_EVENT)
548 zlog_debug ("ospf_intra_add_stub(): routes are equal, merge");
550 ospf_route_copy_nexthops_from_vertex (cur_or, v);
552 if (IPV4_ADDR_CMP (&cur_or->u.std.origin->id, &lsa->header.id) < 0)
553 cur_or->u.std.origin = (struct lsa_header *) lsa;
557 /* Otherwise D is smaller than the routing table cost.
558 Overwrite the current routing table entry by setting the
559 routing table entry's cost to D, and by setting the entry's
560 list of next hops to the newly calculated set. Set the
561 routing table entry's Link State Origin to V's router-LSA.
562 Then go on to examine the next stub network link. */
564 if (cost < cur_or->cost)
566 if (IS_DEBUG_OSPF_EVENT)
567 zlog_debug ("ospf_intra_add_stub(): new route is better, set it");
571 list_delete_all_node (cur_or->paths);
573 ospf_route_copy_nexthops_from_vertex (cur_or, v);
575 cur_or->u.std.origin = (struct lsa_header *) lsa;
580 if (IS_DEBUG_OSPF_EVENT)
581 zlog_debug ("ospf_intra_add_stub(): installing new route");
583 or = ospf_route_new ();
586 or->u.std.area_id = area->area_id;
587 or->u.std.external_routing = area->external_routing;
588 or->path_type = OSPF_PATH_INTRA_AREA;
590 or->type = OSPF_DESTINATION_NETWORK;
591 or->u.std.origin = (struct lsa_header *) lsa;
593 /* Nexthop is depend on connection type. */
596 if (IS_DEBUG_OSPF_EVENT)
597 zlog_debug ("ospf_intra_add_stub(): this network is on remote router");
598 ospf_route_copy_nexthops_from_vertex (or, v);
602 if (IS_DEBUG_OSPF_EVENT)
603 zlog_debug ("ospf_intra_add_stub(): this network is on this router");
605 if ((oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos)))
607 if (IS_DEBUG_OSPF_EVENT)
608 zlog_debug ("ospf_intra_add_stub(): the interface is %s",
611 path = ospf_path_new ();
612 path->nexthop.s_addr = 0;
613 path->ifindex = oi->ifp->ifindex;
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 listnode_add (to->paths, path);
793 ospf_path_lookup (struct list *plist, struct ospf_path *path)
795 struct listnode *node;
796 struct ospf_path *op;
798 for (ALL_LIST_ELEMENTS_RO (plist, node, op))
800 if (!IPV4_ADDR_SAME (&op->nexthop, &path->nexthop))
802 if (!IPV4_ADDR_SAME (&op->adv_router, &path->adv_router))
804 if (op->ifindex != path->ifindex)
812 ospf_route_copy_nexthops (struct ospf_route *to, struct list *from)
814 struct listnode *node, *nnode;
815 struct ospf_path *path;
819 for (ALL_LIST_ELEMENTS (from, node, nnode, path))
820 /* The same routes are just discarded. */
821 if (!ospf_path_lookup (to->paths, path))
822 listnode_add (to->paths, ospf_path_dup (path));
826 ospf_route_subst_nexthops (struct ospf_route *to, struct list *from)
829 list_delete_all_node (to->paths);
830 ospf_route_copy_nexthops (to, from);
834 ospf_route_subst (struct route_node *rn, struct ospf_route *new_or,
835 struct ospf_route *over)
837 route_lock_node (rn);
838 ospf_route_free (rn->info);
840 ospf_route_copy_nexthops (new_or, over->paths);
842 route_unlock_node (rn);
846 ospf_route_add (struct route_table *rt, struct prefix_ipv4 *p,
847 struct ospf_route *new_or, struct ospf_route *over)
849 struct route_node *rn;
851 rn = route_node_get (rt, (struct prefix *) p);
853 ospf_route_copy_nexthops (new_or, over->paths);
857 if (IS_DEBUG_OSPF_EVENT)
858 zlog_debug ("ospf_route_add(): something's wrong !");
859 route_unlock_node (rn);
867 ospf_prune_unreachable_networks (struct route_table *rt)
869 struct route_node *rn, *next;
870 struct ospf_route *or;
872 if (IS_DEBUG_OSPF_EVENT)
873 zlog_debug ("Pruning unreachable networks");
875 for (rn = route_top (rt); rn; rn = next)
877 next = route_next (rn);
878 if (rn->info != NULL)
881 if (listcount (or->paths) == 0)
883 if (IS_DEBUG_OSPF_EVENT)
884 zlog_debug ("Pruning route to %s/%d",
885 inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
887 ospf_route_free (or);
889 route_unlock_node (rn);
896 ospf_prune_unreachable_routers (struct route_table *rtrs)
898 struct route_node *rn, *next;
899 struct ospf_route *or;
900 struct listnode *node, *nnode;
903 if (IS_DEBUG_OSPF_EVENT)
904 zlog_debug ("Pruning unreachable routers");
906 for (rn = route_top (rtrs); rn; rn = next)
908 next = route_next (rn);
909 if ((paths = rn->info) == NULL)
912 for (ALL_LIST_ELEMENTS (paths, node, nnode, or))
914 if (listcount (or->paths) == 0)
916 if (IS_DEBUG_OSPF_EVENT)
918 zlog_debug ("Pruning route to rtr %s",
919 inet_ntoa (rn->p.u.prefix4));
920 zlog_debug (" via area %s",
921 inet_ntoa (or->u.std.area_id));
924 listnode_delete (paths, or);
925 ospf_route_free (or);
929 if (listcount (paths) == 0)
931 if (IS_DEBUG_OSPF_EVENT)
932 zlog_debug ("Pruning router node %s", inet_ntoa (rn->p.u.prefix4));
936 route_unlock_node (rn);
942 ospf_add_discard_route (struct route_table *rt, struct ospf_area *area,
943 struct prefix_ipv4 *p)
945 struct route_node *rn;
946 struct ospf_route *or, *new_or;
948 rn = route_node_get (rt, (struct prefix *) p);
952 if (IS_DEBUG_OSPF_EVENT)
953 zlog_debug ("ospf_add_discard_route(): router installation error");
957 if (rn->info) /* If the route to the same destination is found */
959 route_unlock_node (rn);
963 if (or->path_type == OSPF_PATH_INTRA_AREA)
965 if (IS_DEBUG_OSPF_EVENT)
966 zlog_debug ("ospf_add_discard_route(): "
967 "an intra-area route exists");
971 if (or->type == OSPF_DESTINATION_DISCARD)
973 if (IS_DEBUG_OSPF_EVENT)
974 zlog_debug ("ospf_add_discard_route(): "
975 "discard entry already installed");
979 ospf_route_free (rn->info);
982 if (IS_DEBUG_OSPF_EVENT)
983 zlog_debug ("ospf_add_discard_route(): "
984 "adding %s/%d", inet_ntoa (p->prefix), p->prefixlen);
986 new_or = ospf_route_new ();
987 new_or->type = OSPF_DESTINATION_DISCARD;
988 new_or->id.s_addr = 0;
990 new_or->u.std.area_id = area->area_id;
991 new_or->u.std.external_routing = area->external_routing;
992 new_or->path_type = OSPF_PATH_INTER_AREA;
995 ospf_zebra_add_discard (p);
1001 ospf_delete_discard_route (struct route_table *rt, struct prefix_ipv4 *p)
1003 struct route_node *rn;
1004 struct ospf_route *or;
1006 if (IS_DEBUG_OSPF_EVENT)
1007 zlog_debug ("ospf_delete_discard_route(): "
1008 "deleting %s/%d", inet_ntoa (p->prefix), p->prefixlen);
1010 rn = route_node_lookup (rt, (struct prefix*)p);
1014 if (IS_DEBUG_OSPF_EVENT)
1015 zlog_debug("ospf_delete_discard_route(): no route found");
1021 if (or->path_type == OSPF_PATH_INTRA_AREA)
1023 if (IS_DEBUG_OSPF_EVENT)
1024 zlog_debug ("ospf_delete_discard_route(): "
1025 "an intra-area route exists");
1029 if (or->type != OSPF_DESTINATION_DISCARD)
1031 if (IS_DEBUG_OSPF_EVENT)
1032 zlog_debug ("ospf_delete_discard_route(): "
1033 "not a discard entry");
1037 /* free the route entry and the route node */
1038 ospf_route_free (rn->info);
1041 route_unlock_node (rn);
1042 route_unlock_node (rn);
1044 /* remove the discard entry from the rib */
1045 ospf_zebra_delete_discard(p);