soft-interface.c 17.8 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
 *
 * 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"
23
#include "distributed-arp-table.h"
24 25
#include "routing.h"
#include "send.h"
26
#include "debugfs.h"
27 28 29 30
#include "translation-table.h"
#include "hash.h"
#include "gateway_common.h"
#include "gateway_client.h"
31
#include "sysfs.h"
32
#include "originator.h"
33 34 35 36
#include <linux/slab.h>
#include <linux/ethtool.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
A
Antonio Quartulli 已提交
37
#include <linux/if_ether.h>
38
#include "unicast.h"
39
#include "bridge_loop_avoidance.h"
40 41


42 43 44 45 46 47
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);
48 49 50 51
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);
52

53 54 55 56 57 58
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,
59 60 61
	.get_strings = batadv_get_strings,
	.get_ethtool_stats = batadv_get_ethtool_stats,
	.get_sset_count = batadv_get_sset_count,
62 63
};

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

68
	/* TODO: We must check if we can release all references to non-payload
69 70 71 72 73 74 75 76 77 78 79 80 81 82
	 * 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;
}

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

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

95
static struct net_device_stats *batadv_interface_stats(struct net_device *dev)
96
{
97
	struct batadv_priv *bat_priv = netdev_priv(dev);
98 99 100 101 102 103 104 105
	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;
106 107
}

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

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

117 118 119
	memcpy(old_addr, dev->dev_addr, ETH_ALEN);
	memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);

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

127
	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
128 129 130
	return 0;
}

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

	dev->mtu = new_mtu;

	return 0;
}

142 143
static int batadv_interface_tx(struct sk_buff *skb,
			       struct net_device *soft_iface)
144 145
{
	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
146 147
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
	struct batadv_hard_iface *primary_if = NULL;
148
	struct batadv_bcast_packet *bcast_packet;
149
	struct vlan_ethhdr *vhdr;
A
Antonio Quartulli 已提交
150
	__be16 ethertype = __constant_htons(ETH_P_BATMAN);
151 152 153 154
	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};
155
	unsigned int header_len = 0;
156
	int data_len = skb->len, ret;
157
	short vid __maybe_unused = -1;
158
	bool do_bcast = false;
159
	uint32_t seqno;
160
	unsigned long brd_delay = 1;
161

162
	if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE)
163 164 165 166 167 168 169 170 171
		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;

172
		if (vhdr->h_vlan_encapsulated_proto != ethertype)
173 174 175
			break;

		/* fall through */
A
Antonio Quartulli 已提交
176
	case ETH_P_BATMAN:
177
		goto dropped;
178
	}
179

180
	if (batadv_bla_tx(bat_priv, skb, vid))
181 182
		goto dropped;

183
	/* Register the client MAC in the transtable */
184
	batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
185

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

195 196 197
	if (batadv_compare_eth(ethhdr->h_dest, ectp_addr))
		goto dropped;

198 199
	if (is_multicast_ether_addr(ethhdr->h_dest)) {
		do_bcast = true;
200

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

	/* ethernet packet should be broadcasted */
	if (do_bcast) {
226
		primary_if = batadv_primary_if_get_selected(bat_priv);
227
		if (!primary_if)
228 229
			goto dropped;

230 231 232 233 234 235 236
		/* in case of ARP request, we do not immediately broadcasti the
		 * packet, instead we first wait for DAT to try to retrieve the
		 * correct ARP entry
		 */
		if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
			brd_delay = msecs_to_jiffies(ARP_REQ_DELAY);

237
		if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
238 239
			goto dropped;

240
		bcast_packet = (struct batadv_bcast_packet *)skb->data;
241
		bcast_packet->header.version = BATADV_COMPAT_VERSION;
242
		bcast_packet->header.ttl = BATADV_TTL;
243 244

		/* batman packet type: broadcast */
245
		bcast_packet->header.packet_type = BATADV_BCAST;
246
		bcast_packet->reserved = 0;
247 248

		/* hw address of first interface is the orig mac because only
249 250
		 * this mac is known throughout the mesh
		 */
251
		memcpy(bcast_packet->orig,
252
		       primary_if->net_dev->dev_addr, ETH_ALEN);
253 254

		/* set broadcast sequence number */
255 256
		seqno = atomic_inc_return(&bat_priv->bcast_seqno);
		bcast_packet->seqno = htonl(seqno);
257

258
		batadv_add_bcast_packet_to_list(bat_priv, skb, brd_delay);
259 260

		/* a copy is stored in the bcast list, therefore removing
261 262
		 * the original skb.
		 */
263 264 265 266
		kfree_skb(skb);

	/* unicast packet */
	} else {
267
		if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_OFF) {
268
			ret = batadv_gw_out_of_range(bat_priv, skb, ethhdr);
269 270 271 272
			if (ret)
				goto dropped;
		}

273 274 275 276 277
		if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
			goto dropped;

		batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);

