Skip to contentSkip to conversation

throughput meter on steroids^W netlink

RFC Superseded Sven Eckelmann 1 participant 10 messages May 4, 2016

Subsystems (2)

v4 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

Hi,

I was asked by the batman-adv maintainers to port the tp_meter to netlink. And I shouldn't do it with the patches from Andrew/Matthias applied but with only a small part of patch 4.

I know, this isn't the nicest move but it allowed me to restructure the first commit a little bit. I've extracted the part which introduced the netlink family + a restructured batman_adv.h. I've also added the part which introduces the generic mesh information as extra patch (+kerneldoc). This added some attributes which I need in tp_meter. But I can also remove the patch and only merge the necessary parts.

@Andrew, I hope you don't take it the wrong way. I really like your work and even borrowed parts of the code for the tp_meter interface. So you are now allowed to criticize the hell out of the changes and request some free beer from Antonio, Marek and Simon :). But I hope that you like the adjustments to the initial parts (at least a little bit). You would have to rebase your changes (which I still want to get integrated) on top when these things here are merged. I would also be willing to do the rebase myself and send you the result (so you can add the kerneldoc and maybe make further adjustments).

The only "big" conflicts I see are related to the order of attributes. But this was a long day for me and I may have forgotten something.

@the_rest: Do you find the bugs introduced by moving it to netlink?

