From: Stephen Hemminger Date: Fri, 15 Jan 2010 13:22:10 +0000 (+0300) Subject: bgp: use monotonic clock for time of day X-Git-Tag: frr-2.0-rc1~2166 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=65957886bfd0dd9d95360d8b015781fc82cc09be;p=mirror%2Ffrr.git bgp: use monotonic clock for time of day BGP uses time() to get system time of day; but that value fluctuates with time adjustments from NTP. This can cause premature flapping of peer sessions and other failures. Use the system monotonic clock supported by Quagga thread library to avoid issue. See: http://bugzilla.vyatta.com/show_bug.cgi?id=4467 * bgpd/bgp_fsm.c * bgp_uptime_reset(): dismiss function * bgpd/bgpd.c * bgp_clock(): new function * bgpd/bgp_damp.c * bgp_reuse_timer(): employ bgp_clock() instead of time(NULL) * bgp_damp_withdraw(): idem * bgp_damp_update(): idem * bgp_damp_scan(): idem * bgp_damp_info_vty(): idem * bgp_damp_reuse_time_vty(): idem * bgpd/bgp_fsm.c * bgp_routeadv_timer(): idem * bgp_stop(): idem * bgp_establish(): idem * bgpd/bgp_packet.c * bgp_update_receive(): idem * bgpd/bgp_route.c * bgp_update_rsclient(): idem * bgp_update_main(): idem * bgp_static_update_rsclient(): idem * bgp_static_update_main(): idem * bgp_static_update_vpnv4(): idem * bgp_aggregate_route(): idem * bgp_aggregate_add(): idem * bgp_redistribute_add(): idem * bgpd/bgp_snmp.c * bgpPeerTable(): idem * bgpTrapEstablished(): idem * bgpTrapBackwardTransition(): idem * bgpd/bgpd.c * peer_create(): idem * peer_uptime(): idem * bgp_master_init(): idem --- diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index e21131ef92..ba059f8c1b 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -117,7 +117,7 @@ bgp_reuse_timer (struct thread *t) damp->t_reuse = thread_add_timer (master, bgp_reuse_timer, NULL, DELTA_REUSE); - t_now = time (NULL); + t_now = bgp_clock (); /* 1. save a pointer to the current zeroth queue head and zero the list head entry. */ @@ -181,7 +181,7 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn, struct bgp_damp_info *bdi = NULL; double last_penalty = 0; - t_now = time (NULL); + t_now = bgp_clock (); /* Processing Unreachable Messages. */ if (binfo->extra) @@ -268,7 +268,7 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn, if (!binfo->extra || !((bdi = binfo->extra->damp_info))) return BGP_DAMP_USED; - t_now = time (NULL); + t_now = bgp_clock (); bgp_info_unset_flag (rn, binfo, BGP_INFO_HISTORY); bdi->lastrecord = BGP_RECORD_UPDATE; @@ -306,7 +306,7 @@ bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi) assert (binfo->extra && binfo->extra->damp_info); - t_now = time (NULL); + t_now = bgp_clock (); bdi = binfo->extra->damp_info; if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)) @@ -597,7 +597,7 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo) return; /* Calculate new penalty. */ - t_now = time (NULL); + t_now = bgp_clock (); t_diff = t_now - bdi->t_updated; penalty = bgp_damp_decay (t_diff, bdi->penalty); @@ -633,7 +633,7 @@ bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo, return NULL; /* Calculate new penalty. */ - t_now = time (NULL); + t_now = bgp_clock (); t_diff = t_now - bdi->t_updated; penalty = bgp_damp_decay (t_diff, bdi->penalty); diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index c815f9a17c..487ebddbbe 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -305,7 +305,7 @@ bgp_routeadv_timer (struct thread *thread) "%s [FSM] Timer (routeadv timer expire)", peer->host); - peer->synctime = time (NULL); + peer->synctime = bgp_clock (); BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); @@ -315,13 +315,6 @@ bgp_routeadv_timer (struct thread *thread) return 0; } -/* Reset bgp update timer */ -static void -bgp_uptime_reset (struct peer *peer) -{ - peer->uptime = time (NULL); -} - /* BGP Peer Down Cause */ const char *peer_down_str[] = { @@ -493,17 +486,12 @@ bgp_stop (struct peer *peer) } /* set last reset time */ - peer->resettime = time (NULL); - /* Reset uptime. */ - bgp_uptime_reset (peer); + peer->resettime = peer->uptime = bgp_clock (); #ifdef HAVE_SNMP bgpTrapBackwardTransition (peer); #endif /* HAVE_SNMP */ - /* Reset uptime. */ - bgp_uptime_reset (peer); - /* Reset peer synctime */ peer->synctime = 0; } @@ -857,7 +845,7 @@ bgp_establish (struct peer *peer) #endif /* HAVE_SNMP */ /* Reset uptime, send keepalive, send current table. */ - bgp_uptime_reset (peer); + peer->uptime = bgp_clock (); /* Send route-refresh when ORF is enabled */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 6153419181..b29bc1f036 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1805,7 +1805,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size) /* Increment packet counter. */ peer->update_in++; - peer->update_time = time (NULL); + peer->update_time = bgp_clock (); /* Generate BGP event. */ BGP_EVENT_ADD (peer, Receive_UPDATE_message); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f3144fea30..a92ca4e2bc 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1878,7 +1878,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, /* If the update is implicit withdraw. */ if (ri) { - ri->uptime = time (NULL); + ri->uptime = bgp_clock (); /* Same attribute comes in. */ if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED) @@ -1946,7 +1946,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, new->sub_type = sub_type; new->peer = peer; new->attr = attr_new; - new->uptime = time (NULL); + new->uptime = bgp_clock (); /* Update MPLS tag. */ if (safi == SAFI_MPLS_VPN) @@ -2133,7 +2133,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* If the update is implicit withdraw. */ if (ri) { - ri->uptime = time (NULL); + ri->uptime = bgp_clock (); /* Same attribute comes in. */ if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED) @@ -2284,7 +2284,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, new->sub_type = sub_type; new->peer = peer; new->attr = attr_new; - new->uptime = time (NULL); + new->uptime = bgp_clock (); /* Update MPLS tag. */ if (safi == SAFI_MPLS_VPN) @@ -3337,7 +3337,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, bgp_info_restore(rn, ri); bgp_attr_unintern (ri->attr); ri->attr = attr_new; - ri->uptime = time (NULL); + ri->uptime = bgp_clock (); /* Process change. */ bgp_process (bgp, rn, afi, safi); @@ -3355,7 +3355,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, new->peer = bgp->peer_self; SET_FLAG (new->flags, BGP_INFO_VALID); new->attr = attr_new; - new->uptime = time (NULL); + new->uptime = bgp_clock (); /* Register new BGP information. */ bgp_info_add (rn, new); @@ -3463,7 +3463,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, bgp_aggregate_decrement (bgp, p, ri, afi, safi); bgp_attr_unintern (ri->attr); ri->attr = attr_new; - ri->uptime = time (NULL); + ri->uptime = bgp_clock (); /* Process change. */ bgp_aggregate_increment (bgp, p, ri, afi, safi); @@ -3482,7 +3482,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, new->peer = bgp->peer_self; SET_FLAG (new->flags, BGP_INFO_VALID); new->attr = attr_new; - new->uptime = time (NULL); + new->uptime = bgp_clock (); /* Aggregate address increment. */ bgp_aggregate_increment (bgp, p, new, afi, safi); @@ -3533,7 +3533,7 @@ bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, new->peer = bgp->peer_self; new->attr = bgp_attr_default_intern (BGP_ORIGIN_IGP); SET_FLAG (new->flags, BGP_INFO_VALID); - new->uptime = time (NULL); + new->uptime = bgp_clock (); new->extra = bgp_info_extra_new(); memcpy (new->extra->tag, tag, 3); @@ -4729,7 +4729,7 @@ bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew, new->peer = bgp->peer_self; SET_FLAG (new->flags, BGP_INFO_VALID); new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set); - new->uptime = time (NULL); + new->uptime = bgp_clock (); bgp_info_add (rn, new); bgp_unlock_node (rn); @@ -4900,7 +4900,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi, new->peer = bgp->peer_self; SET_FLAG (new->flags, BGP_INFO_VALID); new->attr = bgp_attr_aggregate_intern (bgp, origin, aspath, community, aggregate->as_set); - new->uptime = time (NULL); + new->uptime = bgp_clock (); bgp_info_add (rn, new); bgp_unlock_node (rn); @@ -5514,7 +5514,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST); bgp_attr_unintern (bi->attr); bi->attr = new_attr; - bi->uptime = time (NULL); + bi->uptime = bgp_clock (); /* Process change. */ bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST); @@ -5532,7 +5532,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, new->peer = bgp->peer_self; SET_FLAG (new->flags, BGP_INFO_VALID); new->attr = new_attr; - new->uptime = time (NULL); + new->uptime = bgp_clock (); bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST); bgp_info_add (bn, new); diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c index 1e37f266ab..86cc087949 100644 --- a/bgpd/bgp_snmp.c +++ b/bgpd/bgp_snmp.c @@ -546,7 +546,7 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length, if (peer->uptime == 0) return SNMP_INTEGER (0); else - return SNMP_INTEGER (time (NULL) - peer->uptime); + return SNMP_INTEGER (bgp_clock () - peer->uptime); break; case BGPPEERCONNECTRETRYINTERVAL: *write_method = write_bgpPeerTable; @@ -584,7 +584,7 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length, if (peer->update_time == 0) return SNMP_INTEGER (0); else - return SNMP_INTEGER (time (NULL) - peer->update_time); + return SNMP_INTEGER (bgp_clock () - peer->update_time); break; default: return NULL; @@ -859,7 +859,7 @@ bgpTrapEstablished (struct peer *peer) smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid), index, IN_ADDR_SIZE, bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object), - bm->start_time - time (NULL), BGPESTABLISHED); + bm->start_time - bgp_clock (), BGPESTABLISHED); } void @@ -878,7 +878,7 @@ bgpTrapBackwardTransition (struct peer *peer) smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid), index, IN_ADDR_SIZE, bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object), - bm->start_time - time (NULL), BGPBACKWARDTRANSITION); + bm->start_time - bgp_clock (), BGPBACKWARDTRANSITION); } void diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index cf3a6b4240..882fe37cad 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -241,6 +241,17 @@ bgp_cluster_id_unset (struct bgp *bgp) return 0; } +/* time_t value that is monotonicly increasing + * and uneffected by adjustments to system clock + */ +time_t bgp_clock (void) +{ + struct timeval tv; + + quagga_gettime(QUAGGA_CLK_MONOTONIC, &tv); + return tv.tv_sec; +} + /* BGP timer configuration. */ int bgp_timers_set (struct bgp *bgp, u_int32_t keepalive, u_int32_t holdtime) @@ -850,11 +861,8 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, if (afi && safi) peer->afc[afi][safi] = 1; - /* Last read time set */ - peer->readtime = time (NULL); - - /* Last reset time set */ - peer->resettime = time (NULL); + /* Last read and reset time set */ + peer->readtime = peer->resettime = bgp_clock (); /* Default TTL set. */ peer->ttl = (peer_sort (peer) == BGP_PEER_IBGP ? 255 : 1); @@ -4453,7 +4461,7 @@ peer_uptime (time_t uptime2, char *buf, size_t len) } /* Get current time. */ - uptime1 = time (NULL); + uptime1 = bgp_clock (); uptime1 -= uptime2; tm = gmtime (&uptime1); @@ -5145,7 +5153,7 @@ bgp_master_init (void) bm->listen_sockets = list_new (); bm->port = BGP_PORT_DEFAULT; bm->master = thread_master_create (); - bm->start_time = time (NULL); + bm->start_time = bgp_clock (); } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index f4ce89859a..a5afaedcc3 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -809,6 +809,7 @@ extern struct thread_master *master; /* Prototypes. */ extern void bgp_terminate (void); extern void bgp_reset (void); +extern time_t bgp_clock (void); extern void bgp_zclient_reset (void); extern int bgp_nexthop_set (union sockunion *, union sockunion *, struct bgp_nexthop *, struct peer *);