diff --git a/modules b/modules index d586f720..450d8195 100644 --- a/modules +++ b/modules @@ -12,7 +12,7 @@ PACKAGES_GLUON_REPO=git://github.com/freifunk-gluon/packages.git PACKAGES_GLUON_COMMIT=738d8a236583233c0d49bbef73ac9b721534d1fc PACKAGES_ROUTING_REPO=git://github.com/openwrt-routing/packages.git -PACKAGES_ROUTING_COMMIT=a4eae82c155079a4372e4b910ec733f77288b717 +PACKAGES_ROUTING_COMMIT=899235a4a6370e86ad3674c38c3f95d23c8f3dc8 PACKAGES_LUCI_REPO=git://github.com/openwrt/luci.git PACKAGES_LUCI_COMMIT=70a4d43cc895b7d728b4fc201f2b6fd9f4b8aaec diff --git a/package/gluon-mesh-batman-adv-core/Makefile b/package/gluon-mesh-batman-adv-core/Makefile index efcf1698..af5016f7 100644 --- a/package/gluon-mesh-batman-adv-core/Makefile +++ b/package/gluon-mesh-batman-adv-core/Makefile @@ -13,7 +13,7 @@ define Package/gluon-mesh-batman-adv-core SECTION:=gluon CATEGORY:=Gluon TITLE:=Support for batman-adv meshing (core) - DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +firewall +libiwinfo +kmod-dummy + DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +firewall +libiwinfo +kmod-dummy +libnl-tiny endef define Build/Prepare diff --git a/package/gluon-mesh-batman-adv-core/src/Makefile b/package/gluon-mesh-batman-adv-core/src/Makefile index 84d9d48e..75ec0ebe 100644 --- a/package/gluon-mesh-batman-adv-core/src/Makefile +++ b/package/gluon-mesh-batman-adv-core/src/Makefile @@ -2,5 +2,23 @@ all: respondd.so CFLAGS += -Wall -respondd.so: respondd.c +ifeq ($(origin PKG_CONFIG), undefined) + PKG_CONFIG = pkg-config + ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),) + $(error $(PKG_CONFIG) not found) + endif +endif + +ifeq ($(origin LIBNL_CFLAGS) $(origin LIBNL_LDLIBS), undefined undefined) + LIBNL_NAME ?= libnl-tiny + ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_NAME) 2>/dev/null),) + $(error No $(LIBNL_NAME) development libraries found!) + endif + LIBNL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_NAME)) + LIBNL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_NAME)) +endif +CFLAGS += $(LIBNL_CFLAGS) +LDLIBS += $(LIBNL_LDLIBS) + +respondd.so: respondd.c netlink.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -liwinfo -luci diff --git a/package/gluon-mesh-batman-adv-core/src/netlink.c b/package/gluon-mesh-batman-adv-core/src/netlink.c new file mode 100644 index 00000000..41be404b --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/src/netlink.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "netlink.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __maybe_unused +#define __maybe_unused __attribute__((unused)) +#endif + +struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { + [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, + [BATADV_ATTR_ORIG_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 }, + [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, + [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_TQ] = { .type = NLA_U8 }, + [BATADV_ATTR_ROUTER] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, +}; + +int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], + size_t num) +{ + size_t i; + + for (i = 0; i < num; i++) + if (!attrs[mandatory[i]]) + return -EINVAL; + + return 0; +} + +static int nlquery_error_cb(struct sockaddr_nl *nla __maybe_unused, + struct nlmsgerr *nlerr, void *arg) +{ + struct nlquery_opts *query_opts = arg; + + query_opts->err = nlerr->error; + + return NL_STOP; +} + +static int nlquery_stop_cb(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlquery_opts *query_opts = arg; + int *error = nlmsg_data(nlh); + + if (*error) + query_opts->err = *error; + + return NL_STOP; +} + +int netlink_query_common(const char *mesh_iface, uint8_t nl_cmd, + nl_recvmsg_msg_cb_t callback, + struct nlquery_opts *query_opts) +{ + struct nl_sock *sock; + struct nl_msg *msg; + struct nl_cb *cb; + int ifindex; + int family; + int ret; + + query_opts->err = 0; + + sock = nl_socket_alloc(); + if (!sock) + return -ENOMEM; + + ret = genl_connect(sock); + if (ret < 0) { + query_opts->err = ret; + goto err_free_sock; + } + + family = genl_ctrl_resolve(sock, BATADV_NL_NAME); + if (family < 0) { + query_opts->err = -EOPNOTSUPP; + goto err_free_sock; + } + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + query_opts->err = -ENODEV; + goto err_free_sock; + } + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + query_opts->err = -ENOMEM; + goto err_free_sock; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, query_opts); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nlquery_stop_cb, query_opts); + nl_cb_err(cb, NL_CB_CUSTOM, nlquery_error_cb, query_opts); + + msg = nlmsg_alloc(); + if (!msg) { + query_opts->err = -ENOMEM; + goto err_free_cb; + } + + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_DUMP, + nl_cmd, 1); + + nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex); + nl_send_auto_complete(sock, msg); + nlmsg_free(msg); + + nl_recvmsgs(sock, cb); + +err_free_cb: + nl_cb_put(cb); +err_free_sock: + nl_socket_free(sock); + + return query_opts->err; +} diff --git a/package/gluon-mesh-batman-adv-core/src/netlink.h b/package/gluon-mesh-batman-adv-core/src/netlink.h new file mode 100644 index 00000000..9594b213 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/src/netlink.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _BATADV_NETLINK_H +#define _BATADV_NETLINK_H + +#include +#include +#include + +struct nlquery_opts { + int err; +}; + +#ifndef container_of +#define container_of(ptr, type, member) __extension__ ({ \ + const __typeof__(((type *)0)->member) *__pmember = (ptr); \ + (type *)((char *)__pmember - offsetof(type, member)); }) +#endif + +int netlink_query_common(const char *mesh_iface, uint8_t nl_cmd, + nl_recvmsg_msg_cb_t callback, + struct nlquery_opts *query_opts); +int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], + size_t num); + +extern struct nla_policy batadv_netlink_policy[]; + +#endif /* _BATADV_NETLINK_H */ diff --git a/package/gluon-mesh-batman-adv-core/src/respondd.c b/package/gluon-mesh-batman-adv-core/src/respondd.c index ba14997a..04921bde 100644 --- a/package/gluon-mesh-batman-adv-core/src/respondd.c +++ b/package/gluon-mesh-batman-adv-core/src/respondd.c @@ -47,15 +47,34 @@ #include #include +#include #include #include #include +#include "netlink.h" + #define _STRINGIFY(s) #s #define STRINGIFY(s) _STRINGIFY(s) +struct neigh_netlink_opts { + struct json_object *interfaces; + struct nlquery_opts query_opts; +}; + +struct gw_netlink_opts { + struct json_object *obj; + struct nlquery_opts query_opts; +}; + +struct clients_netlink_opts { + size_t total; + size_t wifi; + struct nlquery_opts query_opts; +}; + static struct json_object * get_addresses(void) { FILE *f = fopen("/proc/net/if_inet6", "r"); @@ -223,29 +242,69 @@ static struct json_object * respondd_provider_nodeinfo(void) { return ret; } +static const int gateways_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_ROUTER, +}; + +static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlquery_opts *query_opts = arg; + struct genlmsghdr *ghdr; + uint8_t *orig; + uint8_t *router; + struct gw_netlink_opts *opts; + char addr[18]; + + opts = container_of(query_opts, struct gw_netlink_opts, query_opts); + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_GATEWAYS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; + + if (missing_mandatory_attrs(attrs, gateways_mandatory, + ARRAY_SIZE(gateways_mandatory))) + 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]); + + 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)); + + sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", + router[0], router[1], router[2], router[3], router[4], router[5]); + + json_object_object_add(opts->obj, "gateway_nexthop", json_object_new_string(addr)); + + return NL_STOP; +} static void add_gateway(struct json_object *obj) { - FILE *f = fopen("/sys/kernel/debug/batman_adv/bat0/gateways", "r"); - if (!f) - return; + struct gw_netlink_opts opts = { + .obj = obj, + .query_opts = { + .err = 0, + }, + }; - char *line = NULL; - size_t len = 0; - - while (getline(&line, &len, f) >= 0) { - char addr[18]; - char nexthop[18]; - - if (sscanf(line, "=> %17[0-9a-fA-F:] ( %*u) %17[0-9a-fA-F:]", addr, nexthop) != 2) - continue; - - json_object_object_add(obj, "gateway", json_object_new_string(addr)); - json_object_object_add(obj, "gateway_nexthop", json_object_new_string(nexthop)); - break; - } - - free(line); - fclose(f); + netlink_query_common("bat0", BATADV_CMD_GET_GATEWAYS, + parse_gw_list_netlink_cb, &opts.query_opts); } static inline bool ethtool_ioctl(int fd, struct ifreq *ifr, void *data) { @@ -421,39 +480,68 @@ static void count_stations(size_t *wifi24, size_t *wifi5) { uci_free_context(ctx); } +static const int clients_mandatory[] = { + BATADV_ATTR_TT_FLAGS, +}; + +static int parse_clients_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlquery_opts *query_opts = arg; + struct genlmsghdr *ghdr; + struct clients_netlink_opts *opts; + uint32_t flags; + + opts = container_of(query_opts, struct clients_netlink_opts, query_opts); + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; + + if (missing_mandatory_attrs(attrs, clients_mandatory, + ARRAY_SIZE(clients_mandatory))) + return NL_OK; + + flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]); + + if (flags & BATADV_TT_CLIENT_NOPURGE) + return NL_OK; + + if (flags & BATADV_TT_CLIENT_WIFI) + opts->wifi++; + + opts->total++; + + return NL_OK; +} + static struct json_object * get_clients(void) { - size_t total = 0, wifi = 0, wifi24 = 0, wifi5 = 0; + size_t wifi24 = 0, wifi5 = 0; + struct clients_netlink_opts opts = { + .total = 0, + .wifi = 0, + .query_opts = { + .err = 0, + }, + }; - FILE *f = fopen("/sys/kernel/debug/batman_adv/bat0/transtable_local", "r"); - if (!f) - return NULL; - - char *line = NULL; - size_t len = 0; - - while (getline(&line, &len, f) >= 0) { - char flags[16]; - - if (sscanf(line, " * %*[^[] [%15[^]]]", flags) != 1) - continue; - - if (strchr(flags, 'P')) - continue; - - total++; - - if (strchr(flags, 'W')) - wifi++; - } - - free(line); - fclose(f); + netlink_query_common("bat0", BATADV_CMD_GET_TRANSTABLE_LOCAL, + parse_clients_list_netlink_cb, &opts.query_opts); count_stations(&wifi24, &wifi5); struct json_object *ret = json_object_new_object(); - json_object_object_add(ret, "total", json_object_new_int(total)); - json_object_object_add(ret, "wifi", json_object_new_int(wifi)); + json_object_object_add(ret, "total", json_object_new_int(opts.total)); + json_object_object_add(ret, "wifi", json_object_new_int(opts.wifi)); json_object_object_add(ret, "wifi24", json_object_new_int(wifi24)); json_object_object_add(ret, "wifi5", json_object_new_int(wifi5)); return ret; @@ -492,49 +580,103 @@ static struct json_object * ifnames2addrs(struct json_object *interfaces) { return ret; } -static struct json_object * get_batadv(void) { - FILE *f = fopen("/sys/kernel/debug/batman_adv/bat0/originators", "r"); - if (!f) - return NULL; +static const int parse_orig_list_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_TQ, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_LAST_SEEN_MSECS, +}; - char *line = NULL; - size_t len = 0; +static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct 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; + struct neigh_netlink_opts *opts; + char mac1[18]; - struct json_object *interfaces = json_object_new_object(); + opts = container_of(query_opts, struct neigh_netlink_opts, query_opts); - while (getline(&line, &len, f) >= 0) { - char mac1[18], mac2[18]; - /* IF_NAMESIZE would be enough, but adding 1 here is simpler than subtracting 1 in the format string */ - char ifname[IF_NAMESIZE+1]; - double lastseen; - int tq; + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; - if (sscanf(line, - "%17[0-9a-fA-F:] %lfs ( %i ) %17[0-9a-fA-F:] [ %"STRINGIFY(IF_NAMESIZE)"[^]] ]", - mac1, &lastseen, &tq, mac2, ifname) != 5) - continue; + ghdr = nlmsg_data(nlh); - if (strcmp(mac1, mac2)) - continue; + if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS) + return NL_OK; - struct json_object *interface; - if (!json_object_object_get_ex(interfaces, ifname, &interface)) { - interface = json_object_new_object(); - json_object_object_add(interfaces, ifname, interface); - } + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; - struct json_object *obj = json_object_new_object(); - json_object_object_add(obj, "tq", json_object_new_int(tq)); - struct json_object *jso = json_object_new_double(lastseen); - json_object_set_serializer(jso, json_object_double_to_json_string, "%.3f", NULL); - json_object_object_add(obj, "lastseen", jso); - json_object_object_add(interface, mac1, obj); + if (missing_mandatory_attrs(attrs, parse_orig_list_mandatory, + ARRAY_SIZE(parse_orig_list_mandatory))) + return NL_OK; + + if (!attrs[BATADV_ATTR_FLAG_BEST]) + 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) + return NL_OK; + + ifname = if_indextoname(hardif, ifname_buf); + if (!ifname) + return NL_OK; + + sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x", + orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]); + + struct json_object *obj = json_object_new_object(); + if (!obj) + 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); } - fclose(f); - free(line); + 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(interface, mac1, obj); - return ifnames2addrs(interfaces); + return NL_OK; +} + +static struct json_object * get_batadv(void) { + struct neigh_netlink_opts opts = { + .query_opts = { + .err = 0, + }, + }; + int ret; + + opts.interfaces = json_object_new_object(); + if (!opts.interfaces) + return NULL; + + ret = netlink_query_common("bat0", BATADV_CMD_GET_ORIGINATORS, + parse_orig_list_netlink_cb, &opts.query_opts); + if (ret < 0) { + json_object_put(opts.interfaces); + return NULL; + } + + return ifnames2addrs(opts.interfaces); } static struct json_object * get_wifi_neighbours(const char *ifname) { diff --git a/package/gluon-status-page-api/Makefile b/package/gluon-status-page-api/Makefile index ddad2cab..703d97f6 100644 --- a/package/gluon-status-page-api/Makefile +++ b/package/gluon-status-page-api/Makefile @@ -14,7 +14,7 @@ define Package/gluon-status-page-api SECTION:=gluon CATEGORY:=Gluon TITLE:=API for gluon-status-page - DEPENDS:=+gluon-core +uhttpd +sse-multiplex +gluon-neighbour-info +gluon-respondd +libiwinfo +libjson-c + DEPENDS:=+gluon-core +uhttpd +sse-multiplex +gluon-neighbour-info +gluon-respondd +libiwinfo +libjson-c +libnl-tiny endef define Build/Prepare diff --git a/package/gluon-status-page-api/src/Makefile b/package/gluon-status-page-api/src/Makefile index 81b48b6d..319ee5a5 100644 --- a/package/gluon-status-page-api/src/Makefile +++ b/package/gluon-status-page-api/src/Makefile @@ -1,11 +1,30 @@ CFLAGS += -std=c99 -D_BSD_SOURCE +CPPFLAGS += -D_GNU_SOURCE + +ifeq ($(origin PKG_CONFIG), undefined) + PKG_CONFIG = pkg-config + ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),) + $(error $(PKG_CONFIG) not found) + endif +endif + +ifeq ($(origin LIBNL_CFLAGS) $(origin LIBNL_LDLIBS), undefined undefined) + LIBNL_NAME ?= libnl-tiny + ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_NAME) 2>/dev/null),) + $(error No $(LIBNL_NAME) development libraries found!) + endif + LIBNL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_NAME)) + LIBNL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_NAME)) +endif +CFLAGS += $(LIBNL_CFLAGS) +LDLIBS += $(LIBNL_LDLIBS) CFLAGS_JSONC = $(shell pkg-config --cflags json-c) LDFLAGS_JSONC = $(shell pkg-config --libs json-c) all: neighbours-batadv stations respondd.so -neighbours-batadv: neighbours-batadv.c +neighbours-batadv: neighbours-batadv.c netlink.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LDFLAGS) $(LDFLAGS_JSONC) -Wall -o $@ $^ $(LDLIBS) stations: stations.c diff --git a/package/gluon-status-page-api/src/neighbours-batadv.c b/package/gluon-status-page-api/src/neighbours-batadv.c index f0a484b2..8cc3f0a6 100644 --- a/package/gluon-status-page-api/src/neighbours-batadv.c +++ b/package/gluon-status-page-api/src/neighbours-batadv.c @@ -2,47 +2,112 @@ #include #include #include +#include #include +#include "netlink.h" + #define STR(x) #x #define XSTR(x) STR(x) +struct neigh_netlink_opts { + struct json_object *obj; + struct nlquery_opts query_opts; +}; + +static const int parse_orig_list_mandatory[] = { + 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) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct 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; + struct neigh_netlink_opts *opts; + char mac1[18]; + + opts = container_of(query_opts, struct neigh_netlink_opts, query_opts); + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; + + if (missing_mandatory_attrs(attrs, parse_orig_list_mandatory, + ARRAY_SIZE(parse_orig_list_mandatory))) + return NL_OK; + + if (!attrs[BATADV_ATTR_FLAG_BEST]) + 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) + return NL_OK; + + ifname = if_indextoname(hardif, ifname_buf); + if (!ifname) + return NL_OK; + + sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x", + orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]); + + struct json_object *neigh = json_object_new_object(); + if (!neigh) + return NL_OK; + + json_object_object_add(neigh, "tq", json_object_new_int(tq)); + json_object_object_add(neigh, "lastseen", json_object_new_double(lastseen / 1000.)); + json_object_object_add(neigh, "ifname", json_object_new_string(ifname)); + + json_object_object_add(opts->obj, mac1, neigh); + + return NL_OK; +} + static json_object *neighbours(void) { - struct json_object *obj = json_object_new_object(); + struct neigh_netlink_opts opts = { + .query_opts = { + .err = 0, + }, + }; + int ret; - FILE *f; - - f = fopen("/sys/kernel/debug/batman_adv/bat0/originators" , "r"); - - if (f == NULL) + opts.obj = json_object_new_object(); + if (!opts.obj) return NULL; - while (!feof(f)) { - char mac1[18]; - char mac2[18]; - char ifname[IF_NAMESIZE+1]; - int tq; - double lastseen; - - int count = fscanf(f, "%17s%*[\t ]%lfs%*[\t (]%d) %17s%*[[ ]%" XSTR(IF_NAMESIZE) "[^]]]", mac1, &lastseen, &tq, mac2, ifname); - - if (count != 5) - continue; - - if (strcmp(mac1, mac2) == 0) { - struct json_object *neigh = json_object_new_object(); - - json_object_object_add(neigh, "tq", json_object_new_int(tq)); - json_object_object_add(neigh, "lastseen", json_object_new_double(lastseen)); - json_object_object_add(neigh, "ifname", json_object_new_string(ifname)); - - json_object_object_add(obj, mac1, neigh); - } + ret = netlink_query_common("bat0", BATADV_CMD_GET_ORIGINATORS, + parse_orig_list_netlink_cb, &opts.query_opts); + if (ret < 0) { + json_object_put(opts.obj); + return NULL; } - fclose(f); - - return obj; + return opts.obj; } int main(void) { diff --git a/package/gluon-status-page-api/src/netlink.c b/package/gluon-status-page-api/src/netlink.c new file mode 100644 index 00000000..127b6c03 --- /dev/null +++ b/package/gluon-status-page-api/src/netlink.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "netlink.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __maybe_unused +#define __maybe_unused __attribute__((unused)) +#endif + +struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { + [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, + [BATADV_ATTR_ORIG_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, + [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_TQ] = { .type = NLA_U8 }, +}; + +int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], + size_t num) +{ + size_t i; + + for (i = 0; i < num; i++) + if (!attrs[mandatory[i]]) + return -EINVAL; + + return 0; +} + +static int nlquery_error_cb(struct sockaddr_nl *nla __maybe_unused, + struct nlmsgerr *nlerr, void *arg) +{ + struct nlquery_opts *query_opts = arg; + + query_opts->err = nlerr->error; + + return NL_STOP; +} + +static int nlquery_stop_cb(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlquery_opts *query_opts = arg; + int *error = nlmsg_data(nlh); + + if (*error) + query_opts->err = *error; + + return NL_STOP; +} + +int netlink_query_common(const char *mesh_iface, uint8_t nl_cmd, + nl_recvmsg_msg_cb_t callback, + struct nlquery_opts *query_opts) +{ + struct nl_sock *sock; + struct nl_msg *msg; + struct nl_cb *cb; + int ifindex; + int family; + int ret; + + query_opts->err = 0; + + sock = nl_socket_alloc(); + if (!sock) + return -ENOMEM; + + ret = genl_connect(sock); + if (ret < 0) { + query_opts->err = ret; + goto err_free_sock; + } + + family = genl_ctrl_resolve(sock, BATADV_NL_NAME); + if (family < 0) { + query_opts->err = -EOPNOTSUPP; + goto err_free_sock; + } + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + query_opts->err = -ENODEV; + goto err_free_sock; + } + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + query_opts->err = -ENOMEM; + goto err_free_sock; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, query_opts); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nlquery_stop_cb, query_opts); + nl_cb_err(cb, NL_CB_CUSTOM, nlquery_error_cb, query_opts); + + msg = nlmsg_alloc(); + if (!msg) { + query_opts->err = -ENOMEM; + goto err_free_cb; + } + + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_DUMP, + nl_cmd, 1); + + nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex); + nl_send_auto_complete(sock, msg); + nlmsg_free(msg); + + nl_recvmsgs(sock, cb); + +err_free_cb: + nl_cb_put(cb); +err_free_sock: + nl_socket_free(sock); + + return query_opts->err; +} diff --git a/package/gluon-status-page-api/src/netlink.h b/package/gluon-status-page-api/src/netlink.h new file mode 100644 index 00000000..56e841a6 --- /dev/null +++ b/package/gluon-status-page-api/src/netlink.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _BATADV_NETLINK_H +#define _BATADV_NETLINK_H + +#include +#include +#include + +struct nlquery_opts { + int err; +}; + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + +#ifndef container_of +#define container_of(ptr, type, member) __extension__ ({ \ + const __typeof__(((type *)0)->member) *__pmember = (ptr); \ + (type *)((char *)__pmember - offsetof(type, member)); }) +#endif + +int netlink_query_common(const char *mesh_iface, uint8_t nl_cmd, + nl_recvmsg_msg_cb_t callback, + struct nlquery_opts *query_opts); +int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], + size_t num); + +extern struct nla_policy batadv_netlink_policy[]; + +#endif /* _BATADV_NETLINK_H */ diff --git a/patches/openwrt/0083-kernel-Add-uapi-batman_adv.h-from-batman-adv-2016.4.patch b/patches/openwrt/0083-kernel-Add-uapi-batman_adv.h-from-batman-adv-2016.4.patch new file mode 100644 index 00000000..5b78db9d --- /dev/null +++ b/patches/openwrt/0083-kernel-Add-uapi-batman_adv.h-from-batman-adv-2016.4.patch @@ -0,0 +1,240 @@ +From: Sven Eckelmann +Date: Thu, 8 Dec 2016 19:46:21 +0100 +Subject: kernel: Add uapi/batman_adv.h from batman-adv 2016.4 + +The batman_adv.h is required by userspace applications to send/receive +generic netlink messages. This file either has to be included in each +program which uses it (like iw/hostapd/wavemon/... does it for nl80211.h) +or the included file in the uapi kernel headers has to be patched to always +be at the correct version. + +gluon decided to prefer a patched kernel to reduce the number of copies of +this file in its own sources. + +diff --git a/target/linux/generic/patches-3.18/690-uapi-batman_adv.patch b/target/linux/generic/patches-3.18/690-uapi-batman_adv.patch +new file mode 100644 +index 0000000000..b5063eb64b +--- /dev/null ++++ b/target/linux/generic/patches-3.18/690-uapi-batman_adv.patch +@@ -0,0 +1,221 @@ ++--- /dev/null +++++ b/include/uapi/linux/batman_adv.h ++@@ -0,0 +1,208 @@ +++/* Copyright (C) 2016 B.A.T.M.A.N. contributors: +++ * +++ * Matthias Schiffer +++ * +++ * Permission to use, copy, modify, and/or distribute this software for any +++ * purpose with or without fee is hereby granted, provided that the above +++ * copyright notice and this permission notice appear in all copies. +++ * +++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +++ */ +++ +++#ifndef _UAPI_LINUX_BATMAN_ADV_H_ +++#define _UAPI_LINUX_BATMAN_ADV_H_ +++ +++#define BATADV_NL_NAME "batadv" +++ +++#define BATADV_NL_MCAST_GROUP_TPMETER "tpmeter" +++ +++/** +++ * enum batadv_tt_client_flags - TT client specific flags +++ * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table +++ * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and the new +++ * update telling its new real location has not been received/sent yet +++ * @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi interface. +++ * This information is used by the "AP Isolation" feature +++ * @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This +++ * information is used by the Extended Isolation feature +++ * @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from the table +++ * @BATADV_TT_CLIENT_NEW: this client has been added to the local table but has +++ * not been announced yet +++ * @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it is kept +++ * in the table for one more originator interval for consistency purposes +++ * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be part of +++ * the network but no nnode has already announced it +++ * +++ * Bits from 0 to 7 are called _remote flags_ because they are sent on the wire. +++ * Bits from 8 to 15 are called _local flags_ because they are used for local +++ * computations only. +++ * +++ * Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with +++ * the other nodes in the network. To achieve this goal these flags are included +++ * in the TT CRC computation. +++ */ +++enum batadv_tt_client_flags { +++ BATADV_TT_CLIENT_DEL = (1 << 0), +++ BATADV_TT_CLIENT_ROAM = (1 << 1), +++ BATADV_TT_CLIENT_WIFI = (1 << 4), +++ BATADV_TT_CLIENT_ISOLA = (1 << 5), +++ BATADV_TT_CLIENT_NOPURGE = (1 << 8), +++ BATADV_TT_CLIENT_NEW = (1 << 9), +++ BATADV_TT_CLIENT_PENDING = (1 << 10), +++ BATADV_TT_CLIENT_TEMP = (1 << 11), +++}; +++ +++/** +++ * enum batadv_nl_attrs - batman-adv netlink attributes +++ * +++ * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors +++ * @BATADV_ATTR_VERSION: batman-adv version string +++ * @BATADV_ATTR_ALGO_NAME: name of routing algorithm +++ * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface +++ * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface +++ * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface +++ * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface +++ * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface +++ * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv interface +++ * @BATADV_ATTR_ORIG_ADDRESS: originator mac address +++ * @BATADV_ATTR_TPMETER_RESULT: result of run (see batadv_tp_meter_status) +++ * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took +++ * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run +++ * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session +++ * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment +++ * @BATADV_ATTR_ACTIVE: Flag indicating if the hard interface is active +++ * @BATADV_ATTR_TT_ADDRESS: Client MAC address +++ * @BATADV_ATTR_TT_TTVN: Translation table version +++ * @BATADV_ATTR_TT_LAST_TTVN: Previous translation table version +++ * @BATADV_ATTR_TT_CRC32: CRC32 over translation table +++ * @BATADV_ATTR_TT_VID: VLAN ID +++ * @BATADV_ATTR_TT_FLAGS: Translation table client flags +++ * @BATADV_ATTR_FLAG_BEST: Flags indicating entry is the best +++ * @BATADV_ATTR_LAST_SEEN_MSECS: Time in milliseconds since last seen +++ * @BATADV_ATTR_NEIGH_ADDRESS: Neighbour MAC address +++ * @BATADV_ATTR_TQ: TQ to neighbour +++ * @BATADV_ATTR_THROUGHPUT: Estimated throughput to Neighbour +++ * @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth +++ * @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth +++ * @BATADV_ATTR_ROUTER: Gateway router MAC address +++ * @BATADV_ATTR_BLA_OWN: Flag indicating own originator +++ * @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address +++ * @BATADV_ATTR_BLA_VID: BLA VLAN ID +++ * @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address +++ * @BATADV_ATTR_BLA_CRC: BLA CRC +++ * @__BATADV_ATTR_AFTER_LAST: internal use +++ * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available +++ * @BATADV_ATTR_MAX: highest attribute number currently defined +++ */ +++enum batadv_nl_attrs { +++ BATADV_ATTR_UNSPEC, +++ BATADV_ATTR_VERSION, +++ BATADV_ATTR_ALGO_NAME, +++ BATADV_ATTR_MESH_IFINDEX, +++ BATADV_ATTR_MESH_IFNAME, +++ BATADV_ATTR_MESH_ADDRESS, +++ BATADV_ATTR_HARD_IFINDEX, +++ BATADV_ATTR_HARD_IFNAME, +++ BATADV_ATTR_HARD_ADDRESS, +++ BATADV_ATTR_ORIG_ADDRESS, +++ BATADV_ATTR_TPMETER_RESULT, +++ BATADV_ATTR_TPMETER_TEST_TIME, +++ BATADV_ATTR_TPMETER_BYTES, +++ BATADV_ATTR_TPMETER_COOKIE, +++ BATADV_ATTR_PAD, +++ BATADV_ATTR_ACTIVE, +++ BATADV_ATTR_TT_ADDRESS, +++ BATADV_ATTR_TT_TTVN, +++ BATADV_ATTR_TT_LAST_TTVN, +++ BATADV_ATTR_TT_CRC32, +++ BATADV_ATTR_TT_VID, +++ BATADV_ATTR_TT_FLAGS, +++ BATADV_ATTR_FLAG_BEST, +++ BATADV_ATTR_LAST_SEEN_MSECS, +++ BATADV_ATTR_NEIGH_ADDRESS, +++ BATADV_ATTR_TQ, +++ BATADV_ATTR_THROUGHPUT, +++ BATADV_ATTR_BANDWIDTH_UP, +++ BATADV_ATTR_BANDWIDTH_DOWN, +++ BATADV_ATTR_ROUTER, +++ BATADV_ATTR_BLA_OWN, +++ BATADV_ATTR_BLA_ADDRESS, +++ BATADV_ATTR_BLA_VID, +++ BATADV_ATTR_BLA_BACKBONE, +++ BATADV_ATTR_BLA_CRC, +++ /* add attributes above here, update the policy in netlink.c */ +++ __BATADV_ATTR_AFTER_LAST, +++ NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST, +++ BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1 +++}; +++ +++/** +++ * enum batadv_nl_commands - supported batman-adv netlink commands +++ * +++ * @BATADV_CMD_UNSPEC: unspecified command to catch errors +++ * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv device +++ * @BATADV_CMD_TP_METER: Start a tp meter session +++ * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session +++ * @BATADV_CMD_GET_ROUTING_ALGOS: Query the list of routing algorithms. +++ * @BATADV_CMD_GET_HARDIFS: Query list of hard interfaces +++ * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations +++ * @BATADV_CMD_GET_TRANSTABLE_GLOBAL Query list of global translations +++ * @BATADV_CMD_GET_ORIGINATORS: Query list of originators +++ * @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours +++ * @BATADV_CMD_GET_GATEWAYS: Query list of gateways +++ * @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims +++ * @BATADV_CMD_GET_BLA_BACKBONE: Query list of bridge loop avoidance backbones +++ * @__BATADV_CMD_AFTER_LAST: internal use +++ * @BATADV_CMD_MAX: highest used command number +++ */ +++enum batadv_nl_commands { +++ BATADV_CMD_UNSPEC, +++ BATADV_CMD_GET_MESH_INFO, +++ BATADV_CMD_TP_METER, +++ BATADV_CMD_TP_METER_CANCEL, +++ BATADV_CMD_GET_ROUTING_ALGOS, +++ BATADV_CMD_GET_HARDIFS, +++ BATADV_CMD_GET_TRANSTABLE_LOCAL, +++ BATADV_CMD_GET_TRANSTABLE_GLOBAL, +++ BATADV_CMD_GET_ORIGINATORS, +++ BATADV_CMD_GET_NEIGHBORS, +++ BATADV_CMD_GET_GATEWAYS, +++ BATADV_CMD_GET_BLA_CLAIM, +++ BATADV_CMD_GET_BLA_BACKBONE, +++ /* add new commands above here */ +++ __BATADV_CMD_AFTER_LAST, +++ BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1 +++}; +++ +++/** +++ * enum batadv_tp_meter_reason - reason of a tp meter test run stop +++ * @BATADV_TP_REASON_COMPLETE: sender finished tp run +++ * @BATADV_TP_REASON_CANCEL: sender was stopped during run +++ * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or didn't +++ * answer +++ * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit +++ * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node already +++ * ongoing +++ * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory +++ * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface +++ * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions +++ */ +++enum batadv_tp_meter_reason { +++ BATADV_TP_REASON_COMPLETE = 3, +++ BATADV_TP_REASON_CANCEL = 4, +++ /* error status >= 128 */ +++ BATADV_TP_REASON_DST_UNREACHABLE = 128, +++ BATADV_TP_REASON_RESEND_LIMIT = 129, +++ BATADV_TP_REASON_ALREADY_ONGOING = 130, +++ BATADV_TP_REASON_MEMORY_ERROR = 131, +++ BATADV_TP_REASON_CANT_SEND = 132, +++ BATADV_TP_REASON_TOO_MANY = 133, +++}; +++ +++#endif /* _UAPI_LINUX_BATMAN_ADV_H_ */ ++--- a/include/uapi/linux/Kbuild +++++ b/include/uapi/linux/Kbuild ++@@ -61,6 +61,7 @@ header-y += auto_fs4.h ++ header-y += auxvec.h ++ header-y += ax25.h ++ header-y += b1lli.h +++header-y += batman_adv.h ++ header-y += baycom.h ++ header-y += bcm933xx_hcs.h ++ header-y += bfs_fs.h diff --git a/patches/packages/routing/0002-batman-adv-introduce-no_rebroadcast-option.patch b/patches/packages/routing/0002-batman-adv-introduce-no_rebroadcast-option.patch index f564a011..aa0a1009 100644 --- a/patches/packages/routing/0002-batman-adv-introduce-no_rebroadcast-option.patch +++ b/patches/packages/routing/0002-batman-adv-introduce-no_rebroadcast-option.patch @@ -33,18 +33,13 @@ index 1e0c9d0..d0ab238 100644 } diff --git a/batman-adv/patches/1001-batman-adv-introduce-no_rebroadcast-option.patch b/batman-adv/patches/1001-batman-adv-introduce-no_rebroadcast-option.patch new file mode 100644 -index 0000000..e9f5ffb +index 0000000..2f328d2 --- /dev/null +++ b/batman-adv/patches/1001-batman-adv-introduce-no_rebroadcast-option.patch -@@ -0,0 +1,189 @@ -+From bb66988dc6972d5400b4ff4f0b49ed090007d635 Mon Sep 17 00:00:00 2001 -+Message-Id: -+From: =?UTF-8?q?Linus=20L=C3=BCssing?= +@@ -0,0 +1,190 @@ ++From: Linus Lüssing +Date: Tue, 24 Sep 2013 04:36:27 +0200 -+Subject: [PATCH 1/2] batman-adv: introduce 'no_rebroadcast' option -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit ++Subject: [PATCH] batman-adv: introduce 'no_rebroadcast' option + +This patch introduces a new sysfs option named "no_rebroadcast" on +a per hard interface basis. It allows manually enabling a split-horizon @@ -68,20 +63,19 @@ index 0000000..e9f5ffb +--- + .../ABI/testing/sysfs-class-net-batman-adv | 11 ++++ + net/batman-adv/hard-interface.c | 2 + -+ net/batman-adv/send.c | 4 ++ ++ net/batman-adv/send.c | 5 ++ + net/batman-adv/sysfs.c | 59 ++++++++++++++++++++++ + net/batman-adv/types.h | 1 + -+ 5 files changed, 77 insertions(+) ++ 5 files changed, 78 insertions(+) + +diff --git a/Documentation/ABI/testing/sysfs-class-net-batman-adv b/Documentation/ABI/testing/sysfs-class-net-batman-adv -+index 518f6a1..896c480 100644 ++index 8981068..ac04928 100644 +--- a/Documentation/ABI/testing/sysfs-class-net-batman-adv ++++ b/Documentation/ABI/testing/sysfs-class-net-batman-adv -+@@ -28,3 +28,14 @@ Description: -+ The /sys/class/net//batman-adv/mesh_iface file ++@@ -20,6 +20,17 @@ Description: + displays the batman mesh interface this + currently is associated with. -++ ++ ++What: /sys/class/net//batman-adv/no_rebroadcast ++Date: Sep 2013 ++Contact: Linus Lüssing @@ -92,39 +86,49 @@ index 0000000..e9f5ffb ++ and symmetric only, for instance point-to-point wifi longshots ++ or wired links. Using this option wrongly is going to ++ break your mesh network, use at your own risk! +++ ++ What: /sys/class/net//batman-adv/throughput_override ++ Date: Feb 2014 ++ Contact: Antonio Quartulli +diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c -+index 8c2f399..48e53d0 100644 ++index e034afb..b485a88 100644 +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c -+@@ -690,6 +690,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) -+ kref_init(&hard_iface->refcount); -+ kref_get(&hard_iface->refcount); ++@@ -701,6 +701,8 @@ batadv_hardif_add_interface(struct net_device *net_dev) ++ ++ batadv_v_hardif_init(hard_iface); + ++ atomic_set(&hard_iface->no_rebroadcast, 0); ++ + batadv_check_known_mac_addr(hard_iface->net_dev); ++ kref_get(&hard_iface->refcount); + list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); -+ +diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c -+index f2f1256..3736d75 100644 ++index 8d4e1f5..cb1b275 100644 +--- a/net/batman-adv/send.c ++++ b/net/batman-adv/send.c -+@@ -578,6 +578,10 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) -+ if (forw_packet->num_packets >= hard_iface->num_bcasts) ++@@ -639,11 +639,16 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) ++ if (!kref_get_unless_zero(&hard_iface->refcount)) + continue; + ++ if (atomic_read(&hard_iface->no_rebroadcast) && ++ forw_packet->skb->dev == hard_iface->net_dev) -++ continue; +++ goto put_hardif; ++ -+ if (!kref_get_unless_zero(&hard_iface->refcount)) -+ continue; ++ /* send a copy of the saved skb */ ++ skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); ++ if (skb1) ++ batadv_send_broadcast_skb(skb1, hard_iface); + +++put_hardif: ++ batadv_hardif_put(hard_iface); ++ } ++ rcu_read_unlock(); +diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c -+index 414b207..9aa043f 100644 ++index 02d96f2..f91d09c 100644 +--- a/net/batman-adv/sysfs.c ++++ b/net/batman-adv/sysfs.c -+@@ -134,6 +134,17 @@ struct batadv_attribute batadv_attr_vlan_##_name = { \ ++@@ -136,6 +136,17 @@ struct batadv_attribute batadv_attr_vlan_##_name = { \ + .store = _store, \ + } + @@ -142,7 +146,7 @@ index 0000000..e9f5ffb + /* Use this, if you have customized show and store functions */ + #define BATADV_ATTR(_name, _mode, _show, _store) \ + struct batadv_attribute batadv_attr_##_name = { \ -+@@ -293,6 +304,52 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ ++@@ -295,6 +306,52 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \ + static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ + batadv_store_##_name) + @@ -195,7 +199,7 @@ index 0000000..e9f5ffb + static int batadv_store_bool_attr(char *buff, size_t count, + struct net_device *net_dev, + const char *attr_name, atomic_t *attr, -+@@ -993,6 +1050,7 @@ static ssize_t batadv_show_throughput_override(struct kobject *kobj, ++@@ -1119,6 +1176,7 @@ static ssize_t batadv_show_throughput_override(struct kobject *kobj, + static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface, + batadv_store_mesh_iface); + static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL); @@ -203,7 +207,7 @@ index 0000000..e9f5ffb + #ifdef CONFIG_BATMAN_ADV_BATMAN_V + BATADV_ATTR_HIF_UINT(elp_interval, bat_v.elp_interval, S_IRUGO | S_IWUSR, + 2 * BATADV_JITTER, INT_MAX, NULL); -+@@ -1004,6 +1062,7 @@ static BATADV_ATTR(throughput_override, S_IRUGO | S_IWUSR, ++@@ -1130,6 +1188,7 @@ static BATADV_ATTR(throughput_override, S_IRUGO | S_IWUSR, + static struct batadv_attribute *batadv_batman_attrs[] = { + &batadv_attr_mesh_iface, + &batadv_attr_iface_status, @@ -212,7 +216,7 @@ index 0000000..e9f5ffb + &batadv_attr_elp_interval, + &batadv_attr_throughput_override, +diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h -+index ba846b0..1a596c5 100644 ++index b3dd1a3..9ee810d 100644 +--- a/net/batman-adv/types.h ++++ b/net/batman-adv/types.h +@@ -156,6 +156,7 @@ struct batadv_hard_iface { @@ -223,6 +227,3 @@ index 0000000..e9f5ffb + }; + + /** -+-- -+2.8.3 -+ diff --git a/patches/packages/routing/0003-batman-adv-decrease-maximum-fragment-size.patch b/patches/packages/routing/0003-batman-adv-decrease-maximum-fragment-size.patch index ede150b3..d0929d34 100644 --- a/patches/packages/routing/0003-batman-adv-decrease-maximum-fragment-size.patch +++ b/patches/packages/routing/0003-batman-adv-decrease-maximum-fragment-size.patch @@ -4,27 +4,22 @@ Subject: batman-adv: decrease maximum fragment size diff --git a/batman-adv/patches/1002-batman-adv-decrease-maximum-fragment-size.patch b/batman-adv/patches/1002-batman-adv-decrease-maximum-fragment-size.patch new file mode 100644 -index 0000000..a97146b +index 0000000..011380e --- /dev/null +++ b/batman-adv/patches/1002-batman-adv-decrease-maximum-fragment-size.patch -@@ -0,0 +1,28 @@ -+From 9e7384fde3c5a71f733221a137fdc4593a9638be Mon Sep 17 00:00:00 2001 -+Message-Id: <9e7384fde3c5a71f733221a137fdc4593a9638be.1466048916.git.mschiffer@universe-factory.net> -+In-Reply-To: <8e4c2084bbf2a65ad663a2b1ba27144e5dadfd5f.1466048916.git.mschiffer@universe-factory.net> -+References: <8e4c2084bbf2a65ad663a2b1ba27144e5dadfd5f.1466048916.git.mschiffer@universe-factory.net> +@@ -0,0 +1,20 @@ +From: Matthias Schiffer +Date: Thu, 6 Aug 2015 22:27:01 +0200 -+Subject: [PATCH 2/2] batman-adv: decrease maximum fragment size -+ ++Subject: [PATCH] batman-adv: decrease maximum fragment size +--- + net/batman-adv/main.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h -+index 7692526..d314e6c 100644 ++index 09af21e..23ebb8e 100644 +--- a/net/batman-adv/main.h ++++ b/net/batman-adv/main.h -+@@ -159,7 +159,7 @@ enum batadv_uev_type { ++@@ -167,7 +167,7 @@ enum batadv_uev_type { + /* Maximum number of fragments for one packet */ + #define BATADV_FRAG_MAX_FRAGMENTS 16 + /* Maxumim size of each fragment */ @@ -33,6 +28,3 @@ index 0000000..a97146b + /* Time to keep fragments while waiting for rest of the fragments */ + #define BATADV_FRAG_TIMEOUT 10000 + -+-- -+2.8.3 -+