gluon-mesh-{batman-adv,babel}: respondd: use libgluonutil to determine interface type

Also make babel match batman-adv and only emit the wireless/tunnel/other
fields when they are non-empty.

Fixes: #1783
This commit is contained in:
Matthias Schiffer 2020-06-01 21:44:05 +02:00
parent 41b3c91284
commit 3fda210f85
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
2 changed files with 38 additions and 41 deletions

View File

@ -156,14 +156,6 @@ free:
return retval; 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, static void mesh_add_if(const char *ifname, struct json_object *wireless,
struct json_object *tunnel, struct json_object *other) { struct json_object *tunnel, struct json_object *other) {
char str_ip[INET6_ADDRSTRLEN]; 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); 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
json_object_array_add(wireless, address); * to determine the interface type (but not for the interface address) */
else if (interface_file_exists(ifname, "tun_flags")) char lowername[IF_NAMESIZE];
json_object_array_add(tunnel, address); gluonutil_get_interface_lower(lowername, ifname);
else
json_object_array_add(other, address);
switch(gluonutil_get_interface_type(lowername)) {
case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
json_object_array_add(wireless, address);
break;
case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
json_object_array_add(tunnel, 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); 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) { 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 *ret = json_object_new_object();
struct json_object *wireless = json_object_new_array(); 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); blobmsg_handle_list(blobmsg_data(msg), blobmsg_data_len(msg), false, wireless, tunnel, other);
json_object_object_add(ret, "wireless", wireless); add_if_not_empty(ret, "wireless", wireless);
json_object_object_add(ret, "tunnel", tunnel); add_if_not_empty(ret, "tunnel", tunnel);
json_object_object_add(ret, "other", other); add_if_not_empty(ret, "other", other);
*((struct json_object**)(req->priv)) = ret; *((struct json_object**)(req->priv)) = ret;
} }

View File

@ -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 *tunnel, struct json_object *other) {
struct json_object *address = gluonutil_wrap_and_free_string(gluonutil_get_interface_address(ifname)); 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 /* In case of VLAN and bridge interfaces, we want the lower interface
* to determine the interface type (but not for the interface address) */ * to determine the interface type (but not for the interface address) */
while (true) { char lowername[IF_NAMESIZE];
snprintf(pattern, sizeof(pattern), format, lowername); gluonutil_get_interface_lower(lowername, ifname);
size_t pattern_len = strlen(pattern);
glob_t lower; switch(gluonutil_get_interface_type(lowername)) {
if (glob(pattern, GLOB_NOSORT, NULL, &lower)) case GLUONUTIL_INTERFACE_TYPE_WIRELESS:
json_object_array_add(wireless, address);
break; break;
strncpy(lowername, lower.gl_pathv[0] + pattern_len - 1, sizeof(lowername)-1); case GLUONUTIL_INTERFACE_TYPE_TUNNEL:
globfree(&lower);
}
if (interface_file_exists(lowername, "wireless"))
json_object_array_add(wireless, address);
else if (interface_file_exists(lowername, "tun_flags"))
json_object_array_add(tunnel, address); json_object_array_add(tunnel, address);
else break;
json_object_array_add(other, address);
default:
json_object_array_add(other, address);
}
} }
static struct json_object * get_mesh_subifs(const char *ifname) { static struct json_object * get_mesh_subifs(const char *ifname) {