278
		ret = batadv_unicast_send_skb(bat_priv, skb);
279 280 281 282
		if (ret != 0)
			goto dropped_freed;
	}

283 284
	batadv_inc_counter(bat_priv, BATADV_CNT_TX);
	batadv_add_counter(bat_priv, BATADV_CNT_TX_BYTES, data_len);
285 286 287 288 289
	goto end;

dropped:
	kfree_skb(skb);
dropped_freed:
290
	batadv_inc_counter(bat_priv, BATADV_CNT_TX_DROPPED);
291
end:
292
	if (primary_if)
293
		batadv_hardif_free_ref(primary_if);
294 295 296
	return NETDEV_TX_OK;
}

297
void batadv_interface_rx(struct net_device *soft_iface,
298
			 struct sk_buff *skb, struct batadv_hard_iface *recv_if,
299
			 int hdr_size, struct batadv_orig_node *orig_node)
300
{
301
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
302 303
	struct ethhdr *ethhdr;
	struct vlan_ethhdr *vhdr;
304
	struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
305
	short vid __maybe_unused = -1;
A
Antonio Quartulli 已提交
306
	__be16 ethertype = __constant_htons(ETH_P_BATMAN);
307 308
	bool is_bcast;

309
	is_bcast = (batadv_header->packet_type == BATADV_BCAST);
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324

	/* 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;

325
		if (vhdr->h_vlan_encapsulated_proto != ethertype)
326 327 328
			break;

		/* fall through */
A
Antonio Quartulli 已提交
329
	case ETH_P_BATMAN:
330 331 332 333 334 335 336 337
		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 已提交
338
	/* should not be necessary anymore as we use skb_pull_rcsum()
339
	 * TODO: please verify this and remove this TODO
340 341
	 * -- Dec 21st 2009, Simon Wunderlich
	 */
342

343
	/* skb->ip_summed = CHECKSUM_UNNECESSARY; */
344

345 346 347
	batadv_inc_counter(bat_priv, BATADV_CNT_RX);
	batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
			   skb->len + ETH_HLEN);
348 349 350

	soft_iface->last_rx = jiffies;

351 352 353 354 355 356
	/* Let the bridge loop avoidance check the packet. If will
	 * not handle it, we can safely push it up.
	 */
	if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
		goto out;

357 358 359 360
	if (orig_node)
		batadv_tt_add_temporary_global_entry(bat_priv, orig_node,
						     ethhdr->h_source);

361
	if (batadv_is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest))
362 363
		goto dropped;

364
	netif_rx(skb);
365
	goto out;
366 367 368 369 370 371 372

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

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 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
/* 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;
}

416
static const struct net_device_ops batadv_netdev_ops = {
417
	.ndo_init = batadv_softif_init,
418 419 420 421 422 423
	.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,
424 425 426
	.ndo_validate_addr = eth_validate_addr
};

427
static void batadv_interface_setup(struct net_device *dev)
428
{
429
	struct batadv_priv *priv = netdev_priv(dev);
430 431 432

	ether_setup(dev);

433
	dev->netdev_ops = &batadv_netdev_ops;
434
	dev->destructor = free_netdev;
435
	dev->tx_queue_len = 0;
436

437
	/* can't call min_mtu, because the needed variables
438 439 440
	 * have not been initialized yet
	 */
	dev->mtu = ETH_DATA_LEN;
441
	/* reserve more space in the skbuff for our header */
442
	dev->hard_header_len = BATADV_HEADER_LEN;
443 444

	/* generate random address */
445
	eth_hw_addr_random(dev);
446

447
	SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops);
448

449
	memset(priv, 0, sizeof(*priv));
450 451
}

