Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 101 additions & 38 deletions package/gluon-mesh-batman-adv/src/respondd-neighbours.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "respondd-common.h"

#include <batadv-genl.h>
#include <libgluonutil.h>

#include <json-c/json.h>

Expand Down Expand Up @@ -44,28 +43,71 @@ static struct json_object * ifnames2addrs(struct json_object *interfaces) {
return ret;
}

static const enum batadv_nl_attrs parse_orig_list_mandatory[] = {
/* Batman IV mandatory attrs */
static const enum batadv_nl_attrs parse_orig_list_mandatory_batadv_iv[] = {
BATADV_ATTR_ORIG_ADDRESS,
BATADV_ATTR_NEIGH_ADDRESS,
BATADV_ATTR_TQ,
BATADV_ATTR_HARD_IFINDEX,
BATADV_ATTR_LAST_SEEN_MSECS,
};

static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg)
/* Batman V mandatory attrs */
static const enum batadv_nl_attrs parse_neigh_list_mandatory_batadv_v[] = {
BATADV_ATTR_NEIGH_ADDRESS,
BATADV_ATTR_THROUGHPUT,
BATADV_ATTR_HARD_IFINDEX,
BATADV_ATTR_LAST_SEEN_MSECS,
};

static int add_neighbour(struct neigh_netlink_opts *opts, struct nlattr **attrs,
uint8_t *mac, const char *metric_name, struct json_object *metric_value)
{
uint32_t hardif;
uint32_t lastseen;
char ifname_buf[IF_NAMESIZE], *ifname;
char mac1[18];

hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]);
lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);

ifname = if_indextoname(hardif, ifname_buf);
if (!ifname) {
json_object_put(metric_value);
return NL_OK;
}

sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

struct json_object *obj = json_object_new_object();
if (!obj) {
json_object_put(metric_value);
return NL_OK;
}

struct json_object *interface;
if (!json_object_object_get_ex(opts->interfaces, ifname, &interface)) {
interface = json_object_new_object();
json_object_object_add(opts->interfaces, ifname, interface);
}

json_object_object_add(obj, metric_name, metric_value);
json_object_object_add(obj, "lastseen", json_object_new_double(lastseen / 1000.));
json_object_object_add(obj, "best", json_object_new_boolean(nla_get_flag(attrs[BATADV_ATTR_FLAG_BEST])));
json_object_object_add(interface, mac1, obj);

return NL_OK;
}

static int parse_orig_list_netlink_cb_batadv_iv(struct nl_msg *msg, void *arg)
{
struct nlattr *attrs[BATADV_ATTR_MAX+1];
struct nlmsghdr *nlh = nlmsg_hdr(msg);
struct batadv_nlquery_opts *query_opts = arg;
struct genlmsghdr *ghdr;
uint8_t *orig;
uint8_t *dest;
uint8_t tq;
uint32_t hardif;
uint32_t lastseen;
char ifname_buf[IF_NAMESIZE], *ifname;
uint8_t *mac;
struct neigh_netlink_opts *opts;
char mac1[18];

opts = batadv_container_of(query_opts, struct neigh_netlink_opts,
query_opts);
Expand All @@ -82,42 +124,50 @@ static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg)
genlmsg_len(ghdr), batadv_genl_policy))
return NL_OK;

if (batadv_genl_missing_attrs(attrs, parse_orig_list_mandatory,
BATADV_ARRAY_SIZE(parse_orig_list_mandatory)))
if (batadv_genl_missing_attrs(attrs, parse_orig_list_mandatory_batadv_iv,
BATADV_ARRAY_SIZE(parse_orig_list_mandatory_batadv_iv)))
return NL_OK;

orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
dest = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]);
tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);
hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]);
lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]);

if (memcmp(orig, dest, 6) != 0)
mac = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
if (memcmp(mac, nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]), 6) != 0)
return NL_OK;

Comment thread
grische marked this conversation as resolved.
ifname = if_indextoname(hardif, ifname_buf);
if (!ifname)
return add_neighbour(opts, attrs, mac, "tq",
json_object_new_int(nla_get_u8(attrs[BATADV_ATTR_TQ])));
}

static int parse_neigh_list_netlink_cb_batadv_v(struct nl_msg *msg, void *arg)
{
struct nlattr *attrs[BATADV_ATTR_MAX+1];
struct nlmsghdr *nlh = nlmsg_hdr(msg);
struct batadv_nlquery_opts *query_opts = arg;
struct genlmsghdr *ghdr;
uint8_t *mac;
struct neigh_netlink_opts *opts;

opts = batadv_container_of(query_opts, struct neigh_netlink_opts,
query_opts);

if (!genlmsg_valid_hdr(nlh, 0))
return NL_OK;

sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x",
orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]);
ghdr = nlmsg_data(nlh);

struct json_object *obj = json_object_new_object();
if (!obj)
if (ghdr->cmd != BATADV_CMD_GET_NEIGHBORS)
return NL_OK;

struct json_object *interface;
if (!json_object_object_get_ex(opts->interfaces, ifname, &interface)) {
interface = json_object_new_object();
json_object_object_add(opts->interfaces, ifname, interface);
}
if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
genlmsg_len(ghdr), batadv_genl_policy))
return NL_OK;

