From bf717756b50dc96b27d66c5247a5d543c5f75168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 25 Apr 2018 11:29:46 +0200 Subject: [PATCH 1/5] ingress: Don't break JSON output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dash printed by the ingress qdisc breaks JSON output, so only print it in regular output mode. Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: Stephen Hemminger --- tc/q_ingress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tc/q_ingress.c b/tc/q_ingress.c index 1e422298..93313c9c 100644 --- a/tc/q_ingress.c +++ b/tc/q_ingress.c @@ -40,7 +40,7 @@ static int ingress_parse_opt(struct qdisc_util *qu, int argc, char **argv, static int ingress_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) { - fprintf(f, "---------------- "); + print_string(PRINT_FP, NULL, "---------------- ", NULL); return 0; } From 4db2ff0db46f6368d89cfb3498a700e1256d2a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 25 Apr 2018 17:28:57 +0200 Subject: [PATCH 2/5] json_print: Fix hidden 64-bit type promotion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit print_uint() will silently promote its variable type to uint64_t, but there is nothing that ensures that the format string specifier passed along with it fits (and the function name suggest to pass "%u"). Fix this by changing print_uint() to use a native 'unsigned int' type, and introduce a separate print_u64() function for printing 64-bit values. All call sites that were actually printing 64-bit values using print_uint() are converted to use print_u64() instead. Since print_int() was already using native int types, just add a print_s64() to match, but don't convert any call sites. For symmetry, also add a print_luint() method (with no users). Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: Stephen Hemminger --- include/json_print.h | 5 +++- include/json_writer.h | 15 ++++++++--- ip/ipaddress.c | 62 +++++++++++++++++++++---------------------- ip/ipmacsec.c | 8 +++--- ip/ipmroute.c | 6 ++--- ip/ipntable.c | 38 +++++++++++++------------- ip/iproute_lwtunnel.c | 6 ++--- ip/iptuntap.c | 4 +-- ip/tcp_metrics.c | 6 ++--- lib/json_print.c | 5 +++- lib/json_writer.c | 43 +++++++++++++++++++++++++++--- 11 files changed, 123 insertions(+), 75 deletions(-) diff --git a/include/json_print.h b/include/json_print.h index 2ca7830a..218fedc5 100644 --- a/include/json_print.h +++ b/include/json_print.h @@ -56,13 +56,16 @@ void close_json_array(enum output_type type, const char *delim); print_color_##type_name(t, COLOR_NONE, key, fmt, value); \ } _PRINT_FUNC(int, int); +_PRINT_FUNC(s64, int64_t); _PRINT_FUNC(bool, bool); _PRINT_FUNC(null, const char*); _PRINT_FUNC(string, const char*); -_PRINT_FUNC(uint, uint64_t); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(u64, uint64_t); _PRINT_FUNC(hu, unsigned short); _PRINT_FUNC(hex, unsigned int); _PRINT_FUNC(0xhex, unsigned int); +_PRINT_FUNC(luint, unsigned long int); _PRINT_FUNC(lluint, unsigned long long int); _PRINT_FUNC(float, double); #undef _PRINT_FUNC diff --git a/include/json_writer.h b/include/json_writer.h index 4b4dec28..9ab88e1d 100644 --- a/include/json_writer.h +++ b/include/json_writer.h @@ -34,22 +34,29 @@ void jsonw_string(json_writer_t *self, const char *value); void jsonw_bool(json_writer_t *self, bool value); void jsonw_float(json_writer_t *self, double number); void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); -void jsonw_uint(json_writer_t *self, uint64_t number); +void jsonw_uint(json_writer_t *self, unsigned int number); +void jsonw_u64(json_writer_t *self, uint64_t number); void jsonw_xint(json_writer_t *self, uint64_t number); void jsonw_hu(json_writer_t *self, unsigned short number); -void jsonw_int(json_writer_t *self, int64_t number); +void jsonw_int(json_writer_t *self, int number); +void jsonw_s64(json_writer_t *self, int64_t number); void jsonw_null(json_writer_t *self); +void jsonw_luint(json_writer_t *self, unsigned long int num); void jsonw_lluint(json_writer_t *self, unsigned long long int num); /* Useful Combinations of name and value */ void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); void jsonw_float_field(json_writer_t *self, const char *prop, double num); -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num); +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num); +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num); void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num); void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num); +void jsonw_int_field(json_writer_t *self, const char *prop, int num); +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num); void jsonw_null_field(json_writer_t *self, const char *prop); +void jsonw_luint_field(json_writer_t *self, const char *prop, + unsigned long int num); void jsonw_lluint_field(json_writer_t *self, const char *prop, unsigned long long int num); void jsonw_float_field_fmt(json_writer_t *self, const char *prop, diff --git a/ip/ipaddress.c b/ip/ipaddress.c index aecc9a1d..75539e05 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -554,21 +554,21 @@ static void print_vf_stats64(FILE *fp, struct rtattr *vfstats) /* RX stats */ open_json_object("rx"); - print_uint(PRINT_JSON, "bytes", NULL, + print_u64(PRINT_JSON, "bytes", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES])); - print_uint(PRINT_JSON, "packets", NULL, + print_u64(PRINT_JSON, "packets", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS])); - print_uint(PRINT_JSON, "multicast", NULL, + print_u64(PRINT_JSON, "multicast", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST])); - print_uint(PRINT_JSON, "broadcast", NULL, + print_u64(PRINT_JSON, "broadcast", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST])); close_json_object(); /* TX stats */ open_json_object("tx"); - print_uint(PRINT_JSON, "tx_bytes", NULL, + print_u64(PRINT_JSON, "tx_bytes", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES])); - print_uint(PRINT_JSON, "tx_packets", NULL, + print_u64(PRINT_JSON, "tx_packets", NULL, rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS])); close_json_object(); close_json_object(); @@ -608,69 +608,69 @@ static void __print_link_stats(FILE *fp, struct rtattr *tb[]) /* RX stats */ open_json_object("rx"); - print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes); - print_uint(PRINT_JSON, "packets", NULL, s->rx_packets); - print_uint(PRINT_JSON, "errors", NULL, s->rx_errors); - print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped); - print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); - print_uint(PRINT_JSON, "multicast", NULL, s->multicast); + print_u64(PRINT_JSON, "bytes", NULL, s->rx_bytes); + print_u64(PRINT_JSON, "packets", NULL, s->rx_packets); + print_u64(PRINT_JSON, "errors", NULL, s->rx_errors); + print_u64(PRINT_JSON, "dropped", NULL, s->rx_dropped); + print_u64(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); + print_u64(PRINT_JSON, "multicast", NULL, s->multicast); if (s->rx_compressed) - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "compressed", NULL, s->rx_compressed); /* RX error stats */ if (show_stats > 1) { - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "length_errors", NULL, s->rx_length_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "crc_errors", NULL, s->rx_crc_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "frame_errors", NULL, s->rx_frame_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "fifo_errors", NULL, s->rx_fifo_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "missed_errors", NULL, s->rx_missed_errors); if (s->rx_nohandler) - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "nohandler", NULL, s->rx_nohandler); } close_json_object(); /* TX stats */ open_json_object("tx"); - print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes); - print_uint(PRINT_JSON, "packets", NULL, s->tx_packets); - print_uint(PRINT_JSON, "errors", NULL, s->tx_errors); - print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "bytes", NULL, s->tx_bytes); + print_u64(PRINT_JSON, "packets", NULL, s->tx_packets); + print_u64(PRINT_JSON, "errors", NULL, s->tx_errors); + print_u64(PRINT_JSON, "dropped", NULL, s->tx_dropped); + print_u64(PRINT_JSON, "carrier_errors", NULL, s->tx_carrier_errors); - print_uint(PRINT_JSON, "collisions", NULL, s->collisions); + print_u64(PRINT_JSON, "collisions", NULL, s->collisions); if (s->tx_compressed) - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "compressed", NULL, s->tx_compressed); /* TX error stats */ if (show_stats > 1) { - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "aborted_errors", NULL, s->tx_aborted_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "fifo_errors", NULL, s->tx_fifo_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "window_errors", NULL, s->tx_window_errors); - print_uint(PRINT_JSON, + print_u64(PRINT_JSON, "heartbeat_errors", NULL, s->tx_heartbeat_errors); if (carrier_changes) - print_uint(PRINT_JSON, "carrier_changes", NULL, + print_u64(PRINT_JSON, "carrier_changes", NULL, rta_getattr_u32(carrier_changes)); } diff --git a/ip/ipmacsec.c b/ip/ipmacsec.c index 38ec7136..4e4e158e 100644 --- a/ip/ipmacsec.c +++ b/ip/ipmacsec.c @@ -640,7 +640,7 @@ static void print_attrs(struct rtattr *attrs[]) } } -static __u64 getattr_uint(struct rtattr *stat) +static __u64 getattr_u64(struct rtattr *stat) { switch (RTA_PAYLOAD(stat)) { case sizeof(__u64): @@ -681,7 +681,7 @@ static void print_fp_stats(const char *prefix, pad = strlen(names[i]) + 1; if (stats[i]) - printf("%*llu", pad, getattr_uint(stats[i])); + printf("%*llu", pad, getattr_u64(stats[i])); else printf("%*c", pad, '-'); } @@ -697,8 +697,8 @@ static void print_json_stats(const char *names[], unsigned int num, if (!names[i] || !stats[i]) continue; - print_uint(PRINT_JSON, names[i], - NULL, getattr_uint(stats[i])); + print_u64(PRINT_JSON, names[i], + NULL, getattr_u64(stats[i])); } } diff --git a/ip/ipmroute.c b/ip/ipmroute.c index 59c5b771..cdb4d898 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -182,12 +182,12 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) struct rta_mfc_stats *mfcs = RTA_DATA(tb[RTA_MFC_STATS]); print_string(PRINT_FP, NULL, "%s", _SL_); - print_uint(PRINT_ANY, "packets", " %"PRIu64" packets,", + print_u64(PRINT_ANY, "packets", " %"PRIu64" packets,", mfcs->mfcs_packets); - print_uint(PRINT_ANY, "bytes", " %"PRIu64" bytes", mfcs->mfcs_bytes); + print_u64(PRINT_ANY, "bytes", " %"PRIu64" bytes", mfcs->mfcs_bytes); if (mfcs->mfcs_wrong_if) - print_uint(PRINT_ANY, "wrong_if", + print_u64(PRINT_ANY, "wrong_if", ", %"PRIu64" arrived on wrong iif.", mfcs->mfcs_wrong_if); } diff --git a/ip/ipntable.c b/ip/ipntable.c index 82f40f87..4fae181d 100644 --- a/ip/ipntable.c +++ b/ip/ipntable.c @@ -392,7 +392,7 @@ static void print_ndtparams(struct rtattr *tpb[]) if (tpb[NDTPA_REACHABLE_TIME]) { __u64 reachable = rta_getattr_u64(tpb[NDTPA_REACHABLE_TIME]); - print_uint(PRINT_ANY, "reachable", + print_u64(PRINT_ANY, "reachable", "reachable %llu ", reachable); } @@ -400,14 +400,14 @@ static void print_ndtparams(struct rtattr *tpb[]) __u64 breachable = rta_getattr_u64(tpb[NDTPA_BASE_REACHABLE_TIME]); - print_uint(PRINT_ANY, "base_reachable", + print_u64(PRINT_ANY, "base_reachable", "base_reachable %llu ", breachable); } if (tpb[NDTPA_RETRANS_TIME]) { __u64 retrans = rta_getattr_u64(tpb[NDTPA_RETRANS_TIME]); - print_uint(PRINT_ANY, "retrans", "retrans %llu ", retrans); + print_u64(PRINT_ANY, "retrans", "retrans %llu ", retrans); } print_string(PRINT_FP, NULL, "%s ", _SL_); @@ -415,14 +415,14 @@ static void print_ndtparams(struct rtattr *tpb[]) if (tpb[NDTPA_GC_STALETIME]) { __u64 gc_stale = rta_getattr_u64(tpb[NDTPA_GC_STALETIME]); - print_uint(PRINT_ANY, "gc_stale", "gc_stale %llu ", gc_stale); + print_u64(PRINT_ANY, "gc_stale", "gc_stale %llu ", gc_stale); } if (tpb[NDTPA_DELAY_PROBE_TIME]) { __u64 delay_probe = rta_getattr_u64(tpb[NDTPA_DELAY_PROBE_TIME]); - print_uint(PRINT_ANY, "delay_probe", + print_u64(PRINT_ANY, "delay_probe", "delay_probe %llu ", delay_probe); } @@ -459,14 +459,14 @@ static void print_ndtparams(struct rtattr *tpb[]) if (tpb[NDTPA_ANYCAST_DELAY]) { __u64 anycast_delay = rta_getattr_u64(tpb[NDTPA_ANYCAST_DELAY]); - print_uint(PRINT_ANY, "anycast_delay", + print_u64(PRINT_ANY, "anycast_delay", "anycast_delay %llu ", anycast_delay); } if (tpb[NDTPA_PROXY_DELAY]) { __u64 proxy_delay = rta_getattr_u64(tpb[NDTPA_PROXY_DELAY]); - print_uint(PRINT_ANY, "proxy_delay", + print_u64(PRINT_ANY, "proxy_delay", "proxy_delay %llu ", proxy_delay); } @@ -479,7 +479,7 @@ static void print_ndtparams(struct rtattr *tpb[]) if (tpb[NDTPA_LOCKTIME]) { __u64 locktime = rta_getattr_u64(tpb[NDTPA_LOCKTIME]); - print_uint(PRINT_ANY, "locktime", "locktime %llu ", locktime); + print_u64(PRINT_ANY, "locktime", "locktime %llu ", locktime); } print_string(PRINT_FP, NULL, "%s", _SL_); @@ -490,31 +490,31 @@ static void print_ndtstats(const struct ndt_stats *ndts) print_string(PRINT_FP, NULL, " stats ", NULL); - print_uint(PRINT_ANY, "allocs", "allocs %llu ", ndts->ndts_allocs); - print_uint(PRINT_ANY, "destroys", "destroys %llu ", + print_u64(PRINT_ANY, "allocs", "allocs %llu ", ndts->ndts_allocs); + print_u64(PRINT_ANY, "destroys", "destroys %llu ", ndts->ndts_destroys); - print_uint(PRINT_ANY, "hash_grows", "hash_grows %llu ", + print_u64(PRINT_ANY, "hash_grows", "hash_grows %llu ", ndts->ndts_hash_grows); print_string(PRINT_FP, NULL, "%s ", _SL_); - print_uint(PRINT_ANY, "res_failed", "res_failed %llu ", + print_u64(PRINT_ANY, "res_failed", "res_failed %llu ", ndts->ndts_res_failed); - print_uint(PRINT_ANY, "lookups", "lookups %llu ", ndts->ndts_lookups); - print_uint(PRINT_ANY, "hits", "hits %llu ", ndts->ndts_hits); + print_u64(PRINT_ANY, "lookups", "lookups %llu ", ndts->ndts_lookups); + print_u64(PRINT_ANY, "hits", "hits %llu ", ndts->ndts_hits); print_string(PRINT_FP, NULL, "%s ", _SL_); - print_uint(PRINT_ANY, "rcv_probes_mcast", "rcv_probes_mcast %llu ", + print_u64(PRINT_ANY, "rcv_probes_mcast", "rcv_probes_mcast %llu ", ndts->ndts_rcv_probes_mcast); - print_uint(PRINT_ANY, "rcv_probes_ucast", "rcv_probes_ucast %llu ", + print_u64(PRINT_ANY, "rcv_probes_ucast", "rcv_probes_ucast %llu ", ndts->ndts_rcv_probes_ucast); print_string(PRINT_FP, NULL, "%s ", _SL_); - print_uint(PRINT_ANY, "periodic_gc_runs", "periodic_gc_runs %llu ", + print_u64(PRINT_ANY, "periodic_gc_runs", "periodic_gc_runs %llu ", ndts->ndts_periodic_gc_runs); - print_uint(PRINT_ANY, "forced_gc_runs", "forced_gc_runs %llu ", + print_u64(PRINT_ANY, "forced_gc_runs", "forced_gc_runs %llu ", ndts->ndts_forced_gc_runs); print_string(PRINT_FP, NULL, "%s", _SL_); @@ -607,7 +607,7 @@ static int print_ntable(const struct sockaddr_nl *who, if (tb[NDTA_GC_INTERVAL]) { __u64 gc_int = rta_getattr_u64(tb[NDTA_GC_INTERVAL]); - print_uint(PRINT_ANY, "gc_interval", "gc_int %llu ", gc_int); + print_u64(PRINT_ANY, "gc_interval", "gc_int %llu ", gc_int); } if (ret) diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c index cde9b3d2..46a212c8 100644 --- a/ip/iproute_lwtunnel.c +++ b/ip/iproute_lwtunnel.c @@ -273,7 +273,7 @@ static void print_encap_ip(FILE *fp, struct rtattr *encap) parse_rtattr_nested(tb, LWTUNNEL_IP_MAX, encap); if (tb[LWTUNNEL_IP_ID]) - print_uint(PRINT_ANY, "id", "id %llu ", + print_u64(PRINT_ANY, "id", "id %llu ", ntohll(rta_getattr_u64(tb[LWTUNNEL_IP_ID]))); if (tb[LWTUNNEL_IP_SRC]) @@ -333,7 +333,7 @@ static void print_encap_ip6(FILE *fp, struct rtattr *encap) parse_rtattr_nested(tb, LWTUNNEL_IP6_MAX, encap); if (tb[LWTUNNEL_IP6_ID]) - print_uint(PRINT_ANY, "id", "id %llu ", + print_u64(PRINT_ANY, "id", "id %llu ", ntohll(rta_getattr_u64(tb[LWTUNNEL_IP6_ID]))); if (tb[LWTUNNEL_IP6_SRC]) @@ -347,7 +347,7 @@ static void print_encap_ip6(FILE *fp, struct rtattr *encap) rt_addr_n2a_rta(AF_INET6, tb[LWTUNNEL_IP6_DST])); if (tb[LWTUNNEL_IP6_HOPLIMIT]) - print_uint(PRINT_ANY, "hoplimit", + print_u64(PRINT_ANY, "hoplimit", "hoplimit %u ", rta_getattr_u8(tb[LWTUNNEL_IP6_HOPLIMIT])); diff --git a/ip/iptuntap.c b/ip/iptuntap.c index 6c5a7259..58996e6c 100644 --- a/ip/iptuntap.c +++ b/ip/iptuntap.c @@ -440,10 +440,10 @@ static int print_tuntap(const struct sockaddr_nl *who, "ifname", "%s:", name); print_flags(flags); if (owner != -1) - print_uint(PRINT_ANY, "user", + print_u64(PRINT_ANY, "user", " user %ld", owner); if (group != -1) - print_uint(PRINT_ANY, "group", + print_u64(PRINT_ANY, "group", " group %ld", group); if (show_details) { diff --git a/ip/tcp_metrics.c b/ip/tcp_metrics.c index 72dc980c..ad3d6f36 100644 --- a/ip/tcp_metrics.c +++ b/ip/tcp_metrics.c @@ -139,19 +139,19 @@ static void print_tcp_metrics(struct rtattr *a) print_uint(PRINT_JSON, name, NULL, val); print_string(PRINT_FP, NULL, " %s ", name); - print_uint(PRINT_FP, NULL, "%lu", val); + print_uint(PRINT_FP, NULL, "%u", val); } if (rtt) { print_float(PRINT_JSON, "rtt", NULL, (double)rtt / usec_per_sec); - print_uint(PRINT_FP, NULL, + print_u64(PRINT_FP, NULL, " rtt %luus", rtt); } if (rttvar) { print_float(PRINT_JSON, "rttvar", NULL, (double) rttvar / usec_per_sec); - print_uint(PRINT_FP, NULL, + print_u64(PRINT_FP, NULL, " rttvar %luus", rttvar); } } diff --git a/lib/json_print.c b/lib/json_print.c index bda72933..5dc41bfa 100644 --- a/lib/json_print.c +++ b/lib/json_print.c @@ -116,8 +116,11 @@ void close_json_array(enum output_type type, const char *str) } \ } _PRINT_FUNC(int, int); +_PRINT_FUNC(s64, int64_t); _PRINT_FUNC(hu, unsigned short); -_PRINT_FUNC(uint, uint64_t); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(u64, uint64_t); +_PRINT_FUNC(luint, unsigned long int); _PRINT_FUNC(lluint, unsigned long long int); _PRINT_FUNC(float, double); #undef _PRINT_FUNC diff --git a/lib/json_writer.c b/lib/json_writer.c index 0ad04218..aa9ce1c6 100644 --- a/lib/json_writer.c +++ b/lib/json_writer.c @@ -220,7 +220,12 @@ void jsonw_hu(json_writer_t *self, unsigned short num) jsonw_printf(self, "%hu", num); } -void jsonw_uint(json_writer_t *self, uint64_t num) +void jsonw_uint(json_writer_t *self, unsigned int num) +{ + jsonw_printf(self, "%u", num); +} + +void jsonw_u64(json_writer_t *self, uint64_t num) { jsonw_printf(self, "%"PRIu64, num); } @@ -230,12 +235,22 @@ void jsonw_xint(json_writer_t *self, uint64_t num) jsonw_printf(self, "%"PRIx64, num); } +void jsonw_luint(json_writer_t *self, unsigned long int num) +{ + jsonw_printf(self, "%lu", num); +} + void jsonw_lluint(json_writer_t *self, unsigned long long int num) { jsonw_printf(self, "%llu", num); } -void jsonw_int(json_writer_t *self, int64_t num) +void jsonw_int(json_writer_t *self, int num) +{ + jsonw_printf(self, "%d", num); +} + +void jsonw_s64(json_writer_t *self, int64_t num) { jsonw_printf(self, "%"PRId64, num); } @@ -268,12 +283,18 @@ void jsonw_float_field_fmt(json_writer_t *self, jsonw_float_fmt(self, fmt, val); } -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num) { jsonw_name(self, prop); jsonw_uint(self, num); } +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num) +{ + jsonw_name(self, prop); + jsonw_u64(self, num); +} + void jsonw_xint_field(json_writer_t *self, const char *prop, uint64_t num) { jsonw_name(self, prop); @@ -286,6 +307,14 @@ void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) jsonw_hu(self, num); } +void jsonw_luint_field(json_writer_t *self, + const char *prop, + unsigned long int num) +{ + jsonw_name(self, prop); + jsonw_luint(self, num); +} + void jsonw_lluint_field(json_writer_t *self, const char *prop, unsigned long long int num) @@ -294,12 +323,18 @@ void jsonw_lluint_field(json_writer_t *self, jsonw_lluint(self, num); } -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num) +void jsonw_int_field(json_writer_t *self, const char *prop, int num) { jsonw_name(self, prop); jsonw_int(self, num); } +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num) +{ + jsonw_name(self, prop); + jsonw_s64(self, num); +} + void jsonw_null_field(json_writer_t *self, const char *prop) { jsonw_name(self, prop); From 3b07981a27247fd321dedd5aeeaac8a19007f70f Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Tue, 1 May 2018 15:43:07 +0300 Subject: [PATCH 3/5] README: update libdb build dependency information Debian does not distribute libdb4.x-dev for quite some time now. Current stable carries libdb5.3-dev. Update the wording accordingly. Signed-off-by: Baruch Siach Signed-off-by: Stephen Hemminger --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index f66fd5fa..bc82187c 100644 --- a/README +++ b/README @@ -16,8 +16,8 @@ How to compile this. -------------------- 1. libdbm -arpd needs to have the db4 development libraries. For Debian -users this is the package with a name like libdb4.x-dev. +arpd needs to have the berkeleydb development libraries. For Debian +users this is the package with a name like libdbX.X-dev. DBM_INCLUDE points to the directory with db_185.h which is the include file used by arpd to get to the old format Berkeley database routines. Often this is in the db-devel package. From 37bf5c6fcb88d2e21bbf3b2b021d52a04fd1a18a Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Tue, 1 May 2018 15:43:08 +0300 Subject: [PATCH 4/5] arpd: remove pthread dependency Explicit link with pthread is not needed when linking dynamically. Even static link with recent libdb does not pull in the code that uses pthread. Finally, the configure check introduced in commit a25df4887d7 (configure: Check for Berkeley DB for arpd compilation) does not add -lpthread to its link command. This change allows arpd build with toolchains that do not provide threads support. Signed-off-by: Baruch Siach Signed-off-by: Stephen Hemminger --- misc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/Makefile b/misc/Makefile index 34ef6b21..b2dd6b26 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -25,7 +25,7 @@ rtacct: rtacct.c $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o rtacct rtacct.c $(LDLIBS) -lm arpd: arpd.c - $(QUIET_CC)$(CC) $(CFLAGS) -I$(DBM_INCLUDE) $(LDFLAGS) -o arpd arpd.c $(LDLIBS) -ldb -lpthread + $(QUIET_CC)$(CC) $(CFLAGS) -I$(DBM_INCLUDE) $(LDFLAGS) -o arpd arpd.c $(LDLIBS) -ldb ssfilter.c: ssfilter.y $(QUIET_YACC)bison ssfilter.y -o ssfilter.c From c0ec7c9f875cd0d385497bc5e18f0a32e7887663 Mon Sep 17 00:00:00 2001 From: Ido Schimmel Date: Tue, 1 May 2018 16:16:35 +0300 Subject: [PATCH 5/5] iproute: Parse last nexthop in a multipath route Continue parsing a multipath payload as long as another nexthop can fit in the payload. # ip route add 192.0.2.0/24 nexthop dev dummy0 nexthop dev dummy1 Before: # ip route show 192.0.2.0/24 192.0.2.0/24 nexthop dev dummy0 weight 1 After: # ip route show 192.0.2.0/24 192.0.2.0/24 nexthop dev dummy0 weight 1 nexthop dev dummy1 weight 1 Fixes: f48e14880a0e ("iproute: refactor multipath print") Signed-off-by: Ido Schimmel Acked-by: David Ahern Signed-off-by: Stephen Hemminger --- ip/iproute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ip/iproute.c b/ip/iproute.c index 44351bc5..56dd9f25 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -650,7 +650,7 @@ static void print_rta_multipath(FILE *fp, const struct rtmsg *r, int len = RTA_PAYLOAD(rta); int first = 1; - while (len > sizeof(*nh)) { + while (len >= sizeof(*nh)) { struct rtattr *tb[RTA_MAX + 1]; if (nh->rtnh_len > len)