print_uint issues
Subsystems (3)
cover print_uint issues
There are several issues with implicit conversions in json handling print_uint function which were first seen and patches proposed by Alin Nastac. This is my swipe at them.
Final version will be some combination of his patches and some of this.
Spotted some more changing print_uint into a macro, but that got ugly.
Stephen Hemminger (5):
ipneigh: fix missing format specifier
json: make json print_uint take unsigned int
flower: use 16 bit format where possible
tcp_metrics: use print_luint
mroute: use print_uint64
include/json_print.h | 16 +++++++++++++--- ip/ipmroute.c | 10 +++++----- ip/ipneigh.c | 2 +- ip/tcp_metrics.c | 2 +- lib/json_print.c | 33 ++++++++++++++++++++++++++++++--- tc/f_flower.c | 2 +- 6 files changed, 51 insertions(+), 14 deletions(-)
Signature · 1 line
2.17.0
RFC 1/5 ipneigh: fix missing format specifier
--- ip/ipneigh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ip/ipneigh.c +1 -1
@@ -204,7 +204,7 @@ static void print_cacheinfo(const struct nda_cacheinfo *ci)print_uint (PRINT_ANY ,"used" ," used %u" , ci->ndm_used / hz);print_uint (PRINT_ANY ,"confirmed" ,"/%u" , ci->ndm_confirmed / hz); -print_uint (PRINT_ANY ,"updated" ,"/u" , ci->ndm_updated / hz); +print_uint (PRINT_ANY ,"updated" ,"/%u" , ci->ndm_updated / hz); }static void print_neigh_state (unsigned int nud)
Signature · 1 line
2.17.0
RFC 2/5 json: make json print_uint take unsigned int
In reply to Stephen HemmingerIt is a source of possible bugs that json print handler print_uint was doing implict conversion to 64 bit than printing with the format specifier which often had only a unsigned format value.
Instead introduce wider range of print stubs for unsigned integer types. No color versions of these necessary.
--- include/json_print.h | 16 +++++++++++++--- lib/json_print.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-)
include/json_print.h +13 -3
@@ -59,12 +59,22 @@ _PRINT_FUNC(int, int);_PRINT_FUNC (bool, bool); _PRINT_FUNC(null, const char*); _PRINT_FUNC(string, const char*); -_PRINT_FUNC (uint, uint64_t); -_PRINT_FUNC(hu, unsigned short); _PRINT_FUNC(hex, unsigned int); _PRINT_FUNC(0xhex, unsigned int); -_PRINT_FUNC(lluint, unsigned long long int);_PRINT_FUNC (float, double);#undef _PRINT_FUNC +#define _PRINT_FUNC (type_name, type) \ + void print_##type_name(enum output_type t, \ + const char *key, \ + const char *fmt, \ + type value); + +_PRINT_FUNC(hu, unsigned short); +_PRINT_FUNC(uint, unsigned int); +_PRINT_FUNC(luint, unsigned long int); +_PRINT_FUNC (uint64, uint64_t); +_PRINT_FUNC(lluint, unsigned long long int); +#undef _PRINT_FUNC +#endif /* _JSON_PRINT_H_ */
lib/json_print.c +30 -3
@@ -116,12 +116,39 @@ void close_json_array(enum output_type type, const char *str) } \ }_PRINT_FUNC (int, int); -_PRINT_FUNC(hu, unsigned short); -_PRINT_FUNC (uint, uint64_t); -_PRINT_FUNC(lluint, unsigned long long int);_PRINT_FUNC (float, double);#undef _PRINT_FUNC +static void json_print_uint64 (const char *key,uint64_t val) +{ +if (key) +jsonw_uint_field (_jw, key, val); +else +jsonw_uint (_jw, val); +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +#define PRINT_FUNC (type_name, type) \ + void print_##type_name(enum output_type t, \ + const char *key, \ + const char *fmt, \ + type value) \ + { \ + if (_IS_JSON_CONTEXT(t)) \ + json_print_uint64(key, value); \ + else if (_IS_FP_CONTEXT(t)) \ + printf(fmt, value); \ + } + +PRINT_FUNC(hu, unsigned short); +PRINT_FUNC(uint, unsigned int); +PRINT_FUNC(lluint, unsigned long long int); +PRINT_FUNC(luint, unsigned long int); +PRINT_FUNC (uint64, uint64_t); +#undef PRINT_FUNC +#pragma GCC diagnostic pop + void print_color_string(enum output_type type, enum color_attr color, const char *key,
Signature · 1 line
2.17.0
RFC 3/5 flower: use 16 bit format where possible
In reply to Stephen HemmingerShould use print_hu not print_uint for 16 bit value.
--- tc/f_flower.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tc/f_flower.c +1 -1
@@ -1234,7 +1234,7 @@ static void flower_print_port(char *name, struct rtattr *attr)return ;sprintf (namefrm,"\n %s %%u" , name); -print_uint (PRINT_ANY , name, namefrm,rta_getattr_be16 (attr)); +print_hu (PRINT_ANY , name, namefrm,rta_getattr_be16 (attr)); } static void flower_print_tcp_flags(char *name, struct rtattr *flags_attr,
Signature · 1 line
2.17.0
RFC 4/5 tcp_metrics: use print_luint
In reply to Stephen HemmingerMetrics are long unsigned, so use correct print function.
--- ip/tcp_metrics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
ip/tcp_metrics.c +1 -1
@@ -139,7 +139,7 @@ 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_luint (PRINT_FP ,NULL ,"%lu" , val); }if (rtt) {
Signature · 1 line
2.17.0
RFC 5/5 mroute: use print_uint64
In reply to Stephen HemmingerThe values from multicast stats are 64 bit always.
--- ip/ipmroute.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
ip/ipmroute.c +5 -5
@@ -182,14 +182,14 @@ 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_uint64 (PRINT_ANY ,"packets" ," %" PRIu64" packets," , mfcs->mfcs_packets); -print_uint (PRINT_ANY ,"bytes" ," %" PRIu64" bytes" , mfcs->mfcs_bytes); +print_uint64 (PRINT_ANY ,"bytes" ," %" PRIu64" bytes" , mfcs->mfcs_bytes);if (mfcs->mfcs_wrong_if) -print_uint (PRINT_ANY ,"wrong_if" , -", %" PRIu64" arrived on wrong iif." , - mfcs->mfcs_wrong_if); +print_uint64 (PRINT_ANY ,"wrong_if" , +", %" PRIu64" arrived on wrong iif." , + mfcs->mfcs_wrong_if); }if (show_stats && tb[RTA_EXPIRES ]) {
Signature · 1 line
2.17.0