+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* OSPF routing table.
* Copyright (C) 1999, 2000 Toshiaki Takada
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
/* RFC2328 16.1. (4). For "router". */
void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
- struct ospf_area *area)
+ struct ospf_area *area, bool add_only)
{
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");
-
+ if (IS_DEBUG_OSPF_EVENT) {
+ if (!add_only)
+ zlog_debug("%s: Start", __func__);
+ else
+ zlog_debug("%s: REACHRUN: Start", __func__);
+ }
lsa = (struct router_lsa *)v->lsa;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_router: LS ID: %pI4",
- &lsa->header.id);
+ zlog_debug("%s: LS ID: %pI4", __func__, &lsa->header.id);
- if (!OSPF_IS_AREA_BACKBONE(area))
- ospf_vl_up_check(area, lsa->header.id, v);
+ if (!add_only) {
+ 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 (!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;
- }
+ /* 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(
+ "%s: this router is neither ASBR nor ABR, skipping it",
+ __func__);
+ 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++;
+ /* 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
apply_mask_ipv4(&p);
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_router: talking about %pFX", &p);
+ zlog_debug("%s: talking about %pFX", __func__, &p);
rn = route_node_get(rt, (struct prefix *)&p);
listnode_add(rn->info, or);
- if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_router: Stop");
+ if (IS_DEBUG_OSPF_EVENT) {
+ if (!add_only)
+ zlog_debug("%s: Stop", __func__);
+ else
+ zlog_debug("%s: REACHRUN: Stop", __func__);
+ }
}
/* RFC2328 16.1. (4). For transit network. */
struct ospf_path *path;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_stub(): Start");
+ zlog_debug("%s: Start", __func__);
lsa = (struct router_lsa *)v->lsa;
apply_mask_ipv4(&p);
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_stub(): processing route to %pFX",
- &p);
+ zlog_debug("%s: processing route to %pFX", __func__, &p);
/* (1) Calculate the distance D of stub network from the root. D is
equal to the distance from the root to the router vertex
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);
+ zlog_debug("%s: calculated cost is %d + %d = %d", __func__,
+ 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.
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
- "ospf_intra_add_stub(): another route to the same prefix found with cost %u",
- cur_or->cost);
+ "%s: another route to the same prefix found with cost %u",
+ __func__, 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
LSA. */
if (cost > cur_or->cost) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_intra_add_stub(): old route is better, exit");
+ zlog_debug("%s: old route is better, exit",
+ __func__);
return;
}
if (cost == cur_or->cost) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_intra_add_stub(): routes are equal, merge");
+ zlog_debug("%s: routes are equal, merge",
+ __func__);
ospf_route_copy_nexthops_from_vertex(area, 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");
+ zlog_debug("%s: new route is better, set it",
+ __func__);
cur_or->cost = cost;
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_stub(): installing new route");
+ zlog_debug("%s: installing new route", __func__);
or = ospf_route_new();
/* 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");
+ zlog_debug("%s: this network is on remote router",
+ __func__);
ospf_route_copy_nexthops_from_vertex(area, or, v);
} else {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_intra_add_stub(): this network is on this router");
+ zlog_debug("%s: this network is on this router",
+ __func__);
/*
* Only deal with interface data when we
if (oi || area->spf_dry_run) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_intra_add_stub(): the lsa pos is %d",
- lsa_pos);
+ zlog_debug("%s: the lsa pos is %d", __func__,
+ lsa_pos);
path = ospf_path_new();
path->nexthop.s_addr = INADDR_ANY;
listnode_add(or->paths, path);
} else {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_intra_add_stub(): where's the interface ?");
+ zlog_debug("%s: where's the interface ?",
+ __func__);
}
}
rn->info = or ;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_intra_add_stub(): Stop");
+ zlog_debug("%s: Stop", __func__);
}
static const char *const ospf_path_type_str[] = {
zlog_debug("========================================");
}
+void ospf_router_route_table_dump(struct route_table *rt)
+{
+ struct route_node *rn;
+ struct ospf_route *or;
+ struct listnode *node;
+
+ zlog_debug("========== OSPF routing table ==========");
+ for (rn = route_top(rt); rn; rn = route_next(rn)) {
+ for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) {
+ assert(or->type == OSPF_DESTINATION_ROUTER);
+ zlog_debug("R %-18pI4 %-15pI4 %s %d", &rn->p.u.prefix4,
+ &or->u.std.area_id,
+ 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,
if (rn->info) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_route_add(): something's wrong !");
+ zlog_debug("%s: something's wrong !", __func__);
route_unlock_node(rn);
return;
}
&or->u.std.area_id);
}
+ /* Unset the DNA flag on lsa, if the router
+ * which generated this lsa is no longer
+ * reachabele.
+ */
+ (CHECK_FLAG(or->u.std.origin->ls_age,
+ DO_NOT_AGE))
+ ? UNSET_FLAG(or->u.std.origin->ls_age,
+ DO_NOT_AGE)
+ : 0;
+
listnode_delete(paths, or);
ospf_route_free(or);
}
if (rn == NULL) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_add_discard_route(): router installation error");
+ zlog_debug("%s: router installation error", __func__);
return 0;
}
if (or->path_type == OSPF_PATH_INTRA_AREA) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_add_discard_route(): an intra-area route exists");
+ zlog_debug("%s: an intra-area route exists",
+ __func__);
return 0;
}
if (or->type == OSPF_DESTINATION_DISCARD) {
if (IS_DEBUG_OSPF_EVENT)
zlog_debug(
- "ospf_add_discard_route(): discard entry already installed");
+ "%s: discard entry already installed",
+ __func__);
return 0;
}
}
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_add_discard_route(): adding %pFX", p);
+ zlog_debug("%s: adding %pFX", __func__, p);
new_or = ospf_route_new();
new_or->type = OSPF_DESTINATION_DISCARD;
struct ospf_route * or ;
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug("ospf_delete_discard_route(): deleting %pFX", p);
+ zlog_debug("%s: deleting %pFX", __func__, p);
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");
+ zlog_debug("%s: no route found", __func__);
return;
}
if (or->path_type == OSPF_PATH_INTRA_AREA) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_delete_discard_route(): an intra-area route exists");
+ zlog_debug("%s: an intra-area route exists", __func__);
return;
}
if (or->type != OSPF_DESTINATION_DISCARD) {
if (IS_DEBUG_OSPF_EVENT)
- zlog_debug(
- "ospf_delete_discard_route(): not a discard entry");
+ zlog_debug("%s: not a discard entry", __func__);
return;
}