mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
*: introduce function for sequence numbers
Don't directly use `time()` for generating sequence numbers for two reasons: 1. `time()` can go backwards (due to NTP or time adjustments) 2. Coverity Scan warns every time we truncate a `time_t` variable for good reason (verify that we are Y2K38 ready). Found by Coverity Scan (CID 1519812, 1519786, 1519783 and 1519772) Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
parent
b6ee94b5b1
commit
fce7f209fc
|
@ -37,6 +37,7 @@
|
|||
#include "if.h"
|
||||
#include "table.h"
|
||||
#include "memory.h"
|
||||
#include "network.h"
|
||||
#include "command.h"
|
||||
#include "stream.h"
|
||||
#include "log.h"
|
||||
|
@ -83,7 +84,7 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp,
|
|||
/* Initialize neighbor list. */
|
||||
ei->nbrs = list_new();
|
||||
|
||||
ei->crypt_seqnum = time(NULL);
|
||||
ei->crypt_seqnum = frr_sequence32_next();
|
||||
|
||||
/* Initialize lists */
|
||||
for (i = 0; i < EIGRP_FILTER_MAX; i++) {
|
||||
|
|
|
@ -122,3 +122,24 @@ float ntohf(float net)
|
|||
{
|
||||
return htonf(net);
|
||||
}
|
||||
|
||||
uint64_t frr_sequence_next(void)
|
||||
{
|
||||
static uint64_t last_sequence;
|
||||
struct timespec ts;
|
||||
|
||||
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
if (last_sequence == (uint64_t)ts.tv_sec) {
|
||||
last_sequence++;
|
||||
return last_sequence;
|
||||
}
|
||||
|
||||
last_sequence = ts.tv_sec;
|
||||
return last_sequence;
|
||||
}
|
||||
|
||||
uint32_t frr_sequence32_next(void)
|
||||
{
|
||||
/* coverity[Y2K38_SAFETY] */
|
||||
return (uint32_t)frr_sequence_next();
|
||||
}
|
||||
|
|
|
@ -81,6 +81,24 @@ extern float ntohf(float);
|
|||
#error nobody expects the endianish inquisition. check OS endian.h headers.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generate a sequence number using monotonic clock with a same second call
|
||||
* protection to help guarantee a unique incremental sequence number that never
|
||||
* goes back (except when wrapping/overflow).
|
||||
*
|
||||
* **NOTE** this function is not thread safe since it uses `static` variable.
|
||||
*
|
||||
* This function and `frr_sequence32_next` should be used to initialize
|
||||
* sequence numbers without directly calling other `time_t` returning
|
||||
* functions because of `time_t` truncation warnings.
|
||||
*
|
||||
* \returns `uint64_t` number based on the monotonic clock.
|
||||
*/
|
||||
extern uint64_t frr_sequence_next(void);
|
||||
|
||||
/** Same as `frr_sequence_next` but returns truncated number. */
|
||||
extern uint32_t frr_sequence32_next(void);
|
||||
|
||||
/**
|
||||
* Helper function that returns a random long value. The main purpose of
|
||||
* this function is to hide a `random()` call that gets flagged by coverity
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "linklist.h"
|
||||
#include "lib_errors.h"
|
||||
#include "checksum.h"
|
||||
#include "network.h"
|
||||
|
||||
#include "ospf6_proto.h"
|
||||
#include "ospf6_lsa.h"
|
||||
|
@ -2300,7 +2301,7 @@ static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s)
|
|||
/* if this is initial one, initialize sequence number for DbDesc */
|
||||
if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)
|
||||
&& (on->dbdesc_seqnum == 0)) {
|
||||
on->dbdesc_seqnum = monotime(NULL);
|
||||
on->dbdesc_seqnum = frr_sequence32_next();
|
||||
}
|
||||
|
||||
/* reserved */
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "command.h"
|
||||
#include "stream.h"
|
||||
#include "log.h"
|
||||
#include "network.h"
|
||||
#include "zclient.h"
|
||||
#include "bfd.h"
|
||||
#include "ldp_sync.h"
|
||||
|
@ -274,7 +275,7 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp,
|
|||
oi->t_ls_upd_event = NULL;
|
||||
oi->t_ls_ack_direct = NULL;
|
||||
|
||||
oi->crypt_seqnum = time(NULL);
|
||||
oi->crypt_seqnum = frr_sequence32_next();
|
||||
|
||||
ospf_opaque_type9_lsa_init(oi);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "vrf.h"
|
||||
#include "log.h"
|
||||
#include "lib_errors.h"
|
||||
#include "network.h"
|
||||
|
||||
#include "zebra/rib.h"
|
||||
#include "zebra/zebra_dplane.h"
|
||||
|
@ -73,7 +74,7 @@ static struct nlmsghdr *initiate_nlh(char *buf, unsigned int *seq, int type)
|
|||
nlh->nlmsg_flags = NLM_F_REQUEST;
|
||||
if (type == RTM_NEWNSID)
|
||||
nlh->nlmsg_flags |= NLM_F_ACK;
|
||||
nlh->nlmsg_seq = *seq = time(NULL);
|
||||
nlh->nlmsg_seq = *seq = frr_sequence32_next();
|
||||
return nlh;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue