b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status
@ 2016-06-05 18:46 Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 02/10] alfred: Split list of objects in Makefile into separate lines Sven Eckelmann
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:46 UTC (permalink / raw)
  To: b.a.t.m.a.n

The content of batman_adv/iface_status ends with a newline. Thus
register_interfaces has to make sure that it only compares the first line
without the \n when comparing with the status string.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 vis/vis.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/vis/vis.c b/vis/vis.c
index 4d494bc..7eab781 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -257,6 +257,7 @@ static int register_interfaces(struct globals *globals)
 	DIR *iface_base_dir;
 	struct dirent *iface_dir;
 	char *path_buff, *file_content;
+	char *content_newline;
 
 	path_buff = malloc(PATH_BUFF_LEN);
 	if (!path_buff) {
@@ -295,6 +296,10 @@ static int register_interfaces(struct globals *globals)
 		if (!file_content)
 			continue;
 
+		content_newline = strstr(file_content, "\n");
+		if (content_newline)
+			*content_newline = '\0';
+
 		if (strcmp(file_content, "active") == 0)
 			get_if_index(globals, iface_dir->d_name);
 
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 02/10] alfred: Split list of objects in Makefile into separate lines
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies Sven Eckelmann
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

From: Sven Eckelmann <sven.eckelmann@open-mesh.com>

The line of objects which are required to compile alfred gets longer and
becomes harder to read. Instead save each object on its own line to make it
easier to edit and easier to solve conflicts when multiple patches modify
the list of objects.

Signed-off-by: Sven Eckelmann <sven.eckelmann@open-mesh.com>
---
 Makefile      | 12 +++++++++++-
 gpsd/Makefile |  2 +-
 vis/Makefile  |  3 ++-
 3 files changed, 14 insertions(+), 3 deletions(-)
 mode change 100644 => 100755 Makefile
 mode change 100644 => 100755 gpsd/Makefile
 mode change 100644 => 100755 vis/Makefile

diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
index 939e9f8..1c364f7
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,17 @@
 
 # alfred build
 BINARY_NAME = alfred
-OBJ = main.o server.o client.o netsock.o send.o recv.o hash.o unix_sock.o util.o debugfs.o batadv_query.o
+OBJ += batadv_query.o
+OBJ += client.o
+OBJ += debugfs.o
+OBJ += hash.o
+OBJ += main.o
+OBJ += netsock.o
+OBJ += recv.o
+OBJ += send.o
+OBJ += server.o
+OBJ += unix_sock.o
+OBJ += util.o
 MANPAGE = man/alfred.8
 
 # alfred flags and options
diff --git a/gpsd/Makefile b/gpsd/Makefile
old mode 100644
new mode 100755
index 72e4445..bae5660
--- a/gpsd/Makefile
+++ b/gpsd/Makefile
@@ -20,7 +20,7 @@
 
 # alfred-gpsd build
 BINARY_NAME = alfred-gpsd
-OBJ = alfred-gpsd.o
+OBJ += alfred-gpsd.o
 MANPAGE = man/alfred-gpsd.8
 
 # alfred flags and options
diff --git a/vis/Makefile b/vis/Makefile
old mode 100644
new mode 100755
index accd1fa..52ca981
--- a/vis/Makefile
+++ b/vis/Makefile
@@ -20,7 +20,8 @@
 
 # batadv-vis build
 BINARY_NAME = batadv-vis
-OBJ = vis.o debugfs.o
+OBJ += debugfs.o
+OBJ += vis.o
 MANPAGE = man/batadv-vis.8
 
 # batadv-vis flags and options
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 02/10] alfred: Split list of objects in Makefile into separate lines Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-07-21 15:58   ` Simon Wunderlich
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 04/10] alfred: Add CAP_NET_ADMIN capabilities for netlink Sven Eckelmann
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 Makefile         |  35 ++++++++--
 README           |   2 +
 batman_adv.h     | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 netlink.c        |  84 ++++++++++++++++++++++
 netlink.h        |  30 ++++++++
 vis/Makefile     |  30 ++++++++
 vis/batman_adv.h |   1 +
 vis/netlink.c    |   1 +
 vis/netlink.h    |   1 +
 9 files changed, 386 insertions(+), 6 deletions(-)
 create mode 100644 batman_adv.h
 create mode 100644 netlink.c
 create mode 100644 netlink.h
 create mode 120000 vis/batman_adv.h
 create mode 120000 vis/netlink.c
 create mode 120000 vis/netlink.h

diff --git a/Makefile b/Makefile
index 1c364f7..6daa904 100755
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@ OBJ += client.o
 OBJ += debugfs.o
 OBJ += hash.o
 OBJ += main.o
+OBJ += netlink.o
 OBJ += netsock.o
 OBJ += recv.o
 OBJ += send.o
@@ -83,14 +84,36 @@ ifneq ($(CONFIG_ALFRED_GPSD),n)
 	GPSD_INSTALL=gpsd-install
 endif
 
-ifneq ($(CONFIG_ALFRED_CAPABILITIES),n)
-  ifeq ($(origin PKG_CONFIG), undefined)
-    PKG_CONFIG = pkg-config
-    ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),)
-      $(error $(PKG_CONFIG) not found)
-    endif
+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-3.0
+  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)
 
+ifeq ($(origin LIBNL_GENL_CFLAGS) $(origin LIBNL_GENL_LDLIBS), undefined undefined)
+  LIBNL_GENL_NAME ?= libnl-genl-3.0
+  ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_GENL_NAME) 2>/dev/null),)
+    $(error No $(LIBNL_GENL_NAME) development libraries found!)
+  endif
+  LIBNL_GENL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_GENL_NAME))
+  LIBNL_GENL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_GENL_NAME))
+endif
+CFLAGS += $(LIBNL_GENL_CFLAGS)
+LDLIBS += $(LIBNL_GENL_LDLIBS)
+
+ifneq ($(CONFIG_ALFRED_CAPABILITIES),n)
   ifeq ($(origin LIBCAP_CFLAGS) $(origin LIBCAP_LDLIBS), undefined undefined)
     LIBCAP_NAME ?= libcap
     ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBCAP_NAME) 2>/dev/null),)
diff --git a/README b/README
index fbca7d1..2a015b8 100644
--- a/README
+++ b/README
@@ -28,6 +28,8 @@ Compilation
 alfred depends on:
  * librt (usually part of libc)
  * IPv6 support in the kernel/host system
+ * libnl-3 - support for netlink sockets
+ * libnl-3-genl - support for generic netlink messages
 
 and optionally:
  * libgps - if you want to distribute GPS information
diff --git a/batman_adv.h b/batman_adv.h
new file mode 100644
index 0000000..37157d0
--- /dev/null
+++ b/batman_adv.h
@@ -0,0 +1,208 @@
+/* Copyright (C) 2016 B.A.T.M.A.N. contributors:
+ *
+ * Matthias Schiffer
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#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_ */
diff --git a/netlink.c b/netlink.c
new file mode 100644
index 0000000..d9c1f55
--- /dev/null
+++ b/netlink.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009-2016  B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <mareklindner@neomailbox.ch>, Andrew Lunn <andrew@lunn.ch>
+ *
+ * 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 <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+#include <net/ethernet.h>
+
+#include "batman_adv.h"
+
+struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
+	[BATADV_ATTR_VERSION]		= { .type = NLA_STRING },
+	[BATADV_ATTR_ALGO_NAME]		= { .type = NLA_STRING },
+	[BATADV_ATTR_MESH_IFINDEX]	= { .type = NLA_U32 },
+	[BATADV_ATTR_MESH_IFNAME]	= { .type = NLA_STRING,
+					    .maxlen = IFNAMSIZ },
+	[BATADV_ATTR_MESH_ADDRESS]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_HARD_IFINDEX]	= { .type = NLA_U32 },
+	[BATADV_ATTR_HARD_IFNAME]	= { .type = NLA_STRING,
+					    .maxlen = IFNAMSIZ },
+	[BATADV_ATTR_HARD_ADDRESS]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_ORIG_ADDRESS]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_TPMETER_RESULT]	= { .type = NLA_U8 },
+	[BATADV_ATTR_TPMETER_TEST_TIME]	= { .type = NLA_U32 },
+	[BATADV_ATTR_TPMETER_BYTES]	= { .type = NLA_U64 },
+	[BATADV_ATTR_TPMETER_COOKIE]	= { .type = NLA_U32 },
+	[BATADV_ATTR_PAD]		= { .type = NLA_UNSPEC },
+	[BATADV_ATTR_ACTIVE]		= { .type = NLA_FLAG },
+	[BATADV_ATTR_TT_ADDRESS]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_TT_TTVN]		= { .type = NLA_U8 },
+	[BATADV_ATTR_TT_LAST_TTVN]	= { .type = NLA_U8 },
+	[BATADV_ATTR_TT_CRC32]		= { .type = NLA_U32 },
+	[BATADV_ATTR_TT_VID]		= { .type = NLA_U16 },
+	[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_THROUGHPUT]	= { .type = NLA_U32 },
+	[BATADV_ATTR_BANDWIDTH_UP]	= { .type = NLA_U32 },
+	[BATADV_ATTR_BANDWIDTH_DOWN]	= { .type = NLA_U32 },
+	[BATADV_ATTR_ROUTER]		= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_BLA_OWN]		= { .type = NLA_FLAG },
+	[BATADV_ATTR_BLA_ADDRESS]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_BLA_VID]		= { .type = NLA_U16 },
+	[BATADV_ATTR_BLA_BACKBONE]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
+	[BATADV_ATTR_BLA_CRC]		= { .type = NLA_U16 },
+};
diff --git a/netlink.h b/netlink.h
new file mode 100644
index 0000000..f903563
--- /dev/null
+++ b/netlink.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009-2016  B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <mareklindner@neomailbox.ch>, Andrew Lunn <andrew@lunn.ch>
+ *
+ * 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 _ALFRED_NETLINK_H
+#define _ALFRED_NETLINK_H
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+
+extern struct nla_policy batadv_netlink_policy[];
+
+#endif /* _ALFRED_NETLINK_H */
diff --git a/vis/Makefile b/vis/Makefile
index 52ca981..fd99f49 100755
--- a/vis/Makefile
+++ b/vis/Makefile
@@ -21,6 +21,7 @@
 # batadv-vis build
 BINARY_NAME = batadv-vis
 OBJ += debugfs.o
+OBJ += netlink.o
 OBJ += vis.o
 MANPAGE = man/batadv-vis.8
 
@@ -59,6 +60,35 @@ ifneq ($(REVISION),)
 CPPFLAGS += -DSOURCE_VERSION=\"$(REVISION)\"
 endif
 
+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-3.0
+  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)
+
+ifeq ($(origin LIBNL_GENL_CFLAGS) $(origin LIBNL_GENL_LDLIBS), undefined undefined)
+  LIBNL_GENL_NAME ?= libnl-genl-3.0
+  ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_GENL_NAME) 2>/dev/null),)
+    $(error No $(LIBNL_GENL_NAME) development libraries found!)
+  endif
+  LIBNL_GENL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_GENL_NAME))
+  LIBNL_GENL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_GENL_NAME))
+endif
+CFLAGS += $(LIBNL_GENL_CFLAGS)
+LDLIBS += $(LIBNL_GENL_LDLIBS)
+
 # default target
 all: $(BINARY_NAME)
 
diff --git a/vis/batman_adv.h b/vis/batman_adv.h
new file mode 120000
index 0000000..72222e9
--- /dev/null
+++ b/vis/batman_adv.h
@@ -0,0 +1 @@
+../batman_adv.h
\ No newline at end of file
diff --git a/vis/netlink.c b/vis/netlink.c
new file mode 120000
index 0000000..06d13cc
--- /dev/null
+++ b/vis/netlink.c
@@ -0,0 +1 @@
+../netlink.c
\ No newline at end of file
diff --git a/vis/netlink.h b/vis/netlink.h
new file mode 120000
index 0000000..c7a63b5
--- /dev/null
+++ b/vis/netlink.h
@@ -0,0 +1 @@
+../netlink.h
\ No newline at end of file
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 04/10] alfred: Add CAP_NET_ADMIN capabilities for netlink
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 02/10] alfred: Split list of objects in Makefile into separate lines Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 05/10] alfred: Split translate_mac from debugfs backend Sven Eckelmann
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The batman_adv netlink family requires CAP_NET_ADMIN capabilities to query
the debugging tables.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 README         |  8 ++++----
 batadv_query.c |  3 +++
 main.c         | 12 ++++++++++++
 3 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/README b/README
index 2a015b8..bc1c3bc 100644
--- a/README
+++ b/README
@@ -277,11 +277,11 @@ Operations requiring special capabilities:
  * accessing the debugfs filesystem
 
 The first operation can still be executed when the admin grants the special
-capability CAP_NET_RAW to anyone executing the alfred binary. The unix socket
-can also be moved using the parameter '-u' to a different directory which can
-be accessed by the user.
+capability CAP_NET_RAW+CAP_NET_ADMIN to anyone executing the alfred binary.
+The unix socket can also be moved using the parameter '-u' to a different
+directory which can be accessed by the user.
 
- $ sudo setcap cap_net_raw+ep alfred
+ $ sudo setcap cap_net_admin,cap_net_raw+ep alfred
  $ ./alfred -u alfred.sock -i eth0
 
 The user running alfred must still be in a group which is allowed to access
diff --git a/batadv_query.c b/batadv_query.c
index a5fa565..d917242 100644
--- a/batadv_query.c
+++ b/batadv_query.c
@@ -29,6 +29,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef CONFIG_ALFRED_CAPABILITIES
+#include <sys/capability.h>
+#endif
 #include <sys/types.h>
 #include "debugfs.h"
 
diff --git a/main.c b/main.c
index 52dca97..9cab705 100644
--- a/main.c
+++ b/main.c
@@ -77,6 +77,7 @@ static int reduce_capabilities(void)
 	cap_t cap_new;
 	cap_flag_value_t cap_flag;
 	cap_value_t cap_net_raw = CAP_NET_RAW;
+	cap_value_t cap_net_admin = CAP_NET_ADMIN;
 
 	/* get current process capabilities */
 	cap_cur = cap_get_proc();
@@ -105,6 +106,17 @@ static int reduce_capabilities(void)
 		}
 	}
 
+	cap_flag = CAP_CLEAR;
+	cap_get_flag(cap_cur, CAP_NET_ADMIN, CAP_PERMITTED, &cap_flag);
+	if (cap_flag != CAP_CLEAR) {
+		ret = cap_set_flag(cap_new, CAP_PERMITTED, 1, &cap_net_admin,
+				   CAP_SET);
+		if (ret < 0) {
+			perror("cap_set_flag");
+			goto out;
+		}
+	}
+
 	/* set minimal capabilities field */
 	ret = cap_set_proc(cap_new);
 	if (ret < 0) {
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 05/10] alfred: Split translate_mac from debugfs backend
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (2 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 04/10] alfred: Add CAP_NET_ADMIN capabilities for netlink Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 06/10] alfred: Translate mac addresses via netlink Sven Eckelmann
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The debugfs tables cannot be used by the alfred in network namespaces.
These have to use netlink. Thus the translate_mac should be less tightly
linked to the debugfs tables to implement optional netlink support.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 batadv_query.c | 45 ++++++++++++++++++++++++++++++++++-----------
 batadv_query.h |  2 +-
 2 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/batadv_query.c b/batadv_query.c
index d917242..b0679fc 100644
--- a/batadv_query.c
+++ b/batadv_query.c
@@ -125,7 +125,9 @@ int batadv_interface_check(const char *mesh_iface)
 	return 0;
 }
 
-struct ether_addr *translate_mac(const char *mesh_iface, struct ether_addr *mac)
+static int translate_mac_debugfs(const char *mesh_iface,
+				 const struct ether_addr *mac,
+				 struct ether_addr *mac_out)
 {
 	enum {
 		tg_start,
@@ -133,24 +135,21 @@ struct ether_addr *translate_mac(const char *mesh_iface, struct ether_addr *mac)
 		tg_via,
 		tg_originator,
 	} pos;
-	char full_path[MAX_PATH + 1];
-	static struct ether_addr in_mac;
-	struct ether_addr *mac_result, *mac_tmp;
+	char full_path[MAX_PATH+1];
+	struct ether_addr *mac_tmp;
 	FILE *f = NULL;
 	size_t len = 0;
 	char *line = NULL;
 	char *input, *saveptr, *token;
 	int line_invalid;
-
-	memcpy(&in_mac, mac, sizeof(in_mac));
-	mac_result = &in_mac;
+	bool found = false;
 
 	debugfs_make_path(DEBUG_BATIF_PATH_FMT "/" DEBUG_TRANSTABLE_GLOBAL,
 			  mesh_iface, full_path, sizeof(full_path));
 
 	f = fopen(full_path, "r");
 	if (!f)
-		goto out;
+		return -EOPNOTSUPP;
 
 	while (getline(&line, &len, f) != -1) {
 		line_invalid = 0;
@@ -169,8 +168,8 @@ struct ether_addr *translate_mac(const char *mesh_iface, struct ether_addr *mac)
 				break;
 			case tg_mac:
 				mac_tmp = ether_aton(token);
-				if (!mac_tmp || memcmp(mac_tmp, &in_mac,
-						       sizeof(in_mac)) != 0)
+				if (!mac_tmp || memcmp(mac_tmp, mac,
+						       ETH_ALEN) != 0)
 					line_invalid = 1;
 				else
 					pos = tg_via;
@@ -184,7 +183,8 @@ struct ether_addr *translate_mac(const char *mesh_iface, struct ether_addr *mac)
 				if (!mac_tmp) {
 					line_invalid = 1;
 				} else {
-					mac_result = mac_tmp;
+					memcpy(mac_out, mac_tmp, ETH_ALEN);
+					found = true;
 					goto out;
 				}
 				break;
@@ -199,6 +199,29 @@ out:
 	if (f)
 		fclose(f);
 	free(line);
+
+	if (found)
+		return 0;
+	else
+		return -ENOENT;
+}
+
+struct ether_addr *translate_mac(const char *mesh_iface,
+				 const struct ether_addr *mac)
+{
+	struct ether_addr in_mac;
+	static struct ether_addr out_mac;
+	struct ether_addr *mac_result;
+
+	/* input mac has to be copied because it could be in the shared
+	 * ether_aton buffer
+	 */
+	memcpy(&in_mac, mac, sizeof(in_mac));
+	memcpy(&out_mac, mac, sizeof(out_mac));
+	mac_result = &out_mac;
+
+	translate_mac_debugfs(mesh_iface, &in_mac, mac_result);
+
 	return mac_result;
 }
 
diff --git a/batadv_query.h b/batadv_query.h
index d9660bc..320203b 100644
--- a/batadv_query.h
+++ b/batadv_query.h
@@ -25,7 +25,7 @@
 #include <netinet/in.h>
 
 struct ether_addr *translate_mac(const char *mesh_iface,
-				 struct ether_addr *mac);
+				 const struct ether_addr *mac);
 uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac);
 int batadv_interface_check(const char *mesh_iface);
 int mac_to_ipv6(const struct ether_addr *mac, struct in6_addr *addr);
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 06/10] alfred: Translate mac addresses via netlink
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (3 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 05/10] alfred: Split translate_mac from debugfs backend Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 07/10] alfred: Split get_tq from debugfs backend Sven Eckelmann
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The debugfs entries are only available on the main network namespace. All
other network namespaces have to fall back to netlink to read the global
translation table.

alfred has therefore try to access the translation table via netlink and
try to fall back to the debugfs table in case the batman-adv module doesn't
support BATADV_CMD_GET_TRANSTABLE_GLOBAL.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 batadv_query.c |  49 +++++++++++++-
 netlink.c      | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 netlink.h      |  23 +++++++
 3 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/batadv_query.c b/batadv_query.c
index b0679fc..9082576 100644
--- a/batadv_query.c
+++ b/batadv_query.c
@@ -33,12 +33,53 @@
 #include <sys/capability.h>
 #endif
 #include <sys/types.h>
+
+#include "netlink.h"
 #include "debugfs.h"
 
 #define DEBUG_BATIF_PATH_FMT "%s/batman_adv/%s"
 #define DEBUG_TRANSTABLE_GLOBAL "transtable_global"
 #define DEBUG_ORIGINATORS "originators"
 
+static int enable_net_admin_capability(int enable)
+{
+	int ret = 0;
+
+#ifdef CONFIG_ALFRED_CAPABILITIES
+	cap_t cap_cur;
+	cap_flag_value_t cap_flag;
+	cap_value_t cap_net_admin = CAP_NET_ADMIN;
+
+	if (enable)
+		cap_flag = CAP_SET;
+	else
+		cap_flag = CAP_CLEAR;
+
+	cap_cur = cap_get_proc();
+	if (!cap_cur) {
+		perror("cap_get_proc");
+		return -1;
+	}
+
+	ret = cap_set_flag(cap_cur, CAP_EFFECTIVE, 1, &cap_net_admin, cap_flag);
+	if (ret < 0) {
+		perror("cap_set_flag");
+		goto out;
+	}
+
+	ret = cap_set_proc(cap_cur);
+	if (ret < 0) {
+		perror("cap_set_proc");
+		goto out;
+	}
+
+out:
+	cap_free(cap_cur);
+#endif
+
+	return ret;
+}
+
 int mac_to_ipv6(const struct ether_addr *mac, struct in6_addr *addr)
 {
 	memset(addr, 0, sizeof(*addr));
@@ -212,6 +253,7 @@ struct ether_addr *translate_mac(const char *mesh_iface,
 	struct ether_addr in_mac;
 	static struct ether_addr out_mac;
 	struct ether_addr *mac_result;
+	int ret;
 
 	/* input mac has to be copied because it could be in the shared
 	 * ether_aton buffer
@@ -220,7 +262,12 @@ struct ether_addr *translate_mac(const char *mesh_iface,
 	memcpy(&out_mac, mac, sizeof(out_mac));
 	mac_result = &out_mac;
 
-	translate_mac_debugfs(mesh_iface, &in_mac, mac_result);
+	enable_net_admin_capability(1);
+	ret = translate_mac_netlink(mesh_iface, &in_mac, mac_result);
+	enable_net_admin_capability(0);
+
+	if (ret == -EOPNOTSUPP)
+		translate_mac_debugfs(mesh_iface, &in_mac, mac_result);
 
 	return mac_result;
 }
diff --git a/netlink.c b/netlink.c
index d9c1f55..e1ebc07 100644
--- a/netlink.c
+++ b/netlink.c
@@ -21,6 +21,14 @@
 
 #include "netlink.h"
 
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <net/ethernet.h>
+#include <net/if.h>
 #include <netlink/netlink.h>
 #include <netlink/genl/genl.h>
 #include <netlink/genl/ctrl.h>
@@ -28,6 +36,10 @@
 
 #include "batman_adv.h"
 
+#ifndef __unused
+#define __unused __attribute__((unused))
+#endif
+
 struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_VERSION]		= { .type = NLA_STRING },
 	[BATADV_ATTR_ALGO_NAME]		= { .type = NLA_STRING },
@@ -82,3 +94,189 @@ struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 					    .maxlen = ETH_ALEN },
 	[BATADV_ATTR_BLA_CRC]		= { .type = NLA_U16 },
 };
+
+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 __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;
+}
+
+static const int translate_mac_netlink_mandatory[] = {
+	BATADV_ATTR_TT_ADDRESS,
+	BATADV_ATTR_ORIG_ADDRESS,
+};
+
+struct translate_mac_netlink_opts {
+	struct ether_addr mac;
+	bool found;
+	struct nlquery_opts query_opts;
+};
+
+static int translate_mac_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 translate_mac_netlink_opts *opts;
+	struct genlmsghdr *ghdr;
+	uint8_t *addr;
+	uint8_t *orig;
+
+	opts = container_of(query_opts, struct translate_mac_netlink_opts,
+			    query_opts);
+
+	if (!genlmsg_valid_hdr(nlh, 0))
+		return NL_OK;
+
+	ghdr = nlmsg_data(nlh);
+
+	if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_GLOBAL)
+		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, translate_mac_netlink_mandatory,
+				    ARRAY_SIZE(translate_mac_netlink_mandatory)))
+		return NL_OK;
+
+	addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]);
+	orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
+
+	if (!attrs[BATADV_ATTR_FLAG_BEST])
+		return NL_OK;
+
+	if (memcmp(&opts->mac, addr, ETH_ALEN) != 0)
+		return NL_OK;
+
+	memcpy(&opts->mac, orig, ETH_ALEN);
+	opts->found = true;
+	opts->query_opts.err = 0;
+
+	return NL_STOP;
+}
+
+int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
+			  struct ether_addr *mac_out)
+{
+	struct translate_mac_netlink_opts opts = {
+		.found = false,
+		.query_opts = {
+			.err = 0,
+		},
+	};
+	int ret;
+
+	memcpy(&opts.mac, mac, ETH_ALEN);
+
+	ret = netlink_query_common(mesh_iface,
+				   BATADV_CMD_GET_TRANSTABLE_GLOBAL,
+			           translate_mac_netlink_cb, &opts.query_opts);
+	if (ret < 0)
+		return ret;
+
+	if (!opts.found)
+		return -ENOENT;
+
+	memcpy(mac_out, &opts.mac, ETH_ALEN);
+
+	return 0;
+}
diff --git a/netlink.h b/netlink.h
index f903563..8e54235 100644
--- a/netlink.h
+++ b/netlink.h
@@ -24,6 +24,29 @@
 
 #include <netlink/genl/genl.h>
 #include <netlink/genl/ctrl.h>
+#include <stddef.h>
+
+struct ether_addr;
+
+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);
+int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
+			  struct ether_addr *mac_out);
 
 extern struct nla_policy batadv_netlink_policy[];
 
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 07/10] alfred: Split get_tq from debugfs backend
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (4 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 06/10] alfred: Translate mac addresses via netlink Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 08/10] alfred: Query TQ of originators via netlink Sven Eckelmann
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The debugfs tables cannot be used by the alfred in network namespaces.
These have to use netlink. Thus the get_tq should be less tightly linked to
the debugfs tables to implement optional netlink support.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 batadv_query.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/batadv_query.c b/batadv_query.c
index 9082576..a893995 100644
--- a/batadv_query.c
+++ b/batadv_query.c
@@ -272,7 +272,8 @@ struct ether_addr *translate_mac(const char *mesh_iface,
 	return mac_result;
 }
 
-uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac)
+static int get_tq_debugfs(const char *mesh_iface, struct ether_addr *mac,
+			  uint8_t *tq)
 {
 	enum {
 		orig_mac,
@@ -288,7 +289,7 @@ uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac)
 	char *line = NULL;
 	char *input, *saveptr, *token;
 	int line_invalid;
-	uint8_t tq = 0;
+	bool found = false;
 
 	memcpy(&in_mac, mac, sizeof(in_mac));
 
@@ -297,7 +298,7 @@ uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac)
 
 	f = fopen(full_path, "r");
 	if (!f)
-		goto out;
+		return -EOPNOTSUPP;
 
 	while (getline(&line, &len, f) != -1) {
 		line_invalid = 0;
@@ -338,7 +339,8 @@ uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac)
 					line_invalid = 1;
 				} else {
 					token[strlen(token) - 1] = '\0';
-					tq = strtol(token, NULL, 10);
+					*tq = strtol(token, NULL, 10);
+					found = true;
 					goto out;
 				}
 				break;
@@ -353,5 +355,24 @@ out:
 	if (f)
 		fclose(f);
 	free(line);
+
+	if (found)
+		return 0;
+	else
+		return -ENOENT;
+}
+
+uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac)
+{
+	struct ether_addr in_mac;
+	uint8_t tq = 0;
+
+	/* input mac has to be copied because it could be in the shared
+	 * ether_aton buffer
+	 */
+	memcpy(&in_mac, mac, sizeof(in_mac));
+
+	get_tq_debugfs(mesh_iface, &in_mac, &tq);
+
 	return tq;
 }
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 08/10] alfred: Query TQ of originators via netlink
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (5 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 07/10] alfred: Split get_tq from debugfs backend Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 09/10] alfred: vis: Save device index in interface list Sven Eckelmann
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The debugfs entries are only available on the main network namespace. All
other network namespaces have to fall back to netlink to read the
originator table.

alfred has therefore try to access the originator via netlink and try to
fall back to the debugfs table in case the batman-adv module doesn't
support BATADV_CMD_GET_ORIGINATORS.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 batadv_query.c |  8 +++++-
 netlink.c      | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 netlink.h      |  2 ++
 3 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/batadv_query.c b/batadv_query.c
index a893995..a671b79 100644
--- a/batadv_query.c
+++ b/batadv_query.c
@@ -366,13 +366,19 @@ uint8_t get_tq(const char *mesh_iface, struct ether_addr *mac)
 {
 	struct ether_addr in_mac;
 	uint8_t tq = 0;
+	int ret;
 
 	/* input mac has to be copied because it could be in the shared
 	 * ether_aton buffer
 	 */
 	memcpy(&in_mac, mac, sizeof(in_mac));
 
-	get_tq_debugfs(mesh_iface, &in_mac, &tq);
+	enable_net_admin_capability(1);
+	ret = get_tq_netlink(mesh_iface, &in_mac, &tq);
+	enable_net_admin_capability(0);
+
+	if (ret == -EOPNOTSUPP)
+		get_tq_debugfs(mesh_iface, &in_mac, &tq);
 
 	return tq;
 }
diff --git a/netlink.c b/netlink.c
index e1ebc07..1b5695c 100644
--- a/netlink.c
+++ b/netlink.c
@@ -280,3 +280,88 @@ int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
 
 	return 0;
 }
+
+static const int get_tq_netlink_mandatory[] = {
+	BATADV_ATTR_ORIG_ADDRESS,
+	BATADV_ATTR_TQ,
+};
+
+struct get_tq_netlink_opts {
+	struct ether_addr mac;
+	uint8_t tq;
+	bool found;
+	struct nlquery_opts query_opts;
+};
+
+static int get_tq_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 get_tq_netlink_opts *opts;
+	struct genlmsghdr *ghdr;
+	uint8_t *orig;
+	uint8_t tq;
+
+	opts = container_of(query_opts, struct get_tq_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, get_tq_netlink_mandatory,
+				    ARRAY_SIZE(get_tq_netlink_mandatory)))
+		return NL_OK;
+
+	orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]);
+	tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);
+
+	if (!attrs[BATADV_ATTR_FLAG_BEST])
+		return NL_OK;
+
+	if (memcmp(&opts->mac, orig, ETH_ALEN) != 0)
+		return NL_OK;
+
+	opts->tq = tq;
+	opts->found = true;
+	opts->query_opts.err = 0;
+
+	return NL_STOP;
+}
+
+int get_tq_netlink(const char *mesh_iface, const struct ether_addr *mac,
+		   uint8_t *tq)
+{
+	struct get_tq_netlink_opts opts = {
+		.tq = 0,
+		.found = false,
+		.query_opts = {
+			.err = 0,
+		},
+	};
+	int ret;
+
+	memcpy(&opts.mac, mac, ETH_ALEN);
+
+	ret = netlink_query_common(mesh_iface,  BATADV_CMD_GET_ORIGINATORS,
+			           get_tq_netlink_cb, &opts.query_opts);
+	if (ret < 0)
+		return ret;
+
+	if (!opts.found)
+		return -ENOENT;
+
+	*tq = opts.tq;
+
+	return 0;
+}
diff --git a/netlink.h b/netlink.h
index 8e54235..b08e872 100644
--- a/netlink.h
+++ b/netlink.h
@@ -47,6 +47,8 @@ int missing_mandatory_attrs(struct nlattr *attrs[],  const int mandatory[],
 			    size_t num);
 int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
 			  struct ether_addr *mac_out);
+int get_tq_netlink(const char *mesh_iface, const struct ether_addr *mac,
+		   uint8_t *tq);
 
 extern struct nla_policy batadv_netlink_policy[];
 
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 09/10] alfred: vis: Save device index in interface list
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (6 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 08/10] alfred: Query TQ of originators via netlink Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 10/10] alfred: vis: Add support for netlink Sven Eckelmann
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The netlink messages don't contain the complete names. Instead the device
indexes are used. To avoid extra overhead of retrieving the device name for
each index, the interface list can just be used again as cache by making it
queryable via the ifindex.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 vis/vis.c | 13 ++++++++++---
 vis/vis.h |  1 +
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/vis/vis.c b/vis/vis.c
index 7eab781..bac451b 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -125,9 +125,10 @@ static int get_if_mac(char *ifname, uint8_t *mac)
 	return 0;
 }
 
-static int get_if_index(struct globals *globals, char *ifname)
+static int get_if_index_byname(struct globals *globals, char *ifname)
 {
 	struct iface_list_entry *i_entry;
+	int devindex;
 	int i;
 
 	if (!ifname)
@@ -139,6 +140,11 @@ static int get_if_index(struct globals *globals, char *ifname)
 			return i;
 		i++;
 	}
+
+	devindex = if_nametoindex(ifname);
+	if (!devindex)
+		return -1;
+
 	i_entry = malloc(sizeof(*i_entry));
 	if (!i_entry)
 		return -1;
@@ -148,6 +154,7 @@ static int get_if_index(struct globals *globals, char *ifname)
 		return -1;
 	}
 
+	i_entry->devindex = devindex;
 	strncpy(i_entry->name, ifname, sizeof(i_entry->name));
 	/* just to be safe ... */
 	i_entry->name[sizeof(i_entry->name) - 1] = 0;
@@ -301,7 +308,7 @@ static int register_interfaces(struct globals *globals)
 			*content_newline = '\0';
 
 		if (strcmp(file_content, "active") == 0)
-			get_if_index(globals, iface_dir->d_name);
+			get_if_index_byname(globals, iface_dir->d_name);
 
 free_line:
 		free(file_content);
@@ -364,7 +371,7 @@ static int parse_orig_list(struct globals *globals)
 				if (!mac)
 					continue;
 
-				ifindex = get_if_index(globals, iface);
+				ifindex = get_if_index_byname(globals, iface);
 				if (ifindex < 0)
 					continue;
 
diff --git a/vis/vis.h b/vis/vis.h
index 4c98064..c25a75b 100644
--- a/vis/vis.h
+++ b/vis/vis.h
@@ -77,6 +77,7 @@ struct vis_v1 {
 struct iface_list_entry {
 	char name[256];
 	uint8_t mac[ETH_ALEN];
+	int devindex;
 	struct list_head list;
 };
 
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 10/10] alfred: vis: Add support for netlink
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (7 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 09/10] alfred: vis: Save device index in interface list Sven Eckelmann
@ 2016-06-05 18:47 ` Sven Eckelmann
  2016-07-16  7:28 ` [B.A.T.M.A.N.] [PATCH 11/11] alfred: Switch netlink uapi header copyright to ISC Sven Eckelmann
  2016-07-26 11:55 ` [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Simon Wunderlich
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-06-05 18:47 UTC (permalink / raw)
  To: b.a.t.m.a.n

The debugfs entries are only available on the main network namespace.
All other network namespaces have to fallback to netlink to read the local
translation table and the originator table.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 vis/vis.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 217 insertions(+), 2 deletions(-)

diff --git a/vis/vis.c b/vis/vis.c
index bac451b..d6bac41 100644
--- a/vis/vis.c
+++ b/vis/vis.c
@@ -35,10 +35,18 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
+
+#include "batman_adv.h"
+#include "netlink.h"
 #include "debugfs.h"
 
 static struct globals vis_globals;
 
+struct vis_netlink_opts {
+	struct globals *globals;
+	struct nlquery_opts query_opts;
+};
+
 static char *read_file(char *fname)
 {
 	FILE *fp;
@@ -163,6 +171,45 @@ static int get_if_index_byname(struct globals *globals, char *ifname)
 	return i;
 }
 
+static int get_if_index_devindex(struct globals *globals, int devindex)
+{
+	struct iface_list_entry *i_entry;
+	char *ifname;
+	char ifnamebuf[IF_NAMESIZE];
+	int i;
+
+	if (!devindex)
+		return -1;
+
+	i = 0;
+	list_for_each_entry(i_entry, &globals->iface_list, list) {
+		if (i_entry->devindex == devindex)
+			return i;
+		i++;
+	}
+
+	ifname = if_indextoname(devindex, ifnamebuf);
+	if (!ifname)
+		return -1;
+
+	i_entry = malloc(sizeof(*i_entry));
+	if (!i_entry)
+		return -1;
+
+	if (get_if_mac(ifname, i_entry->mac)) {
+		free(i_entry);
+		return -1;
+	}
+
+	i_entry->devindex = devindex;
+	strncpy(i_entry->name, ifname, sizeof(i_entry->name));
+	/* just to be safe ... */
+	i_entry->name[sizeof(i_entry->name) - 1] = 0;
+	list_add_tail(&i_entry->list, &globals->iface_list);
+
+	return i;
+}
+
 static int alfred_open_sock(struct globals *globals)
 {
 	struct sockaddr_un addr;
@@ -189,7 +236,75 @@ static int alfred_open_sock(struct globals *globals)
 	return 0;
 }
 
-static int parse_transtable_local(struct globals *globals)
+static const int parse_transtable_local_mandatory[] = {
+	BATADV_ATTR_TT_ADDRESS,
+};
+
+static int parse_transtable_local_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 vis_netlink_opts *opts;
+	struct genlmsghdr *ghdr;
+	struct vis_list_entry *v_entry;
+	uint8_t *addr;
+
+	opts = container_of(query_opts, struct vis_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, parse_transtable_local_mandatory,
+				    ARRAY_SIZE(parse_transtable_local_mandatory)))
+		return NL_OK;
+
+	addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]);
+
+	v_entry = malloc(sizeof(*v_entry));
+	if (!v_entry)
+		return NL_OK;
+
+	memcpy(v_entry->v.mac, addr, ETH_ALEN);
+	v_entry->v.ifindex = 255;
+	v_entry->v.qual = 0;
+	list_add_tail(&v_entry->list, &opts->globals->entry_list);
+
+	return NL_OK;
+}
+
+static int parse_transtable_local_netlink(struct globals *globals)
+{
+	struct vis_netlink_opts opts = {
+		.globals = globals,
+		.query_opts = {
+			.err = 0,
+		},
+	};
+	int ret;
+
+	ret = netlink_query_common(globals->interface,
+				   BATADV_CMD_GET_TRANSTABLE_LOCAL,
+			           parse_transtable_local_netlink_cb,
+				   &opts.query_opts);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int parse_transtable_local_debugfs(struct globals *globals)
 {
 	char *fbuf;
 	char *lptr, *tptr;
@@ -241,6 +356,17 @@ static int parse_transtable_local(struct globals *globals)
 	return 0;
 }
 
+static int parse_transtable_local(struct globals *globals)
+{
+	int ret;
+
+	ret = parse_transtable_local_netlink(globals);
+	if (ret != EOPNOTSUPP)
+		return ret;
+
+	return parse_transtable_local_debugfs(globals);
+}
+
 static void clear_lists(struct globals *globals)
 {
 	struct vis_list_entry *v_entry, *v_entry_safe;
@@ -325,8 +451,86 @@ err:
 	return EXIT_FAILURE;
 }
 
+static const int parse_orig_list_mandatory[] = {
+	BATADV_ATTR_ORIG_ADDRESS,
+	BATADV_ATTR_TQ,
+	BATADV_ATTR_HARD_IFINDEX,
+};
 
-static int parse_orig_list(struct globals *globals)
+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 vis_netlink_opts *opts;
+	struct genlmsghdr *ghdr;
+	struct vis_list_entry *v_entry;
+	uint8_t *orig;
+	uint8_t tq;
+	uint32_t hardif;
+
+	opts = container_of(query_opts, struct vis_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]);
+	tq = nla_get_u8(attrs[BATADV_ATTR_TQ]);
+	hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]);
+
+	if (tq < 1)
+		return NL_OK;
+
+	v_entry = malloc(sizeof(*v_entry));
+	if (!v_entry)
+		return NL_OK;
+
+	memcpy(v_entry->v.mac, orig, ETH_ALEN);
+	v_entry->v.ifindex = get_if_index_devindex(opts->globals, hardif);
+	v_entry->v.qual = tq;
+	list_add_tail(&v_entry->list, &opts->globals->entry_list);
+
+	return NL_OK;
+}
+
+static int parse_orig_list_netlink(struct globals *globals)
+{
+	struct vis_netlink_opts opts = {
+		.globals = globals,
+		.query_opts = {
+			.err = 0,
+		},
+	};
+	int ret;
+
+	ret = netlink_query_common(globals->interface,
+				   BATADV_CMD_GET_ORIGINATORS,
+			           parse_orig_list_netlink_cb, &opts.query_opts);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int parse_orig_list_debugfs(struct globals *globals)
 {
 	char *fbuf;
 	char *lptr, *tptr;
@@ -393,6 +597,17 @@ static int parse_orig_list(struct globals *globals)
 	return 0;
 }
 
+static int parse_orig_list(struct globals *globals)
+{
+	int ret;
+
+	ret = parse_orig_list_netlink(globals);
+	if (ret != EOPNOTSUPP)
+		return ret;
+
+	return parse_orig_list_debugfs(globals);
+}
+
 static int vis_publish_data(struct globals *globals)
 {
 	int len, ret;
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [B.A.T.M.A.N.] [PATCH 11/11] alfred: Switch netlink uapi header copyright to ISC
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (8 preceding siblings ...)
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 10/10] alfred: vis: Add support for netlink Sven Eckelmann
@ 2016-07-16  7:28 ` Sven Eckelmann
  2016-07-26 11:55 ` [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Simon Wunderlich
  10 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-07-16  7:28 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Marek Lindner

The batman_adv.h netlink header is used by userspace programs to use the
genl interface of batman-adv. These programs may not use the GPL-2 license.
The header should therefore state clearly that it can be used freely and
the license of the program which uses this header is not affected.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Matthias Schiffer <mschiffer@universe-factory.net>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
 batman_adv.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/batman_adv.h b/batman_adv.h
index 37157d0..734fe83 100644
--- a/batman_adv.h
+++ b/batman_adv.h
@@ -2,17 +2,17 @@
  *
  * Matthias Schiffer
  *
- * 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.
+ * 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.
  *
- * 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, see <http://www.gnu.org/licenses/>.
+ * 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_
-- 
2.8.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies
  2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies Sven Eckelmann
@ 2016-07-21 15:58   ` Simon Wunderlich
  2016-07-21 16:01     ` Sven Eckelmann
  0 siblings, 1 reply; 14+ messages in thread
From: Simon Wunderlich @ 2016-07-21 15:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 909 bytes --]

> diff --git a/vis/batman_adv.h b/vis/batman_adv.h
> new file mode 120000
> index 0000000..72222e9
> --- /dev/null
> +++ b/vis/batman_adv.h
> @@ -0,0 +1 @@
> +../batman_adv.h
> \ No newline at end of file
> diff --git a/vis/netlink.c b/vis/netlink.c
> new file mode 120000
> index 0000000..06d13cc
> --- /dev/null
> +++ b/vis/netlink.c
> @@ -0,0 +1 @@
> +../netlink.c
> \ No newline at end of file
> diff --git a/vis/netlink.h b/vis/netlink.h
> new file mode 120000
> index 0000000..c7a63b5
> --- /dev/null
> +++ b/vis/netlink.h
> @@ -0,0 +1 @@
> +../netlink.h
> \ No newline at end of file

I was wondering why you use symlinks here, while we pull in the other headers 
from their original paths (../packet.h, ../list.h).

We should probably keep the header handling consistent. What would be your 
opinion whether we should use relative paths or symlinks?

Thanks,
     Simon

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies
  2016-07-21 15:58   ` Simon Wunderlich
@ 2016-07-21 16:01     ` Sven Eckelmann
  0 siblings, 0 replies; 14+ messages in thread
From: Sven Eckelmann @ 2016-07-21 16:01 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 1259 bytes --]

