ospf6d: Check for MinLSInterval timer when adding to LSUpdate list

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>
This commit is contained in:
Yash Ranjan 2022-03-21 04:30:22 -07:00
parent eb3bd82451
commit ec58bf6f24

View 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);