]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospf6d/ospf6_flood.c
Merge pull request #12989 from opensourcerouting/fix/memory_leaks_bgpd
[mirror_frr.git] / ospf6d / ospf6_flood.c
index 5fed6dfe174f9af54c6b94fa3d293c3629018662..db1520ff20aab4408a354b0b5ecc6ce9df9120d5 100644 (file)
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (C) 2003 Yasuhiro Ohara
- *
- * 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>
@@ -464,11 +449,28 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
                                lsa->header->type, lsa->header->id,
                                lsa->header->adv_router, on->retrans_list);
                        if (!old) {
+                               struct ospf6_lsa *orig;
+                               struct ospf6_lsdb *lsdb;
+
                                if (is_debug)
                                        zlog_debug(
                                                "Increment %s from retrans_list of %s",
                                                lsa->name, on->name);
-                               ospf6_increment_retrans_count(lsa);
+
+                               /* Increment the retrans count on the original
+                                * copy of LSA if present, to maintain the
+                                * counter consistency.
+                                */
+
+                               lsdb = ospf6_get_scoped_lsdb(lsa);
+                               orig = ospf6_lsdb_lookup(
+                                       lsa->header->type, lsa->header->id,
+                                       lsa->header->adv_router, lsdb);
+                               if (orig)
+                                       ospf6_increment_retrans_count(orig);
+                               else
+                                       ospf6_increment_retrans_count(lsa);
+
                                ospf6_lsdb_add(ospf6_lsa_copy(lsa),
                                               on->retrans_list);
                                thread_add_timer(
@@ -861,6 +863,28 @@ static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa,
        return 0;
 }
 
+static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa *lsa,
+                                       struct ospf6_neighbor *from)
+{
+       struct timeval now, res;
+       unsigned int time_delta_ms;
+
+       monotime(&now);
+       timersub(&now, &lsa->installed, &res);
+       time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec / 1000);
+
+       if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) {
+               if (IS_OSPF6_DEBUG_FLOODING ||
+                   IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
+                       zlog_debug(
+                               "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
+                               time_delta_ms,
+                               from->ospf6_if->area->ospf6->lsa_minarrival);
+               return true;
+       }
+       return false;
+}
+
 /* RFC2328 section 13 The Flooding Procedure */
 void ospf6_receive_lsa(struct ospf6_neighbor *from,
                       struct ospf6_lsa_header *lsa_header)
@@ -868,7 +892,6 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
        struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
        int ismore_recent;
        int is_debug = 0;
-       unsigned int time_delta_ms;
 
        ismore_recent = 1;
        assert(from);
@@ -976,19 +999,7 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
 
                /* (a) MinLSArrival check */
                if (old) {
-                       struct timeval now, res;
-                       monotime(&now);
-                       timersub(&now, &old->installed, &res);
-                       time_delta_ms =
-                               (res.tv_sec * 1000) + (int)(res.tv_usec / 1000);
-                       if (time_delta_ms
-                           < from->ospf6_if->area->ospf6->lsa_minarrival) {
-                               if (is_debug)
-                                       zlog_debug(
-                                               "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
-                                               time_delta_ms,
-                                               from->ospf6_if->area->ospf6
-                                                       ->lsa_minarrival);
+                       if (ospf6_lsa_check_min_arrival(old, from)) {
                                ospf6_lsa_delete(new);
                                return; /* examin next lsa */
                        }
@@ -1094,9 +1105,12 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
                                         &new->refresh);
                }
 
+               /* GR: check for network topology change. */
                struct ospf6 *ospf6 = from->ospf6_if->area->ospf6;
                struct ospf6_area *area = from->ospf6_if->area;
-               if (ospf6->gr_info.restart_in_progress)
+               if (ospf6->gr_info.restart_in_progress &&
+                   (new->header->type == ntohs(OSPF6_LSTYPE_ROUTER) ||
+                    new->header->type == ntohs(OSPF6_LSTYPE_NETWORK)))
                        ospf6_gr_check_lsdb_consistency(ospf6, area);
 
                return;
@@ -1205,7 +1219,11 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
                                                __PRETTY_FUNCTION__, old->name);
                        }
 
-                       /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
+                       /* MinLSArrival check as per RFC 2328 13 (8) */
+                       if (ospf6_lsa_check_min_arrival(old, from)) {
+                               ospf6_lsa_delete(new);
+                               return; /* examin next lsa */
+                       }
 
                        ospf6_lsdb_add(ospf6_lsa_copy(old),
                                       from->lsupdate_list);