On Donnerstag, 21. Juli 2016 17:58:07 CEST Simon Wunderlich wrote:
> > diff --git a/vis/batman_adv.h b/vis/batman_adv.h
> > new file mode 120000
> > index 0000000..72222e9
> > --- /dev/null
> > +++ b/vis/batman_adv.h
> > @@ -0,0 +1 @@
> > +../batman_adv.h
> > \ No newline at end of file
> > diff --git a/vis/netlink.c b/vis/netlink.c
> > new file mode 120000
> > index 0000000..06d13cc
> > --- /dev/null
> > +++ b/vis/netlink.c
> > @@ -0,0 +1 @@
> > +../netlink.c
> > \ No newline at end of file
> > diff --git a/vis/netlink.h b/vis/netlink.h
> > new file mode 120000
> > index 0000000..c7a63b5
> > --- /dev/null
> > +++ b/vis/netlink.h
> > @@ -0,0 +1 @@
> > +../netlink.h
> > \ No newline at end of file
> 
> I was wondering why you use symlinks here, while we pull in the other
> headers from their original paths (../packet.h, ../list.h).
> 
> We should probably keep the header handling consistent. What would be your
> opinion whether we should use relative paths or symlinks?

This doesn't work for netlink.c because it would break during parallel builds. 
And netlink.c requires batman_adv.h which must be in the search path for it.

