diff options
-rw-r--r-- | conf/conf.c | 6 | ||||
-rw-r--r-- | conf/conf.h | 2 | ||||
-rw-r--r-- | conf/confbase.Y | 12 | ||||
-rw-r--r-- | doc/bird.sgml | 28 | ||||
-rw-r--r-- | lib/timer.c | 135 | ||||
-rw-r--r-- | lib/timer.h | 19 | ||||
-rw-r--r-- | nest/cmds.c | 6 | ||||
-rw-r--r-- | nest/config.Y | 39 | ||||
-rw-r--r-- | nest/password.c | 9 | ||||
-rw-r--r-- | nest/password.h | 4 | ||||
-rw-r--r-- | nest/proto.c | 10 | ||||
-rw-r--r-- | nest/protocol.h | 4 | ||||
-rw-r--r-- | nest/route.h | 4 | ||||
-rw-r--r-- | nest/rt-show.c | 2 | ||||
-rw-r--r-- | nest/rt-table.c | 10 | ||||
-rw-r--r-- | proto/bfd/bfd.c | 8 | ||||
-rw-r--r-- | proto/bfd/bfd.h | 2 | ||||
-rw-r--r-- | sysdep/unix/config.Y | 26 | ||||
-rw-r--r-- | sysdep/unix/io.c | 97 | ||||
-rw-r--r-- | sysdep/unix/log.c | 2 | ||||
-rw-r--r-- | sysdep/unix/timer.h | 12 |
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) |