Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8214865 authored by Martin Hundebøll's avatar Martin Hundebøll Committed by Antonio Quartulli
Browse files

batman-adv: Add get_ethtool_stats() support



Added additional counters in a bat_stats structure, which are exported
through the ethtool api. The counters are specific to batman-adv and
includes:
 forwarded packets and bytes
 management packets and bytes (aggregated OGMs at this point)
 translation table packets

New counters are added by extending "enum bat_counters" in types.h and
adding corresponding  descriptive string(s) to bat_counters_strings in
soft-iface.c.

Counters are increased by calling batadv_add_counter() and incremented
by one by calling batadv_inc_counter().

Signed-off-by: default avatarMartin Hundebøll <martin@hundeboll.net>
Signed-off-by: default avatarSven Eckelmann <sven@narfation.org>
parent 66a1b2bc
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -211,6 +211,11 @@ The debug output can be changed at runtime using the file

will enable debug messages for when routes change.

Counters for different types of packets entering and leaving the
batman-adv module are available through ethtool:

# ethtool --statistics bat0


BATCTL
------
+9 −1
Original line number Diff line number Diff line
@@ -196,9 +196,13 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,

	/* create clone because function is called more than once */
	skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
	if (skb)
	if (skb) {
		batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX);
		batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES,
				   skb->len + ETH_HLEN);
		send_skb_packet(skb, hard_iface, broadcast_addr);
	}
}

/* send a batman ogm packet */
static void bat_iv_ogm_emit(struct forw_packet *forw_packet)
@@ -1203,6 +1207,10 @@ static int bat_iv_ogm_receive(struct sk_buff *skb,
	if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit)
		return NET_RX_DROP;

	batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX);
	batadv_add_counter(bat_priv, BAT_CNT_MGMT_RX_BYTES,
			   skb->len + ETH_HLEN);

	packet_len = skb_headlen(skb);
	ethhdr = (struct ethhdr *)skb_mac_header(skb);
	packet_buff = skb->data;
+2 −0
Original line number Diff line number Diff line
@@ -153,6 +153,8 @@ void mesh_free(struct net_device *soft_iface)

	bla_free(bat_priv);

	free_percpu(bat_priv->bat_counters);

	atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
}

+27 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ enum dbg_level {
#include <linux/kthread.h>	/* kernel threads */
#include <linux/pkt_sched.h>	/* schedule types */
#include <linux/workqueue.h>	/* workqueue */
#include <linux/percpu.h>
#include <linux/slab.h>
#include <net/sock.h>		/* struct sock */
#include <linux/jiffies.h>
@@ -242,4 +243,30 @@ static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout)
			  _dummy > smallest_signed_int(_dummy); })
#define seq_after(x, y) seq_before(y, x)

/* Stop preemption on local cpu while incrementing the counter */
static inline void batadv_add_counter(struct bat_priv *bat_priv, size_t idx,
				      size_t count)
{
	int cpu = get_cpu();
	per_cpu_ptr(bat_priv->bat_counters, cpu)[idx] += count;
	put_cpu();
}

#define batadv_inc_counter(b, i) batadv_add_counter(b, i, 1)

/* Sum and return the cpu-local counters for index 'idx' */
static inline uint64_t batadv_sum_counter(struct bat_priv *bat_priv, size_t idx)
{
	uint64_t *counters;
	int cpu;
	int sum = 0;

	for_each_possible_cpu(cpu) {
		counters = per_cpu_ptr(bat_priv->bat_counters, cpu);
		sum += counters[idx];
	}

	return sum;
}

#endif /* _NET_BATMAN_ADV_MAIN_H_ */
+11 −0
Original line number Diff line number Diff line
@@ -600,6 +600,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)

	switch (tt_query->flags & TT_QUERY_TYPE_MASK) {
	case TT_REQUEST:
		batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX);

		/* If we cannot provide an answer the tt_request is
		 * forwarded */
		if (!send_tt_response(bat_priv, tt_query)) {
@@ -612,6 +614,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)
		}
		break;
	case TT_RESPONSE:
		batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_RX);

		if (is_my_mac(tt_query->dst)) {
			/* packet needs to be linearized to access the TT
			 * changes */
@@ -665,6 +669,8 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
	if (is_broadcast_ether_addr(ethhdr->h_source))
		goto out;

	batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_RX);

	roam_adv_packet = (struct roam_adv_packet *)skb->data;

	if (!is_my_mac(roam_adv_packet->dst))
@@ -872,6 +878,11 @@ static int route_unicast_packet(struct sk_buff *skb, struct hard_iface *recv_if)
	/* decrement ttl */
	unicast_packet->header.ttl--;

	/* Update stats counter */
	batadv_inc_counter(bat_priv, BAT_CNT_FORWARD);
	batadv_add_counter(bat_priv, BAT_CNT_FORWARD_BYTES,
			   skb->len + ETH_HLEN);

	/* route it */
	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
	ret = NET_RX_SUCCESS;
Loading