]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_route.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / ospfd / ospf_route.c
index c5b26bbd76a01f646e78e840d7869bf5d6ccb1e4..5f18bff1cf79996de3b9523a3e982fc669cc0e5d 100644 (file)
@@ -1,22 +1,7 @@
+// 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>
@@ -363,44 +348,49 @@ void ospf_route_install(struct ospf *ospf, struct route_table *rt)
 
 /* RFC2328 16.1. (4). For "router". */
 void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
-                          struct ospf_area *area, bool add_all)
+                          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 (!add_all && !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
@@ -434,7 +424,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
        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);
 
@@ -448,8 +438,12 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
 
        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. */
@@ -526,7 +520,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        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;
 
@@ -536,8 +530,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        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
@@ -546,9 +539,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        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.
@@ -574,8 +566,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
 
                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
@@ -584,8 +576,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
                   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;
                }
 
@@ -604,8 +596,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
 
                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);
 
@@ -625,8 +617,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
 
                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;
 
@@ -640,7 +632,7 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        }
 
        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();
 
@@ -655,13 +647,13 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        /* 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
@@ -672,9 +664,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
 
                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;
@@ -689,15 +680,15 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
                        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[] = {
@@ -931,7 +922,7 @@ void ospf_route_add(struct route_table *rt, struct prefix_ipv4 *p,
 
        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;
        }
@@ -989,6 +980,16 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs)
                                                &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);
                        }
@@ -1016,8 +1017,7 @@ int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
 
        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;
        }
 
@@ -1029,15 +1029,16 @@ int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
 
                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;
                }
 
@@ -1045,7 +1046,7 @@ int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
        }
 
        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;
@@ -1068,14 +1069,13 @@ void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
        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;
        }
 
@@ -1083,15 +1083,13 @@ void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
 
        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;
        }