soft-interface.c 18.8 KB
Newer Older
1
/* Copyright (C) 2007-2013 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
#include "network-coding.h"
41 42


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

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

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

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

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

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

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

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

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

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

121
	/* only modify transtable if it has been initialized before */
122
	if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_ACTIVE) {
123
		batadv_tt_local_remove(bat_priv, old_addr,
124
				       "mac address changed", false);
125
		batadv_tt_local_add(dev, addr->sa_data, BATADV_NULL_IFINDEX);
126 127 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 185
	if (!is_multicast_ether_addr(ethhdr->h_source))
		batadv_tt_local_add(soft_iface, ethhdr->h_source, skb->skb_iif);
186

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

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

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

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

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

231 232 233 234 235 236 237
		/* 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);

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

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

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

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

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

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

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

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

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

		batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);

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

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

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

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

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

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

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

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

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

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

	soft_iface->last_rx = jiffies;

352 353 354 355 356 357
	/* 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;

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

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

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

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

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

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

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

	ether_setup(dev);

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

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

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

448
	SET_ETHTOOL_OPS(dev, &batadv_ethtool_ops);
449

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

453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
/**
 * batadv_softif_destroy_finish - cleans up the remains of a softif
 * @work: work queue item
 *
 * Free the parts of the soft interface which can not be removed under
 * rtnl lock (to prevent deadlock situations).
 */
static void batadv_softif_destroy_finish(struct work_struct *work)
{
	struct batadv_priv *bat_priv;
	struct net_device *soft_iface;

	bat_priv = container_of(work, struct batadv_priv,
				cleanup_work);
	soft_iface = bat_priv->soft_iface;

	batadv_debugfs_del_meshif(soft_iface);
	batadv_sysfs_del_meshif(soft_iface);

	rtnl_lock();
	unregister_netdevice(soft_iface);
	rtnl_unlock();
}

477
struct net_device *batadv_softif_create(const char *name)
478 479
{
	struct net_device *soft_iface;
480
	struct batadv_priv *bat_priv;
481
	int ret;
482
	size_t cnt_len = sizeof(uint64_t) * BATADV_CNT_NUM;
483

484 485
	soft_iface = alloc_netdev(sizeof(*bat_priv), name,
				  batadv_interface_setup);
486

487
	if (!soft_iface)
488 489
		goto out;

490
	bat_priv = netdev_priv(soft_iface);
491 492
	bat_priv->soft_iface = soft_iface;
	INIT_WORK(&bat_priv->cleanup_work, batadv_softif_destroy_finish);
493 494 495 496 497 498 499 500

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

501
	ret = register_netdevice(soft_iface);
502 503 504
	if (ret < 0) {
		pr_err("Unable to register the batman interface '%s': %i\n",
		       name, ret);
505
		goto free_bat_counters;
506 507 508 509
	}

	atomic_set(&bat_priv->aggregated_ogms, 1);
	atomic_set(&bat_priv->bonding, 0);
510
#ifdef CONFIG_BATMAN_ADV_BLA
511
	atomic_set(&bat_priv->bridge_loop_avoidance, 0);
512
#endif
513 514 515
#ifdef CONFIG_BATMAN_ADV_DAT
	atomic_set(&bat_priv->distributed_arp_table, 1);
#endif
516
	atomic_set(&bat_priv->ap_isolation, 0);
517
	atomic_set(&bat_priv->vis_mode, BATADV_VIS_TYPE_CLIENT_UPDATE);
518
	atomic_set(&bat_priv->gw_mode, BATADV_GW_MODE_OFF);
519 520 521
	atomic_set(&bat_priv->gw_sel_class, 20);
	atomic_set(&bat_priv->gw_bandwidth, 41);
	atomic_set(&bat_priv->orig_interval, 1000);
522
	atomic_set(&bat_priv->hop_penalty, 30);
523
#ifdef CONFIG_BATMAN_ADV_DEBUG
524
	atomic_set(&bat_priv->log_level, 0);
525
#endif
526
	atomic_set(&bat_priv->fragmentation, 1);
527 528
	atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
	atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
529

530
	atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
531
	atomic_set(&bat_priv->bcast_seqno, 1);
532 533 534 535 536 537 538 539
	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;
540 541 542 543

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

544
	ret = batadv_algo_select(bat_priv, batadv_routing_algo);
545
	if (ret < 0)
546
		goto unreg_soft_iface;
547

548 549
	batadv_nc_init_bat_priv(bat_priv);

550
	ret = batadv_sysfs_add_meshif(soft_iface);
551
	if (ret < 0)
552
		goto unreg_soft_iface;
553

554
	ret = batadv_debugfs_add_meshif(soft_iface);
555 556 557
	if (ret < 0)
		goto unreg_sysfs;

558
	ret = batadv_mesh_init(soft_iface);
559 560 561 562 563 564
	if (ret < 0)
		goto unreg_debugfs;

	return soft_iface;

unreg_debugfs:
565
	batadv_debugfs_del_meshif(soft_iface);
566
unreg_sysfs:
567
	batadv_sysfs_del_meshif(soft_iface);
568
unreg_soft_iface:
569
	free_percpu(bat_priv->bat_counters);
570
	unregister_netdevice(soft_iface);
571 572
	return NULL;

573 574
free_bat_counters:
	free_percpu(bat_priv->bat_counters);
575 576 577 578 579 580
free_soft_iface:
	free_netdev(soft_iface);
out:
	return NULL;
}

581
void batadv_softif_destroy(struct net_device *soft_iface)
582
{
583 584
	struct batadv_priv *bat_priv = netdev_priv(soft_iface);

585
	batadv_mesh_free(soft_iface);
586
	queue_work(batadv_event_workqueue, &bat_priv->cleanup_work);
587 588
}

589
int batadv_softif_is_valid(const struct net_device *net_dev)
590
{
591
	if (net_dev->netdev_ops->ndo_start_xmit == batadv_interface_tx)
592 593 594 595 596
		return 1;

	return 0;
}

597
/* ethtool */
598
static int batadv_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
599 600 601
{
	cmd->supported = 0;
	cmd->advertising = 0;
602
	ethtool_cmd_speed_set(cmd, SPEED_10);
603 604 605 606 607 608 609 610 611 612 613
	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;
}

614 615
static void batadv_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
616
{
617 618 619 620
	strlcpy(info->driver, "B.A.T.M.A.N. advanced", sizeof(info->driver));
	strlcpy(info->version, BATADV_SOURCE_VERSION, sizeof(info->version));
	strlcpy(info->fw_version, "N/A", sizeof(info->fw_version));
	strlcpy(info->bus_info, "batman", sizeof(info->bus_info));
621 622
}

623
static u32 batadv_get_msglevel(struct net_device *dev)
624 625 626 627
{
	return -EOPNOTSUPP;
}

628
static void batadv_set_msglevel(struct net_device *dev, u32 value)
629 630 631
{
}

632
static u32 batadv_get_link(struct net_device *dev)
633 634 635
{
	return 1;
}
636 637 638 639 640 641 642

/* 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];
643
} batadv_counters_strings[] = {
644 645 646 647 648
	{ "tx" },
	{ "tx_bytes" },
	{ "tx_dropped" },
	{ "rx" },
	{ "rx_bytes" },
649 650 651 652 653 654 655 656 657 658 659 660
	{ "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" },
661 662 663 664 665 666 667
#ifdef CONFIG_BATMAN_ADV_DAT
	{ "dat_get_tx" },
	{ "dat_get_rx" },
	{ "dat_put_tx" },
	{ "dat_put_rx" },
	{ "dat_cached_reply_tx" },
#endif
668 669 670 671 672
#ifdef CONFIG_BATMAN_ADV_NC
	{ "nc_code" },
	{ "nc_code_bytes" },
	{ "nc_recode" },
	{ "nc_recode_bytes" },
673
	{ "nc_buffer" },
674
#endif
675 676 677 678 679 680
};

static void batadv_get_strings(struct net_device *dev, uint32_t stringset,
			       uint8_t *data)
{
	if (stringset == ETH_SS_STATS)
681 682
		memcpy(data, batadv_counters_strings,
		       sizeof(batadv_counters_strings));
683 684 685 686 687 688
}

static void batadv_get_ethtool_stats(struct net_device *dev,
				     struct ethtool_stats *stats,
				     uint64_t *data)
{
689
	struct batadv_priv *bat_priv = netdev_priv(dev);
690 691
	int i;

692
	for (i = 0; i < BATADV_CNT_NUM; i++)
693 694 695 696 697 698
		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)
699
		return BATADV_CNT_NUM;
700 701 702

	return -EOPNOTSUPP;
}