soft-interface.c 17.1 KB
Newer Older
1
/* Copyright (C) 2007-2012 B.A.T.M.A.N. contributors:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 */

#include "main.h"
#include "soft-interface.h"
#include "hard-interface.h"
#include "routing.h"
#include "send.h"
25
#include "debugfs.h"
26 27 28 29
#include "translation-table.h"
#include "hash.h"
#include "gateway_common.h"
#include "gateway_client.h"
30
#include "sysfs.h"
31
#include "originator.h"
32 33 34 35 36
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include "unicast.h"
37
#include "bridge_loop_avoidance.h"
38 39


40 41 42 43 44 45
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
static void batadv_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info);
static u32 batadv_get_msglevel(struct net_device *dev);
static void batadv_set_msglevel(struct net_device *dev, u32 value);
static u32 batadv_get_link(struct net_device *dev);
46 47 48 49
static void batadv_get_strings(struct net_device *dev, u32 stringset, u8 *data);
static void batadv_get_ethtool_stats(struct net_device *dev,
				     struct ethtool_stats *stats, u64 *data);
static int batadv_get_sset_count(struct net_device *dev, int stringset);
50

51 52 53 54 55 56
static const struct ethtool_ops batadv_ethtool_ops = {
	.get_settings = batadv_get_settings,
	.get_drvinfo = batadv_get_drvinfo,
	.get_msglevel = batadv_get_msglevel,
	.set_msglevel = batadv_set_msglevel,
	.get_link = batadv_get_link,
57 58 59
	.get_strings = batadv_get_strings,
	.get_ethtool_stats = batadv_get_ethtool_stats,
	.get_sset_count = batadv_get_sset_count,
60 61
};

62
int batadv_skb_head_push(struct sk_buff *skb, unsigned int len)
63 64 65
{
	int result;

66
	/* TODO: We must check if we can release all references to non-payload
67 68 69 70 71 72 73 74 75 76 77 78 79 80
	 * data using skb_header_release in our skbs to allow skb_cow_header to
	 * work optimally. This means that those skbs are not allowed to read
	 * or write any data which is before the current position of skb->data
	 * after that call and thus allow other skbs with the same data buffer
	 * to write freely in that area.
	 */
	result = skb_cow_head(skb, len);
	if (result < 0)
		return result;

	skb_push(skb, len);
	return 0;
}

81
static int batadv_interface_open(struct net_device *dev)
82 83 84 85 86
{
	netif_start_queue(dev);
	return 0;
}

87
static int batadv_interface_release(struct net_device *dev)
88 89 90 91 92
{
	netif_stop_queue(dev);
	return 0;
}

93
static struct net_device_stats *batadv_interface_stats(struct net_device *dev)
94
{
95
	struct batadv_priv *bat_priv = netdev_priv(dev);
96 97 98 99 100 101 102 103
	struct net_device_stats *stats = &bat_priv->stats;

	stats->tx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_TX);
	stats->tx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_TX_BYTES);
	stats->tx_dropped = batadv_sum_counter(bat_priv, BATADV_CNT_TX_DROPPED);
	stats->rx_packets = batadv_sum_counter(bat_priv, BATADV_CNT_RX);
	stats->rx_bytes = batadv_sum_counter(bat_priv, BATADV_CNT_RX_BYTES);
	return stats;
104 105
}

106
static int batadv_interface_set_mac_addr(struct net_device *dev, void *p)
107
{
108
	struct batadv_priv *bat_priv = netdev_priv(dev);
109
	struct sockaddr *addr = p;
110
	uint8_t old_addr[ETH_ALEN];
111 112 113 114

	if (!is_valid_ether_addr(addr->sa_data))
		return -EADDRNOTAVAIL;

115 116 117
	memcpy(old_addr, dev->dev_addr, ETH_ALEN);
	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);

118
	/* only modify transtable if it has been initialized before */
119
	if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
120
		batadv_tt_local_remove(bat_priv, old_addr,
121
				       "mac address changed", false);
122
		batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
123 124
	}

125
	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
126 127 128
	return 0;
}

129
static int batadv_interface_change_mtu(struct net_device *dev, int new_mtu)
130 131
{
	/* check ranges */
132
	if ((new_mtu < 68) || (new_mtu > batadv_hardif_min_mtu(dev)))
133 134 135 136 137 138 139
		return -EINVAL;

	dev->mtu = new_mtu;

	return 0;
}

