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 Original line 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.
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
BATCTL
------
------
+9 −1
Original line number Original line 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 */
	/* create clone because function is called more than once */
	skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
	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_skb_packet(skb, hard_iface, broadcast_addr);
	}
	}
}


/* send a batman ogm packet */
/* send a batman ogm packet */
static void bat_iv_ogm_emit(struct forw_packet *forw_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)
	if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit)
		return NET_RX_DROP;
		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);
	packet_len = skb_headlen(skb);
	ethhdr = (struct ethhdr *)skb_mac_header(skb);
	ethhdr = (struct ethhdr *)skb_mac_header(skb);
	packet_buff = skb->data;
	packet_buff = skb->data;
+2 −0
Original line number Original line Diff line number Diff line
@@ -153,6 +153,8 @@ void mesh_free(struct net_device *soft_iface)


	bla_free(bat_priv);
	bla_free(bat_priv);


	free_percpu(bat_priv->bat_counters);

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


+27 −0
Original line number Original line Diff line number Diff line
@@ -138,6 +138,7 @@ enum dbg_level {
#include <linux/kthread.h>	/* kernel threads */
#include <linux/kthread.h>	/* kernel threads */
#include <linux/pkt_sched.h>	/* schedule types */
#include <linux/pkt_sched.h>	/* schedule types */
#include <linux/workqueue.h>	/* workqueue */
#include <linux/workqueue.h>	/* workqueue */
#include <linux/percpu.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <net/sock.h>		/* struct sock */
#include <net/sock.h>		/* struct sock */
#include <linux/jiffies.h>
#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); })
			  _dummy > smallest_signed_int(_dummy); })
#define seq_after(x, y) seq_before(y, x)
#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_ */
#endif /* _NET_BATMAN_ADV_MAIN_H_ */
+11 −0
Original line number Original line 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) {
	switch (tt_query->flags & TT_QUERY_TYPE_MASK) {
	case TT_REQUEST:
	case TT_REQUEST:
		batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX);

		/* If we cannot provide an answer the tt_request is
		/* If we cannot provide an answer the tt_request is
		 * forwarded */
		 * forwarded */
		if (!send_tt_response(bat_priv, tt_query)) {
		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;
		break;
	case TT_RESPONSE:
	case TT_RESPONSE:
		batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_RX);

		if (is_my_mac(tt_query->dst)) {
		if (is_my_mac(tt_query->dst)) {
			/* packet needs to be linearized to access the TT
			/* packet needs to be linearized to access the TT
			 * changes */
			 * 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))
	if (is_broadcast_ether_addr(ethhdr->h_source))
		goto out;
		goto out;


	batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_RX);

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


	if (!is_my_mac(roam_adv_packet->dst))
	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 */
	/* decrement ttl */
	unicast_packet->header.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 */
	/* route it */
	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
	send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
	ret = NET_RX_SUCCESS;
	ret = NET_RX_SUCCESS;
Loading