The one which I know about is the inability to receive signals while the kernel is doing the wait_event (So the BATADV_CMD_TP_METER_CANCEL doesn't work at all). I am waiting for recommendations. The one which
comes to my mind is not to wait for the thing to finish but to just return immediately. The client would then have to some kind of event listener enabled which waits until the thing finished. This approach would also require some kind of session info exchange. Does anyone else have a good idea?

Kind regards,
Sven

#1 lore raw

PATCH v4 1/5 batman-adv: Add stripped down version of MAINTAINERS file

From: Sven Eckelmann <[email protected]>

The MAINTAINERS file has to modified from time to time when either some URLs change or some new files are added. These changes can easily be lost when they actually should be part of a change adding/deleting a file.

---
 MAINTAINERS | 12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 MAINTAINERS
MAINTAINERS new file +12 -0
new file mode 100644
index 0000000..7e47274
@@ -0,0 +1,12 @@
+BATMAN ADVANCED
+M:	Marek Lindner <[email protected]>
+M:	Simon Wunderlich <[email protected]>
+M:	Antonio Quartulli <[email protected]>
+L:	[email protected] (moderated for non-subscribers)
+W:	https://www.open-mesh.org/
+Q:	https://patchwork.open-mesh.org/project/batman/list/
+S:	Maintained
+F:	Documentation/ABI/testing/sysfs-class-net-batman-adv
+F:	Documentation/ABI/testing/sysfs-class-net-mesh
+F:	Documentation/networking/batman-adv.txt
+F:	net/batman-adv/
Signature · 1 line
2.8.1
#2 lore raw

PATCH v4 2/5 batman-adv: add generic netlink family for batman-adv

In reply to Sven Eckelmann

From: Matthias Schiffer <[email protected]>

debugfs is currently severely broken virtually everywhere in the kernel where files are dynamically added and removed (see
http://lkml.iu.edu/hypermail/linux/kernel/1506.1/02196.html for some details). In addition to that, debugfs is not namespace-aware.

Instead of adding new debugfs entries, the whole infrastructure should be moved to netlink. This will fix the long standing problem of large buffers for debug tables and hard to parse text files.

[[email protected]: Strip down commit to only add genl family, add missing kerneldoc]

---
 MAINTAINERS                     |  1 +
 Makefile                        |  1 +
 compat-include/net/genetlink.h  | 34 ++++++++++++++++++++++++
 include/uapi/linux/batman_adv.h | 53 ++++++++++++++++++++++++++++++++++++++
 net/batman-adv/Makefile         |  1 +
 net/batman-adv/main.c           |  3 +++
 net/batman-adv/netlink.c        | 57 +++++++++++++++++++++++++++++++++++++++++
 net/batman-adv/netlink.h        | 24 +++++++++++++++++
 8 files changed, 174 insertions(+)
 create mode 100644 compat-include/net/genetlink.h
 create mode 100644 include/uapi/linux/batman_adv.h
 create mode 100644 net/batman-adv/netlink.c
 create mode 100644 net/batman-adv/netlink.h
MAINTAINERS +1 -0
index 7e47274..ff0322d 100644
@@ -9,4 +9,5 @@ S:	Maintained
 F:	Documentation/ABI/testing/sysfs-class-net-batman-adv
 F:	Documentation/ABI/testing/sysfs-class-net-mesh
 F:	Documentation/networking/batman-adv.txt
+F:	include/uapi/linux/batman_adv.h
 F:	net/batman-adv/
Makefile +1 -0
index 5d2c058..f17bde5 100644
@@ -45,6 +45,7 @@ REVISION= $(shell	if [ -d "$(PWD)/.git" ]; then \
 			fi)
 export NOSTDINC_FLAGS := \
 	-I$(PWD)/compat-include/ \
+	-I$(PWD)/include/ \
 	-include $(PWD)/compat.h \
 	$(CFLAGS)
 
compat-include/net/genetlink.h new file +34 -0
new file mode 100644
index 0000000..bf1ba3d
@@ -0,0 +1,34 @@
+/* Copyright (C) 2007-2016 B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner, Simon Wunderlich
+ *
+ * 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/>.
+ *
+ * This file contains macros for maintaining compatibility with older versions
+ * of the Linux kernel.
+ */
+
+#ifndef _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_
+#define _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_
+
+#include <linux/version.h>
+#include_next <net/genetlink.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
+
+#define genl_register_family_with_ops(family, ops)     \
+	genl_register_family_with_ops((family), (ops), ARRAY_SIZE(ops))
+
+#endif /* < KERNEL_VERSION(3, 13, 0) */
+
+#endif /* _NET_BATMAN_ADV_COMPAT_NET_GENETLINK_H_ */
include/uapi/linux/batman_adv.h new file +53 -0

53 lines not on this page · raw message

net/batman-adv/Makefile +1 -0
index 797cf2f..4e5adba 100644
@@ -33,6 +33,7 @@ batman-adv-y += hash.o
 batman-adv-y += icmp_socket.o
 batman-adv-y += main.o
 batman-adv-$(CONFIG_BATMAN_ADV_MCAST) += multicast.o
+batman-adv-y += netlink.o
 batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o
 batman-adv-y += originator.o
 batman-adv-y += routing.o
net/batman-adv/main.c +3 -0
index 5f2974b..f229af8 100644
@@ -57,6 +57,7 @@
 #include "hard-interface.h"
 #include "icmp_socket.h"
 #include "multicast.h"
+#include "netlink.h"
 #include "network-coding.h"
 #include "originator.h"
 #include "packet.h"
@@ -101,6 +102,7 @@ static int __init batadv_init(void)
 
 	register_netdevice_notifier(&batadv_hard_if_notifier);
 	rtnl_link_register(&batadv_link_ops);
+	batadv_netlink_register();
 
 	pr_info("B.A.T.M.A.N. advanced %s (compatibility version %i) loaded\n",
 		BATADV_SOURCE_VERSION, BATADV_COMPAT_VERSION);
@@ -111,6 +113,7 @@ static int __init batadv_init(void)
 static void __exit batadv_exit(void)
 {
 	batadv_debugfs_destroy();
+	batadv_netlink_unregister();
 	rtnl_link_unregister(&batadv_link_ops);
 	unregister_netdevice_notifier(&batadv_hard_if_notifier);
 	batadv_hardif_remove_interfaces();
net/batman-adv/netlink.c new file +57 -0

57 lines not on this page · raw message

net/batman-adv/netlink.h new file +24 -0
new file mode 100644
index 0000000..fa152a8
@@ -0,0 +1,24 @@
+/* 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 _NET_BATMAN_ADV_NETLINK_H_
+#define _NET_BATMAN_ADV_NETLINK_H_
+
+void batadv_netlink_register(void);
+void batadv_netlink_unregister(void);
+
+#endif /* _NET_BATMAN_ADV_NETLINK_H_ */
Signature · 1 line
2.8.1
#3 lore raw

PATCH v4 3/5 batman-adv: add netlink command to query generic mesh information files

In reply to Sven Eckelmann

From: Matthias Schiffer <[email protected]>

BATADV_CMD_GET_MESH_INFO is used to query basic information about a batman-adv softif (name, index and MAC address for both the softif and the primary hardif; routing algorithm; batman-adv version).

[[email protected]: Reduce the number of changes to BATADV_CMD_GET_MESH_INFO, add missing kerneldoc, add policy for attributes]

---
 compat.h                        |   6 ++
 include/uapi/linux/batman_adv.h |  18 ++++++
 net/batman-adv/netlink.c        | 135 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+)
compat.h +6 -0
index 5a5f478..7d5c8b6 100644
@@ -62,6 +62,12 @@ static int __batadv_interface_kill_vid(struct net_device *dev, __be16 proto,\
 
 #endif /* < KERNEL_VERSION(3, 3, 0) */
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
+
+#define snd_portid snd_pid
+
+#endif /* < KERNEL_VERSION(3, 7, 0) */
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
 
 #define batadv_interface_set_mac_addr(x, y) \
include/uapi/linux/batman_adv.h +18 -0
index ba611a7..a908140 100644
@@ -24,12 +24,28 @@
  * 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_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,
 	/* add attributes above here, update the policy in netlink.c */
 	__BATADV_ATTR_AFTER_LAST,
 	NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
@@ -40,11 +56,13 @@ enum batadv_nl_attrs {
  * 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_AFTER_LAST: internal use
  * @BATADV_CMD_MAX: highest used command number
  */
 enum batadv_nl_commands {
 	BATADV_CMD_UNSPEC,
+	BATADV_CMD_GET_MESH_INFO,
 	/* add new commands above here */
 	__BATADV_CMD_AFTER_LAST,
 	BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
net/batman-adv/netlink.c +135 -0

154 lines not on this page · raw message

Signature · 1 line
2.8.1
#4 lore raw

PATCH v4 4/5 batman-adv: return netdev status in the TX path

In reply to Sven Eckelmann

From: Antonio Quartulli <[email protected]>

Return the proper netdev TX status along the TX path so that the tp_meter can understand when the queue is full and should stop sending packets.

---
 net/batman-adv/fragmentation.c | 41 +++++++++++++++++++++++++----------------
 net/batman-adv/fragmentation.h |  6 +++---
 net/batman-adv/main.c          |  4 +++-
 net/batman-adv/routing.c       | 24 ++++++++++++++----------
 net/batman-adv/send.c          | 25 +++++++++++++------------
 5 files changed, 58 insertions(+), 42 deletions(-)
net/batman-adv/fragmentation.c +25 -16
index 65536db..4cb7da2 100644
@@ -434,11 +434,12 @@ err:
  * @orig_node: final destination of the created fragments
  * @neigh_node: next-hop of the created fragments
  *
- * Return: true on success, false otherwise.
+ * Return: the netdev tx status or -1 in case of error.
+ * When -1 is returned the skb is not consumed.
  */
-bool batadv_frag_send_packet(struct sk_buff *skb,
-			     struct batadv_orig_node *orig_node,
-			     struct batadv_neigh_node *neigh_node)
+int batadv_frag_send_packet(struct sk_buff *skb,
+			    struct batadv_orig_node *orig_node,
+			    struct batadv_neigh_node *neigh_node)
 {
 	struct batadv_priv *bat_priv;
 	struct batadv_hard_iface *primary_if = NULL;
@@ -447,7 +448,7 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
 	unsigned int mtu = neigh_node->if_incoming->net_dev->mtu;
 	unsigned int header_size = sizeof(frag_header);
 	unsigned int max_fragment_size, max_packet_size;
-	bool ret = false;
+	int ret = -1;
 
 	/* To avoid merge and refragmentation at next-hops we never send
 	 * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE
@@ -458,12 +459,12 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
 
 	/* Don't even try to fragment, if we need more than 16 fragments */
 	if (skb->len > max_packet_size)
-		goto out_err;
+		goto out;
 
 	bat_priv = orig_node->bat_priv;
 	primary_if = batadv_primary_if_get_selected(bat_priv);
 	if (!primary_if)
-		goto out_err;
+		goto out;
 
 	/* Create one header to be copied to all fragments */
 	frag_header.packet_type = BATADV_UNICAST_FRAG;
@@ -480,23 +481,33 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
 	while (skb->len > max_fragment_size) {
 		skb_fragment = batadv_frag_create(skb, &frag_header, mtu);
 		if (!skb_fragment)
-			goto out_err;
+			goto out;
 
 		batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
 		batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
 				   skb_fragment->len + ETH_HLEN);
-		batadv_send_unicast_skb(skb_fragment, neigh_node);
+		ret = batadv_send_unicast_skb(skb_fragment, neigh_node);
+		if (ret != NET_XMIT_SUCCESS) {
+			/* return -1 so that the caller can free the original
+			 * skb
+			 */
+			ret = -1;
+			goto out;
+		}
+
 		frag_header.no++;
 
 		/* The initial check in this function should cover this case */
-		if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1)
-			goto out_err;
+		if (frag_header.no == BATADV_FRAG_MAX_FRAGMENTS - 1) {
+			ret = -1;
+			goto out;
+		}
 	}
 
 	/* Make room for the fragment header. */
 	if (batadv_skb_head_push(skb, header_size) < 0 ||
 	    pskb_expand_head(skb, header_size + ETH_HLEN, 0, GFP_ATOMIC) < 0)
-		goto out_err;
+		goto out;
 
 	memcpy(skb->data, &frag_header, header_size);
 
@@ -504,11 +515,9 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
 	batadv_inc_counter(bat_priv, BATADV_CNT_FRAG_TX);
 	batadv_add_counter(bat_priv, BATADV_CNT_FRAG_TX_BYTES,
 			   skb->len + ETH_HLEN);
-	batadv_send_unicast_skb(skb, neigh_node);
+	ret = batadv_send_unicast_skb(skb, neigh_node);
 
-	ret = true;
-
-out_err:
+out:
 	if (primary_if)
 		batadv_hardif_put(primary_if);
 
net/batman-adv/fragmentation.h +3 -3
index 9ff77c7..3202fe3 100644
@@ -34,9 +34,9 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
 			 struct batadv_orig_node *orig_node_src);
 bool batadv_frag_skb_buffer(struct sk_buff **skb,
 			    struct batadv_orig_node *orig_node);
-bool batadv_frag_send_packet(struct sk_buff *skb,
-			     struct batadv_orig_node *orig_node,
-			     struct batadv_neigh_node *neigh_node);
+int batadv_frag_send_packet(struct sk_buff *skb,
+			    struct batadv_orig_node *orig_node,
+			    struct batadv_neigh_node *neigh_node);
 
 /**
  * batadv_frag_check_entry - check if a list of fragments has timed out
net/batman-adv/main.c +3 -1
index f229af8..29e7920 100644
@@ -1196,6 +1196,7 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src,
 	unsigned char *tvlv_buff;
 	unsigned int tvlv_len;
 	ssize_t hdr_len = sizeof(*unicast_tvlv_packet);
+	int res;
 
 	orig_node = batadv_orig_hash_find(bat_priv, dst);
 	if (!orig_node)
@@ -1228,7 +1229,8 @@ void batadv_tvlv_unicast_send(struct batadv_priv *bat_priv, u8 *src,
 	tvlv_buff += sizeof(*tvlv_hdr);
 	memcpy(tvlv_buff, tvlv_value, tvlv_value_len);
 
-	if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP)
+	res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+	if (!(res != -1 && dev_xmit_complete(res)))
 		kfree_skb(skb);
 out:
 	batadv_orig_node_put(orig_node);
net/batman-adv/routing.c +14 -10
index ae850f2..1c3fea0 100644
@@ -268,7 +268,10 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 		icmph->ttl = BATADV_TTL;
 
 		res = batadv_send_skb_to_orig(skb, orig_node, NULL);
-		if (res != NET_XMIT_DROP)
+		if (res == -1)
+			goto out;
+
+		if (dev_xmit_complete(res))
 			ret = NET_RX_SUCCESS;
 
 		break;
@@ -290,7 +293,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
 	struct batadv_hard_iface *primary_if = NULL;
 	struct batadv_orig_node *orig_node = NULL;
 	struct batadv_icmp_packet *icmp_packet;
-	int ret = NET_RX_DROP;
+	int res, ret = NET_RX_DROP;
 
 	icmp_packet = (struct batadv_icmp_packet *)skb->data;
 
@@ -321,7 +324,8 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
 	icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
 	icmp_packet->ttl = BATADV_TTL;
 
-	if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
+	res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+	if (res != -1 && dev_xmit_complete(res))
 		ret = NET_RX_SUCCESS;
 
 out:
@@ -341,7 +345,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
 	struct ethhdr *ethhdr;
 	struct batadv_orig_node *orig_node = NULL;
 	int hdr_size = sizeof(struct batadv_icmp_header);
-	int ret = NET_RX_DROP;
+	int res, ret = NET_RX_DROP;
 
 	/* drop packet if it has not necessary minimum size */
 	if (unlikely(!pskb_may_pull(skb, hdr_size)))
@@ -407,7 +411,8 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
 	icmph->ttl--;
 
 	/* route it */
-	if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
+	res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
+	if (res != -1 && dev_xmit_complete(res))
 		ret = NET_RX_SUCCESS;
 
 out:
@@ -642,6 +647,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
 		batadv_skb_set_priority(skb, hdr_len);
 
 	res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
+	if (res == -1)
+		goto out;
 
 	/* translate transmit result into receive result */
 	if (res == NET_XMIT_SUCCESS) {
@@ -649,12 +656,9 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
 		batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
 		batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
 				   skb->len + ETH_HLEN);
-
-		ret = NET_RX_SUCCESS;
-	} else if (res == NET_XMIT_POLICED) {
-		/* skb was buffered and consumed */
-		ret = NET_RX_SUCCESS;
 	}
+	if (dev_xmit_complete(res))
+		ret = NET_RX_SUCCESS;
 
 out:
 	if (orig_node)
net/batman-adv/send.c +13 -12
index f2f1256..e9b30d6 100644
@@ -155,8 +155,11 @@ int batadv_send_unicast_skb(struct sk_buff *skb,
  * host, NULL can be passed as recv_if and no interface alternating is
  * attempted.
  *
- * Return: NET_XMIT_SUCCESS on success, NET_XMIT_DROP on failure, or
- * NET_XMIT_POLICED if the skb is buffered for later transmit.
+ * Return: -1 on failure (and the skb is not consumed), NET_XMIT_POLICED if the
+ * skb is buffered for later transmit or the NET_XMIT status returned by the
+ * lower routine if the packet has been passed down.
+ *
+ * If the returning value is not -1 the skb has been consumed.
  */
 int batadv_send_skb_to_orig(struct sk_buff *skb,
 			    struct batadv_orig_node *orig_node,
@@ -164,7 +167,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
 {
 	struct batadv_priv *bat_priv = orig_node->bat_priv;
 	struct batadv_neigh_node *neigh_node;
-	int ret = NET_XMIT_DROP;
+	int ret = -1;
 
 	/* batadv_find_router() increases neigh_nodes refcount if found. */
 	neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
@@ -177,8 +180,7 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
 	if (atomic_read(&bat_priv->fragmentation) &&
 	    skb->len > neigh_node->if_incoming->net_dev->mtu) {
 		/* Fragment and send packet. */
-		if (batadv_frag_send_packet(skb, orig_node, neigh_node))
-			ret = NET_XMIT_SUCCESS;
+		ret = batadv_frag_send_packet(skb, orig_node, neigh_node);
 
 		goto out;
 	}
@@ -187,12 +189,10 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
 	 * (i.e. being forwarded). If the packet originates from this node or if
 	 * network coding fails, then send the packet as usual.
 	 */
-	if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) {
+	if (recv_if && batadv_nc_skb_forward(skb, neigh_node))
 		ret = NET_XMIT_POLICED;
-	} else {
-		batadv_send_unicast_skb(skb, neigh_node);
-		ret = NET_XMIT_SUCCESS;
-	}
+	else
+		ret = batadv_send_unicast_skb(skb, neigh_node);
 
 out:
 	if (neigh_node)
@@ -318,7 +318,7 @@ int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
 {
 	struct batadv_unicast_packet *unicast_packet;
 	struct ethhdr *ethhdr;
-	int ret = NET_XMIT_DROP;
+	int res, ret = NET_XMIT_DROP;
 
 	if (!orig_node)
 		goto out;
@@ -355,7 +355,8 @@ int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
 	if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
 		unicast_packet->ttvn = unicast_packet->ttvn - 1;
 
-	if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
+	res = batadv_send_skb_to_orig(skb, orig_node, NULL);
+	if (res != -1 && dev_xmit_complete(res))
 		ret = NET_XMIT_SUCCESS;
 
 out:
Signature · 1 line
2.8.1
#5 lore raw

PATCH v4 5/5 batman-adv: throughput meter implementation

In reply to Sven Eckelmann

From: Antonio Quartulli <[email protected]>

The throughput meter module is a simple, kernel-space replacement for throughtput measurements tool like iperf and netperf. It is intended to approximate TCP behaviour.

It is invoked through batctl: the protocol is connection oriented, with cumulative acknowledgment and a dynamic-size sliding window.

The test *can* be interrupted by batctl. A receiver side timeout avoids unlimited waitings for sender packets: after one second of inactivity, the receiver abort the ongoing test.

Based on a prototype from Edo Monticelli <[email protected]>

---
v4: converted interface to netlink

---
 include/uapi/linux/batman_adv.h |   35 +
 net/batman-adv/Makefile         |    1 +
 net/batman-adv/icmp_socket.c    |    2 +
 net/batman-adv/main.c           |    2 +
 net/batman-adv/main.h           |   24 +-
 net/batman-adv/netlink.c        |  174 +++++
 net/batman-adv/packet.h         |   54 ++
 net/batman-adv/routing.c        |    9 +-
 net/batman-adv/soft-interface.c |    2 +
 net/batman-adv/tp_meter.c       | 1448 +++++++++++++++++++++++++++++++++++++++
 net/batman-adv/tp_meter.h       |   35 +
 net/batman-adv/types.h          |  128 ++++
 12 files changed, 1906 insertions(+), 8 deletions(-)
 create mode 100644 net/batman-adv/tp_meter.c
 create mode 100644 net/batman-adv/tp_meter.h
include/uapi/linux/batman_adv.h +35 -0
index a908140..33f48e6 100644
@@ -32,6 +32,10 @@
  * @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_AFTER_LAST: internal use
  * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available
  * @BATADV_ATTR_MAX: highest attribute number currently defined
@@ -46,6 +50,10 @@ enum batadv_nl_attrs {
 	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,
 	/* add attributes above here, update the policy in netlink.c */
 	__BATADV_ATTR_AFTER_LAST,
 	NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
@@ -57,15 +65,42 @@ enum batadv_nl_attrs {
  *
  * @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_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,
 	/* 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 a tp meter test run stop
+ * @BATADV_TP_COMPLETE: sender finished tp run
+ * @BATADV_TP_SIGINT: sender was stopped during run
+ * @BATADV_TP_DST_UNREACHABLE: receiver could not be reached or didn't answer
+ * @BATADV_TP_RESEND_LIMIT: (unused) sender retry reached limit
+ * @BATADV_TP_ALREADY_ONGOING: test to or from the same node already ongoing
+ * @BATADV_TP_MEMORY_ERROR: test was stopped due to low memory
+ * @BATADV_TP_CANT_SEND: failed to send via outgoing interface
+ * @BATADV_TP_TOO_MANY: too many ongoing sessions
+ */
+enum batadv_tp_meter_reason {
+	BATADV_TP_COMPLETE		= 3,
+	BATADV_TP_SIGINT		= 4,
+	/* error status >= 128 */
+	BATADV_TP_DST_UNREACHABLE	= 128,
+	BATADV_TP_RESEND_LIMIT		= 129,
+	BATADV_TP_ALREADY_ONGOING	= 130,
+	BATADV_TP_MEMORY_ERROR		= 131,
+	BATADV_TP_CANT_SEND		= 132,
+	BATADV_TP_TOO_MANY		= 133,
+};
+
 #endif /* _UAPI_LINUX_BATMAN_ADV_H_ */
net/batman-adv/Makefile +1 -0
index 4e5adba..91c96c3 100644
@@ -40,4 +40,5 @@ batman-adv-y += routing.o
 batman-adv-y += send.o
 batman-adv-y += soft-interface.o
 batman-adv-y += sysfs.o
+batman-adv-y += tp_meter.o
 batman-adv-y += translation-table.o
net/batman-adv/icmp_socket.c +2 -0
index 777aea1..5da3afa 100644
@@ -48,6 +48,7 @@
 #include "originator.h"
 #include "packet.h"
 #include "send.h"
+#include "tp_meter.h"
 
 static struct batadv_socket_client *batadv_socket_client_hash[256];
 
@@ -58,6 +59,7 @@ static void batadv_socket_add_packet(struct batadv_socket_client *socket_client,
 void batadv_socket_init(void)
 {
 	memset(batadv_socket_client_hash, 0, sizeof(batadv_socket_client_hash));
+	batadv_tp_meter_init();
 }
 
 static int batadv_socket_open(struct inode *inode, struct file *file)
net/batman-adv/main.c +2 -0
index 29e7920..5aa529d 100644
@@ -144,6 +144,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	spin_lock_init(&bat_priv->tvlv.container_list_lock);
 	spin_lock_init(&bat_priv->tvlv.handler_list_lock);
 	spin_lock_init(&bat_priv->softif_vlan_list_lock);
+	spin_lock_init(&bat_priv->tp_list_lock);
 
 	INIT_HLIST_HEAD(&bat_priv->forw_bat_list);
 	INIT_HLIST_HEAD(&bat_priv->forw_bcast_list);
@@ -162,6 +163,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
 	INIT_HLIST_HEAD(&bat_priv->tvlv.container_list);
 	INIT_HLIST_HEAD(&bat_priv->tvlv.handler_list);
 	INIT_HLIST_HEAD(&bat_priv->softif_vlan_list);
+	INIT_HLIST_HEAD(&bat_priv->tp_list);
 
 	ret = batadv_v_mesh_init(bat_priv);
 	if (ret < 0)
net/batman-adv/main.h +17 -7
index 7692526..e28f698 100644
@@ -100,6 +100,9 @@
 #define BATADV_NUM_BCASTS_WIRELESS 3
 #define BATADV_NUM_BCASTS_MAX 3
 
+/* length of the single packet used by the TP meter */
+#define BATADV_TP_PACKET_LEN ETH_DATA_LEN
+
 /* msecs after which an ARP_REQUEST is sent in broadcast as fallback */
 #define ARP_REQ_DELAY 250
 /* numbers of originator to contact for any PUT/GET DHT operation */
@@ -131,6 +134,11 @@
 
 #define BATADV_NC_NODE_TIMEOUT 10000 /* Milliseconds */
 
+/**
+ * BATADV_TP_MAX_NUM - maximum number of simultaneously active tp sessions
+ */
+#define BATADV_TP_MAX_NUM 5
+
 enum batadv_mesh_state {
 	BATADV_MESH_INACTIVE,
 	BATADV_MESH_ACTIVE,
@@ -231,16 +239,18 @@ __be32 batadv_skb_crc32(struct sk_buff *skb, u8 *payload_ptr);
  * @BATADV_DBG_BLA: bridge loop avoidance messages
  * @BATADV_DBG_DAT: ARP snooping and DAT related messages
  * @BATADV_DBG_NC: network coding related messages
+ * @BATADV_DBG_TP_METER: throughput meter messages
  * @BATADV_DBG_ALL: the union of all the above log levels
  */
 enum batadv_dbg_level {
-	BATADV_DBG_BATMAN = BIT(0),
-	BATADV_DBG_ROUTES = BIT(1),
-	BATADV_DBG_TT	  = BIT(2),
-	BATADV_DBG_BLA    = BIT(3),
-	BATADV_DBG_DAT    = BIT(4),
-	BATADV_DBG_NC	  = BIT(5),
-	BATADV_DBG_ALL    = 63,
+	BATADV_DBG_BATMAN	= BIT(0),
+	BATADV_DBG_ROUTES	= BIT(1),
+	BATADV_DBG_TT		= BIT(2),
+	BATADV_DBG_BLA		= BIT(3),
+	BATADV_DBG_DAT		= BIT(4),
+	BATADV_DBG_NC		= BIT(5),
+	BATADV_DBG_TP_METER	= BIT(6),
+	BATADV_DBG_ALL		= 127,
 };
 
 #ifdef CONFIG_BATMAN_ADV_DEBUG
net/batman-adv/netlink.c +174 -0

204 lines not on this page · raw message

net/batman-adv/packet.h +54 -0

78 lines not on this page · raw message

net/batman-adv/routing.c +8 -1
index 1c3fea0..4e86290 100644
@@ -45,6 +45,7 @@
 #include "packet.h"
 #include "send.h"
 #include "soft-interface.h"
+#include "tp_meter.h"
 #include "translation-table.h"
 
 static int batadv_route_unicast_packet(struct sk_buff *skb,
@@ -242,7 +243,6 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 		/* receive the packet */
 		if (skb_linearize(skb) < 0)
 			break;
-
 		batadv_socket_receive_packet(icmph, skb->len);
 		break;
 	case BATADV_ECHO_REQUEST:
@@ -275,6 +275,13 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
 			ret = NET_RX_SUCCESS;
 
 		break;
+	case BATADV_TP:
+		if (!pskb_may_pull(skb, sizeof(struct batadv_icmp_tp_packet)))
+			goto out;
+
+		batadv_tp_meter_recv(bat_priv, skb);
+		ret = NET_RX_SUCCESS;
+		goto out;
 	default:
 		/* drop unknown type */
 		goto out;
net/batman-adv/soft-interface.c +2 -0
index f37ce39..31d1df2 100644
@@ -837,6 +837,8 @@ static int batadv_softif_init_late(struct net_device *dev)
 #ifdef CONFIG_BATMAN_ADV_BLA
 	atomic_set(&bat_priv->bla.num_requests, 0);
 #endif
+	atomic_set(&bat_priv->tp_num, 0);
+
 	bat_priv->tt.last_changeset = NULL;
 	bat_priv->tt.last_changeset_len = 0;
 	bat_priv->isolation_mark = 0;
net/batman-adv/tp_meter.c new file +1448 -0

1,448 lines not on this page · raw message

net/batman-adv/tp_meter.h new file +35 -0
new file mode 100644
index 0000000..0e46e50
@@ -0,0 +1,35 @@
+/* Copyright (C) 2012-2016 B.A.T.M.A.N. contributors:
+ *
+ * Edo Monticelli, Antonio Quartulli
+ *
+ * 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 _NET_BATMAN_ADV_TP_METER_H_
+#define _NET_BATMAN_ADV_TP_METER_H_
+
+#include "main.h"
+
+struct sk_buff;
+
+#include <linux/types.h>
+
+void batadv_tp_meter_init(void);
+void batadv_tp_start(struct batadv_priv *bat_priv,
+		     struct batadv_tp_vars_wait *tp_wait, const u8 *dst,
+		     u32 test_length);
+void batadv_tp_stop(struct batadv_priv *bat_priv, const u8 *dst,
+		    u8 return_value);
+void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb);
+
+#endif /* _NET_BATMAN_ADV_TP_METER_H_ */
net/batman-adv/types.h +128 -0

158 lines not on this page · raw message

Signature · 1 line
2.8.1
#6 lore raw

PATCH v4 1/4 batctl: Split list of objects in Makefile into separate lines

In reply to Sven Eckelmann

From: Sven Eckelmann <[email protected]>

The line of objects which are required to compile batctl 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.

---
 Makefile | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
Makefile +13 -1
index b82c0c6..a037847 100755
@@ -24,7 +24,19 @@ export CONFIG_BATCTL_BISECT=n
 
 # batctl build
 BINARY_NAME = batctl
-OBJ = main.o bat-hosts.o functions.o sys.o debug.o ping.o traceroute.o tcpdump.o  hash.o debugfs.o ioctl.o list-batman.o translate.o
+OBJ += bat-hosts.o
+OBJ += debugfs.o
+OBJ += debug.o
+OBJ += functions.o
+OBJ += hash.o
+OBJ += ioctl.o
+OBJ += list-batman.o
+OBJ += main.o
+OBJ += ping.o
+OBJ += sys.o
+OBJ += tcpdump.o
+OBJ += traceroute.o
+OBJ += translate.o
 OBJ_BISECT = bisect_iv.o
 MANPAGE = man/batctl.8
 
Signature · 1 line
2.8.1
#7 lore raw

PATCH v4 2/4 batctl: Add basic infrastructure to integrate netlink

In reply to Sven Eckelmann

From: Sven Eckelmann <[email protected]>

Netlink can be used to add new communication functionality to the kernel module. It can also be used to replace the old debugfs files. The binary interface used for this will be defined in the added files.

---
 Makefile     | 12 ++++++++++++
 batman_adv.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 netlink.c    | 28 ++++++++++++++++++++++++++++
 netlink.h    | 30 ++++++++++++++++++++++++++++++
 4 files changed, 123 insertions(+)
 create mode 100644 batman_adv.h
 create mode 100644 netlink.c
 create mode 100644 netlink.h
Makefile +12 -0
index a037847..3fa21f4 100755
@@ -32,6 +32,7 @@ OBJ += hash.o
 OBJ += ioctl.o
 OBJ += list-batman.o
 OBJ += main.o
+OBJ += netlink.o
 OBJ += ping.o
 OBJ += sys.o
 OBJ += tcpdump.o
@@ -73,6 +74,17 @@ 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)
+
 # standard build tools
 ifeq ($(CONFIG_BATCTL_BISECT),y)
 OBJ += $(OBJ_BISECT)
batman_adv.h new file +53 -0

53 lines not on this page · raw message

netlink.c new file +28 -0
new file mode 100644
index 0000000..409953a
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2009-2016  B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <[email protected]>
+ *
+ * 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 "main.h"
+
+#include "batman_adv.h"
+
+struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
+};
netlink.h new file +30 -0
new file mode 100644
index 0000000..0a4d3dd
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009-2016  B.A.T.M.A.N. contributors:
+ *
+ * Marek Lindner <[email protected]>
+ *
+ * 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 _BATCTL_NETLINK_H
+#define _BATCTL_NETLINK_H
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/ctrl.h>
+
+extern struct nla_policy batadv_netlink_policy[];
+
+#endif /* _BATCTL_NETLINK_H */
Signature · 1 line
2.8.1
#8 lore raw

PATCH v4 3/4 batctl: Add attributes/command for BATADV_CMD_GET_MESH_INFO

In reply to Sven Eckelmann

From: Sven Eckelmann <[email protected]>

BATADV_CMD_GET_MESH_INFO will be used as common function to retrieve information from the kernel. This information can be used to display a header for debugfs tables.

---
 batman_adv.h | 18 ++++++++++++++++++
 netlink.c    | 14 ++++++++++++++
 2 files changed, 32 insertions(+)
batman_adv.h +18 -0
index ba611a7..a908140 100644
@@ -24,12 +24,28 @@
  * 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_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,
 	/* add attributes above here, update the policy in netlink.c */
 	__BATADV_ATTR_AFTER_LAST,
 	NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
@@ -40,11 +56,13 @@ enum batadv_nl_attrs {
  * 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_AFTER_LAST: internal use
  * @BATADV_CMD_MAX: highest used command number
  */
 enum batadv_nl_commands {
 	BATADV_CMD_UNSPEC,
+	BATADV_CMD_GET_MESH_INFO,
 	/* add new commands above here */
 	__BATADV_CMD_AFTER_LAST,
 	BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
netlink.c +14 -0
index 409953a..2404a25 100644
@@ -22,7 +22,21 @@
 #include "netlink.h"
 #include "main.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 },
+	[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 },
+	[BATADV_ATTR_HARD_ADDRESS]	= { .type = NLA_UNSPEC,
+					    .minlen = ETH_ALEN,
+					    .maxlen = ETH_ALEN },
 };
Signature · 1 line
2.8.1
#9 lore raw

PATCH v4 4/4 batctl: introduce throughput meter support

In reply to Sven Eckelmann

From: Antonio Quartulli <[email protected]>

Add command to launch the throughput meter test. The throughput meter is a batman kernelspace tool for throughput measurements. The syntax is:

batctl tp <MAC>

The test is interruptible with SIGINT or SIGTERM; if the test succeeds with no error the throughput and the elapsed time are printed to stdout, otherwise occurred an error message is displayed (on stdout) accordingly.

Based on a prototype from Edo Monticelli <[email protected]>

---
 Makefile     |   1 +
 batman_adv.h |  35 ++++++
 main.c       |   6 +
 main.h       |   2 +
 man/batctl.8 |  24 +++-
 netlink.c    |   6 +
 packet.h     |  54 +++++++++
 tcpdump.c    |  14 ++-
 tp_meter.c   | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tp_meter.h   |  22 ++++
 10 files changed, 545 insertions(+), 3 deletions(-)
 create mode 100644 tp_meter.c
 create mode 100644 tp_meter.h
Makefile +1 -0
index 3fa21f4..c8bec98 100755
@@ -36,6 +36,7 @@ OBJ += netlink.o
 OBJ += ping.o
 OBJ += sys.o
 OBJ += tcpdump.o
+OBJ += tp_meter.o
 OBJ += traceroute.o
 OBJ += translate.o
 OBJ_BISECT = bisect_iv.o
batman_adv.h +35 -0
index a908140..33f48e6 100644
@@ -32,6 +32,10 @@
  * @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_AFTER_LAST: internal use
  * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available
  * @BATADV_ATTR_MAX: highest attribute number currently defined
@@ -46,6 +50,10 @@ enum batadv_nl_attrs {
 	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,
 	/* add attributes above here, update the policy in netlink.c */
 	__BATADV_ATTR_AFTER_LAST,
 	NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST,
@@ -57,15 +65,42 @@ enum batadv_nl_attrs {
  *
  * @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_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,
 	/* 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 a tp meter test run stop
+ * @BATADV_TP_COMPLETE: sender finished tp run
+ * @BATADV_TP_SIGINT: sender was stopped during run
+ * @BATADV_TP_DST_UNREACHABLE: receiver could not be reached or didn't answer
+ * @BATADV_TP_RESEND_LIMIT: (unused) sender retry reached limit
+ * @BATADV_TP_ALREADY_ONGOING: test to or from the same node already ongoing
+ * @BATADV_TP_MEMORY_ERROR: test was stopped due to low memory
+ * @BATADV_TP_CANT_SEND: failed to send via outgoing interface
+ * @BATADV_TP_TOO_MANY: too many ongoing sessions
+ */
+enum batadv_tp_meter_reason {
+	BATADV_TP_COMPLETE		= 3,
+	BATADV_TP_SIGINT		= 4,
+	/* error status >= 128 */
+	BATADV_TP_DST_UNREACHABLE	= 128,
+	BATADV_TP_RESEND_LIMIT		= 129,
+	BATADV_TP_ALREADY_ONGOING	= 130,
+	BATADV_TP_MEMORY_ERROR		= 131,
+	BATADV_TP_CANT_SEND		= 132,
+	BATADV_TP_TOO_MANY		= 133,
+};
+
 #endif /* _UAPI_LINUX_BATMAN_ADV_H_ */
main.c +6 -0
index a2cda5b..5e1ecc7 100644
@@ -33,6 +33,7 @@
 #include "translate.h"
 #include "traceroute.h"
 #include "tcpdump.h"
+#include "tp_meter.h"
 #include "bisect_iv.h"
 #include "ioctl.h"
 #include "functions.h"
@@ -82,6 +83,7 @@ static void print_usage(void)
 	fprintf(stderr, " \tping|p                     <destination>     \tping another batman adv host via layer 2\n");
 	fprintf(stderr, " \ttraceroute|tr              <destination>     \ttraceroute another batman adv host via layer 2\n");
 	fprintf(stderr, " \ttcpdump|td                 <interface>       \ttcpdump layer 2 traffic on the given interface\n");
+	printf(" \tthroughputmeter|tp         <destination>     \tstart a throughput measurement\n");
 	fprintf(stderr, " \ttranslate|t                <destination>     \ttranslate a destination to the originator responsible for it\n");
 #ifdef BATCTL_BISECT
 	fprintf(stderr, " \tbisect_iv                  <file1> .. <fileN>\tanalyze given batman iv log files for routing stability\n");
@@ -162,6 +164,10 @@ int main(int argc, char **argv)
 
 		ret = ping(mesh_iface, argc - 1, argv + 1);
 
+	} else if ((strcmp(argv[1], "throughputmeter") == 0) || (strcmp(argv[1], "tp") == 0)) {
+
+		ret = tp_meter (mesh_iface, argc -1, argv + 1);
+
 	} else if ((strcmp(argv[1], "traceroute") == 0) || (strcmp(argv[1], "tr") == 0)) {
 
 		ret = traceroute(mesh_iface, argc - 1, argv + 1);
main.h +2 -0
index e94fc33..0e57f32 100644
@@ -47,10 +47,12 @@
 #endif
 
 #define __packed __attribute((packed))   /* linux kernel compat */
+#define __unused __attribute__((unused))
 #define BIT(nr)                 (1UL << (nr)) /* linux kernel compat */
 
 typedef uint8_t u8; /* linux kernel compat */
 typedef uint16_t u16; /* linux kernel compat */
+typedef uint32_t u32; /* linux kernel compat */
 
 extern char module_ver_path[];
 
man/batctl.8 +22 -2
index e804a08..69a2537 100644
@@ -36,9 +36,11 @@ B.A.T.M.A.N. advanced operates on layer 2. Thus all hosts participating in the v
 connected together for all protocols above layer 2. Therefore the common diagnosis tools do not work as expected. To
 overcome these problems batctl contains the commands \fBping\fP, \fBtraceroute\fP, \fBtcpdump\fP which provide similar
 functionality to the normal \fBping\fP(1), \fBtraceroute\fP(1), \fBtcpdump\fP(1) commands, but modified to layer 2
-behaviour or using the B.A.T.M.A.N. advanced protocol.
-.PP
+behaviour or using the B.A.T.M.A.N. advanced protocol. For similar reasons, \fBthroughputmeter\fP, a command to test network
+performances, is also included.
+
 .PP
+.Pp
 .SH OPTIONS
 .TP
 .I \fBoptions:
@@ -319,6 +321,24 @@ for routing loops. Use "\-t" to trace OGMs of a host throughout the network. Use
 nodes. The option "\-s" can be used to limit the output to a range of sequence numbers, between min and max, or to one
 specific sequence number, min. Furthermore using "\-o" you can filter the output to a specified originator. If "\-n" is
 given batctl will not replace the MAC addresses with bat\-host names in the output.
+.RE
+.br
+.IP "\fBthroughputmeter\fP|\fBtp\fP \fBMAC\fP"
+This command starts a throughput test entirely controlled by batman module in
+kernel space: the computational resources needed to align memory and copy data
+between user and kernel space that are required by other user space tools may
+represent a bootleneck on some low profile device.
+
+The test consist of the transfer of 14 MB of data between the two nodes. The
+protocol used to transfer the data is somehow similar to TCP, but simpler: some
+TCP features are still missing, thus protocol performances could be worst. Since
+a fixed amount of data is transferred the experiment duration depends on the
+network conditions. The experiment can be interrupted with CTRL + C. At the end
+of a succesful experiment the throughput in KBytes per second is returned,
+togheter with the experiment duration in millisecond and the amount of bytes
+transferred. If too many packets are lost or the specified MAC address is not
+reachable, a message notifing the error is returned instead of the result.
+.RE
 .br
 .SH FILES
 .TP
netlink.c +6 -0
index 2404a25..0c643e3 100644
@@ -39,4 +39,10 @@ struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[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_U32 },
 };
packet.h +54 -0

78 lines not on this page · raw message

tcpdump.c +13 -1
index 363e9e4..be0c4f0 100644
@@ -808,11 +808,14 @@ static void dump_batman_elp(unsigned char *packet_buff, ssize_t buff_len,
 static void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int read_opt, int time_printed)
 {
 	struct batadv_icmp_packet *icmp_packet;
+	struct batadv_icmp_tp_packet *tp;
+
 	char *name;
 
 	LEN_CHECK((size_t)buff_len - sizeof(struct ether_header), sizeof(struct batadv_icmp_packet), "BAT ICMP");
 
 	icmp_packet = (struct batadv_icmp_packet *)(packet_buff + sizeof(struct ether_header));
+	tp = (struct batadv_icmp_tp_packet *)icmp_packet;
 
 	if (!time_printed)
 		print_time();
@@ -820,7 +823,8 @@ static void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int r
 	printf("BAT %s > ",
 	       get_name_by_macaddr((struct ether_addr *)icmp_packet->orig, read_opt));
 
-	name = get_name_by_macaddr((struct ether_addr *)icmp_packet->dst, read_opt);
+	name = get_name_by_macaddr((struct ether_addr *)icmp_packet->dst,
+				    read_opt);
 
 	switch (icmp_packet->msg_type) {
 	case BATADV_ECHO_REPLY:
@@ -841,6 +845,14 @@ static void dump_batman_icmp(unsigned char *packet_buff, ssize_t buff_len, int r
 			icmp_packet->ttl, icmp_packet->version,
 			(size_t)buff_len - sizeof(struct ether_header));
 		break;
+	case BATADV_TP:
+		printf("%s: ICMP TP type %s (%hhu), id %hhu, seq %u, ttl %2d, v %d, length %zu\n",
+		       name, tp->subtype == BATADV_TP_MSG ? "MSG" :
+			     tp->subtype == BATADV_TP_ACK ? "ACK" : "N/A",
+		       tp->subtype, tp->uid, ntohl(tp->seqno), tp->ttl,
+		       tp->version,
+		       (size_t)buff_len - sizeof(struct ether_header));
+		break;
 	default:
 		printf("%s: ICMP type %hhu, length %zu\n",
 			name, icmp_packet->msg_type,
tp_meter.c new file +384 -0

384 lines not on this page · raw message

tp_meter.h new file +22 -0
new file mode 100644
index 0000000..59bca07
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013-2016 B.A.T.M.A.N. contributors:
+ *
+ * Antonio Quartulli <[email protected]>
+ *
+ * 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
+ *
+ */
+
+int tp_meter(char *mesh_iface, int argc, char **argv);
Signature · 1 line
2.8.1