summaryrefslogtreecommitdiffstats
path: root/ospfd/ospf_route.c
diff options
context:
space:
mode:
authorwhitespace / reindent <invalid@invalid.invalid>2017-07-17 14:03:14 +0200
committerwhitespace / reindent <invalid@invalid.invalid>2017-07-17 14:04:07 +0200
commitd62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch)
tree3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /ospfd/ospf_route.c
parent*: add indent control files (diff)
downloadfrr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.tar.xz
frr-d62a17aedeb0eebdba98238874bb13d62c48dbf9.zip
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'` Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospfd/ospf_route.c')
-rw-r--r--ospfd/ospf_route.c1631
1 files changed, 799 insertions, 832 deletions
diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c
index fcd5f18a7..9c4dca2e2 100644
--- a/ospfd/ospf_route.c
+++ b/ospfd/ospf_route.c
@@ -39,1012 +39,979 @@
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"
-struct ospf_route *
-ospf_route_new ()
+struct ospf_route *ospf_route_new()
{
- struct ospf_route *new;
+ struct ospf_route *new;
- new = XCALLOC (MTYPE_OSPF_ROUTE, sizeof (struct ospf_route));
+ new = XCALLOC(MTYPE_OSPF_ROUTE, sizeof(struct ospf_route));
- new->paths = list_new ();
- new->paths->del = (void (*) (void *))ospf_path_free;
+ new->paths = list_new();
+ new->paths->del = (void (*)(void *))ospf_path_free;
- return new;
+ return new;
}
-void
-ospf_route_free (struct ospf_route *or)
+void ospf_route_free(struct ospf_route * or)
{
- if (or->paths)
- list_delete (or->paths);
+ if (or->paths)
+ list_delete(or->paths);
- XFREE (MTYPE_OSPF_ROUTE, or);
+ XFREE(MTYPE_OSPF_ROUTE, or);
}
-struct ospf_path *
-ospf_path_new ()
+struct ospf_path *ospf_path_new()
{
- struct ospf_path *new;
+ struct ospf_path *new;
- new = XCALLOC (MTYPE_OSPF_PATH, sizeof (struct ospf_path));
+ new = XCALLOC(MTYPE_OSPF_PATH, sizeof(struct ospf_path));
- return new;
+ return new;
}
-static struct ospf_path *
-ospf_path_dup (struct ospf_path *path)
+static struct ospf_path *ospf_path_dup(struct ospf_path *path)
{
- struct ospf_path *new;
+ struct ospf_path *new;
- new = ospf_path_new ();
- memcpy (new, path, sizeof (struct ospf_path));
+ new = ospf_path_new();
+ memcpy(new, path, sizeof(struct ospf_path));
- return new;
+ return new;
}
-void
-ospf_path_free (struct ospf_path *op)
+void ospf_path_free(struct ospf_path *op)
{
- XFREE (MTYPE_OSPF_PATH, op);
+ XFREE(MTYPE_OSPF_PATH, op);
}
-void
-ospf_route_delete (struct route_table *rt)
+void ospf_route_delete(struct route_table *rt)
{
- struct route_node *rn;
- struct ospf_route *or;
-
- for (rn = route_top (rt); rn; rn = route_next (rn))
- if ((or = rn->info) != NULL)
- {
- if (or->type == OSPF_DESTINATION_NETWORK)
- ospf_zebra_delete ((struct prefix_ipv4 *) &rn->p,
- or);
- else if (or->type == OSPF_DESTINATION_DISCARD)
- ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p);
- }
+ struct route_node *rn;
+ struct ospf_route * or ;
+
+ for (rn = route_top(rt); rn; rn = route_next(rn))
+ if ((or = rn->info) != NULL) {
+ if (or->type == OSPF_DESTINATION_NETWORK)
+ ospf_zebra_delete((struct prefix_ipv4 *)&rn->p,
+ or);
+ else if (or->type == OSPF_DESTINATION_DISCARD)
+ ospf_zebra_delete_discard(
+ (struct prefix_ipv4 *)&rn->p);
+ }
}
-void
-ospf_route_table_free (struct route_table *rt)
+void ospf_route_table_free(struct route_table *rt)
{
- struct route_node *rn;
- struct ospf_route *or;
+ struct route_node *rn;
+ struct ospf_route * or ;
- for (rn = route_top (rt); rn; rn = route_next (rn))
- if ((or = rn->info) != NULL)
- {
- ospf_route_free (or);
+ for (rn = route_top(rt); rn; rn = route_next(rn))
+ if ((or = rn->info) != NULL) {
+ ospf_route_free(or);
- rn->info = NULL;
- route_unlock_node (rn);
- }
+ rn->info = NULL;
+ route_unlock_node(rn);
+ }
- route_table_finish (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)
+static int ospf_route_exist_new_table(struct route_table *rt,
+ struct prefix_ipv4 *prefix)
{
- struct route_node *rn;
+ struct route_node *rn;
- assert (rt);
- assert (prefix);
+ assert(rt);
+ assert(prefix);
- rn = route_node_lookup (rt, (struct prefix *) prefix);
- if (!rn) {
- return 0;
- }
- route_unlock_node (rn);
+ rn = route_node_lookup(rt, (struct prefix *)prefix);
+ if (!rn) {
+ return 0;
+ }
+ route_unlock_node(rn);
- if (!rn->info) {
- return 0;
- }
+ if (!rn->info) {
+ return 0;
+ }
- return 1;
+ return 1;
}
/* If a prefix and a nexthop match any route in the routing table,
then return 1, otherwise return 0. */
-int
-ospf_route_match_same (struct route_table *rt, struct prefix_ipv4 *prefix,
- struct ospf_route *newor)
+int ospf_route_match_same(struct route_table *rt, struct prefix_ipv4 *prefix,
+ struct ospf_route *newor)
{
- struct route_node *rn;
- struct ospf_route *or;
- struct ospf_path *op;
- struct ospf_path *newop;
- struct listnode *n1;
- struct listnode *n2;
-
- if (! rt || ! prefix)
- return 0;
-
- rn = route_node_lookup (rt, (struct prefix *) prefix);
- if (! rn || ! rn->info)
- return 0;
-
- route_unlock_node (rn);
-
- or = rn->info;
- if (or->type == newor->type && or->cost == newor->cost)
- {
- if (or->type == OSPF_DESTINATION_NETWORK)
- {
- if (or->paths->count != newor->paths->count)
- return 0;
-
- /* Check each path. */
- for (n1 = listhead (or->paths), n2 = listhead (newor->paths);
- n1 && n2; n1 = listnextnode (n1), n2 = listnextnode (n2))
- {
- op = listgetdata (n1);
- newop = listgetdata (n2);
-
- if (! IPV4_ADDR_SAME (&op->nexthop, &newop->nexthop))
- return 0;
- if (op->ifindex != newop->ifindex)
- return 0;
- }
- return 1;
- }
- else if (prefix_same (&rn->p, (struct prefix *) prefix))
- return 1;
- }
- return 0;
+ struct route_node *rn;
+ struct ospf_route * or ;
+ struct ospf_path *op;
+ struct ospf_path *newop;
+ struct listnode *n1;
+ struct listnode *n2;
+
+ if (!rt || !prefix)
+ return 0;
+
+ rn = route_node_lookup(rt, (struct prefix *)prefix);
+ if (!rn || !rn->info)
+ return 0;
+
+ route_unlock_node(rn);
+
+ or = rn->info;
+ if (or->type == newor->type && or->cost == newor->cost) {
+ if (or->type == OSPF_DESTINATION_NETWORK) {
+ if (or->paths->count != newor->paths->count)
+ return 0;
+
+ /* Check each path. */
+ for (n1 = listhead(or->paths),
+ n2 = listhead(newor->paths);
+ n1 && n2;
+ n1 = listnextnode(n1), n2 = listnextnode(n2)) {
+ op = listgetdata(n1);
+ newop = listgetdata(n2);
+
+ if (!IPV4_ADDR_SAME(&op->nexthop,
+ &newop->nexthop))
+ return 0;
+ if (op->ifindex != newop->ifindex)
+ return 0;
+ }
+ return 1;
+ } else if (prefix_same(&rn->p, (struct prefix *)prefix))
+ return 1;
+ }
+ return 0;
}
/* delete routes generated from AS-External routes if there is a inter/intra
* area route
*/
-static void
-ospf_route_delete_same_ext(struct route_table *external_routes,
- struct route_table *routes)
+static 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 = (struct prefix_ipv4 *)(&rn->p);
- if ( (ext_rn = route_node_lookup (external_routes, (struct prefix *)p)) )
- {
- if (ext_rn->info)
- {
- ospf_zebra_delete (p, ext_rn->info);
- ospf_route_free( ext_rn->info);
- ext_rn->info = NULL;
- }
- route_unlock_node (ext_rn);
- }
- }
- }
+ 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 = (struct prefix_ipv4 *)(&rn->p);
+ if ((ext_rn = route_node_lookup(external_routes,
+ (struct prefix *)p))) {
+ if (ext_rn->info) {
+ ospf_zebra_delete(p, ext_rn->info);
+ ospf_route_free(ext_rn->info);
+ ext_rn->info = NULL;
+ }
+ route_unlock_node(ext_rn);
+ }
+ }
+ }
}
/* rt: Old, cmprt: New */
-static void
-ospf_route_delete_uniq (struct route_table *rt, struct route_table *cmprt)
+static void ospf_route_delete_uniq(struct route_table *rt,
+ struct route_table *cmprt)
{
- struct route_node *rn;
- struct ospf_route *or;
-
- for (rn = route_top (rt); rn; rn = route_next (rn))
- if ((or = rn->info) != NULL)
- if (or->path_type == OSPF_PATH_INTRA_AREA ||
- or->path_type == OSPF_PATH_INTER_AREA)
- {
- if (or->type == OSPF_DESTINATION_NETWORK)
- {
- 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_exist_new_table (cmprt,
- (struct prefix_ipv4 *) &rn->p))
- ospf_zebra_delete_discard ((struct prefix_ipv4 *) &rn->p);
- }
+ struct route_node *rn;
+ struct ospf_route * or ;
+
+ for (rn = route_top(rt); rn; rn = route_next(rn))
+ if ((or = rn->info) != NULL)
+ if (or->path_type == OSPF_PATH_INTRA_AREA ||
+ or->path_type == OSPF_PATH_INTER_AREA) {
+ if (or->type == OSPF_DESTINATION_NETWORK) {
+ 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_exist_new_table(
+ cmprt,
+ (struct prefix_ipv4 *)&rn
+ ->p))
+ ospf_zebra_delete_discard(
+ (struct prefix_ipv4
+ *)&rn->p);
+ }
}
/* Install routes to table. */
-void
-ospf_route_install (struct ospf *ospf, struct route_table *rt)
+void 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->old_table)
- ospf_route_table_free (ospf->old_table);
-
- ospf->old_table = ospf->new_table;
- ospf->new_table = rt;
-
- /* Delete old routes. */
- 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))
- if ((or = rn->info) != NULL)
- {
- if (or->type == OSPF_DESTINATION_NETWORK)
- {
- 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->old_table,
- (struct prefix_ipv4 *) &rn->p, or))
- ospf_zebra_add_discard ((struct prefix_ipv4 *) &rn->p);
- }
+ struct route_node *rn;
+ struct ospf_route * or ;
+
+ /* rt contains new routing table, new_table contains an old one.
+ updating pointers */
+ 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->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))
+ if ((or = rn->info) != NULL) {
+ if (or->type == OSPF_DESTINATION_NETWORK) {
+ 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->old_table,
+ (struct prefix_ipv4 *)&rn->p, or))
+ ospf_zebra_add_discard(
+ (struct prefix_ipv4 *)&rn->p);
+ }
}
/* RFC2328 16.1. (4). For "router". */
-void
-ospf_intra_add_router (struct route_table *rt, struct vertex *v,
- struct ospf_area *area)
+void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
+ struct ospf_area *area)
{
- struct route_node *rn;
- struct ospf_route *or;
- struct prefix_ipv4 p;
- struct router_lsa *lsa;
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_router: Start");
-
- lsa = (struct router_lsa *) v->lsa;
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_router: LS ID: %s",
- inet_ntoa (lsa->header.id));
-
- if (!OSPF_IS_AREA_BACKBONE(area))
- ospf_vl_up_check (area, lsa->header.id, v);
-
- if (!CHECK_FLAG (lsa->flags, ROUTER_LSA_SHORTCUT))
- area->shortcut_capability = 0;
-
- /* If the newly added vertex is an area border router or AS boundary
- router, a routing table entry is added whose destination type is
- "router". */
- if (! IS_ROUTER_LSA_BORDER (lsa) && ! IS_ROUTER_LSA_EXTERNAL (lsa))
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_router: "
- "this router is neither ASBR nor ABR, skipping it");
- return;
- }
-
- /* Update ABR and ASBR count in this area. */
- if (IS_ROUTER_LSA_BORDER (lsa))
- area->abr_count++;
- if (IS_ROUTER_LSA_EXTERNAL (lsa))
- area->asbr_count++;
-
- /* The Options field found in the associated router-LSA is copied
- into the routing table entry's Optional capabilities field. Call
- the newly added vertex Router X. */
- or = ospf_route_new ();
-
- or->id = v->id;
- or->u.std.area_id = area->area_id;
- or->u.std.external_routing = area->external_routing;
- or->path_type = OSPF_PATH_INTRA_AREA;
- or->cost = v->distance;
- or->type = OSPF_DESTINATION_ROUTER;
- or->u.std.origin = (struct lsa_header *) lsa;
- or->u.std.options = lsa->header.options;
- or->u.std.flags = lsa->flags;
-
- /* If Router X is the endpoint of one of the calculating router's
- virtual links, and the virtual link uses Area A as Transit area:
- the virtual link is declared up, the IP address of the virtual
- interface is set to the IP address of the outgoing interface
- calculated above for Router X, and the virtual neighbor's IP
- address is set to Router X's interface address (contained in
- Router X's router-LSA) that points back to the root of the
- shortest- path tree; equivalently, this is the interface that
- points back to Router X's parent vertex on the shortest-path tree
- (similar to the calculation in Section 16.1.1). */
-
- p.family = AF_INET;
- p.prefix = v->id;
- p.prefixlen = IPV4_MAX_BITLEN;
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_router: talking about %s/%d",
- inet_ntoa (p.prefix), p.prefixlen);
-
- rn = route_node_get (rt, (struct prefix *) &p);
-
- /* Note that we keep all routes to ABRs and ASBRs, not only the best */
- if (rn->info == NULL)
- rn->info = list_new ();
- else
- route_unlock_node (rn);
-
- ospf_route_copy_nexthops_from_vertex (or, v);
-
- listnode_add (rn->info, or);
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_router: Stop");
+ struct route_node *rn;
+ struct ospf_route * or ;
+ struct prefix_ipv4 p;
+ struct router_lsa *lsa;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_router: Start");
+
+ lsa = (struct router_lsa *)v->lsa;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_router: LS ID: %s",
+ inet_ntoa(lsa->header.id));
+
+ if (!OSPF_IS_AREA_BACKBONE(area))
+ ospf_vl_up_check(area, lsa->header.id, v);
+
+ if (!CHECK_FLAG(lsa->flags, ROUTER_LSA_SHORTCUT))
+ area->shortcut_capability = 0;
+
+ /* If the newly added vertex is an area border router or AS boundary
+ router, a routing table entry is added whose destination type is
+ "router". */
+ if (!IS_ROUTER_LSA_BORDER(lsa) && !IS_ROUTER_LSA_EXTERNAL(lsa)) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_router: "
+ "this router is neither ASBR nor ABR, skipping it");
+ return;
+ }
+
+ /* Update ABR and ASBR count in this area. */
+ if (IS_ROUTER_LSA_BORDER(lsa))
+ area->abr_count++;
+ if (IS_ROUTER_LSA_EXTERNAL(lsa))
+ area->asbr_count++;
+
+ /* The Options field found in the associated router-LSA is copied
+ into the routing table entry's Optional capabilities field. Call
+ the newly added vertex Router X. */
+ or = ospf_route_new();
+
+ or->id = v->id;
+ or->u.std.area_id = area->area_id;
+ or->u.std.external_routing = area->external_routing;
+ or->path_type = OSPF_PATH_INTRA_AREA;
+ or->cost = v->distance;
+ or->type = OSPF_DESTINATION_ROUTER;
+ or->u.std.origin = (struct lsa_header *)lsa;
+ or->u.std.options = lsa->header.options;
+ or->u.std.flags = lsa->flags;
+
+ /* If Router X is the endpoint of one of the calculating router's
+ virtual links, and the virtual link uses Area A as Transit area:
+ the virtual link is declared up, the IP address of the virtual
+ interface is set to the IP address of the outgoing interface
+ calculated above for Router X, and the virtual neighbor's IP
+ address is set to Router X's interface address (contained in
+ Router X's router-LSA) that points back to the root of the
+ shortest- path tree; equivalently, this is the interface that
+ points back to Router X's parent vertex on the shortest-path tree
+ (similar to the calculation in Section 16.1.1). */
+
+ p.family = AF_INET;
+ p.prefix = v->id;
+ p.prefixlen = IPV4_MAX_BITLEN;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_router: talking about %s/%d",
+ inet_ntoa(p.prefix), p.prefixlen);
+
+ rn = route_node_get(rt, (struct prefix *)&p);
+
+ /* Note that we keep all routes to ABRs and ASBRs, not only the best */
+ if (rn->info == NULL)
+ rn->info = list_new();
+ else
+ route_unlock_node(rn);
+
+ ospf_route_copy_nexthops_from_vertex(or, v);
+
+ listnode_add(rn->info, or);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_router: Stop");
}
/* RFC2328 16.1. (4). For transit network. */
-void
-ospf_intra_add_transit (struct route_table *rt, struct vertex *v,
- struct ospf_area *area)
+void ospf_intra_add_transit(struct route_table *rt, struct vertex *v,
+ struct ospf_area *area)
{
- struct route_node *rn;
- struct ospf_route *or;
- struct prefix_ipv4 p;
- struct network_lsa *lsa;
-
- lsa = (struct network_lsa*) v->lsa;
-
- /* If the newly added vertex is a transit network, the routing table
- entry for the network is located. The entry's Destination ID is
- the IP network number, which can be obtained by masking the
- Vertex ID (Link State ID) with its associated subnet mask (found
- in the body of the associated network-LSA). */
- p.family = AF_INET;
- p.prefix = v->id;
- p.prefixlen = ip_masklen (lsa->mask);
- apply_mask_ipv4 (&p);
-
- rn = route_node_get (rt, (struct prefix *) &p);
-
- /* If the routing table entry already exists (i.e., there is already
- an intra-area route to the destination installed in the routing
- table), multiple vertices have mapped to the same IP network.
- For example, this can occur when a new Designated Router is being
- established. In this case, the current routing table entry
- should be overwritten if and only if the newly found path is just
- as short and the current routing table entry's Link State Origin
- has a smaller Link State ID than the newly added vertex' LSA. */
- if (rn->info)
- {
- struct ospf_route *cur_or;
-
- route_unlock_node (rn);
- cur_or = rn->info;
-
- if (v->distance > cur_or->cost ||
- IPV4_ADDR_CMP (&cur_or->u.std.origin->id, &lsa->header.id) > 0)
- return;
-
- ospf_route_free (rn->info);
- }
-
- or = ospf_route_new ();
-
- or->id = v->id;
- or->u.std.area_id = area->area_id;
- or->u.std.external_routing = area->external_routing;
- or->path_type = OSPF_PATH_INTRA_AREA;
- or->cost = v->distance;
- or->type = OSPF_DESTINATION_NETWORK;
- or->u.std.origin = (struct lsa_header *) lsa;
-
- ospf_route_copy_nexthops_from_vertex (or, v);
-
- rn->info = or;
+ struct route_node *rn;
+ struct ospf_route * or ;
+ struct prefix_ipv4 p;
+ struct network_lsa *lsa;
+
+ lsa = (struct network_lsa *)v->lsa;
+
+ /* If the newly added vertex is a transit network, the routing table
+ entry for the network is located. The entry's Destination ID is
+ the IP network number, which can be obtained by masking the
+ Vertex ID (Link State ID) with its associated subnet mask (found
+ in the body of the associated network-LSA). */
+ p.family = AF_INET;
+ p.prefix = v->id;
+ p.prefixlen = ip_masklen(lsa->mask);
+ apply_mask_ipv4(&p);
+
+ rn = route_node_get(rt, (struct prefix *)&p);
+
+ /* If the routing table entry already exists (i.e., there is already
+ an intra-area route to the destination installed in the routing
+ table), multiple vertices have mapped to the same IP network.
+ For example, this can occur when a new Designated Router is being
+ established. In this case, the current routing table entry
+ should be overwritten if and only if the newly found path is just
+ as short and the current routing table entry's Link State Origin
+ has a smaller Link State ID than the newly added vertex' LSA. */
+ if (rn->info) {
+ struct ospf_route *cur_or;
+
+ route_unlock_node(rn);
+ cur_or = rn->info;
+
+ if (v->distance > cur_or->cost
+ || IPV4_ADDR_CMP(&cur_or->u.std.origin->id, &lsa->header.id)
+ > 0)
+ return;
+
+ ospf_route_free(rn->info);
+ }
+
+ or = ospf_route_new();
+
+ or->id = v->id;
+ or->u.std.area_id = area->area_id;
+ or->u.std.external_routing = area->external_routing;
+ or->path_type = OSPF_PATH_INTRA_AREA;
+ or->cost = v->distance;
+ or->type = OSPF_DESTINATION_NETWORK;
+ or->u.std.origin = (struct lsa_header *)lsa;
+
+ ospf_route_copy_nexthops_from_vertex(or, v);
+
+ rn->info = or ;
}
/* RFC2328 16.1. second stage. */
-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 lsa_pos)
+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 lsa_pos)
{
- u_int32_t cost;
- struct route_node *rn;
- struct ospf_route *or;
- struct prefix_ipv4 p;
- struct router_lsa *lsa;
- struct ospf_interface *oi;
- struct ospf_path *path;
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): Start");
-
- lsa = (struct router_lsa *) v->lsa;
-
- p.family = AF_INET;
- p.prefix = link->link_id;
- p.prefixlen = ip_masklen (link->link_data);
- apply_mask_ipv4 (&p);
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): processing route to %s/%d",
- inet_ntoa (p.prefix), p.prefixlen);
-
- /* (1) Calculate the distance D of stub network from the root. D is
- equal to the distance from the root to the router vertex
- (calculated in stage 1), plus the stub network link's advertised
- cost. */
- cost = v->distance + ntohs (link->m[0].metric);
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d",
- v->distance, ntohs(link->m[0].metric), cost);
-
- /* PtP links with /32 masks adds host routes to remote, directly
- * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
- * Such routes can just be ignored for the sake of tidyness.
- */
- if (parent_is_root && link->link_data.s_addr == 0xffffffff &&
- ospf_if_lookup_by_local_addr (area->ospf, NULL, link->link_id))
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("%s: ignoring host route %s/32 to self.",
- __func__, inet_ntoa (link->link_id));
- return;
- }
-
- rn = route_node_get (rt, (struct prefix *) &p);
-
- /* Lookup current routing table. */
- if (rn->info)
- {
- struct ospf_route *cur_or;
-
- route_unlock_node (rn);
-
- cur_or = rn->info;
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): "
- "another route to the same prefix found with cost %u",
- cur_or->cost);
-
- /* Compare this distance to the current best cost to the stub
- network. This is done by looking up the stub network's
- current routing table entry. If the calculated distance D is
- larger, go on to examine the next stub network link in the
- LSA. */
- if (cost > cur_or->cost)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): old route is better, exit");
- return;
+ u_int32_t cost;
+ struct route_node *rn;
+ struct ospf_route * or ;
+ struct prefix_ipv4 p;
+ struct router_lsa *lsa;
+ struct ospf_interface *oi;
+ struct ospf_path *path;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_stub(): Start");
+
+ lsa = (struct router_lsa *)v->lsa;
+
+ p.family = AF_INET;
+ p.prefix = link->link_id;
+ p.prefixlen = ip_masklen(link->link_data);
+ apply_mask_ipv4(&p);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_stub(): processing route to %s/%d",
+ inet_ntoa(p.prefix), p.prefixlen);
+
+ /* (1) Calculate the distance D of stub network from the root. D is
+ equal to the distance from the root to the router vertex
+ (calculated in stage 1), plus the stub network link's advertised
+ cost. */
+ cost = v->distance + ntohs(link->m[0].metric);
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): calculated cost is %d + %d = %d",
+ v->distance, ntohs(link->m[0].metric), cost);
+
+ /* PtP links with /32 masks adds host routes to remote, directly
+ * connected hosts, see RFC 2328, 12.4.1.1, Option 1.
+ * Such routes can just be ignored for the sake of tidyness.
+ */
+ if (parent_is_root && link->link_data.s_addr == 0xffffffff
+ && ospf_if_lookup_by_local_addr(area->ospf, NULL, link->link_id)) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("%s: ignoring host route %s/32 to self.",
+ __func__, inet_ntoa(link->link_id));
+ return;
}
- /* (2) If this step is reached, the stub network's routing table
- entry must be updated. Calculate the set of next hops that
- would result from using the stub network link. This
- calculation is shown in Section 16.1.1; input to this
- calculation is the destination (the stub network) and the
- parent vertex (the router vertex). If the distance D is the
- same as the current routing table cost, simply add this set
- of next hops to the routing table entry's list of next hops.
- In this case, the routing table already has a Link State
- Origin. If this Link State Origin is a router-LSA whose Link
- State ID is smaller than V's Router ID, reset the Link State
- Origin to V's router-LSA. */
-
- if (cost == cur_or->cost)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): routes are equal, merge");
+ rn = route_node_get(rt, (struct prefix *)&p);
- ospf_route_copy_nexthops_from_vertex (cur_or, v);
+ /* Lookup current routing table. */
+ if (rn->info) {
+ struct ospf_route *cur_or;
- if (IPV4_ADDR_CMP (&cur_or->u.std.origin->id, &lsa->header.id) < 0)
- cur_or->u.std.origin = (struct lsa_header *) lsa;
- return;
- }
+ route_unlock_node(rn);
- /* Otherwise D is smaller than the routing table cost.
- Overwrite the current routing table entry by setting the
- routing table entry's cost to D, and by setting the entry's
- list of next hops to the newly calculated set. Set the
- routing table entry's Link State Origin to V's router-LSA.
- Then go on to examine the next stub network link. */
+ cur_or = rn->info;
- if (cost < cur_or->cost)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): new route is better, set it");
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): "
+ "another route to the same prefix found with cost %u",
+ cur_or->cost);
+
+ /* Compare this distance to the current best cost to the stub
+ network. This is done by looking up the stub network's
+ current routing table entry. If the calculated distance D is
+ larger, go on to examine the next stub network link in the
+ LSA. */
+ if (cost > cur_or->cost) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): old route is better, exit");
+ return;
+ }
- cur_or->cost = cost;
+ /* (2) If this step is reached, the stub network's routing table
+ entry must be updated. Calculate the set of next hops that
+ would result from using the stub network link. This
+ calculation is shown in Section 16.1.1; input to this
+ calculation is the destination (the stub network) and the
+ parent vertex (the router vertex). If the distance D is the
+ same as the current routing table cost, simply add this set
+ of next hops to the routing table entry's list of next hops.
+ In this case, the routing table already has a Link State
+ Origin. If this Link State Origin is a router-LSA whose Link
+ State ID is smaller than V's Router ID, reset the Link State
+ Origin to V's router-LSA. */
+
+ if (cost == cur_or->cost) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): routes are equal, merge");
+
+ ospf_route_copy_nexthops_from_vertex(cur_or, v);
+
+ if (IPV4_ADDR_CMP(&cur_or->u.std.origin->id,
+ &lsa->header.id)
+ < 0)
+ cur_or->u.std.origin = (struct lsa_header *)lsa;
+ return;
+ }
- list_delete_all_node (cur_or->paths);
+ /* Otherwise D is smaller than the routing table cost.
+ Overwrite the current routing table entry by setting the
+ routing table entry's cost to D, and by setting the entry's
+ list of next hops to the newly calculated set. Set the
+ routing table entry's Link State Origin to V's router-LSA.
+ Then go on to examine the next stub network link. */
- ospf_route_copy_nexthops_from_vertex (cur_or, v);
+ if (cost < cur_or->cost) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): new route is better, set it");
- cur_or->u.std.origin = (struct lsa_header *) lsa;
- return;
- }
- }
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): installing new route");
-
- or = ospf_route_new ();
-
- or->id = v->id;
- or->u.std.area_id = area->area_id;
- or->u.std.external_routing = area->external_routing;
- or->path_type = OSPF_PATH_INTRA_AREA;
- or->cost = cost;
- or->type = OSPF_DESTINATION_NETWORK;
- or->u.std.origin = (struct lsa_header *) lsa;
-
- /* Nexthop is depend on connection type. */
- if (v != area->spf)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): this network is on remote router");
- ospf_route_copy_nexthops_from_vertex (or, v);
- }
- else
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): this network is on this router");
-
- 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",
- IF_NAME (oi));
-
- path = ospf_path_new ();
- path->nexthop.s_addr = 0;
- path->ifindex = oi->ifp->ifindex;
- if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
- path->unnumbered = 1;
- listnode_add (or->paths, path);
+ cur_or->cost = cost;
+
+ list_delete_all_node(cur_or->paths);
+
+ ospf_route_copy_nexthops_from_vertex(cur_or, v);
+
+ cur_or->u.std.origin = (struct lsa_header *)lsa;
+ return;
+ }
}
- else
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_intra_add_stub(): where's the interface ?");
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_stub(): installing new route");
+
+ or = ospf_route_new();
+
+ or->id = v->id;
+ or->u.std.area_id = area->area_id;
+ or->u.std.external_routing = area->external_routing;
+ or->path_type = OSPF_PATH_INTRA_AREA;
+ or->cost = cost;
+ or->type = OSPF_DESTINATION_NETWORK;
+ or->u.std.origin = (struct lsa_header *)lsa;
+
+ /* Nexthop is depend on connection type. */
+ if (v != area->spf) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): this network is on remote router");
+ ospf_route_copy_nexthops_from_vertex(or, v);
+ } else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): this network is on this router");
+
+ 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",
+ IF_NAME(oi));
+
+ path = ospf_path_new();
+ path->nexthop.s_addr = 0;
+ path->ifindex = oi->ifp->ifindex;
+ if (CHECK_FLAG(oi->connected->flags,
+ ZEBRA_IFA_UNNUMBERED))
+ path->unnumbered = 1;
+ listnode_add(or->paths, path);
+ } else {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_intra_add_stub(): where's the interface ?");
+ }
}
- }
- rn->info = or;
+ rn->info = or ;
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_stub(): Stop");
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_intra_add_stub(): Stop");
}
-const char *ospf_path_type_str[] =
-{
- "unknown-type",
- "intra-area",
- "inter-area",
- "type1-external",
- "type2-external"
-};
-
-void
-ospf_route_table_dump (struct route_table *rt)
+const char *ospf_path_type_str[] = {"unknown-type", "intra-area", "inter-area",
+ "type1-external", "type2-external"};
+
+void ospf_route_table_dump(struct route_table *rt)
{
- struct route_node *rn;
- struct ospf_route *or;
- char buf1[BUFSIZ];
- char buf2[BUFSIZ];
- struct listnode *pnode;
- struct ospf_path *path;
+ struct route_node *rn;
+ struct ospf_route * or ;
+ char buf1[BUFSIZ];
+ char buf2[BUFSIZ];
+ struct listnode *pnode;
+ struct ospf_path *path;
#if 0
zlog_debug ("Type Dest Area Path Type Cost Next Adv.");
zlog_debug (" Hop(s) Router(s)");
#endif /* 0 */
- zlog_debug ("========== OSPF routing table ==========");
- for (rn = route_top (rt); rn; rn = route_next (rn))
- if ((or = rn->info) != NULL)
- {
- if (or->type == OSPF_DESTINATION_NETWORK)
- {
- zlog_debug ("N %s/%d\t%s\t%s\t%d",
- inet_ntop (AF_INET, &rn->p.u.prefix4, buf1, BUFSIZ),
- rn->p.prefixlen,
- inet_ntop (AF_INET, &or->u.std.area_id, buf2,
- BUFSIZ),
- ospf_path_type_str[or->path_type],
- or->cost);
- for (ALL_LIST_ELEMENTS_RO (or->paths, pnode, path))
- zlog_debug (" -> %s", inet_ntoa (path->nexthop));
- }
- else
- zlog_debug ("R %s\t%s\t%s\t%d",
- inet_ntop (AF_INET, &rn->p.u.prefix4, buf1, BUFSIZ),
- inet_ntop (AF_INET, &or->u.std.area_id, buf2,
- BUFSIZ),
- ospf_path_type_str[or->path_type],
- or->cost);
- }
- zlog_debug ("========================================");
+ zlog_debug("========== OSPF routing table ==========");
+ for (rn = route_top(rt); rn; rn = route_next(rn))
+ if ((or = rn->info) != NULL) {
+ if (or->type == OSPF_DESTINATION_NETWORK) {
+ zlog_debug("N %s/%d\t%s\t%s\t%d",
+ inet_ntop(AF_INET, &rn->p.u.prefix4,
+ buf1, BUFSIZ),
+ rn->p.prefixlen,
+ inet_ntop(AF_INET,
+ & or->u.std.area_id, buf2,
+ BUFSIZ),
+ ospf_path_type_str[or->path_type],
+ or->cost);
+ for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
+ path))
+ zlog_debug(" -> %s",
+ inet_ntoa(path->nexthop));
+ } else
+ zlog_debug("R %s\t%s\t%s\t%d",
+ inet_ntop(AF_INET, &rn->p.u.prefix4,
+ buf1, BUFSIZ),
+ inet_ntop(AF_INET,
+ & or->u.std.area_id, buf2,
+ BUFSIZ),
+ ospf_path_type_str[or->path_type],
+ or->cost);
+ }
+ zlog_debug("========================================");
}
/* This is 16.4.1 implementation.
o Intra-area paths using non-backbone areas are always the most preferred.
o The other paths, intra-area backbone paths and inter-area paths,
are of equal preference. */
-static int
-ospf_asbr_route_cmp (struct ospf *ospf, struct ospf_route *r1,
- struct ospf_route *r2)
+static int ospf_asbr_route_cmp(struct ospf *ospf, struct ospf_route *r1,
+ struct ospf_route *r2)
{
- u_char r1_type, r2_type;
+ u_char r1_type, r2_type;
- r1_type = r1->path_type;
- r2_type = r2->path_type;
+ r1_type = r1->path_type;
+ r2_type = r2->path_type;
- /* r1/r2 itself is backbone, and it's Inter-area path. */
- if (OSPF_IS_AREA_ID_BACKBONE (r1->u.std.area_id))
- r1_type = OSPF_PATH_INTER_AREA;
- if (OSPF_IS_AREA_ID_BACKBONE (r2->u.std.area_id))
- r2_type = OSPF_PATH_INTER_AREA;
+ /* r1/r2 itself is backbone, and it's Inter-area path. */
+ if (OSPF_IS_AREA_ID_BACKBONE(r1->u.std.area_id))
+ r1_type = OSPF_PATH_INTER_AREA;
+ if (OSPF_IS_AREA_ID_BACKBONE(r2->u.std.area_id))
+ r2_type = OSPF_PATH_INTER_AREA;
- return (r1_type - r2_type);
+ return (r1_type - r2_type);
}
/* Compare two routes.
ret < 0 -- r1 is better.
ret == 0 -- r1 and r2 are the same.
ret > 0 -- r2 is better. */
-int
-ospf_route_cmp (struct ospf *ospf, struct ospf_route *r1,
- struct ospf_route *r2)
+int ospf_route_cmp(struct ospf *ospf, struct ospf_route *r1,
+ struct ospf_route *r2)
{
- int ret = 0;
-
- /* Path types of r1 and r2 are not the same. */
- if ((ret = (r1->path_type - r2->path_type)))
- return ret;
-
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("Route[Compare]: Path types are the same.");
- /* Path types are the same, compare any cost. */
- switch (r1->path_type)
- {
- case OSPF_PATH_INTRA_AREA:
- case OSPF_PATH_INTER_AREA:
- break;
- case OSPF_PATH_TYPE1_EXTERNAL:
- if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
- {
- ret = ospf_asbr_route_cmp (ospf, r1->u.ext.asbr, r2->u.ext.asbr);
- if (ret != 0)
- return ret;
- }
- break;
- case OSPF_PATH_TYPE2_EXTERNAL:
- if ((ret = (r1->u.ext.type2_cost - r2->u.ext.type2_cost)))
- return ret;
-
- if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE))
- {
- ret = ospf_asbr_route_cmp (ospf, r1->u.ext.asbr, r2->u.ext.asbr);
- if (ret != 0)
- return ret;
+ int ret = 0;
+
+ /* Path types of r1 and r2 are not the same. */
+ if ((ret = (r1->path_type - r2->path_type)))
+ return ret;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Route[Compare]: Path types are the same.");
+ /* Path types are the same, compare any cost. */
+ switch (r1->path_type) {
+ case OSPF_PATH_INTRA_AREA:
+ case OSPF_PATH_INTER_AREA:
+ break;
+ case OSPF_PATH_TYPE1_EXTERNAL:
+ if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
+ ret = ospf_asbr_route_cmp(ospf, r1->u.ext.asbr,
+ r2->u.ext.asbr);
+ if (ret != 0)
+ return ret;
+ }
+ break;
+ case OSPF_PATH_TYPE2_EXTERNAL:
+ if ((ret = (r1->u.ext.type2_cost - r2->u.ext.type2_cost)))
+ return ret;
+
+ if (!CHECK_FLAG(ospf->config, OSPF_RFC1583_COMPATIBLE)) {
+ ret = ospf_asbr_route_cmp(ospf, r1->u.ext.asbr,
+ r2->u.ext.asbr);
+ if (ret != 0)
+ return ret;
+ }
+ break;
}
- break;
- }
- /* Anyway, compare the costs. */
- return (r1->cost - r2->cost);
+ /* Anyway, compare the costs. */
+ return (r1->cost - r2->cost);
}
-static int
-ospf_path_exist (struct list *plist, struct in_addr nexthop,
- struct ospf_interface *oi)
+static int ospf_path_exist(struct list *plist, struct in_addr nexthop,
+ struct ospf_interface *oi)
{
- struct listnode *node, *nnode;
- struct ospf_path *path;
+ struct listnode *node, *nnode;
+ struct ospf_path *path;
- for (ALL_LIST_ELEMENTS (plist, node, nnode, path))
- if (IPV4_ADDR_SAME (&path->nexthop, &nexthop) &&
- path->ifindex == oi->ifp->ifindex)
- return 1;
+ for (ALL_LIST_ELEMENTS(plist, node, nnode, path))
+ if (IPV4_ADDR_SAME(&path->nexthop, &nexthop)
+ && path->ifindex == oi->ifp->ifindex)
+ return 1;
- return 0;
+ return 0;
}
-void
-ospf_route_copy_nexthops_from_vertex (struct ospf_route *to,
- struct vertex *v)
+void ospf_route_copy_nexthops_from_vertex(struct ospf_route *to,
+ struct vertex *v)
{
- struct listnode *node;
- struct ospf_path *path;
- struct vertex_nexthop *nexthop;
- struct vertex_parent *vp;
-
- assert (to->paths);
-
- for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
- {
- nexthop = vp->nexthop;
-
- if (nexthop->oi != NULL)
- {
- if (! ospf_path_exist (to->paths, nexthop->router, nexthop->oi))
- {
- path = ospf_path_new ();
- path->nexthop = nexthop->router;
- path->ifindex = nexthop->oi->ifp->ifindex;
- if (CHECK_FLAG(nexthop->oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
- path->unnumbered = 1;
- listnode_add (to->paths, path);
- }
+ struct listnode *node;
+ struct ospf_path *path;
+ struct vertex_nexthop *nexthop;
+ struct vertex_parent *vp;
+
+ assert(to->paths);
+
+ for (ALL_LIST_ELEMENTS_RO(v->parents, node, vp)) {
+ nexthop = vp->nexthop;
+
+ if (nexthop->oi != NULL) {
+ if (!ospf_path_exist(to->paths, nexthop->router,
+ nexthop->oi)) {
+ path = ospf_path_new();
+ path->nexthop = nexthop->router;
+ path->ifindex = nexthop->oi->ifp->ifindex;
+ if (CHECK_FLAG(nexthop->oi->connected->flags,
+ ZEBRA_IFA_UNNUMBERED))
+ path->unnumbered = 1;
+ listnode_add(to->paths, path);
+ }
+ }
}
- }
}
-struct ospf_path *
-ospf_path_lookup (struct list *plist, struct ospf_path *path)
+struct ospf_path *ospf_path_lookup(struct list *plist, struct ospf_path *path)
{
- struct listnode *node;
- struct ospf_path *op;
-
- for (ALL_LIST_ELEMENTS_RO (plist, node, op))
- {
- if (!IPV4_ADDR_SAME (&op->nexthop, &path->nexthop))
- continue;
- if (!IPV4_ADDR_SAME (&op->adv_router, &path->adv_router))
- continue;
- if (op->ifindex != path->ifindex)
- continue;
- return op;
- }
- return NULL;
+ struct listnode *node;
+ struct ospf_path *op;
+
+ for (ALL_LIST_ELEMENTS_RO(plist, node, op)) {
+ if (!IPV4_ADDR_SAME(&op->nexthop, &path->nexthop))
+ continue;
+ if (!IPV4_ADDR_SAME(&op->adv_router, &path->adv_router))
+ continue;
+ if (op->ifindex != path->ifindex)
+ continue;
+ return op;
+ }
+ return NULL;
}
-void
-ospf_route_copy_nexthops (struct ospf_route *to, struct list *from)
+void ospf_route_copy_nexthops(struct ospf_route *to, struct list *from)
{
- struct listnode *node, *nnode;
- struct ospf_path *path;
+ struct listnode *node, *nnode;
+ struct ospf_path *path;
- assert (to->paths);
+ assert(to->paths);
- for (ALL_LIST_ELEMENTS (from, node, nnode, path))
- /* The same routes are just discarded. */
- if (!ospf_path_lookup (to->paths, path))
- listnode_add (to->paths, ospf_path_dup (path));
+ for (ALL_LIST_ELEMENTS(from, node, nnode, path))
+ /* The same routes are just discarded. */
+ if (!ospf_path_lookup(to->paths, path))
+ listnode_add(to->paths, ospf_path_dup(path));
}
-void
-ospf_route_subst_nexthops (struct ospf_route *to, struct list *from)
+void ospf_route_subst_nexthops(struct ospf_route *to, struct list *from)
{
- list_delete_all_node (to->paths);
- ospf_route_copy_nexthops (to, from);
+ list_delete_all_node(to->paths);
+ ospf_route_copy_nexthops(to, from);
}
-void
-ospf_route_subst (struct route_node *rn, struct ospf_route *new_or,
- struct ospf_route *over)
+void ospf_route_subst(struct route_node *rn, struct ospf_route *new_or,
+ struct ospf_route *over)
{
- route_lock_node (rn);
- ospf_route_free (rn->info);
+ route_lock_node(rn);
+ ospf_route_free(rn->info);
- ospf_route_copy_nexthops (new_or, over->paths);
- rn->info = new_or;
- route_unlock_node (rn);
+ ospf_route_copy_nexthops(new_or, over->paths);
+ rn->info = new_or;
+ route_unlock_node(rn);
}
-void
-ospf_route_add (struct route_table *rt, struct prefix_ipv4 *p,
- struct ospf_route *new_or, struct ospf_route *over)
+void ospf_route_add(struct route_table *rt, struct prefix_ipv4 *p,
+ struct ospf_route *new_or, struct ospf_route *over)
{
- struct route_node *rn;
+ struct route_node *rn;
- rn = route_node_get (rt, (struct prefix *) p);
+ rn = route_node_get(rt, (struct prefix *)p);
- ospf_route_copy_nexthops (new_or, over->paths);
+ ospf_route_copy_nexthops(new_or, over->paths);
+
+ if (rn->info) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("ospf_route_add(): something's wrong !");
+ route_unlock_node(rn);
+ return;
+ }
- if (rn->info)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_route_add(): something's wrong !");
- route_unlock_node (rn);
- return;
- }
+ rn->info = new_or;
+}
- rn->info = new_or;
+void ospf_prune_unreachable_networks(struct route_table *rt)
+{
+ struct route_node *rn, *next;
+ struct ospf_route * or ;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Pruning unreachable networks");
+
+ for (rn = route_top(rt); rn; rn = next) {
+ next = route_next(rn);
+ if (rn->info != NULL) {
+ or = rn->info;
+ if (listcount(or->paths) == 0) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Pruning route to %s/%d",
+ inet_ntoa(rn->p.u.prefix4),
+ rn->p.prefixlen);
+
+ ospf_route_free(or);
+ rn->info = NULL;
+ route_unlock_node(rn);
+ }
+ }
+ }
}
-void
-ospf_prune_unreachable_networks (struct route_table *rt)
+void ospf_prune_unreachable_routers(struct route_table *rtrs)
{
- struct route_node *rn, *next;
- struct ospf_route *or;
+ struct route_node *rn, *next;
+ struct ospf_route * or ;
+ struct listnode *node, *nnode;
+ struct list *paths;
+
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Pruning unreachable routers");
+
+ for (rn = route_top(rtrs); rn; rn = next) {
+ next = route_next(rn);
+ if ((paths = rn->info) == NULL)
+ continue;
+
+ for (ALL_LIST_ELEMENTS(paths, node, nnode, or)) {
+ if (listcount(or->paths) == 0) {
+ if (IS_DEBUG_OSPF_EVENT) {
+ zlog_debug("Pruning route to rtr %s",
+ inet_ntoa(rn->p.u.prefix4));
+ zlog_debug(
+ " via area %s",
+ inet_ntoa(or->u.std.area_id));
+ }
+
+ listnode_delete(paths, or);
+ ospf_route_free(or);
+ }
+ }
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("Pruning unreachable networks");
+ if (listcount(paths) == 0) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug("Pruning router node %s",
+ inet_ntoa(rn->p.u.prefix4));
- for (rn = route_top (rt); rn; rn = next)
- {
- next = route_next (rn);
- if (rn->info != NULL)
- {
- or = rn->info;
- if (listcount (or->paths) == 0)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("Pruning route to %s/%d",
- inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
-
- ospf_route_free (or);
- rn->info = NULL;
- route_unlock_node (rn);
- }
+ list_delete(paths);
+ rn->info = NULL;
+ route_unlock_node(rn);
+ }
}
- }
}
-void
-ospf_prune_unreachable_routers (struct route_table *rtrs)
+int ospf_add_discard_route(struct route_table *rt, struct ospf_area *area,
+ struct prefix_ipv4 *p)
{
- struct route_node *rn, *next;
- struct ospf_route *or;
- struct listnode *node, *nnode;
- struct list *paths;
+ struct route_node *rn;
+ struct ospf_route * or, *new_or;
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("Pruning unreachable routers");
+ rn = route_node_get(rt, (struct prefix *)p);
- for (rn = route_top (rtrs); rn; rn = next)
- {
- next = route_next (rn);
- if ((paths = rn->info) == NULL)
- continue;
+ if (rn == NULL) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_add_discard_route(): router installation error");
+ return 0;
+ }
- for (ALL_LIST_ELEMENTS (paths, node, nnode, or))
+ if (rn->info) /* If the route to the same destination is found */
{
- if (listcount (or->paths) == 0)
- {
- if (IS_DEBUG_OSPF_EVENT)
- {
- zlog_debug ("Pruning route to rtr %s",
- inet_ntoa (rn->p.u.prefix4));
- zlog_debug (" via area %s",
- inet_ntoa (or->u.std.area_id));
- }
+ route_unlock_node(rn);
- listnode_delete (paths, or);
- ospf_route_free (or);
- }
- }
+ or = rn->info;
- if (listcount (paths) == 0)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("Pruning router node %s", inet_ntoa (rn->p.u.prefix4));
+ if (or->path_type == OSPF_PATH_INTRA_AREA) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_add_discard_route(): "
+ "an intra-area route exists");
+ return 0;
+ }
- list_delete (paths);
- rn->info = NULL;
- route_unlock_node (rn);
- }
- }
-}
+ if (or->type == OSPF_DESTINATION_DISCARD) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_add_discard_route(): "
+ "discard entry already installed");
+ return 0;
+ }
-int
-ospf_add_discard_route (struct route_table *rt, struct ospf_area *area,
- struct prefix_ipv4 *p)
-{
- struct route_node *rn;
- struct ospf_route *or, *new_or;
+ ospf_route_free(rn->info);
+ }
- rn = route_node_get (rt, (struct prefix *) p);
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_add_discard_route(): "
+ "adding %s/%d",
+ inet_ntoa(p->prefix), p->prefixlen);
- if (rn == NULL)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_add_discard_route(): router installation error");
- return 0;
- }
+ new_or = ospf_route_new();
+ new_or->type = OSPF_DESTINATION_DISCARD;
+ new_or->id.s_addr = 0;
+ new_or->cost = 0;
+ new_or->u.std.area_id = area->area_id;
+ new_or->u.std.external_routing = area->external_routing;
+ new_or->path_type = OSPF_PATH_INTER_AREA;
+ rn->info = new_or;
- if (rn->info) /* If the route to the same destination is found */
- {
- route_unlock_node (rn);
+ ospf_zebra_add_discard(p);
- or = rn->info;
+ return 1;
+}
- if (or->path_type == OSPF_PATH_INTRA_AREA)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_add_discard_route(): "
- "an intra-area route exists");
- return 0;
+void 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;
}
- if (or->type == OSPF_DESTINATION_DISCARD)
- {
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_add_discard_route(): "
- "discard entry already installed");
- return 0;
+ 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;
}
- ospf_route_free (rn->info);
- }
+ if (or->type != OSPF_DESTINATION_DISCARD) {
+ if (IS_DEBUG_OSPF_EVENT)
+ zlog_debug(
+ "ospf_delete_discard_route(): "
+ "not a discard entry");
+ return;
+ }
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug ("ospf_add_discard_route(): "
- "adding %s/%d", inet_ntoa (p->prefix), p->prefixlen);
+ /* free the route entry and the route node */
+ ospf_route_free(rn->info);
- new_or = ospf_route_new ();
- new_or->type = OSPF_DESTINATION_DISCARD;
- new_or->id.s_addr = 0;
- new_or->cost = 0;
- new_or->u.std.area_id = area->area_id;
- new_or->u.std.external_routing = area->external_routing;
- new_or->path_type = OSPF_PATH_INTER_AREA;
- rn->info = new_or;
+ rn->info = NULL;
+ route_unlock_node(rn);
+ route_unlock_node(rn);
- ospf_zebra_add_discard (p);
+ /* remove the discard entry from the rib */
+ ospf_zebra_delete_discard(p);
- return 1;
-}
-
-void
-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;
+ return;
}
-