2003-06-19 "Suraev, Vadim" <vadim.suraev@terayon.com>
* ospf_route.c: delete routes generated from AS-External routes if
there is a inter/intra route. Adds ospf_route_delete_same_ext()
which prunes external routes, which is called from
ospf_route_install() when new route table is installed.
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index 96f7531..0de415e 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -179,6 +179,39 @@
return 0;
}
+/* delete routes generated from AS-External routes if there is a inter/intra
+ * area route
+ */
+void
+ospf_route_delete_same_ext(struct route_table *external_routes,
+ struct route_table *routes)
+{
+ struct route_node *rn,
+ *ext_rn;
+
+ if ( (external_routes == NULL) || (routes == NULL) )
+ return;
+
+ /* Remove deleted routes */
+ for ( rn = route_top (routes); rn; rn = route_next (rn) )
+ {
+ if (rn && rn->info)
+ {
+ struct prefix_ipv4 *p = &rn->p;
+ if ( (ext_rn = route_node_lookup (external_routes, p)) )
+ {
+ ospf_zebra_delete (p, ext_rn->info);
+ if (ext_rn->info)
+ {
+ ospf_route_free( ext_rn->info);
+ ext_rn->info = NULL;
+ }
+ route_unlock_node (ext_rn);
+ }
+ }
+ }
+}
+
/* rt: Old, cmprt: New */
void
ospf_route_delete_uniq (struct route_table *rt, struct route_table *cmprt)
@@ -206,22 +239,24 @@
/* Install routes to table. */
void
-ospf_route_install (struct route_table *rt)
+ospf_route_install (struct ospf *ospf, struct route_table *rt)
{
struct route_node *rn;
struct ospf_route *or;
/* rt contains new routing table, new_table contains an old one.
updating pointers */
- if (ospf_top->old_table)
- ospf_route_table_free (ospf_top->old_table);
-
- ospf_top->old_table = ospf_top->new_table;
- ospf_top->new_table = rt;
+ if (ospf->old_table)
+ ospf_route_table_free (ospf->old_table);
+
+ ospf->old_table = ospf->new_table;
+ ospf->new_table = rt;
/* Delete old routes. */
- if (ospf_top->old_table)
- ospf_route_delete_uniq (ospf_top->old_table, rt);
+ if (ospf->old_table)
+ ospf_route_delete_uniq (ospf->old_table, rt);
+ if (ospf->old_external_route)
+ ospf_route_delete_same_ext (ospf->old_external_route, rt);
/* Install new routes. */
for (rn = route_top (rt); rn; rn = route_next (rn))
@@ -229,12 +264,12 @@
{
if (or->type == OSPF_DESTINATION_NETWORK)
{
- if (! ospf_route_match_same (ospf_top->old_table,
+ if (! ospf_route_match_same (ospf->old_table,
(struct prefix_ipv4 *)&rn->p, or))
ospf_zebra_add ((struct prefix_ipv4 *) &rn->p, or);
}
else if (or->type == OSPF_DESTINATION_DISCARD)
- if (! ospf_route_match_same (ospf_top->old_table,
+ if (! ospf_route_match_same (ospf->old_table,
(struct prefix_ipv4 *) &rn->p, or))
ospf_zebra_add_discard ((struct prefix_ipv4 *) &rn->p);
}
@@ -595,7 +630,7 @@
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_intra_add_stub(): this network is on this router");
- if ((oi = ospf_if_lookup_by_prefix (&p)))
+ if ((oi = ospf_if_lookup_by_prefix (area->ospf, &p)))
{
if (IS_DEBUG_OSPF_EVENT)
zlog_info ("ospf_intra_add_stub(): the interface is %s",
@@ -676,12 +711,15 @@
void
ospf_terminate ()
{
- if (ospf_top)
+ struct ospf *ospf;
+ listnode node;
+
+ LIST_LOOP (om->ospf, ospf, node)
{
- if (ospf_top->new_table)
- ospf_route_delete (ospf_top->new_table);
- if (ospf_top->old_external_route)
- ospf_route_delete (ospf_top->old_external_route);
+ if (ospf->new_table)
+ ospf_route_delete (ospf->new_table);
+ if (ospf->old_external_route)
+ ospf_route_delete (ospf->old_external_route);
}
}
@@ -690,7 +728,8 @@
o The other paths, intra-area backbone paths and inter-area paths,
are of equal preference. */
int
-ospf_asbr_route_cmp (struct ospf_route *r1, struct ospf_route *r2)
+ospf_asbr_route_cmp (struct ospf *ospf, struct ospf_route *r1,
+ struct ospf_route *r2)
{
u_char r1_type, r2_type;
@@ -698,7 +737,7 @@
r2_type = r2->path_type;
/* If RFC1583Compat flag is on -- all paths are equal. */
- if (CHECK_FLAG (ospf_top->config, OSPF_RFC1583_COMPATIBLE))
+ if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
return 0;
/* r1/r2 itself is backbone, and it's Inter-area path. */
@@ -715,7 +754,8 @@
ret == 0 -- r1 and r2 are the same.
ret > 0 -- r2 is better. */
int
-ospf_route_cmp (struct ospf_route *r1, struct ospf_route *r2)
+ospf_route_cmp (struct ospf *ospf, struct ospf_route *r1,
+ struct ospf_route *r2)
{
int ret = 0;
@@ -732,9 +772,9 @@
case OSPF_PATH_INTER_AREA:
break;
case OSPF_PATH_TYPE1_EXTERNAL:
- if (!CHECK_FLAG (ospf_top->config, OSPF_RFC1583_COMPATIBLE))
+ if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
{
- ret = ospf_asbr_route_cmp (r1->u.ext.asbr, r2->u.ext.asbr);
+ ret = ospf_asbr_route_cmp (ospf, r1->u.ext.asbr, r2->u.ext.asbr);
if (ret != 0)
return ret;
}
@@ -743,9 +783,9 @@
if ((ret = (r1->u.ext.type2_cost - r2->u.ext.type2_cost)))
return ret;
- if (!CHECK_FLAG (ospf_top->config, OSPF_RFC1583_COMPATIBLE))
+ if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
{
- ret = ospf_asbr_route_cmp (r1->u.ext.asbr, r2->u.ext.asbr);
+ ret = ospf_asbr_route_cmp (ospf, r1->u.ext.asbr, r2->u.ext.asbr);
if (ret != 0)
return ret;
}