diff --git a/package/gluon-mesh-babel/src/respondd.c b/package/gluon-mesh-babel/src/respondd.c
index 124500a2e5e6e203c627d9e1c2f82bd8d83d1f68..94fc3f871df934e145ee85e1bb9488caf5414359 100644
--- a/package/gluon-mesh-babel/src/respondd.c
+++ b/package/gluon-mesh-babel/src/respondd.c
@@ -156,14 +156,6 @@ free:
 	return retval;
 }
 
-static bool interface_file_exists(const char *ifname, const char *name) {
-	const char *format = "/sys/class/net/%s/%s";
-	char path[strlen(format) + strlen(ifname) + strlen(name)+1];
-	snprintf(path, sizeof(path), format, ifname, name);
-
-	return !access(path, F_OK);
-}
-
 static void mesh_add_if(const char *ifname, struct json_object *wireless,
 		struct json_object *tunnel, struct json_object *other) {
 	char str_ip[INET6_ADDRSTRLEN];
@@ -173,13 +165,23 @@ static void mesh_add_if(const char *ifname, struct json_object *wireless,
 
 	struct json_object *address = json_object_new_string(str_ip);
 
-	if (interface_file_exists(ifname, "wireless"))
+	/* In case of VLAN and bridge interfaces, we want the lower interface
+	 * to determine the interface type (but not for the interface address) */
+	char lowername[IF_NAMESIZE];
+	gluonutil_get_interface_lower(lowername, ifname);
+
+	switch(gluonutil_get_interface_type(lowername)) {
+	case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
 		json_object_array_add(wireless, address);
-	else if (interface_file_exists(ifname, "tun_flags"))
+		break;
+
+	case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
 		json_object_array_add(tunnel, address);
-	else
-		json_object_array_add(other, address);
+		break;
 
+	default:
+		json_object_array_add(other, address);
+	}
 }
 
 
@@ -282,6 +284,13 @@ static void blobmsg_handle_list(struct blob_attr *attr, int len, bool array, str
 	free(proto);
 }
 
+static void add_if_not_empty(struct json_object *obj, const char *key, struct json_object *val) {
+	if (json_object_array_length(val))
+		json_object_object_add(obj, key, val);
+	else
+		json_object_put(val);
+}
+
 static void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg) {
 	struct json_object *ret = json_object_new_object();
 	struct json_object *wireless = json_object_new_array();
@@ -303,9 +312,9 @@ static void receive_call_result_data(struct ubus_request *req, int type, struct
 
 	blobmsg_handle_list(blobmsg_data(msg), blobmsg_data_len(msg), false, wireless, tunnel, other);
 
-	json_object_object_add(ret, "wireless", wireless);
-	json_object_object_add(ret, "tunnel", tunnel);
-	json_object_object_add(ret, "other", other);
+	add_if_not_empty(ret, "wireless", wireless);
+	add_if_not_empty(ret, "tunnel", tunnel);
+	add_if_not_empty(ret, "other", other);
 
 	*((struct json_object**)(req->priv)) = ret;
 }
diff --git a/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c b/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
index 36e330f9e7958bb5c63f39190da330d7214047d5..268a3623e77b011cd9237fec6858a56e9bd31cd1 100644
--- a/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
+++ b/package/gluon-mesh-batman-adv/src/respondd-nodeinfo.c
@@ -131,35 +131,23 @@ static void mesh_add_subif(const char *ifname, struct json_object *wireless,
 			   struct json_object *tunnel, struct json_object *other) {
 	struct json_object *address = gluonutil_wrap_and_free_string(gluonutil_get_interface_address(ifname));
 
-	char lowername[IFNAMSIZ];
-	strncpy(lowername, ifname, sizeof(lowername)-1);
-	lowername[sizeof(lowername)-1] = 0;
-
-	const char *format = "/sys/class/net/%s/lower_*";
-	char pattern[strlen(format) + IFNAMSIZ];
-
 	/* In case of VLAN and bridge interfaces, we want the lower interface
 	 * to determine the interface type (but not for the interface address) */
-	while (true) {
-		snprintf(pattern, sizeof(pattern), format, lowername);
-		size_t pattern_len = strlen(pattern);
-
-		glob_t lower;
-		if (glob(pattern, GLOB_NOSORT, NULL, &lower))
-			break;
+	char lowername[IF_NAMESIZE];
+	gluonutil_get_interface_lower(lowername, ifname);
 
-		strncpy(lowername, lower.gl_pathv[0] + pattern_len - 1, sizeof(lowername)-1);
-
-		globfree(&lower);
-	}
-
-	if (interface_file_exists(lowername, "wireless"))
+	switch(gluonutil_get_interface_type(lowername)) {
+	case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
 		json_object_array_add(wireless, address);
-	else if (interface_file_exists(lowername, "tun_flags"))
+		break;
+
+	case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
 		json_object_array_add(tunnel, address);
-	else
-		json_object_array_add(other, address);
+		break;
 
+	default:
+		json_object_array_add(other, address);
+	}
 }
 
 static struct json_object * get_mesh_subifs(const char *ifname) {