452
struct net_device *batadv_softif_create(const char *name)
453 454
{
	struct net_device *soft_iface;
455
	struct batadv_priv *bat_priv;
456
	int ret;
457
	size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM;
458

459 460
	soft_iface = alloc_netdev(sizeof(*bat_priv), name,
				  batadv_interface_setup);
461

462
	if (!soft_iface)
463 464
		goto out;

465 466 467 468 469 470 471 472 473
	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;

474
	ret = register_netdevice(soft_iface);
475 476 477
	if (ret < 0) {
		pr_err("Unable to register the batman interface '%s': %i\n",
		       name, ret);
478
		goto free_bat_counters;
479 480 481 482
	}

	atomic_set(&bat_priv->aggregated_ogms, 1);
	atomic_set(&bat_priv->bonding, 0);
483
	atomic_set(&bat_priv->bridge_loop_avoidance, 0);
484 485 486
#ifdef CONFIG_BATMAN_ADV_DAT
	atomic_set(&bat_priv->distributed_arp_table, 1);
#endif
487
	atomic_set(&bat_priv->ap_isolation, 0);
488
	atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
489
	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
490 491 492
	atomic_set(&bat_priv->gw_sel_class, 20);
	atomic_set(&bat_priv->gw_bandwidth, 41);
	atomic_set(&bat_priv->orig_interval, 1000);
493
	atomic_set(&bat_priv->hop_penalty, 30);
494 495
	atomic_set(&bat_priv->log_level, 0);
	atomic_set(&bat_priv->fragmentation, 1);
496 497
	atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
	atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
498

499
	atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
500
	atomic_set(&bat_priv->bcast_seqno, 1);
501 502 503 504 505 506 507 508
	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;
509 510 511 512

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

513
	ret = batadv_algo_select(bat_priv, batadv_routing_algo);
514
	if (ret < 0)
515
		goto unreg_soft_iface;
516

517
	ret = batadv_sysfs_add_meshif(soft_iface);
518
	if (ret < 0)
519
		goto unreg_soft_iface;
520

521
	ret = batadv_debugfs_add_meshif(soft_iface);
522 523 524
	if (ret < 0)
		goto unreg_sysfs;

525
	ret = batadv_mesh_init(soft_iface);
526 527 528 529 530 531
	if (ret < 0)
		goto unreg_debugfs;

	return soft_iface;

unreg_debugfs:
532
	batadv_debugfs_del_meshif(soft_iface);
533
unreg_sysfs:
534
	batadv_sysfs_del_meshif(soft_iface);
535
unreg_soft_iface:
536
	free_percpu(bat_priv->bat_counters);
537
	unregister_netdevice(soft_iface);
538 539
	return NULL;

540 541
free_bat_counters:
	free_percpu(bat_priv->bat_counters);
542 543 544 545 546 547
free_soft_iface:
	free_netdev(soft_iface);
out:
	return NULL;
}

548
void batadv_softif_destroy(struct net_device *soft_iface)
549
{
550
	batadv_debugfs_del_meshif(soft_iface);
551
	batadv_sysfs_del_meshif(soft_iface);
552
	batadv_mesh_free(soft_iface);
553 554 555
	unregister_netdevice(soft_iface);
}

556
int batadv_softif_is_valid(const struct net_device *net_dev)
557
{
558
	if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx)
559 560 561 562 563
		return 1;

	return 0;
}

564
/* ethtool */
565
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
566 567 568
{
	cmd->supported = 0;
	cmd->advertising = 0;
569
	ethtool_cmd_speed_set(cmd, SPEED_10);
570 571 572 573 574 575 576 577 578 579 580
	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;
}

581 582
static void batadv_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
583 584
{
	strcpy(info->driver, "B.A.T.M.A.N. advanced");
585
	strcpy(info->version, BATADV_SOURCE_VERSION);
586 587 588 589
	strcpy(info->fw_version, "N/A");
	strcpy(info->bus_info, "batman");
}

590
static u32 batadv_get_msglevel(struct net_device *dev)
591 592 593 594
{
	return -EOPNOTSUPP;
}

595
static void batadv_set_msglevel(struct net_device *dev, u32 value)
596 597 598
{
}

599
static u32 batadv_get_link(struct net_device *dev)
600 601 602
{
	return 1;
}
603 604 605 606 607 608 609

/* 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];
610
} batadv_counters_strings[] = {
611 612 613 614 615
	{ "tx" },
	{ "tx_bytes" },
	{ "tx_dropped" },
	{ "rx" },
	{ "rx_bytes" },
616 617 618 619 620 621 622 623 624 625 626 627
	{ "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" },
628 629 630 631 632 633 634
#ifdef CONFIG_BATMAN_ADV_DAT
	{ "dat_get_tx" },
	{ "dat_get_rx" },
	{ "dat_put_tx" },
	{ "dat_put_rx" },
	{ "dat_cached_reply_tx" },
#endif
635 636 637 638 639 640
};

static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
			       uint8_t *data)
{
	if (stringset == ETH_SS_STATS)
641 642
		memcpy(data, batadv_counters_strings,
		       sizeof(batadv_counters_strings));
643 644 645 646 647 648
}

static void batadv_get_ethtool_stats(struct net_device *dev,
				     struct ethtool_stats *stats,
				     uint64_t *data)
{
649
	struct batadv_priv *bat_priv = netdev_priv(dev);
650 651
	int i;

652
	for (i = 0; i < BATADV_CNT_NUM; i++)
653 654 655 656 657 658
		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)
659
		return BATADV_CNT_NUM;
660 661 662

	return -EOPNOTSUPP;
}