aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2017-06-06 16:47:30 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2017-12-07 13:49:27 +0100
commitf047271cb963c62663687d63b2f7cf8dd5edfbb7 (patch)
treecec19ec5f00167aabc3a5233cef5bc6c5e384526
parent025525266f6861437ca54aca2a86eb505a486baf (diff)
downloadbird-f047271cb963c62663687d63b2f7cf8dd5edfbb7.tar.gz
Timers: Parse and format functions for microsecond times
Date/time output (e.g. in logs, show commands) can use %f to specify subsecond time. By default, millisecond precision is used in output.
-rw-r--r--conf/conf.c6
-rw-r--r--conf/conf.h2
-rw-r--r--conf/confbase.Y12
-rw-r--r--doc/bird.sgml28
-rw-r--r--lib/timer.c135
-rw-r--r--lib/timer.h19
-rw-r--r--nest/cmds.c6
-rw-r--r--nest/config.Y39
-rw-r--r--nest/password.c9
-rw-r--r--nest/password.h4
-rw-r--r--nest/proto.c10
-rw-r--r--nest/protocol.h4
-rw-r--r--nest/route.h4
-rw-r--r--nest/rt-show.c2
-rw-r--r--nest/rt-table.c10
-rw-r--r--proto/bfd/bfd.c8
-rw-r--r--proto/bfd/bfd.h2
-rw-r--r--sysdep/unix/config.Y26
-rw-r--r--sysdep/unix/io.c97
-rw-r--r--sysdep/unix/log.c2
-rw-r--r--sysdep/unix/timer.h12
21 files changed, 244 insertions, 193 deletions
diff --git a/conf/conf.c b/conf/conf.c
index c4933122..a570fad5 100644
--- a/conf/conf.c
+++ b/conf/conf.c
@@ -102,9 +102,9 @@ config_alloc(const char *name)
c->pool = p;
c->mem = l;
c->file_name = ndup;
- c->load_time = now;
- c->tf_route = c->tf_proto = (struct timeformat){"%T", "%F", 20*3600};
- c->tf_base = c->tf_log = (struct timeformat){"%F %T", NULL, 0};
+ c->load_time = current_time();
+ c->tf_route = c->tf_proto = TM_ISO_SHORT_MS;
+ c->tf_base = c->tf_log = TM_ISO_LONG_MS;
c->gr_wait = DEFAULT_GR_WAIT;
return c;
diff --git a/conf/conf.h b/conf/conf.h
index af92f056..552d0120 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -57,7 +57,7 @@ struct config {
struct config *fallback; /* Link to regular config for CLI parsing */
int obstacle_count; /* Number of items blocking freeing of this config */
int shutdown; /* This is a pseudo-config for daemon shutdown */
- bird_clock_t load_time; /* When we've got this configuration */
+ btime load_time; /* When we've got this configuration */
};
/* Please don't use these variables in protocols. Use proto_config->global instead. */
diff --git a/conf/confbase.Y b/conf/confbase.Y
index 901ca2b2..390041c4 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -14,7 +14,7 @@ CF_HDR
#include "conf/conf.h"
#include "lib/resource.h"
#include "lib/socket.h"
-#include "sysdep/unix/timer.h"
+#include "lib/timer.h"
#include "lib/string.h"
#include "nest/protocol.h"
#include "nest/iface.h"
@@ -60,7 +60,7 @@ CF_DECLS
struct lsadb_show_data *ld;
struct iface *iface;
void *g;
- bird_clock_t time;
+ btime time;
struct f_prefix px;
struct proto_spec ps;
struct channel_limit cl;
@@ -81,7 +81,7 @@ CF_DECLS
%type <i> expr bool pxlen4
%type <i32> expr_us
-%type <time> datetime
+%type <time> time
%type <a> ipa
%type <net> net_ip4_ net_ip6_ net_ip6 net_ip_ net_ip net_or_ipa
%type <net_ptr> net_ net_any net_vpn4_ net_vpn6_ net_vpn_ net_roa4_ net_roa6_ net_roa_
@@ -308,11 +308,11 @@ label_stack:
}
;
-datetime:
+time:
TEXT {
- $$ = tm_parse_datetime($1);
+ $$ = tm_parse_time($1);
if (!$$)
- cf_error("Invalid date and time");
+ cf_error("Invalid date/time");
}
;
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 1b4b3d67..65efebb8 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -456,24 +456,26 @@ protocol rip {
used for other commands and <cf/log/ is used in a log file.
"<m/format1/" is a format string using <it/strftime(3)/ notation (see
- <it/man strftime/ for details). <m/limit> and "<m/format2/" allow to
- specify the second format string for times in past deeper than <m/limit/
- seconds. There are few shorthands: <cf/iso long/ is a ISO 8601 date/time
- format (YYYY-MM-DD hh:mm:ss) that can be also specified using <cf/"%F %T"/.
+ <it/man strftime/ for details). It is extended to support sub-second
+ time part with variable precision (up to microseconds) using "%f"
+ conversion code (e.g., "%T.%3f" is hh:mm:ss.sss time). <m/limit/ and
+ "<m/format2/" allow to specify the second format string for times in
+ past deeper than <m/limit/ seconds.
+
+ There are several shorthands: <cf/iso long/ is a ISO 8601 date/time
+ format (YYYY-MM-DD hh:mm:ss) that can be also specified using <cf/"%F
+ %T"/. Similarly, <cf/iso long ms/ and <cf/iso long us/ are ISO 8601
+ date/time formats with millisecond or microsecond precision.
<cf/iso short/ is a variant of ISO 8601 that uses just the time format
(hh:mm:ss) for near times (up to 20 hours in the past) and the date
- format (YYYY-MM-DD) for far times. This is a shorthand for
- <cf/"%T" 72000 "%F"/.
+ format (YYYY-MM-DD) for far times. This is a shorthand for <cf/"%T"
+ 72000 "%F"/. And there are also <cf/iso short ms/ and <cf/iso short us/
+ high-precision variants of that.
- By default, BIRD uses the <cf/iso short/ format for <cf/route/ and
- <cf/protocol/ times, and the <cf/iso long/ format for <cf/base/ and
+ By default, BIRD uses the <cf/iso short ms/ format for <cf/route/ and
+ <cf/protocol/ times, and the <cf/iso long ms/ format for <cf/base/ and
<cf/log/ times.
- In pre-1.4.0 versions, BIRD used an short, ad-hoc format for <cf/route/
- and <cf/protocol/ times, and a <cf/iso long/ similar format (DD-MM-YYYY
- hh:mm:ss) for <cf/base/ and <cf/log/. These timeformats could be set by
- <cf/old short/ and <cf/old long/ compatibility shorthands.
-
<tag><label id="opt-table">table <m/name/ [sorted]</tag>
Create a new routing table. The default routing table is created
implicitly, other routing tables have to be added by this command.
diff --git a/lib/timer.c b/lib/timer.c
index 2c08b353..3136a56b 100644
--- a/lib/timer.c
+++ b/lib/timer.c
@@ -8,6 +8,7 @@
*/
+#include <stdio.h>
#include <stdlib.h>
#include "nest/bird.h"
@@ -222,3 +223,137 @@ timer_init(void)
timers_init(&main_timeloop, &root_pool);
timeloop_init_current();
}
+
+
+/**
+ * tm_parse_time - parse a date and time
+ * @x: time string
+ *
+ * tm_parse_time() takes a textual representation of a date and time
+ * (yyyy-mm-dd[ hh:mm:ss[.sss]]) and converts it to the corresponding value of
+ * type &btime.
+ */
+btime
+tm_parse_time(char *x)
+{
+ struct tm tm;
+ int usec, n1, n2, n3, r;
+
+ r = sscanf(x, "%d-%d-%d%n %d:%d:%d%n.%d%n",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &n1,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &n2,
+ &usec, &n3);
+
+ if ((r == 3) && !x[n1])
+ tm.tm_hour = tm.tm_min = tm.tm_sec = usec = 0;
+ else if ((r == 6) && !x[n2])
+ usec = 0;
+ else if ((r == 7) && !x[n3])
+ {
+ /* Convert subsecond digits to proper precision */
+ int digits = n3 - n2 - 1;
+ if ((usec < 0) || (usec > 999999) || (digits < 1) || (digits > 6))
+ return 0;
+
+ while (digits++ < 6)
+ usec *= 10;
+ }
+ else
+ return 0;
+
+ tm.tm_mon--;
+ tm.tm_year -= 1900;
+ s64 ts = mktime(&tm);
+ if ((ts == (s64) (time_t) -1) || (ts < 0) || (ts > ((s64) 1 << 40)))
+ return 0;
+
+ return ts S + usec;
+}
+
+/**
+ * tm_format_time - convert date and time to textual representation
+ * @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
+ * @fmt: specification of resulting textual representation of the time
+ * @t: time
+ *
+ * This function formats the given relative time value @t to a textual
+ * date/time representation (dd-mm-yyyy hh:mm:ss) in real time.
+ */
+void
+tm_format_time(char *x, struct timeformat *fmt, btime t)
+{
+ btime dt = current_time() - t;
+ btime rt = current_real_time() - dt;
+ int v1 = !fmt->limit || (dt < fmt->limit);
+
+ tm_format_real_time(x, v1 ? fmt->fmt1 : fmt->fmt2, rt);
+}
+
+/* Replace %f in format string with usec scaled to requested precision */
+static int
+strfusec(char *buf, int size, const char *fmt, uint usec)
+{
+ char *str = buf;
+ int parity = 0;
+
+ while (*fmt)
+ {
+ if (!size)
+ return 0;
+
+ if ((fmt[0] == '%') && (!parity) &&
+ ((fmt[1] == 'f') || (fmt[1] >= '1') && (fmt[1] <= '6') && (fmt[2] == 'f')))
+ {
+ int digits = (fmt[1] == 'f') ? 6 : (fmt[1] - '0');
+ uint d = digits, u = usec;
+
+ /* Convert microseconds to requested precision */
+ while (d++ < 6)
+ u /= 10;
+
+ int num = bsnprintf(str, size, "%0*u", digits, u);
+ if (num < 0)
+ return 0;
+
+ fmt += (fmt[1] == 'f') ? 2 : 3;
+ ADVANCE(str, size, num);
+ }
+ else
+ {
+ /* Handle '%%' expression */
+ parity = (*fmt == '%') ? !parity : 0;
+ *str++ = *fmt++;
+ size--;
+ }
+ }
+
+ if (!size)
+ return 0;
+
+ *str = 0;
+ return str - buf;
+}
+
+void
+tm_format_real_time(char *x, const char *fmt, btime t)
+{
+ s64 t1 = t TO_S;
+ s64 t2 = t - t1 S;
+
+ time_t ts = t1;
+ struct tm tm;
+ if (!localtime_r(&ts, &tm))
+ goto err;
+
+ byte tbuf[TM_DATETIME_BUFFER_SIZE];
+ if (!strfusec(tbuf, TM_DATETIME_BUFFER_SIZE, fmt, t2))
+ goto err;
+
+ if (!strftime(x, TM_DATETIME_BUFFER_SIZE, tbuf, &tm))
+ goto err;
+
+ return;
+
+err:
+ strcpy(x, "<error>");
+}
diff --git a/lib/timer.h b/lib/timer.h
index b70ac48d..61a2aa94 100644
--- a/lib/timer.h
+++ b/lib/timer.h
@@ -105,4 +105,23 @@ void timers_fire(struct timeloop *loop);
void timer_init(void);
+struct timeformat {
+ char *fmt1, *fmt2;
+ btime limit;
+};
+
+#define TM_ISO_SHORT_S (struct timeformat){"%T", "%F", (s64) (20*3600) S_}
+#define TM_ISO_SHORT_MS (struct timeformat){"%T.%3f", "%F", (s64) (20*3600) S_}
+#define TM_ISO_SHORT_US (struct timeformat){"%T.%6f", "%F", (s64) (20*3600) S_}
+
+#define TM_ISO_LONG_S (struct timeformat){"%F %T", NULL, 0}
+#define TM_ISO_LONG_MS (struct timeformat){"%F %T.%3f", NULL, 0}
+#define TM_ISO_LONG_US (struct timeformat){"%F %T.%6f", NULL, 0}
+
+#define TM_DATETIME_BUFFER_SIZE 32 /* Buffer size required by tm_format_time() */
+
+btime tm_parse_time(char *x);
+void tm_format_time(char *x, struct timeformat *fmt, btime t);
+void tm_format_real_time(char *x, const char *fmt, btime t);
+
#endif
diff --git a/nest/cmds.c b/nest/cmds.c
index 371e8877..ca601ef2 100644
--- a/nest/cmds.c
+++ b/nest/cmds.c
@@ -25,12 +25,12 @@ cmd_show_status(void)
byte tim[TM_DATETIME_BUFFER_SIZE];
cli_msg(-1000, "BIRD " BIRD_VERSION);
- tm_format_datetime(tim, &config->tf_base, now);
+ tm_format_time(tim, &config->tf_base, current_time());
cli_msg(-1011, "Router ID is %R", config->router_id);
cli_msg(-1011, "Current server time is %s", tim);
- tm_format_datetime(tim, &config->tf_base, boot_time TO_S);
+ tm_format_time(tim, &config->tf_base, boot_time);
cli_msg(-1011, "Last reboot on %s", tim);
- tm_format_datetime(tim, &config->tf_base, config->load_time);
+ tm_format_time(tim, &config->tf_base, config->load_time);
cli_msg(-1011, "Last reconfiguration on %s", tim);
graceful_restart_show_status();
diff --git a/nest/config.Y b/nest/config.Y
index 220fa8b0..ef29fb96 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -73,6 +73,7 @@ CF_KEYWORDS(ALGORITHM, KEYED, HMAC, MD5, SHA1, SHA256, SHA384, SHA512)
CF_KEYWORDS(PRIMARY, STATS, COUNT, BY, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
+CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, ROUTE, PROTOCOL, BASE, LOG, S, MS, US)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
/* For r_args_channel */
@@ -295,6 +296,7 @@ limit_spec:
| OFF { $$ = (struct channel_limit){}; }
;
+
CF_ADDTO(conf, debug_default)
debug_default:
@@ -304,6 +306,31 @@ debug_default:
/* MRTDUMP PROTOCOLS is in systep/unix/config.Y */
+CF_ADDTO(conf, timeformat_base)
+
+timeformat_which:
+ ROUTE { $$ = &new_config->tf_route; }
+ | PROTOCOL { $$ = &new_config->tf_proto; }
+ | BASE { $$ = &new_config->tf_base; }
+ | LOG { $$ = &new_config->tf_log; }
+ ;
+
+timeformat_spec:
+ timeformat_which TEXT { *$1 = (struct timeformat){$2, NULL, 0}; }
+ | timeformat_which TEXT expr TEXT { *$1 = (struct timeformat){$2, $4, (s64) $3 S_}; }
+ | timeformat_which ISO SHORT { *$1 = TM_ISO_SHORT_S; }
+ | timeformat_which ISO SHORT MS { *$1 = TM_ISO_SHORT_MS; }
+ | timeformat_which ISO SHORT US { *$1 = TM_ISO_SHORT_US; }
+ | timeformat_which ISO LONG { *$1 = TM_ISO_LONG_S; }
+ | timeformat_which ISO LONG MS { *$1 = TM_ISO_LONG_MS; }
+ | timeformat_which ISO LONG US { *$1 = TM_ISO_LONG_US; }
+ ;
+
+timeformat_base:
+ TIMEFORMAT timeformat_spec ';'
+ ;
+
+
/* Interface patterns */
iface_patt_node_init:
@@ -462,12 +489,12 @@ password_item_begin:
password_item_params:
/* empty */ { }
- | GENERATE FROM datetime ';' password_item_params { this_p_item->genfrom = $3; }
- | GENERATE TO datetime ';' password_item_params { this_p_item->gento = $3; }
- | ACCEPT FROM datetime ';' password_item_params { this_p_item->accfrom = $3; }
- | ACCEPT TO datetime ';' password_item_params { this_p_item->accto = $3; }
- | FROM datetime ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; }
- | TO datetime ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; }
+ | GENERATE FROM time ';' password_item_params { this_p_item->genfrom = $3; }
+ | GENERATE TO time ';' password_item_params { this_p_item->gento = $3; }
+ | ACCEPT FROM time ';' password_item_params { this_p_item->accfrom = $3; }
+ | ACCEPT TO time ';' password_item_params { this_p_item->accto = $3; }
+ | FROM time ';' password_item_params { this_p_item->genfrom = this_p_item->accfrom = $2; }
+ | TO time ';' password_item_params { this_p_item->gento = this_p_item->accto = $2; }
| ID expr ';' password_item_params { this_p_item->id = $2; if ($2 <= 0) cf_error("Password ID has to be greated than zero."); }
| ALGORITHM password_algorithm ';' password_item_params { this_p_item->alg = $2; }
;
diff --git a/nest/password.c b/nest/password.c
index e4813741..72f23f5d 100644
--- a/nest/password.c
+++ b/nest/password.c
@@ -19,12 +19,13 @@ password_find(list *l, int first_fit)
{
struct password_item *pi;
struct password_item *pf = NULL;
+ btime now_ = current_real_time();
if (l)
{
WALK_LIST(pi, *l)
{
- if ((pi->genfrom < now_real) && (pi->gento > now_real))
+ if ((pi->genfrom < now_) && (pi->gento > now_))
{
if (first_fit)
return pi;
@@ -41,12 +42,13 @@ struct password_item *
password_find_by_id(list *l, uint id)
{
struct password_item *pi;
+ btime now_ = current_real_time();
if (!l)
return NULL;
WALK_LIST(pi, *l)
- if ((pi->id == id) && (pi->accfrom <= now_real) && (now_real < pi->accto))
+ if ((pi->id == id) && (pi->accfrom <= now_) && (now_ < pi->accto))
return pi;
return NULL;
@@ -56,12 +58,13 @@ struct password_item *
password_find_by_value(list *l, char *pass, uint size)
{
struct password_item *pi;
+ btime now_ = current_real_time();
if (!l)
return NULL;
WALK_LIST(pi, *l)
- if (password_verify(pi, pass, size) && (pi->accfrom <= now_real) && (now_real < pi->accto))
+ if (password_verify(pi, pass, size) && (pi->accfrom <= now_) && (now_ < pi->accto))
return pi;
return NULL;
diff --git a/nest/password.h b/nest/password.h
index 78244985..c4017848 100644
--- a/nest/password.h
+++ b/nest/password.h
@@ -10,15 +10,13 @@
#ifndef PASSWORD_H
#define PASSWORD_H
-#include "sysdep/unix/timer.h"
-
struct password_item {
node n;
char *password; /* Key data, null terminated */
uint length; /* Key length, without null */
uint id; /* Key ID */
uint alg; /* MAC algorithm */
- bird_clock_t accfrom, accto, genfrom, gento;
+ btime accfrom, accto, genfrom, gento;
};
extern struct password_item *last_password_item;
diff --git a/nest/proto.c b/nest/proto.c
index 65375c35..3043b648 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -162,7 +162,7 @@ proto_add_channel(struct proto *p, struct channel_config *cf)
c->channel_state = CS_DOWN;
c->export_state = ES_DOWN;
- c->last_state_change = now;
+ c->last_state_change = current_time();
c->reloadable = 1;
CALL(c->channel->init, c, cf);
@@ -341,7 +341,7 @@ channel_set_state(struct channel *c, uint state)
return;
c->channel_state = state;
- c->last_state_change = now;
+ c->last_state_change = current_time();
switch (state)
{
@@ -672,7 +672,7 @@ proto_init(struct proto_config *c, node *n)
struct proto *p = pr->init(c);
p->proto_state = PS_DOWN;
- p->last_state_change = now;
+ p->last_state_change = current_time();
insert_node(&p->n, n);
p->event = ev_new(proto_pool);
@@ -1500,7 +1500,7 @@ proto_notify_state(struct proto *p, uint state)
return;
p->proto_state = state;
- p->last_state_change = now;
+ p->last_state_change = current_time();
switch (state)
{
@@ -1631,7 +1631,7 @@ proto_cmd_show(struct proto *p, uint verbose, int cnt)
buf[0] = 0;
if (p->proto->get_status)
p->proto->get_status(p, buf);
- tm_format_datetime(tbuf, &config->tf_proto, p->last_state_change);
+ tm_format_time(tbuf, &config->tf_proto, p->last_state_change);
cli_msg(-1002, "%-8s %-8s %-8s %-5s %-10s %s",
p->name,
p->proto->name,
diff --git a/nest/protocol.h b/nest/protocol.h
index eed0a291..abd11aff 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -159,7 +159,7 @@ struct proto {
byte down_sched; /* Shutdown is scheduled for later (PDS_*) */
byte down_code; /* Reason for shutdown (PDC_* codes) */
u32 hash_key; /* Random key used for hashing of neighbors */
- bird_clock_t last_state_change; /* Time of last state transition */
+ btime last_state_change; /* Time of last state transition */
char *last_state_name_announced; /* Last state name we've announced to the user */
/*
@@ -508,7 +508,7 @@ struct channel {
u8 gr_lock; /* Graceful restart mechanism should wait for this channel */
u8 gr_wait; /* Route export to channel is postponed until graceful restart */
- bird_clock_t last_state_change; /* Time of last state transition */
+ btime last_state_change; /* Time of last state transition */
};
diff --git a/nest/route.h b/nest/route.h
index c1a60ccc..2aa2bcd8 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -159,8 +159,8 @@ typedef struct rtable {
* obstacle from this routing table.
*/
struct event *rt_event; /* Routing table event */
+ btime gc_time; /* Time of last GC */
int gc_counter; /* Number of operations since last GC */
- bird_clock_t gc_time; /* Time of last GC */
byte prune_state; /* Table prune state, 1 -> scheduled, 2-> running */
byte hcu_scheduled; /* Hostcache update is scheduled */
byte nhu_state; /* Next Hop Update state */
@@ -213,7 +213,7 @@ typedef struct rte {
byte flags; /* Flags (REF_...) */
byte pflags; /* Protocol-specific flags */
word pref; /* Route preference */
- bird_clock_t lastmod; /* Last modified */
+ btime lastmod; /* Last modified */
union { /* Protocol-dependent data (metrics etc.) */
#ifdef CONFIG_RIP
struct {
diff --git a/nest/rt-show.c b/nest/rt-show.c
index afde2810..9989afa4 100644
--- a/nest/rt-show.c
+++ b/nest/rt-show.c
@@ -39,7 +39,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d, ea_list *tm
void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs);
struct nexthop *nh;
- tm_format_datetime(tm, &config->tf_route, e->lastmod);
+ tm_format_time(tm, &config->tf_route, e->lastmod);
if (ipa_nonzero(a->from) && !ipa_equal(a->from, a->nh.gw))
bsprintf(from, " from %I", a->from);
else
diff --git a/nest/rt-table.c b/nest/rt-table.c
index 2bb78cf2..c42d3a97 100644
--- a/nest/rt-table.c
+++ b/nest/rt-table.c
@@ -1173,7 +1173,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
}
if (new)
- new->lastmod = now;
+ new->lastmod = current_time();
/* Log the route change */
if (p->debug & D_ROUTES)
@@ -1201,7 +1201,7 @@ rte_recalculate(struct channel *c, net *net, rte *new, struct rte_src *src)
if (!net->routes &&
(table->gc_counter++ >= table->config->gc_max_ops) &&
- (table->gc_time + table->config->gc_min_time <= now))
+ (table->gc_time + table->config->gc_min_time <= current_time()))
rt_schedule_prune(table);
if (old_ok && p->rte_remove)
@@ -1497,7 +1497,7 @@ rte_dump(rte *e)
{
net *n = e->net;
debug("%-1N ", n->n.addr);
- debug("KF=%02x PF=%02x pref=%d lm=%d ", n->n.flags, e->pflags, e->pref, now-e->lastmod);
+ debug("KF=%02x PF=%02x pref=%d ", n->n.flags, e->pflags, e->pref);
rta_dump(e->attrs);
if (e->attrs->src->proto->proto->dump_attrs)
e->attrs->src->proto->proto->dump_attrs(e);
@@ -1609,7 +1609,7 @@ rt_setup(pool *p, rtable *t, char *name, struct rtable_config *cf)
t->rt_event = ev_new(p);
t->rt_event->hook = rt_event;
t->rt_event->data = t;
- t->gc_time = now;
+ t->gc_time = current_time();
}
}
@@ -1708,7 +1708,7 @@ again:
#endif
tab->gc_counter = 0;
- tab->gc_time = now;
+ tab->gc_time = current_time();
/* state change 2->0, 3->1 */
tab->prune_state &= 1;
diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c
index e2c6050b..2374cfe8 100644
--- a/proto/bfd/bfd.c
+++ b/proto/bfd/bfd.c
@@ -145,6 +145,7 @@ bfd_session_update_state(struct bfd_session *s, uint state, uint diag)
bfd_lock_sessions(p);
s->loc_state = state;
s->loc_diag = diag;
+ s->last_state_change = current_time();
notify = !NODE_VALID(&s->n);
if (notify)
@@ -438,7 +439,7 @@ bfd_add_session(struct bfd_proto *p, ip_addr addr, ip_addr local, struct iface *
bfd_session_control_tx_timer(s, 1);
init_list(&s->request_list);
- s->last_state_change = now;
+ s->last_state_change = current_time();
TRACE(D_EVENTS, "Session to %I added", s->addr);
@@ -879,9 +880,6 @@ bfd_notify_hook(sock *sk, uint len UNUSED)
diag = s->loc_diag;
bfd_unlock_sessions(p);
- /* FIXME: convert to btime and move to bfd_session_update_state() */
- s->last_state_change = now;
-
s->notify_running = 1;
WALK_LIST_DELSAFE(n, nn, s->request_list)
bfd_request_notify(SKIP_BACK(struct bfd_request, n, n), state, diag);
@@ -1105,7 +1103,7 @@ bfd_show_sessions(struct proto *P)
timeout = (MAX(s->req_min_rx_int, s->rem_min_tx_int) TO_MS) * s->rem_detect_mult;
state = (state < 4) ? state : 0;
- tm_format_datetime(tbuf, &config->tf_proto, s->last_state_change);
+ tm_format_time(tbuf, &config->tf_proto, s->last_state_change);
cli_msg(-1020, "%-25I %-10s %-10s %-10s %3u.%03u %3u.%03u",
s->addr, ifname, bfd_state_names[state], tbuf,
diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h
index e2e75753..203da437 100644
--- a/proto/bfd/bfd.h
+++ b/proto/bfd/bfd.h
@@ -144,7 +144,7 @@ struct bfd_session
timer2 *hold_timer; /* Timer for session down detection time */
list request_list; /* List of client requests (struct bfd_request) */
- bird_clock_t last_state_change; /* Time of last state change */
+ btime last_state_change; /* Time of last state change */
u8 notify_running; /* 1 if notify hooks are running */
u8 rx_csn_known; /* Received crypto sequence number is known */
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index ebadd454..ccca4a62 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -14,8 +14,7 @@ CF_HDR
CF_DECLS
CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
-CF_KEYWORDS(TIMEFORMAT, ISO, OLD, SHORT, LONG, BASE, NAME, CONFIRM, UNDO, CHECK, TIMEOUT)
-CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT)
+CF_KEYWORDS(NAME, CONFIRM, UNDO, CHECK, TIMEOUT, DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING)
%type <i> log_mask log_mask_list log_cat cfg_timeout
%type <g> log_file
@@ -85,29 +84,6 @@ mrtdump_base:
;
-CF_ADDTO(conf, timeformat_base)
-
-timeformat_which:
- ROUTE { $$ = &new_config->tf_route; }
- | PROTOCOL { $$ = &new_config->tf_proto; }
- | BASE { $$ = &new_config->tf_base; }
- | LOG { $$ = &new_config->tf_log; }
- ;
-
-timeformat_spec:
- timeformat_which TEXT { *$1 = (struct timeformat){$2, NULL, 0}; }
- | timeformat_which TEXT expr TEXT { *$1 = (struct timeformat){$2, $4, $3}; }
- | timeformat_which ISO SHORT { *$1 = (struct timeformat){"%T", "%F", 20*3600}; }
- | timeformat_which ISO LONG { *$1 = (struct timeformat){"%F %T", NULL, 0}; }
- | timeformat_which OLD SHORT { *$1 = (struct timeformat){NULL, NULL, 0}; }
- | timeformat_which OLD LONG { *$1 = (struct timeformat){"%d-%m-%Y %T", NULL, 0}; }
- ;
-
-timeformat_base:
- TIMEFORMAT timeformat_spec ';'
- ;
-
-
CF_ADDTO(conf, debug_unix)
debug_unix:
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index d3506d75..99f52aa9 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -40,6 +40,7 @@
#include "lib/timer.h"
#include "lib/string.h"
#include "nest/iface.h"
+#include "conf/conf.h"
#include "sysdep/unix/unix.h"
#include CONFIG_INCLUDE_SYSIO_H
@@ -385,102 +386,6 @@ tm_shot(void)
}
#endif
-/**
- * tm_parse_datetime - parse a date and time
- * @x: datetime string
- *
- * tm_parse_datetime() takes a textual representation of
- * a date and time (dd-mm-yyyy hh:mm:ss)
- * and converts it to the corresponding value of type &bird_clock_t.
- */
-bird_clock_t
-tm_parse_datetime(char *x)
-{
- struct tm tm;
- int n;
- time_t t;
-
- if (sscanf(x, "%d-%d-%d %d:%d:%d%n", &tm.tm_mday, &tm.tm_mon, &tm.tm_year, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &n) != 6 || x[n])
- return tm_parse_date(x);
- tm.tm_mon--;
- tm.tm_year -= 1900;
- t = mktime(&tm);
- if (t == (time_t) -1)
- return 0;
- return t;
-}
-/**
- * tm_parse_date - parse a date
- * @x: date string
- *
- * tm_parse_date() takes a textual representation of a date (dd-mm-yyyy)
- * and converts it to the corresponding value of type &bird_clock_t.
- */
-bird_clock_t
-tm_parse_date(char *x)
-{
- struct tm tm;
- int n;
- time_t t;
-
- if (sscanf(x, "%d-%d-%d%n", &tm.tm_mday, &tm.tm_mon, &tm.tm_year, &n) != 3 || x[n])
- return 0;
- tm.tm_mon--;
- tm.tm_year -= 1900;
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
- t = mktime(&tm);
- if (t == (time_t) -1)
- return 0;
- return t;
-}
-
-static void
-tm_format_reltime(char *x, struct tm *tm, bird_clock_t delta)
-{
- static char *month_names[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
- if (delta < 20*3600)
- bsprintf(x, "%02d:%02d", tm->tm_hour, tm->tm_min);
- else if (delta < 360*86400)
- bsprintf(x, "%s%02d", month_names[tm->tm_mon], tm->tm_mday);
- else
- bsprintf(x, "%d", tm->tm_year+1900);
-}
-
-#include "conf/conf.h"
-
-/**
- * tm_format_datetime - convert date and time to textual representation
- * @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE
- * @fmt_spec: specification of resulting textual representation of the time
- * @t: time
- *
- * This function formats the given relative time value @t to a textual
- * date/time representation (dd-mm-yyyy hh:mm:ss) in real time.
- */
-void
-tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t)
-{
- const char *fmt_used;
- struct tm *tm;
- bird_clock_t delta = now - t;
- t = now_real - delta;
- tm = localtime(&t);
-
- if (fmt_spec->fmt1 == NULL)
- return tm_format_reltime(x, tm, delta);
-
- if ((fmt_spec->limit == 0) || (delta < fmt_spec->limit))
- fmt_used = fmt_spec->fmt1;
- else
- fmt_used = fmt_spec->fmt2;
-
- int rv = strftime(x, TM_DATETIME_BUFFER_SIZE, fmt_used, tm);
- if (((rv == 0) && fmt_used[0]) || (rv == TM_DATETIME_BUFFER_SIZE))
- strcpy(x, "<too-long>");
-}
-
/*
* Time clock
diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c
index 06d3b09e..e564f8f2 100644
--- a/sysdep/unix/log.c
+++ b/sysdep/unix/log.c
@@ -120,7 +120,7 @@ log_commit(int class, buffer *buf)
else
{
byte tbuf[TM_DATETIME_BUFFER_SIZE];
- tm_format_datetime(tbuf, &config->tf_log, now);
+ tm_format_real_time(tbuf, config->tf_log.fmt1, current_real_time());
fprintf(l->fh, "%s <%s> ", tbuf, class_names[class]);
}
fputs(buf->start, l->fh);
diff --git a/sysdep/unix/timer.h b/sysdep/unix/timer.h
index 1c4f6e3b..495d10c7 100644
--- a/sysdep/unix/timer.h
+++ b/sysdep/unix/timer.h
@@ -45,18 +45,6 @@ static inline timer * tm_new_set(pool *p, void (*hook)(timer *), void *data, uin
{ return tm2_new_init(p, hook, data, rec S_, rand S_); }
-struct timeformat {
- char *fmt1, *fmt2;
- bird_clock_t limit;
-};
-
-bird_clock_t tm_parse_date(char *); /* Convert date to bird_clock_t */
-bird_clock_t tm_parse_datetime(char *); /* Convert date to bird_clock_t */
-
-#define TM_DATETIME_BUFFER_SIZE 32 /* Buffer size required by tm_format_datetime */
-void
-tm_format_datetime(char *x, struct timeformat *fmt_spec, bird_clock_t t);
-
#define TIME_INFINITY ((s64) 0x7fffffffffffffff)