aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/bat_iv_ogm.c10
-rw-r--r--net/batman-adv/main.c2
-rw-r--r--net/batman-adv/main.h27
-rw-r--r--net/batman-adv/routing.c11
-rw-r--r--net/batman-adv/soft-interface.c66
-rw-r--r--net/batman-adv/translation-table.c8
-rw-r--r--net/batman-adv/types.h17
7 files changed, 138 insertions, 3 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index ec351199c652..99ec218df7f2 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -196,8 +196,12 @@ static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet,
196 196
197 /* create clone because function is called more than once */ 197 /* create clone because function is called more than once */
198 skb = skb_clone(forw_packet->skb, GFP_ATOMIC); 198 skb = skb_clone(forw_packet->skb, GFP_ATOMIC);
199 if (skb) 199 if (skb) {
200 batadv_inc_counter(bat_priv, BAT_CNT_MGMT_TX);
201 batadv_add_counter(bat_priv, BAT_CNT_MGMT_TX_BYTES,
202 skb->len + ETH_HLEN);
200 send_skb_packet(skb, hard_iface, broadcast_addr); 203 send_skb_packet(skb, hard_iface, broadcast_addr);
204 }
201} 205}
202 206
203/* send a batman ogm packet */ 207/* send a batman ogm packet */
@@ -1203,6 +1207,10 @@ static int bat_iv_ogm_receive(struct sk_buff *skb,
1203 if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit) 1207 if (bat_priv->bat_algo_ops->bat_ogm_emit != bat_iv_ogm_emit)
1204 return NET_RX_DROP; 1208 return NET_RX_DROP;
1205 1209
1210 batadv_inc_counter(bat_priv, BAT_CNT_MGMT_RX);
1211 batadv_add_counter(bat_priv, BAT_CNT_MGMT_RX_BYTES,
1212 skb->len + ETH_HLEN);
1213
1206 packet_len = skb_headlen(skb); 1214 packet_len = skb_headlen(skb);
1207 ethhdr = (struct ethhdr *)skb_mac_header(skb); 1215 ethhdr = (struct ethhdr *)skb_mac_header(skb);
1208 packet_buff = skb->data; 1216 packet_buff = skb->data;
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 083a2993efe4..bd83aa4e7c87 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -153,6 +153,8 @@ void mesh_free(struct net_device *soft_iface)
153 153
154 bla_free(bat_priv); 154 bla_free(bat_priv);
155 155
156 free_percpu(bat_priv->bat_counters);
157
156 atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); 158 atomic_set(&bat_priv->mesh_state, MESH_INACTIVE);
157} 159}
158 160
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 630bbe8968ca..6e0cbdc48321 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -138,6 +138,7 @@ enum dbg_level {
138#include <linux/kthread.h> /* kernel threads */ 138#include <linux/kthread.h> /* kernel threads */
139#include <linux/pkt_sched.h> /* schedule types */ 139#include <linux/pkt_sched.h> /* schedule types */
140#include <linux/workqueue.h> /* workqueue */ 140#include <linux/workqueue.h> /* workqueue */
141#include <linux/percpu.h>
141#include <linux/slab.h> 142#include <linux/slab.h>
142#include <net/sock.h> /* struct sock */ 143#include <net/sock.h> /* struct sock */
143#include <linux/jiffies.h> 144#include <linux/jiffies.h>
@@ -242,4 +243,30 @@ static inline bool has_timed_out(unsigned long timestamp, unsigned int timeout)
242 _dummy > smallest_signed_int(_dummy); }) 243 _dummy > smallest_signed_int(_dummy); })
243#define seq_after(x, y) seq_before(y, x) 244#define seq_after(x, y) seq_before(y, x)
244 245
246/* Stop preemption on local cpu while incrementing the counter */
247static inline void batadv_add_counter(struct bat_priv *bat_priv, size_t idx,
248 size_t count)
249{
250 int cpu = get_cpu();
251 per_cpu_ptr(bat_priv->bat_counters, cpu)[idx] += count;
252 put_cpu();
253}
254
255#define batadv_inc_counter(b, i) batadv_add_counter(b, i, 1)
256
257/* Sum and return the cpu-local counters for index 'idx' */
258static inline uint64_t batadv_sum_counter(struct bat_priv *bat_priv, size_t idx)
259{
260 uint64_t *counters;
261 int cpu;
262 int sum = 0;
263
264 for_each_possible_cpu(cpu) {
265 counters = per_cpu_ptr(bat_priv->bat_counters, cpu);
266 sum += counters[idx];
267 }
268
269 return sum;
270}
271
245#endif /* _NET_BATMAN_ADV_MAIN_H_ */ 272#endif /* _NET_BATMAN_ADV_MAIN_H_ */
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 015471d801b4..369604c99a46 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -600,6 +600,8 @@ int recv_tt_query(struct sk_buff *skb, struct hard_iface *recv_if)
600 600
601 switch (tt_query->flags & TT_QUERY_TYPE_MASK) { 601 switch (tt_query->flags & TT_QUERY_TYPE_MASK) {
602 case TT_REQUEST: 602 case TT_REQUEST:
603 batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_RX);
604
603 /* If we cannot provide an answer the tt_request is 605 /* If we cannot provide an answer the tt_request is
604 * forwarded */ 606 * forwarded */
605 if (!send_tt_response(bat_priv, tt_query)) { 607 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)
612 } 614 }
613 break; 615 break;
614 case TT_RESPONSE: 616 case TT_RESPONSE:
617 batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_RX);
618
615 if (is_my_mac(tt_query->dst)) { 619 if (is_my_mac(tt_query->dst)) {
616 /* packet needs to be linearized to access the TT 620 /* packet needs to be linearized to access the TT
617 * changes */ 621 * changes */
@@ -665,6 +669,8 @@ int recv_roam_adv(struct sk_buff *skb, struct hard_iface *recv_if)
665 if (is_broadcast_ether_addr(ethhdr->h_source)) 669 if (is_broadcast_ether_addr(ethhdr->h_source))
666 goto out; 670 goto out;
667 671
672 batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_RX);
673
668 roam_adv_packet = (struct roam_adv_packet *)skb->data; 674 roam_adv_packet = (struct roam_adv_packet *)skb->data;
669 675
670 if (!is_my_mac(roam_adv_packet->dst)) 676 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)
872 /* decrement ttl */ 878 /* decrement ttl */
873 unicast_packet->header.ttl--; 879 unicast_packet->header.ttl--;
874 880
881 /* Update stats counter */
882 batadv_inc_counter(bat_priv, BAT_CNT_FORWARD);
883 batadv_add_counter(bat_priv, BAT_CNT_FORWARD_BYTES,
884 skb->len + ETH_HLEN);
885
875 /* route it */ 886 /* route it */
876 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 887 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
877 ret = NET_RX_SUCCESS; 888 ret = NET_RX_SUCCESS;
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 6e2530b02043..304a7ba09e03 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -45,6 +45,10 @@ static void bat_get_drvinfo(struct net_device *dev,
45static u32 bat_get_msglevel(struct net_device *dev); 45static u32 bat_get_msglevel(struct net_device *dev);
46static void bat_set_msglevel(struct net_device *dev, u32 value); 46static void bat_set_msglevel(struct net_device *dev, u32 value);
47static u32 bat_get_link(struct net_device *dev); 47static u32 bat_get_link(struct net_device *dev);
48static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data);
49static void batadv_get_ethtool_stats(struct net_device *dev,
50 struct ethtool_stats *stats, u64 *data);
51static int batadv_get_sset_count(struct net_device *dev, int stringset);
48 52
49static const struct ethtool_ops bat_ethtool_ops = { 53static const struct ethtool_ops bat_ethtool_ops = {
50 .get_settings = bat_get_settings, 54 .get_settings = bat_get_settings,
@@ -52,6 +56,9 @@ static const struct ethtool_ops bat_ethtool_ops = {
52 .get_msglevel = bat_get_msglevel, 56 .get_msglevel = bat_get_msglevel,
53 .set_msglevel = bat_set_msglevel, 57 .set_msglevel = bat_set_msglevel,
54 .get_link = bat_get_link, 58 .get_link = bat_get_link,
59 .get_strings = batadv_get_strings,
60 .get_ethtool_stats = batadv_get_ethtool_stats,
61 .get_sset_count = batadv_get_sset_count,
55}; 62};
56 63
57int my_skb_head_push(struct sk_buff *skb, unsigned int len) 64int my_skb_head_push(struct sk_buff *skb, unsigned int len)
@@ -399,13 +406,18 @@ struct net_device *softif_create(const char *name)
399 bat_priv->primary_if = NULL; 406 bat_priv->primary_if = NULL;
400 bat_priv->num_ifaces = 0; 407 bat_priv->num_ifaces = 0;
401 408
409 bat_priv->bat_counters = __alloc_percpu(sizeof(uint64_t) * BAT_CNT_NUM,
410 __alignof__(uint64_t));
411 if (!bat_priv->bat_counters)
412 goto unreg_soft_iface;
413
402 ret = bat_algo_select(bat_priv, bat_routing_algo); 414 ret = bat_algo_select(bat_priv, bat_routing_algo);
403 if (ret < 0) 415 if (ret < 0)
404 goto unreg_soft_iface; 416 goto free_bat_counters;
405 417
406 ret = sysfs_add_meshif(soft_iface); 418 ret = sysfs_add_meshif(soft_iface);
407 if (ret < 0) 419 if (ret < 0)
408 goto unreg_soft_iface; 420 goto free_bat_counters;
409 421
410 ret = debugfs_add_meshif(soft_iface); 422 ret = debugfs_add_meshif(soft_iface);
411 if (ret < 0) 423 if (ret < 0)
@@ -421,6 +433,8 @@ unreg_debugfs:
421 debugfs_del_meshif(soft_iface); 433 debugfs_del_meshif(soft_iface);
422unreg_sysfs: 434unreg_sysfs:
423 sysfs_del_meshif(soft_iface); 435 sysfs_del_meshif(soft_iface);
436free_bat_counters:
437 free_percpu(bat_priv->bat_counters);
424unreg_soft_iface: 438unreg_soft_iface:
425 unregister_netdevice(soft_iface); 439 unregister_netdevice(soft_iface);
426 return NULL; 440 return NULL;
@@ -486,3 +500,51 @@ static u32 bat_get_link(struct net_device *dev)
486{ 500{
487 return 1; 501 return 1;
488} 502}
503
504/* Inspired by drivers/net/ethernet/dlink/sundance.c:1702
505 * Declare each description string in struct.name[] to get fixed sized buffer
506 * and compile time checking for strings longer than ETH_GSTRING_LEN.
507 */
508static const struct {
509 const char name[ETH_GSTRING_LEN];
510} bat_counters_strings[] = {
511 { "forward" },
512 { "forward_bytes" },
513 { "mgmt_tx" },
514 { "mgmt_tx_bytes" },
515 { "mgmt_rx" },
516 { "mgmt_rx_bytes" },
517 { "tt_request_tx" },
518 { "tt_request_rx" },
519 { "tt_response_tx" },
520 { "tt_response_rx" },
521 { "tt_roam_adv_tx" },
522 { "tt_roam_adv_rx" },
523};
524
525static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
526 uint8_t *data)
527{
528 if (stringset == ETH_SS_STATS)
529 memcpy(data, bat_counters_strings,
530 sizeof(bat_counters_strings));
531}
532
533static void batadv_get_ethtool_stats(struct net_device *dev,
534 struct ethtool_stats *stats,
535 uint64_t *data)
536{
537 struct bat_priv *bat_priv = netdev_priv(dev);
538 int i;
539
540 for (i = 0; i < BAT_CNT_NUM; i++)
541 data[i] = batadv_sum_counter(bat_priv, i);
542}
543
544static int batadv_get_sset_count(struct net_device *dev, int stringset)
545{
546 if (stringset == ETH_SS_STATS)
547 return BAT_CNT_NUM;
548
549 return -EOPNOTSUPP;
550}
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index a66c2dcd1088..ca53542e1e8e 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1356,6 +1356,8 @@ static int send_tt_request(struct bat_priv *bat_priv,
1356 dst_orig_node->orig, neigh_node->addr, 1356 dst_orig_node->orig, neigh_node->addr,
1357 (full_table ? 'F' : '.')); 1357 (full_table ? 'F' : '.'));
1358 1358
1359 batadv_inc_counter(bat_priv, BAT_CNT_TT_REQUEST_TX);
1360
1359 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1361 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1360 ret = 0; 1362 ret = 0;
1361 1363
@@ -1480,6 +1482,8 @@ static bool send_other_tt_response(struct bat_priv *bat_priv,
1480 res_dst_orig_node->orig, neigh_node->addr, 1482 res_dst_orig_node->orig, neigh_node->addr,
1481 req_dst_orig_node->orig, req_ttvn); 1483 req_dst_orig_node->orig, req_ttvn);
1482 1484
1485 batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX);
1486
1483 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1487 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1484 ret = true; 1488 ret = true;
1485 goto out; 1489 goto out;
@@ -1596,6 +1600,8 @@ static bool send_my_tt_response(struct bat_priv *bat_priv,
1596 orig_node->orig, neigh_node->addr, 1600 orig_node->orig, neigh_node->addr,
1597 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.')); 1601 (tt_response->flags & TT_FULL_TABLE ? 'F' : '.'));
1598 1602
1603 batadv_inc_counter(bat_priv, BAT_CNT_TT_RESPONSE_TX);
1604
1599 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1605 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1600 ret = true; 1606 ret = true;
1601 goto out; 1607 goto out;
@@ -1895,6 +1901,8 @@ static void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
1895 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n", 1901 "Sending ROAMING_ADV to %pM (client %pM) via %pM\n",
1896 orig_node->orig, client, neigh_node->addr); 1902 orig_node->orig, client, neigh_node->addr);
1897 1903
1904 batadv_inc_counter(bat_priv, BAT_CNT_TT_ROAM_ADV_TX);
1905
1898 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); 1906 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1899 ret = 0; 1907 ret = 0;
1900 1908
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 547dc339f33d..6b569debc1a6 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -148,9 +148,26 @@ struct bcast_duplist_entry {
148}; 148};
149#endif 149#endif
150 150
151enum bat_counters {
152 BAT_CNT_FORWARD,
153 BAT_CNT_FORWARD_BYTES,
154 BAT_CNT_MGMT_TX,
155 BAT_CNT_MGMT_TX_BYTES,
156 BAT_CNT_MGMT_RX,
157 BAT_CNT_MGMT_RX_BYTES,
158 BAT_CNT_TT_REQUEST_TX,
159 BAT_CNT_TT_REQUEST_RX,
160 BAT_CNT_TT_RESPONSE_TX,
161 BAT_CNT_TT_RESPONSE_RX,
162 BAT_CNT_TT_ROAM_ADV_TX,
163 BAT_CNT_TT_ROAM_ADV_RX,
164 BAT_CNT_NUM,
165};
166
151struct bat_priv { 167struct bat_priv {
152 atomic_t mesh_state; 168 atomic_t mesh_state;
153 struct net_device_stats stats; 169 struct net_device_stats stats;
170 uint64_t __percpu *bat_counters; /* Per cpu counters */
154 atomic_t aggregated_ogms; /* boolean */ 171 atomic_t aggregated_ogms; /* boolean */
155 atomic_t bonding; /* boolean */ 172 atomic_t bonding; /* boolean */
156 atomic_t fragmentation; /* boolean */ 173 atomic_t fragmentation; /* boolean */