140 141
static int batadv_interface_tx(struct sk_buff *skb,
			       struct net_device *soft_iface)
142 143
{
	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
144 145
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
	struct batadv_hard_iface *primary_if = NULL;
146
	struct batadv_bcast_packet *bcast_packet;
147
	struct vlan_ethhdr *vhdr;
148
	__be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN);
149 150 151 152
	static const uint8_t stp_addr[ETH_ALEN] = {0x01, 0x80, 0xC2, 0x00,
						   0x00, 0x00};
	static const uint8_t ectp_addr[ETH_ALEN] = {0xCF, 0x00, 0x00, 0x00,
						    0x00, 0x00};
153
	unsigned int header_len = 0;
154
	int data_len = skb->len, ret;
155
	short vid __maybe_unused = -1;
156
	bool do_bcast = false;
157
	uint32_t seqno;
158

159
	if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
160 161 162 163 164 165 166 167 168
		goto dropped;

	soft_iface->trans_start = jiffies;

	switch (ntohs(ethhdr->h_proto)) {
	case ETH_P_8021Q:
		vhdr = (struct vlan_ethhdr *)skb->data;
		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;

169
		if (vhdr->h_vlan_encapsulated_proto != ethertype)
170 171 172
			break;

		/* fall through */
173
	case BATADV_ETH_P_BATMAN:
174
		goto dropped;
175
	}
176

177
	if (batadv_bla_tx(bat_priv, skb, vid))
178 179
		goto dropped;

180
	/* Register the client MAC in the transtable */
181
	batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
182

183 184
	/* don't accept stp packets. STP does not help in meshes.
	 * better use the bridge loop avoidance ...
185 186 187
	 *
	 * The same goes for ECTP sent at least by some Cisco Switches,
	 * it might confuse the mesh when used with bridge loop avoidance.
188
	 */
189
	if (batadv_compare_eth(ethhdr->h_dest, stp_addr))
190 191
		goto dropped;

192 193 194
	if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
		goto dropped;

195 196
	if (is_multicast_ether_addr(ethhdr->h_dest)) {
		do_bcast = true;
197

198
		switch (atomic_read(&bat_priv->gw_mode)) {
199
		case BATADV_GW_MODE_SERVER:
200
			/* gateway servers should not send dhcp
201 202
			 * requests into the mesh
			 */
203
			ret = batadv_gw_is_dhcp_target(skb, &header_len);
204 205 206
			if (ret)
				goto dropped;
			break;
207
		case BATADV_GW_MODE_CLIENT:
208
			/* gateway clients should send dhcp requests
209 210
			 * via unicast to their gateway
			 */
211
			ret = batadv_gw_is_dhcp_target(skb, &header_len);
212 213 214
			if (ret)
				do_bcast = false;
			break;
215
		case BATADV_GW_MODE_OFF:
216 217 218
		default:
			break;
		}
219 220 221 222
	}

	/* ethernet packet should be broadcasted */
	if (do_bcast) {
223
		primary_if = batadv_primary_if_get_selected(bat_priv);
224
		if (!primary_if)
225 226
			goto dropped;

227
		if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
228 229
			goto dropped;

230
		bcast_packet = (struct batadv_bcast_packet *)skb->data;
231
		bcast_packet->header.version = BATADV_COMPAT_VERSION;
232
		bcast_packet->header.ttl = BATADV_TTL;
233 234

		/* batman packet type: broadcast */
235
		bcast_packet->header.packet_type = BATADV_BCAST;
236
		bcast_packet->reserved = 0;
237 238

		/* hw address of first interface is the orig mac because only
239 240
		 * this mac is known throughout the mesh
		 */
241
		memcpy(bcast_packet->orig,
242
		       primary_if->net_dev->dev_addr, ETH_ALEN);
243 244

		/* set broadcast sequence number */
245 246
		seqno = atomic_inc_return(&bat_priv->bcast_seqno);
		bcast_packet->seqno = htonl(seqno);
247

248
		batadv_add_bcast_packet_to_list(bat_priv, skb, 1);
249 250

		/* a copy is stored in the bcast list, therefore removing
251 252
		 * the original skb.
		 */
253 254 255 256
		kfree_skb(skb);

	/* unicast packet */
	} else {
257
		if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_OFF) {
258
			ret = batadv_gw_out_of_range(bat_priv, skb, ethhdr);
259 260 261 262
			if (ret)
				goto dropped;
		}

