]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ospf6d: Check for MinLSInterval timer when adding to LSUpdate list
authorYash Ranjan <ranjany@vmware.com>
Mon, 21 Mar 2022 11:30:22 +0000 (04:30 -0700)
committerYash Ranjan <ranjany@vmware.com>
Mon, 18 Apr 2022 04:55:22 +0000 (21:55 -0700)
A router has some static routes and redistributes turned on.
"clear ipv6 ospf process" command is applied. Then static routes
are deleted. In 1 in 5 runs, AS-External LSAs are not getting removed
from the neighbors even though it gets removed from its own LSDB.

Because of the clear process command, MAX_AGE LSAs are advertised and
fresh LSAs are installed in the LSDB. When the MAX_LSAs are advertised
back to the same router as part of the flooding process, it gets added
to the LSUpdate list even though it comes inside the MinLSArrival time.
When the static routes get deleted, it removed the LSA from the
LSRetrans list but not from LSUpdate list. The LSAs present in the
LSUpdate list gets advertised when sending LS Updates.

When an old copy of an LSA is more recent than the new LSA, check if it
has come inside the MinLSArrival time before adding to the LSUpdate
list.

Signed-off-by: Yash Ranjan <ranjany@vmware.com>
ospf6d/ospf6_flood.c

index cc82084e5e92f18e00f175c5fcd70206aa034083..bc9e2c340547a04f3038fcda5cb3184c55babd5e 100644 (file)
@@ -878,6 +878,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)
@@ -885,7 +907,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);
@@ -993,19 +1014,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 */
                        }
@@ -1222,7 +1231,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);