diff options
| -rw-r--r-- | eigrpd/eigrp_interface.c | 3 | ||||
| -rw-r--r-- | lib/network.c | 21 | ||||
| -rw-r--r-- | lib/network.h | 18 | ||||
| -rw-r--r-- | ospf6d/ospf6_message.c | 3 | ||||
| -rw-r--r-- | ospfd/ospf_interface.c | 3 | ||||
| -rw-r--r-- | zebra/zebra_netns_id.c | 3 |
6 files changed, 47 insertions, 4 deletions
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 28987b4af6..891d282307 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -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++) { diff --git a/lib/network.c b/lib/network.c index b60ad9a57c..cd62b8b593 100644 --- a/lib/network.c +++ b/lib/network.c @@ -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(); +} diff --git a/lib/network.h b/lib/network.h index 10ed917572..c163eab8f7 100644 --- a/lib/network.h +++ b/lib/network.h @@ -82,6 +82,24 @@ extern float ntohf(float); #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 * scan and put it into one place. diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index fb54ebab15..3d29a65d1b 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -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 */ diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index a0b14e73ee..831906b908 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -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); diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 73d585c1a3..8905b72ec5 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -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; } |