263
		ret = batadv_unicast_send_skb(bat_priv, skb);
264 265 266 267
		if (ret != 0)
			goto dropped_freed;
	}

268 269
	batadv_inc_counter(bat_priv, BATADV_CNT_TX);
	batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len);
270 271 272 273 274
	goto end;

dropped:
	kfree_skb(skb);
dropped_freed:
275
	batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
276
end:
277
	if (primary_if)
278
		batadv_hardif_free_ref(primary_if);
279 280 281
	return NETDEV_TX_OK;
}

282
void batadv_interface_rx(struct net_device *soft_iface,
283
			 struct sk_buff *skb, struct batadv_hard_iface *recv_if,
284
			 int hdr_size, struct batadv_orig_node *orig_node)
285
{
286
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
287 288
	struct ethhdr *ethhdr;
	struct vlan_ethhdr *vhdr;
289
	struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
290
	short vid __maybe_unused = -1;
291
	__be16 ethertype = __constant_htons(BATADV_ETH_P_BATMAN);
292 293
	bool is_bcast;

294
	is_bcast = (batadv_header->packet_type == BATADV_BCAST);
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309

	/* check if enough space is available for pulling, and pull */
	if (!pskb_may_pull(skb, hdr_size))
		goto dropped;

	skb_pull_rcsum(skb, hdr_size);
	skb_reset_mac_header(skb);

	ethhdr = (struct ethhdr *)skb_mac_header(skb);

	switch (ntohs(ethhdr->h_proto)) {
	case ETH_P_8021Q:
		vhdr = (struct vlan_ethhdr *)skb->data;
		vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK;

310
		if (vhdr->h_vlan_encapsulated_proto != ethertype)
311 312 313
			break;

		/* fall through */
314
	case BATADV_ETH_P_BATMAN:
315 316 317 318 319 320 321 322
		goto dropped;
	}

	/* skb->dev & skb->pkt_type are set here */
	if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
		goto dropped;
	skb->protocol = eth_type_trans(skb, soft_iface);

L
Lucas De Marchi 已提交
323
	/* should not be necessary anymore as we use skb_pull_rcsum()
324
	 * TODO: please verify this and remove this TODO
325 326
	 * -- Dec 21st 2009, Simon Wunderlich
	 */
327

328
	/* skb->ip_summed = CHECKSUM_UNNECESSARY; */
329

330 331 332
	batadv_inc_counter(bat_priv, BATADV_CNT_RX);
	batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
			   skb->len + ETH_HLEN);
333 334 335

	soft_iface->last_rx = jiffies;

336 337 338 339
	if (orig_node)
		batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
						     ethhdr->h_source);

340
	if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
341 342
		goto dropped;

343 344 345
	/* Let the bridge loop avoidance check the packet. If will
	 * not handle it, we can safely push it up.
	 */
346
	if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
347 348
		goto out;

349
	netif_rx(skb);
350
	goto out;
351 352 353 354 355 356 357

dropped:
	kfree_skb(skb);
out:
	return;
}

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400
/* batman-adv network devices have devices nesting below it and are a special
 * "super class" of normal network devices; split their locks off into a
 * separate class since they always nest.
 */
static struct lock_class_key batadv_netdev_xmit_lock_key;
static struct lock_class_key batadv_netdev_addr_lock_key;

/**
 * batadv_set_lockdep_class_one - Set lockdep class for a single tx queue
 * @dev: device which owns the tx queue
 * @txq: tx queue to modify
 * @_unused: always NULL
 */
static void batadv_set_lockdep_class_one(struct net_device *dev,
					 struct netdev_queue *txq,
					 void *_unused)
{
	lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key);
}

/**
 * batadv_set_lockdep_class - Set txq and addr_list lockdep class
 * @dev: network device to modify
 */
static void batadv_set_lockdep_class(struct net_device *dev)
{
	lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key);
	netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL);
}

/**
 * batadv_softif_init - Late stage initialization of soft interface
 * @dev: registered network device to modify
 *
 * Returns error code on failures
 */
