diff options
| -rw-r--r-- | babeld/babel_main.c | 1 | ||||
| -rw-r--r-- | eigrpd/eigrpd.c | 7 | ||||
| -rw-r--r-- | isisd/isis_zebra.c | 2 | ||||
| -rw-r--r-- | lib/log.c | 94 | ||||
| -rw-r--r-- | lib/nexthop.c | 33 | ||||
| -rw-r--r-- | lib/nexthop.h | 10 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 3 | ||||
| -rw-r--r-- | pimd/pimd.c | 2 | ||||
| -rw-r--r-- | ripd/rip_main.c | 1 | ||||
| -rw-r--r-- | ripngd/ripng_main.c | 1 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 6 | ||||
| -rw-r--r-- | zebra/rt_socket.c | 4 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 16 | ||||
| -rw-r--r-- | zebra/zebra_vty.c | 140 |
14 files changed, 202 insertions, 118 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 54626a4aeb..6a8f9bb75f 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -335,6 +335,7 @@ babel_exit_properly(void) babel_save_state_file(); debugf(BABEL_DEBUG_COMMON, "Remove pid file."); debugf(BABEL_DEBUG_COMMON, "Done."); + frr_fini(); exit(0); } diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 99d88b2d00..ee60898f86 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -42,6 +42,7 @@ #include "plist.h" #include "sockopt.h" #include "keychain.h" +#include "libfrr.h" #include "eigrpd/eigrp_structs.h" #include "eigrpd/eigrpd.h" @@ -241,12 +242,10 @@ void eigrp_terminate(void) SET_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN); - /* exit immediately if EIGRP not actually running */ - if (listcount(eigrp_om->eigrp) == 0) - exit(0); - for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) eigrp_finish(eigrp); + + frr_fini(); } void eigrp_finish(struct eigrp *eigrp) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index ed96bd31c2..99eb698b75 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -35,6 +35,7 @@ #include "linklist.h" #include "nexthop.h" #include "vrf.h" +#include "libfrr.h" #include "isisd/dict.h" #include "isisd/isis_constants.h" @@ -427,4 +428,5 @@ void isis_zebra_stop(void) { zclient_stop(zclient); zclient_free(zclient); + frr_fini(); } @@ -43,6 +43,9 @@ static int logfile_fd = -1; /* Used in signal handler. */ struct zlog *zlog_default = NULL; bool zlog_startup_stderr = true; +/* lock protecting zlog_default for mt-safe zlog */ +pthread_mutex_t loglock = PTHREAD_MUTEX_INITIALIZER; + const char *zlog_priority[] = { "emergencies", "alerts", "critical", "errors", "warnings", "notifications", "informational", "debugging", NULL, @@ -195,6 +198,8 @@ static void vzlog_file(struct zlog *zl, struct timestamp_control *tsctl, /* va_list version of zlog. */ void vzlog(int priority, const char *format, va_list args) { + pthread_mutex_lock(&loglock); + char proto_str[32]; int original_errno = errno; struct timestamp_control tsctl; @@ -212,6 +217,7 @@ void vzlog(int priority, const char *format, va_list args) /* In this case we return at here. */ errno = original_errno; + pthread_mutex_unlock(&loglock); return; } tsctl.precision = zl->timestamp_precision; @@ -252,37 +258,36 @@ void vzlog(int priority, const char *format, va_list args) proto_str, format, &tsctl, args); errno = original_errno; + pthread_mutex_unlock(&loglock); } int vzlog_test(int priority) { + pthread_mutex_lock(&loglock); + + int ret = 0; + struct zlog *zl = zlog_default; /* When zlog_default is also NULL, use stderr for logging. */ - if (zl == NULL) { - return 1; - } - + if (zl == NULL) + ret = 1; /* Syslog output */ - if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) { - return 1; - } - + else if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) + ret = 1; /* File output. */ - if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) { - return 1; - } - + else if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) + ret = 1; /* stdout output. */ - if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) { - return 1; - } - + else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) + ret = 1; /* Terminal monitor. */ - if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) - return 1; + else if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) + ret = 1; - return 0; + pthread_mutex_unlock(&loglock); + + return ret; } static char *str_append(char *dst, int len, const char *src) @@ -737,7 +742,10 @@ void openzlog(const char *progname, const char *protoname, u_short instance, zl->default_lvl = LOG_DEBUG; openlog(progname, syslog_flags, zl->facility); + + pthread_mutex_lock(&loglock); zlog_default = zl; + pthread_mutex_unlock(&loglock); #ifdef HAVE_GLIBC_BACKTRACE /* work around backtrace() using lazily resolved dynamically linked @@ -754,6 +762,7 @@ void openzlog(const char *progname, const char *protoname, u_short instance, void closezlog(void) { + pthread_mutex_lock(&loglock); struct zlog *zl = zlog_default; closelog(); @@ -766,19 +775,23 @@ void closezlog(void) XFREE(MTYPE_ZLOG, zl); zlog_default = NULL; + pthread_mutex_unlock(&loglock); } /* Called from command.c. */ void zlog_set_level(zlog_dest_t dest, int log_level) { + pthread_mutex_lock(&loglock); zlog_default->maxlvl[dest] = log_level; + pthread_mutex_unlock(&loglock); } int zlog_set_file(const char *filename, int log_level) { - struct zlog *zl = zlog_default; + struct zlog *zl; FILE *fp; mode_t oldumask; + int ret = 1; /* There is opend file. */ zlog_reset_file(); @@ -787,21 +800,28 @@ int zlog_set_file(const char *filename, int log_level) oldumask = umask(0777 & ~LOGFILE_MASK); fp = fopen(filename, "a"); umask(oldumask); - if (fp == NULL) - return 0; - - /* Set flags. */ - zl->filename = XSTRDUP(MTYPE_ZLOG, filename); - zl->maxlvl[ZLOG_DEST_FILE] = log_level; - zl->fp = fp; - logfile_fd = fileno(fp); + if (fp == NULL) { + ret = 0; + } else { + pthread_mutex_lock(&loglock); + zl = zlog_default; + + /* Set flags. */ + zl->filename = XSTRDUP(MTYPE_ZLOG, filename); + zl->maxlvl[ZLOG_DEST_FILE] = log_level; + zl->fp = fp; + logfile_fd = fileno(fp); + pthread_mutex_unlock(&loglock); + } - return 1; + return ret; } /* Reset opend file. */ int zlog_reset_file(void) { + pthread_mutex_lock(&loglock); + struct zlog *zl = zlog_default; if (zl->fp) @@ -814,14 +834,19 @@ int zlog_reset_file(void) XFREE(MTYPE_ZLOG, zl->filename); zl->filename = NULL; + pthread_mutex_unlock(&loglock); + return 1; } /* Reopen log file. */ int zlog_rotate(void) { + pthread_mutex_lock(&loglock); + struct zlog *zl = zlog_default; int level; + int ret = 1; if (zl->fp) fclose(zl->fp); @@ -842,13 +867,16 @@ int zlog_rotate(void) zlog_err( "Log rotate failed: cannot open file %s for append: %s", zl->filename, safe_strerror(save_errno)); - return -1; + ret = -1; + } else { + logfile_fd = fileno(zl->fp); + zl->maxlvl[ZLOG_DEST_FILE] = level; } - logfile_fd = fileno(zl->fp); - zl->maxlvl[ZLOG_DEST_FILE] = level; } - return 1; + pthread_mutex_unlock(&loglock); + + return ret; } /* Wrapper around strerror to handle case where it returns NULL. */ diff --git a/lib/nexthop.c b/lib/nexthop.c index 2dba412f45..ea6a310a4a 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -71,6 +71,39 @@ int nexthop_same_no_recurse(const struct nexthop *next1, return 1; } +int +nexthop_same_firsthop (struct nexthop *next1, struct nexthop *next2) +{ + int type1 = NEXTHOP_FIRSTHOPTYPE(next1->type); + int type2 = NEXTHOP_FIRSTHOPTYPE(next2->type); + + if (type1 != type2) + return 0; + switch (type1) + { + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (! IPV4_ADDR_SAME (&next1->gate.ipv4, &next2->gate.ipv4)) + return 0; + if (next1->ifindex != next2->ifindex) + return 0; + break; + case NEXTHOP_TYPE_IFINDEX: + if (next1->ifindex != next2->ifindex) + return 0; + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + if (! IPV6_ADDR_SAME (&next1->gate.ipv6, &next2->gate.ipv6)) + return 0; + if (next1->ifindex != next2->ifindex) + return 0; + break; + default: + /* do nothing */ + break; + } + return 1; +} + /* * nexthop_type_to_str */ diff --git a/lib/nexthop.h b/lib/nexthop.h index 781eb93413..20b0cd5227 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -50,6 +50,11 @@ enum blackhole_type { BLACKHOLE_ADMINPROHIB, }; +/* IPV[46] -> IPV[46]_IFINDEX */ +#define NEXTHOP_FIRSTHOPTYPE(type) \ + ((type) == NEXTHOP_TYPE_IFINDEX || (type) == NEXTHOP_TYPE_BLACKHOLE) \ + ? (type) : ((type) | 1) + /* Nexthop label structure. */ struct nexthop_label { u_int8_t num_labels; @@ -74,6 +79,10 @@ struct nexthop { #define NEXTHOP_FLAG_ONLINK (1 << 3) /* Nexthop should be installed onlink. */ #define NEXTHOP_FLAG_MATCHED (1 << 4) /* Already matched vs a nexthop */ #define NEXTHOP_FLAG_FILTERED (1 << 5) /* rmap filtered, used by static only */ +#define NEXTHOP_FLAG_DUPLICATE (1 << 6) /* nexthop duplicates another active one */ +#define NEXTHOP_IS_ACTIVE(flags) \ + (CHECK_FLAG(flags, NEXTHOP_FLAG_ACTIVE) \ + && !CHECK_FLAG(flags, NEXTHOP_FLAG_DUPLICATE)) /* Nexthop address */ union { @@ -141,6 +150,7 @@ extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type); extern int nexthop_same_no_recurse(const struct nexthop *next1, const struct nexthop *next2); extern int nexthop_labels_match(struct nexthop *nh1, struct nexthop *nh2); +extern int nexthop_same_firsthop (struct nexthop *next1, struct nexthop *next2); extern const char *nexthop2str(struct nexthop *nexthop, char *str, int size); extern struct nexthop *nexthop_next(struct nexthop *nexthop); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 20cee713bd..ed1d8901fb 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -35,6 +35,7 @@ #include "plist.h" #include "sockopt.h" #include "bfd.h" +#include "libfrr.h" #include "defaults.h" #include "ospfd/ospfd.h" @@ -489,6 +490,8 @@ void ospf_terminate(void) */ zclient_stop(zclient); zclient_free(zclient); + + frr_fini(); } void ospf_finish(struct ospf *ospf) diff --git a/pimd/pimd.c b/pimd/pimd.c index 9a8e92cbb2..37c79d4554 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -139,4 +139,6 @@ void pim_terminate() zclient_stop(zclient); zclient_free(zclient); } + + frr_fini(); } diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 91b623beb4..9a448e8958 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -89,6 +89,7 @@ static void sigint(void) rip_clean(); rip_zclient_stop(); + frr_fini(); exit(0); } diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index 0cb54d4335..8ef27daaba 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -92,6 +92,7 @@ static void sigint(void) ripng_clean(); ripng_zebra_stop(); + frr_fini(); exit(0); } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 12b6185395..e59d5f00fb 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1383,7 +1383,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p, if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) continue; if (cmd == RTM_NEWROUTE - && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + && !NEXTHOP_IS_ACTIVE(nexthop->flags)) continue; if (cmd == RTM_DELROUTE && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) @@ -1438,7 +1438,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p, } if ((cmd == RTM_NEWROUTE - && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + && NEXTHOP_IS_ACTIVE(nexthop->flags)) || (cmd == RTM_DELROUTE && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) { @@ -1521,7 +1521,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p, } if ((cmd == RTM_NEWROUTE - && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + && NEXTHOP_IS_ACTIVE(nexthop->flags)) || (cmd == RTM_DELROUTE && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) { diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index d8e37a10c3..75207a2dde 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -136,7 +136,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re) * other than ADD and DELETE? */ if ((cmd == RTM_ADD - && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + && NEXTHOP_IS_ACTIVE(nexthop->flags)) || (cmd == RTM_DELETE && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) { if (nexthop->type == NEXTHOP_TYPE_IPV4 @@ -314,7 +314,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re) gate = 0; if ((cmd == RTM_ADD - && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + && NEXTHOP_IS_ACTIVE(nexthop->flags)) || (cmd == RTM_DELETE #if 0 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 376425329b..d04b64b19c 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1000,8 +1000,24 @@ int rib_install_kernel(struct route_node *rn, struct route_entry *re, for (ALL_NEXTHOPS(re->nexthop, nexthop)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); return ret; + } else { + struct nexthop *prev; + + for (ALL_NEXTHOPS(re->nexthop, nexthop)) { + UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE); + for (ALL_NEXTHOPS(re->nexthop, prev)) { + if (prev == nexthop) + break; + if (nexthop_same_firsthop (nexthop, prev)) + { + SET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE); + break; + } + } + } } + /* * Make sure we update the FPM any time we send new information to * the kernel. diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 1573646adc..1ce4f66b16 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -408,39 +408,34 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, vty_out(vty, ", best"); vty_out(vty, "\n"); - if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF - || re->type == ZEBRA_ROUTE_ISIS - || re->type == ZEBRA_ROUTE_NHRP - || re->type == ZEBRA_ROUTE_TABLE - || re->type == ZEBRA_ROUTE_BGP) { - time_t uptime; - struct tm *tm; - - uptime = time(NULL); - uptime -= re->uptime; - tm = gmtime(&uptime); - - vty_out(vty, " Last update "); - - if (uptime < ONE_DAY_SECOND) - vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, - tm->tm_min, tm->tm_sec); - else if (uptime < ONE_WEEK_SECOND) - vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, - tm->tm_hour, tm->tm_min); - else - vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7, - tm->tm_yday - ((tm->tm_yday / 7) * 7), - tm->tm_hour); - vty_out(vty, " ago\n"); - } + time_t uptime; + struct tm *tm; + + uptime = time(NULL); + uptime -= re->uptime; + tm = gmtime(&uptime); + + vty_out(vty, " Last update "); + + if (uptime < ONE_DAY_SECOND) + vty_out(vty, "%02d:%02d:%02d", tm->tm_hour, + tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out(vty, "%dd%02dh%02dm", tm->tm_yday, + tm->tm_hour, tm->tm_min); + else + vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) * 7), + tm->tm_hour); + vty_out(vty, " ago\n"); for (ALL_NEXTHOPS(re->nexthop, nexthop)) { char addrstr[32]; vty_out(vty, " %c%s", CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) - ? '*' + ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE) + ? ' ' : '*' : ' ', nexthop->rparent ? " " : ""); @@ -489,6 +484,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, default: break; } + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + vty_out(vty, " (duplicate nexthop removed)"); + if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) vty_out(vty, " inactive"); @@ -553,6 +551,12 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object *json_nexthop = NULL; json_object *json_route = NULL; json_object *json_labels = NULL; + time_t uptime; + struct tm *tm; + + uptime = time(NULL); + uptime -= re->uptime; + tm = gmtime(&uptime); if (json) { json_route = json_object_new_object(); @@ -579,35 +583,26 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, json_object_int_add(json_route, "metric", re->metric); } - if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF - || re->type == ZEBRA_ROUTE_ISIS - || re->type == ZEBRA_ROUTE_NHRP - || re->type == ZEBRA_ROUTE_TABLE - || re->type == ZEBRA_ROUTE_BGP) { - time_t uptime; - struct tm *tm; - - uptime = time(NULL); - uptime -= re->uptime; - tm = gmtime(&uptime); - - if (uptime < ONE_DAY_SECOND) - sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, - tm->tm_min, tm->tm_sec); - else if (uptime < ONE_WEEK_SECOND) - sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, - tm->tm_hour, tm->tm_min); - else - sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7, - tm->tm_yday - ((tm->tm_yday / 7) * 7), - tm->tm_hour); + if (uptime < ONE_DAY_SECOND) + sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, + tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + sprintf(buf, "%dd%02dh%02dm", tm->tm_yday, + tm->tm_hour, tm->tm_min); + else + sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) * 7), + tm->tm_hour); - json_object_string_add(json_route, "uptime", buf); - } + json_object_string_add(json_route, "uptime", buf); for (ALL_NEXTHOPS(re->nexthop, nexthop)) { json_nexthop = json_object_new_object(); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + json_object_boolean_true_add(json_nexthop, + "duplicate"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) json_object_boolean_true_add(json_nexthop, "fib"); @@ -687,6 +682,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, break; } + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + json_object_boolean_true_add(json_nexthop, + "duplicate"); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) json_object_boolean_true_add(json_nexthop, "active"); @@ -774,12 +773,14 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, if (re->type != ZEBRA_ROUTE_CONNECT) len += vty_out(vty, " [%d/%d]", re->distance, re->metric); - } else + } else { vty_out(vty, " %c%*c", CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB) - ? '*' + ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE) + ? ' ' : '*' : ' ', len - 3 + (2 * nexthop_level(nexthop)), ' '); + } switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: @@ -862,29 +863,16 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, sizeof buf, 1)); } - if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF - || re->type == ZEBRA_ROUTE_ISIS - || re->type == ZEBRA_ROUTE_NHRP - || re->type == ZEBRA_ROUTE_TABLE - || re->type == ZEBRA_ROUTE_BGP) { - time_t uptime; - struct tm *tm; - - uptime = time(NULL); - uptime -= re->uptime; - tm = gmtime(&uptime); - - if (uptime < ONE_DAY_SECOND) - vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour, - tm->tm_min, tm->tm_sec); - else if (uptime < ONE_WEEK_SECOND) - vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday, - tm->tm_hour, tm->tm_min); - else - vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7, - tm->tm_yday - ((tm->tm_yday / 7) * 7), - tm->tm_hour); - } + if (uptime < ONE_DAY_SECOND) + vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour, + tm->tm_min, tm->tm_sec); + else if (uptime < ONE_WEEK_SECOND) + vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday, + tm->tm_hour, tm->tm_min); + else + vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7, + tm->tm_yday - ((tm->tm_yday / 7) * 7), + tm->tm_hour); vty_out(vty, "\n"); } } |
