diff mbox series

[iproute2-next,2/4] iptunnel: Use do_each_proc_net_dev()

Message ID 1517428189-29279-3-git-send-email-serhe.popovych@gmail.com
State Changes Requested, archived
Delegated to: David Ahern
Headers show
Series ip: Introduce and use helper to read /proc/net/dev | expand

Commit Message

Serhey Popovych Jan. 31, 2018, 7:49 p.m. UTC
Now we have helper to iterate over entries in /proc/net/dev we can
simplify and cleanup do_tunnels_list() in ip/iptunnel.c.

While there replace printf("\n") with fputc('\n', stdout) and printf()
with fputs() where string does not contain format specifiers.

Also move tunnel parameter matching to new static helper function to
match ip6tunnel.c.

Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
---
 ip/iptunnel.c |  102 ++++++++++++++++++++++++++-------------------------------
 1 file changed, 47 insertions(+), 55 deletions(-)
diff mbox series

Patch

diff --git a/ip/iptunnel.c b/ip/iptunnel.c
index 0aa3b33..b60a7b7 100644
--- a/ip/iptunnel.c
+++ b/ip/iptunnel.c
@@ -373,66 +373,58 @@  static void print_tunnel(struct ip_tunnel_parm *p)
 		printf("%s  Checksum output packets.", _SL_);
 }
 
-static int do_tunnels_list(struct ip_tunnel_parm *p)
+/*
+ * @p1: user specified parameter
+ * @p2: database entry
+ */
+static int ip_tunnel_parm_match(const struct ip_tunnel_parm *p1,
+				const struct ip_tunnel_parm *p2)
 {
-	char buf[512];
-	int err = -1;
-	FILE *fp = fopen("/proc/net/dev", "r");
+	return ((!p1->link || p1->link == p2->link) &&
+		(!p1->name[0] || strcmp(p1->name, p2->name) == 0) &&
+		(!p1->iph.daddr || p1->iph.daddr == p2->iph.daddr) &&
+		(!p1->iph.saddr || p1->iph.saddr == p2->iph.saddr) &&
+		(!p1->i_key || p1->i_key == p2->i_key));
+}
 
-	if (fp == NULL) {
-		perror("fopen");
-		return -1;
-	}
+static pnd_result_t do_tunnels_list(char *name, char *stats, void *arg)
+{
+	struct ip_tunnel_parm p1, *p = arg;
+	int index, type;
+
+	if (p->name[0] && strcmp(p->name, name))
+		return PND_NEXT;
 
-	/* skip header lines */
-	if (!fgets(buf, sizeof(buf), fp) ||
-	    !fgets(buf, sizeof(buf), fp)) {
-		fprintf(stderr, "/proc/net/dev read error\n");
-		goto end;
+	index = ll_name_to_index(name);
+	if (index <= 0)
+		return PND_NEXT;
+
+	type = ll_index_to_type(index);
+	if (type == -1) {
+		fprintf(stderr, "Failed to get type of \"%s\"\n", name);
+		return PND_NEXT;
 	}
 
-	while (fgets(buf, sizeof(buf), fp) != NULL) {
-		char name[IFNAMSIZ];
-		int index, type;
-		struct ip_tunnel_parm p1 = {};
-		char *ptr;
-
-		buf[sizeof(buf) - 1] = 0;
-		ptr = strchr(buf, ':');
-		if (ptr == NULL ||
-		    (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
-			fprintf(stderr, "Wrong format for /proc/net/dev. Giving up.\n");
-			goto end;
-		}
-		if (p->name[0] && strcmp(p->name, name))
-			continue;
-		index = ll_name_to_index(name);
-		if (index == 0)
-			continue;
-		type = ll_index_to_type(index);
-		if (type == -1) {
-			fprintf(stderr, "Failed to get type of \"%s\"\n", name);
-			continue;
-		}
-		if (type != ARPHRD_TUNNEL && type != ARPHRD_IPGRE && type != ARPHRD_SIT)
-			continue;
-		if (tnl_get_ioctl(name, &p1))
-			continue;
-		if ((p->link && p1.link != p->link) ||
-		    (p->name[0] && strcmp(p1.name, p->name)) ||
-		    (p->iph.daddr && p1.iph.daddr != p->iph.daddr) ||
-		    (p->iph.saddr && p1.iph.saddr != p->iph.saddr) ||
-		    (p->i_key && p1.i_key != p->i_key))
-			continue;
-		print_tunnel(&p1);
-		if (show_stats)
-			tnl_print_stats(ptr);
-		printf("\n");
+	switch (type) {
+	case ARPHRD_TUNNEL:
+	case ARPHRD_IPGRE:
+	case ARPHRD_SIT:
+		return PND_NEXT;
 	}
-	err = 0;
- end:
-	fclose(fp);
-	return err;
+
+	memset(&p1, 0, sizeof(p1));
+	if (tnl_get_ioctl(name, &p1))
+		return PND_NEXT;
+
+	if (!ip_tunnel_parm_match(p, &p1))
+		return PND_NEXT;
+
+	print_tunnel(&p1);
+	if (show_stats)
+		tnl_print_stats(stats);
+	fputc('\n', stdout);
+
+	return PND_NEXT;
 }
 
 static int do_show(int argc, char **argv)
@@ -446,7 +438,7 @@  static int do_show(int argc, char **argv)
 
 	basedev = tnl_defname(&p);
 	if (!basedev)
-		return do_tunnels_list(&p);
+		return do_each_proc_net_dev(do_tunnels_list, &p);
 
 	if (tnl_get_ioctl(p.name[0] ? p.name : basedev, &p))
 		return -1;