--- embedaddon/quagga/ospfd/ospf_route.c 2012/10/09 09:22:29 1.1.1.2 +++ embedaddon/quagga/ospfd/ospf_route.c 2013/07/21 23:54:40 1.1.1.3 @@ -126,6 +126,31 @@ ospf_route_table_free (struct route_table *rt) route_table_finish (rt); } +/* If a prefix exists in the new routing table, then return 1, + otherwise return 0. Since the ZEBRA-RIB does an implicit + withdraw, it is not necessary to send a delete, an add later + will act like an implicit delete. */ +static int +ospf_route_exist_new_table (struct route_table *rt, struct prefix_ipv4 *prefix) +{ + struct route_node *rn; + + assert (rt); + assert (prefix); + + rn = route_node_lookup (rt, (struct prefix *) prefix); + if (!rn) { + return 0; + } + route_unlock_node (rn); + + if (!rn->info) { + return 0; + } + + return 1; +} + /* If a prefix and a nexthop match any route in the routing table, then return 1, otherwise return 0. */ int @@ -223,13 +248,13 @@ ospf_route_delete_uniq (struct route_table *rt, struct { if (or->type == OSPF_DESTINATION_NETWORK) { - if (! ospf_route_match_same (cmprt, - (struct prefix_ipv4 *) &rn->p, or)) + if (! ospf_route_exist_new_table (cmprt, + (struct prefix_ipv4 *) &rn->p)) ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p, or); } else if (or->type == OSPF_DESTINATION_DISCARD) - if (! ospf_route_match_same (cmprt, - (struct prefix_ipv4 *) &rn->p, or)) + if (! ospf_route_exist_new_table (cmprt, + (struct prefix_ipv4 *) &rn->p)) ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p); } } @@ -429,7 +454,7 @@ ospf_intra_add_transit (struct route_table *rt, struct void ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link, struct vertex *v, struct ospf_area *area, - int parent_is_root) + int parent_is_root, int lsa_pos) { u_int32_t cost; struct route_node *rn; @@ -577,7 +602,7 @@ ospf_intra_add_stub (struct route_table *rt, struct ro if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_intra_add_stub(): this network is on this router"); - if ((oi = ospf_if_lookup_by_prefix (area->ospf, &p))) + if ((oi = ospf_if_lookup_by_lsa_pos (area, lsa_pos))) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_intra_add_stub(): the interface is %s", @@ -954,6 +979,10 @@ ospf_add_discard_route (struct route_table *rt, struct ospf_route_free (rn->info); } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("ospf_add_discard_route(): " + "adding %s/%d", inet_ntoa (p->prefix), p->prefixlen); + new_or = ospf_route_new (); new_or->type = OSPF_DESTINATION_DISCARD; new_or->id.s_addr = 0; @@ -969,8 +998,52 @@ ospf_add_discard_route (struct route_table *rt, struct } void -ospf_delete_discard_route (struct prefix_ipv4 *p) +ospf_delete_discard_route (struct route_table *rt, struct prefix_ipv4 *p) { + struct route_node *rn; + struct ospf_route *or; + + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("ospf_delete_discard_route(): " + "deleting %s/%d", inet_ntoa (p->prefix), p->prefixlen); + + rn = route_node_lookup (rt, (struct prefix*)p); + + if (rn == NULL) + { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("ospf_delete_discard_route(): no route found"); + return; + } + + or = rn->info; + + if (or->path_type == OSPF_PATH_INTRA_AREA) + { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("ospf_delete_discard_route(): " + "an intra-area route exists"); + return; + } + + if (or->type != OSPF_DESTINATION_DISCARD) + { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("ospf_delete_discard_route(): " + "not a discard entry"); + return; + } + + /* free the route entry and the route node */ + ospf_route_free (rn->info); + + rn->info = NULL; + route_unlock_node (rn); + route_unlock_node (rn); + + /* remove the discard entry from the rib */ ospf_zebra_delete_discard(p); + + return; }