json_object_object_add(obj, "tq", json_object_new_int(tq));
json_object_object_add(obj, "lastseen", json_object_new_double(lastseen / 1000.));
json_object_object_add(obj, "best", json_object_new_boolean(nla_get_flag(attrs[BATADV_ATTR_FLAG_BEST])));
json_object_object_add(interface, mac1, obj);
if (batadv_genl_missing_attrs(attrs, parse_neigh_list_mandatory_batadv_v,
BATADV_ARRAY_SIZE(parse_neigh_list_mandatory_batadv_v)))
return NL_OK;

return NL_OK;
mac = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]);

return add_neighbour(opts, attrs, mac, "throughput",
json_object_new_int64(nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT])));
}

static struct json_object * get_batadv(void) {
Expand All @@ -127,14 +177,27 @@ static struct json_object * get_batadv(void) {
},
};
int ret;
enum batadv_algo algo;

opts.interfaces = json_object_new_object();
if (!opts.interfaces)
return NULL;

ret = batadv_genl_query("bat0", BATADV_CMD_GET_ORIGINATORS,
parse_orig_list_netlink_cb, NLM_F_DUMP,
&opts.query_opts);
if (batadv_genl_get_algo("bat0", &algo) < 0) {
json_object_put(opts.interfaces);
return NULL;
}

if (algo == BATADV_ALGO_BATMAN_V) {
ret = batadv_genl_query("bat0", BATADV_CMD_GET_NEIGHBORS,
parse_neigh_list_netlink_cb_batadv_v, NLM_F_DUMP,
&opts.query_opts);
} else {
ret = batadv_genl_query("bat0", BATADV_CMD_GET_ORIGINATORS,
Comment thread
grische marked this conversation as resolved.
parse_orig_list_netlink_cb_batadv_iv, NLM_F_DUMP,
&opts.query_opts);
}

if (ret < 0) {
json_object_put(opts.interfaces);
return NULL;
Expand Down
34 changes: 27 additions & 7 deletions package/gluon-mesh-batman-adv/src/respondd-statistics.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,23 @@ struct clients_netlink_opts {

struct gw_netlink_opts {
struct json_object *obj;
enum batadv_algo algo;
struct batadv_nlquery_opts query_opts;
};


static const enum batadv_nl_attrs gateways_mandatory[] = {
static const enum batadv_nl_attrs gateways_mandatory_batadv_iv[] = {
BATADV_ATTR_ORIG_ADDRESS,
BATADV_ATTR_ROUTER,
BATADV_ATTR_TQ,
};

static const enum batadv_nl_attrs gateways_mandatory_batadv_v[] = {
BATADV_ATTR_ORIG_ADDRESS,
BATADV_ATTR_ROUTER,
BATADV_ATTR_THROUGHPUT,
};

static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg)
{
struct nlattr *attrs[BATADV_ATTR_MAX+1];
Expand All @@ -52,7 +59,6 @@ static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg)
struct genlmsghdr *ghdr;
uint8_t *orig;
uint8_t *router;
uint8_t tq;
struct gw_netlink_opts *opts;
char addr[18];

Expand All @@ -71,22 +77,34 @@ static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg)
genlmsg_len(ghdr), batadv_genl_policy))
return NL_OK;

if (batadv_genl_missing_attrs(attrs, gateways_mandatory,
BATADV_ARRAY_SIZE(gateways_mandatory)))
return NL_OK;
if (opts->algo == BATADV_ALGO_BATMAN_V) {
if (batadv_genl_missing_attrs(attrs, gateways_mandatory_batadv_v,
BATADV_ARRAY_SIZE(gateways_mandatory_batadv_v)))
return NL_OK;
} else {
if (batadv_genl_missing_attrs(attrs, gateways_mandatory_batadv_iv,
BATADV_ARRAY_SIZE(gateways_mandatory_batadv_iv)))
return NL_OK;
}

if (!attrs[BATADV_ATTR_FLAG_BEST])
return NL_OK;

orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
router = nla_data(attrs[BATADV_ATTR_ROUTER]);
tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);

sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x",
orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]);

json_object_object_add(opts->obj, "gateway", json_object_new_string(addr));
json_object_object_add(opts->obj, "gateway_tq", json_object_new_int(tq));

if (opts->algo == BATADV_ALGO_BATMAN_V) {
uint32_t throughput = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]);
json_object_object_add(opts->obj, "gateway_throughput", json_object_new_int64(throughput));
} else {
uint8_t tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);
json_object_object_add(opts->obj, "gateway_tq", json_object_new_int(tq));
}

sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x",
router[0], router[1], router[2], router[3], router[4], router[5]);
Expand All @@ -103,6 +121,8 @@ static void add_gateway(struct json_object *obj) {
.err = 0,
},
};
if (batadv_genl_get_algo("bat0", &opts.algo) < 0)
return;

batadv_genl_query("bat0", BATADV_CMD_GET_GATEWAYS,
parse_gw_list_netlink_cb, NLM_F_DUMP,
Expand Down
Loading
Loading