static int batadv_softif_init(struct net_device *dev)
{
	batadv_set_lockdep_class(dev);

	return 0;
}

401
static const struct net_device_ops batadv_netdev_ops = {
402
	.ndo_init = batadv_softif_init,
403 404 405 406 407 408
	.ndo_open = batadv_interface_open,
	.ndo_stop = batadv_interface_release,
	.ndo_get_stats = batadv_interface_stats,
	.ndo_set_mac_address = batadv_interface_set_mac_addr,
	.ndo_change_mtu = batadv_interface_change_mtu,
	.ndo_start_xmit = batadv_interface_tx,
409 410 411
	.ndo_validate_addr = eth_validate_addr
};

412
static void batadv_interface_setup(struct net_device *dev)
413
{
414
	struct batadv_priv *priv = netdev_priv(dev);
415 416 417

	ether_setup(dev);

418
	dev->netdev_ops = &batadv_netdev_ops;
419
	dev->destructor = free_netdev;
420
	dev->tx_queue_len = 0;
421

422
	/* can't call min_mtu, because the needed variables
423 424 425
	 * have not been initialized yet
	 */
	dev->mtu = ETH_DATA_LEN;
426
	/* reserve more space in the skbuff for our header */
427
	dev->hard_header_len = BATADV_HEADER_LEN;
428 429

	/* generate random address */
430
	eth_hw_addr_random(dev);
431

432
	SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops);
433

434
	memset(priv, 0, sizeof(*priv));
435 436
}

437
struct net_device *batadv_softif_create(const char *name)
438 439
{
	struct net_device *soft_iface;
440
	struct batadv_priv *bat_priv;
441
	int ret;
442
	size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM;
443

444 445
	soft_iface = alloc_netdev(sizeof(*bat_priv), name,
				  batadv_interface_setup);
446

447
	if (!soft_iface)
448 449
		goto out;

450 451 452 453 454 455 456 457 458
	bat_priv = netdev_priv(soft_iface);

	/* batadv_interface_stats() needs to be available as soon as
	 * register_netdevice() has been called
	 */
	bat_priv->bat_counters = __alloc_percpu(cnt_len, __alignof__(uint64_t));
	if (!bat_priv->bat_counters)
		goto free_soft_iface;

459
	ret = register_netdevice(soft_iface);
460 461 462
	if (ret < 0) {
		pr_err("Unable to register the batman interface '%s': %i\n",
		       name, ret);
463
		goto free_bat_counters;
464 465 466 467
	}

	atomic_set(&bat_priv->aggregated_ogms, 1);
	atomic_set(&bat_priv->bonding, 0);
468
	atomic_set(&bat_priv->bridge_loop_avoidance, 0);
469
	atomic_set(&bat_priv->ap_isolation, 0);
470
	atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
471
	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
472 473 474
	atomic_set(&bat_priv->gw_sel_class, 20);
	atomic_set(&bat_priv->gw_bandwidth, 41);
	atomic_set(&bat_priv->orig_interval, 1000);
475
	atomic_set(&bat_priv->hop_penalty, 30);
476 477
	atomic_set(&bat_priv->log_level, 0);
	atomic_set(&bat_priv->fragmentation, 1);
478 479
	atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
	atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
480

481
	atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
482
	atomic_set(&bat_priv->bcast_seqno, 1);
483 484 485 486 487 488 489 490 491
	atomic_set(&bat_priv->tt.vn, 0);
	atomic_set(&bat_priv->tt.local_changes, 0);
	atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
#ifdef CONFIG_BATMAN_ADV_BLA
	atomic_set(&bat_priv->bla.num_requests, 0);
#endif
	bat_priv->tt.last_changeset = NULL;
	bat_priv->tt.last_changeset_len = 0;
	bat_priv->tt.poss_change = false;
492 493 494 495

	bat_priv->primary_if = NULL;
	bat_priv->num_ifaces = 0;

496
	ret = batadv_algo_select(bat_priv, batadv_routing_algo);
497
	if (ret < 0)
498
		goto unreg_soft_iface;
499

500
	ret = batadv_sysfs_add_meshif(soft_iface);
501
	if (ret < 0)
502
		goto unreg_soft_iface;
503

504
	ret = batadv_debugfs_add_meshif(soft_iface);
505 506 507
	if (ret < 0)
		goto unreg_sysfs;

508
	ret = batadv_mesh_init(soft_iface);
509 510 511 512 513 514
	if (ret < 0)
		goto unreg_debugfs;

	return soft_iface;

unreg_debugfs:
515
	batadv_debugfs_del_meshif(soft_iface);
516
unreg_sysfs:
517
	batadv_sysfs_del_meshif(soft_iface);
518
unreg_soft_iface:
519
	free_percpu(bat_priv->bat_counters);
520
	unregister_netdevice(soft_iface);
521 522
	return NULL;

523 524
free_bat_counters:
	free_percpu(bat_priv->bat_counters);
525 526 527 528 529 530
free_soft_iface:
	free_netdev(soft_iface);
out:
	return NULL;
}