Possible would be to symlink netlink.c and netlink.h and Add "-I.." to 
CPPFLAGS of batadv-vis.

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status
  2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
                   ` (9 preceding siblings ...)
  2016-07-16  7:28 ` [B.A.T.M.A.N.] [PATCH 11/11] alfred: Switch netlink uapi header copyright to ISC Sven Eckelmann
@ 2016-07-26 11:55 ` Simon Wunderlich
  10 siblings, 0 replies; 14+ messages in thread
From: Simon Wunderlich @ 2016-07-26 11:55 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 420 bytes --]

On Sunday 05 June 2016 20:46:59 Sven Eckelmann wrote:
> The content of batman_adv/iface_status ends with a newline. Thus
> register_interfaces has to make sure that it only compares the first line
> without the \n when comparing with the status string.
> 
> Signed-off-by: Sven Eckelmann <sven@narfation.org>

I've applied the whole series (78e1d64..5b67293). We can beautify the header 
stuff later.

Cheers,
     Simon

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-07-26 11:55 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-05 18:46 [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 02/10] alfred: Split list of objects in Makefile into separate lines Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 03/10] alfred: Add netlink dependencies Sven Eckelmann
2016-07-21 15:58   ` Simon Wunderlich
2016-07-21 16:01     ` Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 04/10] alfred: Add CAP_NET_ADMIN capabilities for netlink Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 05/10] alfred: Split translate_mac from debugfs backend Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 06/10] alfred: Translate mac addresses via netlink Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 07/10] alfred: Split get_tq from debugfs backend Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 08/10] alfred: Query TQ of originators via netlink Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 09/10] alfred: vis: Save device index in interface list Sven Eckelmann
2016-06-05 18:47 ` [B.A.T.M.A.N.] [PATCH 10/10] alfred: vis: Add support for netlink Sven Eckelmann
2016-07-16  7:28 ` [B.A.T.M.A.N.] [PATCH 11/11] alfred: Switch netlink uapi header copyright to ISC Sven Eckelmann
2016-07-26 11:55 ` [B.A.T.M.A.N.] [PATCH 01/10] alfred: vis: Fix parsing of iface_status Simon Wunderlich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).