Skip to contentSkip to conversation

print_uint issues

RFC New Stephen Hemminger 1 participant 6 messages Apr 20, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

RFC 1/5 ipneigh: fix missing format specifier

---
 ip/ipneigh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
ip/ipneigh.c +1 -1
index 4748381701e4..bd6e5c5e18ca 100644
@@ -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
#2 lore raw

RFC 2/5 json: make json print_uint take unsigned int

In reply to Stephen Hemminger

It 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
index 2ca7830adbd6..3d400ecf8f50 100644
@@ -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
index bda7293350c3..696d8c01d3e6 100644
@@ -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
#3 lore raw

RFC 3/5 flower: use 16 bit format where possible

In reply to Stephen Hemminger

Should 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
index 9d4bfd2f808b..ba8eb66cdd11 100644
@@ -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
#4 lore raw

RFC 4/5 tcp_metrics: use print_luint

In reply to Stephen Hemminger

Metrics 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
index 72dc980c92a6..3b82a4e1d2f2 100644
@@ -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
#5 lore raw

RFC 5/5 mroute: use print_uint64

In reply to Stephen Hemminger

The values from multicast stats are 64 bit always.

---
 ip/ipmroute.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
ip/ipmroute.c +5 -5
index 59c5b7718e18..eb6b2816324f 100644
@@ -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