531
void batadv_softif_destroy(struct net_device *soft_iface)
532
{
533
	batadv_debugfs_del_meshif(soft_iface);
534
	batadv_sysfs_del_meshif(soft_iface);
535
	batadv_mesh_free(soft_iface);
536 537 538
	unregister_netdevice(soft_iface);
}

539
int batadv_softif_is_valid(const struct net_device *net_dev)
540
{
541
	if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx)
542 543 544 545 546
		return 1;

	return 0;
}

547
/* ethtool */
548
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
549 550 551
{
	cmd->supported = 0;
	cmd->advertising = 0;
552
	ethtool_cmd_speed_set(cmd, SPEED_10);
553 554 555 556 557 558 559 560 561 562 563
	cmd->duplex = DUPLEX_FULL;
	cmd->port = PORT_TP;
	cmd->phy_address = 0;
	cmd->transceiver = XCVR_INTERNAL;
	cmd->autoneg = AUTONEG_DISABLE;
	cmd->maxtxpkt = 0;
	cmd->maxrxpkt = 0;

	return 0;
}

564 565
static void batadv_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
566 567
{
	strcpy(info->driver, "B.A.T.M.A.N. advanced");
568
	strcpy(info->version, BATADV_SOURCE_VERSION);
569 570 571 572
	strcpy(info->fw_version, "N/A");
	strcpy(info->bus_info, "batman");
}

573
static u32 batadv_get_msglevel(struct net_device *dev)
574 575 576 577
{
	return -EOPNOTSUPP;
}

578
static void batadv_set_msglevel(struct net_device *dev, u32 value)
579 580 581
{
}

582
static u32 batadv_get_link(struct net_device *dev)
583 584 585
{
	return 1;
}
586 587 588 589 590 591 592

/* Inspired by drivers/net/ethernet/dlink/sundance.c:1702
 * Declare each description string in struct.name[] to get fixed sized buffer
 * and compile time checking for strings longer than ETH_GSTRING_LEN.
 */
static const struct {
	const char name[ETH_GSTRING_LEN];
593
} batadv_counters_strings[] = {
594 595 596 597 598
	{ "tx" },
	{ "tx_bytes" },
	{ "tx_dropped" },
	{ "rx" },
	{ "rx_bytes" },
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
	{ "forward" },
	{ "forward_bytes" },
	{ "mgmt_tx" },
	{ "mgmt_tx_bytes" },
	{ "mgmt_rx" },
	{ "mgmt_rx_bytes" },
	{ "tt_request_tx" },
	{ "tt_request_rx" },
	{ "tt_response_tx" },
	{ "tt_response_rx" },
	{ "tt_roam_adv_tx" },
	{ "tt_roam_adv_rx" },
};

static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
			       uint8_t *data)
{
	if (stringset == ETH_SS_STATS)
617 618
		memcpy(data, batadv_counters_strings,
		       sizeof(batadv_counters_strings));
619 620 621 622 623 624
}

static void batadv_get_ethtool_stats(struct net_device *dev,
				     struct ethtool_stats *stats,
				     uint64_t *data)
{
625
	struct batadv_priv *bat_priv = netdev_priv(dev);
626 627
	int i;

628
	for (i = 0; i < BATADV_CNT_NUM; i++)
629 630 631 632 633 634
		data[i] = batadv_sum_counter(bat_priv, i);
}

static int batadv_get_sset_count(struct net_device *dev, int stringset)
{
	if (stringset == ETH_SS_STATS)
635
		return BATADV_CNT_NUM;
636 637 638

	return -EOPNOTSUPP;
}