sysfs.c 26.4 KB
Newer Older
1
/* Copyright (C) 2010-2015 B.A.T.M.A.N. contributors:
2 3 4 5 6 7 8 9 10 11 12 13 14
 *
 * Marek Lindner
 *
 * 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
15
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 17
 */

18
#include "sysfs.h"
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#include "main.h"

#include <linux/atomic.h>
#include <linux/compiler.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/if.h>
#include <linux/if_vlan.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/printk.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/rtnetlink.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/stringify.h>

40
#include "distributed-arp-table.h"
41 42
#include "gateway_client.h"
#include "gateway_common.h"
43
#include "bridge_loop_avoidance.h"
44
#include "hard-interface.h"
45 46
#include "network-coding.h"
#include "packet.h"
47
#include "soft-interface.h"
48

49
static struct net_device *batadv_kobj_to_netdev(struct kobject *obj)
50 51
{
	struct device *dev = container_of(obj->parent, struct device, kobj);
52

53 54 55
	return to_net_dev(dev);
}

56
static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
57
{
58
	struct net_device *net_dev = batadv_kobj_to_netdev(obj);
59

60 61
	return netdev_priv(net_dev);
}
62

63 64 65 66
/**
 * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv
 * @obj: kobject to covert
 *
67
 * Return: the associated batadv_priv struct.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
 */
static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj)
{
	/* VLAN specific attributes are located in the root sysfs folder if they
	 * refer to the untagged VLAN..
	 */
	if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name))
		return batadv_kobj_to_batpriv(obj);

	/* ..while the attributes for the tagged vlans are located in
	 * the in the corresponding "vlan%VID" subfolder
	 */
	return batadv_kobj_to_batpriv(obj->parent);
}

/**
 * batadv_kobj_to_vlan - convert a kobj in the associated softif_vlan struct
 * @obj: kobject to covert
 *
87
 * Return: the associated softif_vlan struct if found, NULL otherwise.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
 */
static struct batadv_softif_vlan *
batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj)
{
	struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;

	rcu_read_lock();
	hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
		if (vlan_tmp->kobj != obj)
			continue;

		if (!atomic_inc_not_zero(&vlan_tmp->refcount))
			continue;

		vlan = vlan_tmp;
		break;
	}
	rcu_read_unlock();

	return vlan;
}

110 111 112
#define BATADV_UEV_TYPE_VAR	"BATTYPE="
#define BATADV_UEV_ACTION_VAR	"BATACTION="
#define BATADV_UEV_DATA_VAR	"BATDATA="
113

114
static char *batadv_uev_action_str[] = {
115 116 117 118 119
	"add",
	"del",
	"change"
};

120
static char *batadv_uev_type_str[] = {
121 122 123
	"gw"
};

124 125 126 127 128 129 130
/* Use this, if you have customized show and store functions for vlan attrs */
#define BATADV_ATTR_VLAN(_name, _mode, _show, _store)	\
struct batadv_attribute batadv_attr_vlan_##_name = {	\
	.attr = {.name = __stringify(_name),		\
		 .mode = _mode },			\
	.show   = _show,				\
	.store  = _store,				\
131
}
132

133
/* Use this, if you have customized show and store functions */
134
#define BATADV_ATTR(_name, _mode, _show, _store)	\
135
struct batadv_attribute batadv_attr_##_name = {		\
136 137 138 139
	.attr = {.name = __stringify(_name),		\
		 .mode = _mode },			\
	.show   = _show,				\
	.store  = _store,				\
140
}
141

142
#define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func)			\
143 144 145
ssize_t batadv_store_##_name(struct kobject *kobj,			\
			     struct attribute *attr, char *buff,	\
			     size_t count)				\
146
{									\
147
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
148
	struct batadv_priv *bat_priv = netdev_priv(net_dev);		\
149
									\
150 151
	return __batadv_store_bool_attr(buff, count, _post_func, attr,	\
					&bat_priv->_name, net_dev);	\
152 153
}

154
#define BATADV_ATTR_SIF_SHOW_BOOL(_name)				\
155 156
ssize_t batadv_show_##_name(struct kobject *kobj,			\
			    struct attribute *attr, char *buff)		\
157
{									\
158
	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);	\
159
									\
160 161 162 163 164
	return sprintf(buff, "%s\n",					\
		       atomic_read(&bat_priv->_name) == 0 ?		\
		       "disabled" : "enabled");				\
}									\

165
/* Use this, if you are going to turn a [name] in the soft-interface
166 167
 * (bat_priv) on or off
 */
168 169 170 171 172
#define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func)			\
	static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func)		\
	static BATADV_ATTR_SIF_SHOW_BOOL(_name)				\
	static BATADV_ATTR(_name, _mode, batadv_show_##_name,		\
			   batadv_store_##_name)
173

174
#define BATADV_ATTR_SIF_STORE_UINT(_name, _var, _min, _max, _post_func)	\
175 176 177
ssize_t batadv_store_##_name(struct kobject *kobj,			\
			     struct attribute *attr, char *buff,	\
			     size_t count)				\
178
{									\
179
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
180
	struct batadv_priv *bat_priv = netdev_priv(net_dev);		\
181
									\
182 183
	return __batadv_store_uint_attr(buff, count, _min, _max,	\
					_post_func, attr,		\
184
					&bat_priv->_var, net_dev);	\
185 186
}

187
#define BATADV_ATTR_SIF_SHOW_UINT(_name, _var)				\
188 189
ssize_t batadv_show_##_name(struct kobject *kobj,			\
			    struct attribute *attr, char *buff)		\
190
{									\
191
	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);	\
192
									\
193
	return sprintf(buff, "%i\n", atomic_read(&bat_priv->_var));	\
194 195
}									\

196
/* Use this, if you are going to set [name] in the soft-interface
197 198
 * (bat_priv) to an unsigned integer value
 */
199 200 201
#define BATADV_ATTR_SIF_UINT(_name, _var, _mode, _min, _max, _post_func)\
	static BATADV_ATTR_SIF_STORE_UINT(_name, _var, _min, _max, _post_func)\
	static BATADV_ATTR_SIF_SHOW_UINT(_name, _var)			\
202 203
	static BATADV_ATTR(_name, _mode, batadv_show_##_name,		\
			   batadv_store_##_name)
204

205 206 207 208 209 210 211 212 213 214 215
#define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func)			\
ssize_t batadv_store_vlan_##_name(struct kobject *kobj,			\
				  struct attribute *attr, char *buff,	\
				  size_t count)				\
{									\
	struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
	struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv,	\
							      kobj);	\
	size_t res = __batadv_store_bool_attr(buff, count, _post_func,	\
					      attr, &vlan->_name,	\
					      bat_priv->soft_iface);	\
216
									\
217 218 219 220 221 222 223 224 225 226 227 228 229 230
	batadv_softif_vlan_free_ref(vlan);				\
	return res;							\
}

#define BATADV_ATTR_VLAN_SHOW_BOOL(_name)				\
ssize_t batadv_show_vlan_##_name(struct kobject *kobj,			\
				 struct attribute *attr, char *buff)	\
{									\
	struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
	struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv,	\
							      kobj);	\
	size_t res = sprintf(buff, "%s\n",				\
			     atomic_read(&vlan->_name) == 0 ?		\
			     "disabled" : "enabled");			\
231
									\
232 233 234 235 236 237 238 239 240 241
	batadv_softif_vlan_free_ref(vlan);				\
	return res;							\
}

/* Use this, if you are going to turn a [name] in the vlan struct on or off */
#define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func)			\
	static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func)		\
	static BATADV_ATTR_VLAN_SHOW_BOOL(_name)			\
	static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name,	\
				batadv_store_vlan_##_name)
242

243 244
static int batadv_store_bool_attr(char *buff, size_t count,
				  struct net_device *net_dev,
245 246
				  const char *attr_name, atomic_t *attr,
				  bool *changed)
247 248 249
{
	int enabled = -1;

250 251
	*changed = false;

252 253 254 255 256 257 258 259 260 261 262 263 264 265
	if (buff[count - 1] == '\n')
		buff[count - 1] = '\0';

	if ((strncmp(buff, "1", 2) == 0) ||
	    (strncmp(buff, "enable", 7) == 0) ||
	    (strncmp(buff, "enabled", 8) == 0))
		enabled = 1;

	if ((strncmp(buff, "0", 2) == 0) ||
	    (strncmp(buff, "disable", 8) == 0) ||
	    (strncmp(buff, "disabled", 9) == 0))
		enabled = 0;

	if (enabled < 0) {
266 267
		batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
			    attr_name, buff);
268 269 270 271 272 273
		return -EINVAL;
	}

	if (atomic_read(attr) == enabled)
		return count;

274 275 276
	batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name,
		    atomic_read(attr) == 1 ? "enabled" : "disabled",
		    enabled == 1 ? "enabled" : "disabled");
277

278 279
	*changed = true;

280
	atomic_set(attr, (unsigned int)enabled);
281 282 283
	return count;
}

284 285 286 287 288
static inline ssize_t
__batadv_store_bool_attr(char *buff, size_t count,
			 void (*post_func)(struct net_device *),
			 struct attribute *attr,
			 atomic_t *attr_store, struct net_device *net_dev)
289
{
290
	bool changed;
291 292
	int ret;

293
	ret = batadv_store_bool_attr(buff, count, net_dev, attr->name,
294 295
				     attr_store, &changed);
	if (post_func && changed)
296 297 298 299 300
		post_func(net_dev);

	return ret;
}

301 302 303 304 305
static int batadv_store_uint_attr(const char *buff, size_t count,
				  struct net_device *net_dev,
				  const char *attr_name,
				  unsigned int min, unsigned int max,
				  atomic_t *attr)
306 307 308 309
{
	unsigned long uint_val;
	int ret;

310
	ret = kstrtoul(buff, 10, &uint_val);
311
	if (ret) {
312 313
		batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
			    attr_name, buff);
314 315 316 317
		return -EINVAL;
	}

	if (uint_val < min) {
318 319
		batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n",
			    attr_name, uint_val, min);
320 321 322 323
		return -EINVAL;
	}

	if (uint_val > max) {
324 325
		batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n",
			    attr_name, uint_val, max);
326 327 328 329 330 331
		return -EINVAL;
	}

	if (atomic_read(attr) == uint_val)
		return count;

332 333
	batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
		    attr_name, atomic_read(attr), uint_val);
334 335 336 337 338

	atomic_set(attr, uint_val);
	return count;
}

339 340 341 342 343 344
static inline ssize_t
__batadv_store_uint_attr(const char *buff, size_t count,
			 int min, int max,
			 void (*post_func)(struct net_device *),
			 const struct attribute *attr,
			 atomic_t *attr_store, struct net_device *net_dev)
345 346 347
{
	int ret;

348 349
	ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
				     attr_store);
350 351 352 353 354 355
	if (post_func && ret)
		post_func(net_dev);

	return ret;
}

356 357
static ssize_t batadv_show_bat_algo(struct kobject *kobj,
				    struct attribute *attr, char *buff)
358
{
359
	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
360

361 362 363
	return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name);
}

364
static void batadv_post_gw_reselect(struct net_device *net_dev)
365
{
366
	struct batadv_priv *bat_priv = netdev_priv(net_dev);
367

368
	batadv_gw_reselect(bat_priv);
369 370
}

371 372
static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr,
				   char *buff)
373
{
374
	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
375 376 377
	int bytes_written;

	switch (atomic_read(&bat_priv->gw_mode)) {
378
	case BATADV_GW_MODE_CLIENT:
379 380
		bytes_written = sprintf(buff, "%s\n",
					BATADV_GW_MODE_CLIENT_NAME);
381
		break;
382
	case BATADV_GW_MODE_SERVER:
383 384
		bytes_written = sprintf(buff, "%s\n",
					BATADV_GW_MODE_SERVER_NAME);
385 386
		break;
	default:
387 388
		bytes_written = sprintf(buff, "%s\n",
					BATADV_GW_MODE_OFF_NAME);
389 390 391 392 393 394
		break;
	}

	return bytes_written;
}

395 396 397
static ssize_t batadv_store_gw_mode(struct kobject *kobj,
				    struct attribute *attr, char *buff,
				    size_t count)
398
{
399
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
400
	struct batadv_priv *bat_priv = netdev_priv(net_dev);
401 402 403 404 405 406
	char *curr_gw_mode_str;
	int gw_mode_tmp = -1;

	if (buff[count - 1] == '\n')
		buff[count - 1] = '\0';

407 408
	if (strncmp(buff, BATADV_GW_MODE_OFF_NAME,
		    strlen(BATADV_GW_MODE_OFF_NAME)) == 0)
409
		gw_mode_tmp = BATADV_GW_MODE_OFF;
410

411 412
	if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME,
		    strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0)
413
		gw_mode_tmp = BATADV_GW_MODE_CLIENT;
414

415 416
	if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME,
		    strlen(BATADV_GW_MODE_SERVER_NAME)) == 0)
417
		gw_mode_tmp = BATADV_GW_MODE_SERVER;
418 419

	if (gw_mode_tmp < 0) {
420 421 422
		batadv_info(net_dev,
			    "Invalid parameter for 'gw mode' setting received: %s\n",
			    buff);
423 424 425 426 427 428 429
		return -EINVAL;
	}

	if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp)
		return count;

	switch (atomic_read(&bat_priv->gw_mode)) {
430
	case BATADV_GW_MODE_CLIENT:
431
		curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME;
432
		break;
433
	case BATADV_GW_MODE_SERVER:
434
		curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME;
435 436
		break;
	default:
437
		curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME;
438 439 440
		break;
	}

441 442
	batadv_info(net_dev, "Changing gw mode from: %s to: %s\n",
		    curr_gw_mode_str, buff);
443

444 445 446 447 448 449 450 451 452
	/* Invoking batadv_gw_reselect() is not enough to really de-select the
	 * current GW. It will only instruct the gateway client code to perform
	 * a re-election the next time that this is needed.
	 *
	 * When gw client mode is being switched off the current GW must be
	 * de-selected explicitly otherwise no GW_ADD uevent is thrown on
	 * client mode re-activation. This is operation is performed in
	 * batadv_gw_check_client_stop().
	 */
453
	batadv_gw_reselect(bat_priv);
454 455 456 457
	/* always call batadv_gw_check_client_stop() before changing the gateway
	 * state
	 */
	batadv_gw_check_client_stop(bat_priv);
458
	atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
459
	batadv_gw_tvlv_container_update(bat_priv);
460 461 462
	return count;
}

463 464
static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
				     struct attribute *attr, char *buff)
465
{
466
	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
467
	u32 down, up;
468 469 470 471 472 473

	down = atomic_read(&bat_priv->gw.bandwidth_down);
	up = atomic_read(&bat_priv->gw.bandwidth_up);

	return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10,
		       down % 10, up / 10, up % 10);
474 475
}

476 477 478
static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
				      struct attribute *attr, char *buff,
				      size_t count)
479
{
480
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
481 482 483 484

	if (buff[count - 1] == '\n')
		buff[count - 1] = '\0';

485
	return batadv_gw_bandwidth_set(net_dev, buff, count);
486 487
}

488 489 490 491 492 493
/**
 * batadv_show_isolation_mark - print the current isolation mark/mask
 * @kobj: kobject representing the private mesh sysfs directory
 * @attr: the batman-adv attribute the user is interacting with
 * @buff: the buffer that will contain the data to send back to the user
 *
494
 * Return: the number of bytes written into 'buff' on success or a negative
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
 * error code in case of failure
 */
static ssize_t batadv_show_isolation_mark(struct kobject *kobj,
					  struct attribute *attr, char *buff)
{
	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);

	return sprintf(buff, "%#.8x/%#.8x\n", bat_priv->isolation_mark,
		       bat_priv->isolation_mark_mask);
}

/**
 * batadv_store_isolation_mark - parse and store the isolation mark/mask entered
 *  by the user
 * @kobj: kobject representing the private mesh sysfs directory
 * @attr: the batman-adv attribute the user is interacting with
 * @buff: the buffer containing the user data
 * @count: number of bytes in the buffer
 *
514
 * Return: 'count' on success or a negative error code in case of failure
515 516 517 518 519 520 521
 */
static ssize_t batadv_store_isolation_mark(struct kobject *kobj,
					   struct attribute *attr, char *buff,
					   size_t count)
{
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
	struct batadv_priv *bat_priv = netdev_priv(net_dev);
522
	u32 mark, mask;
523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
	char *mask_ptr;

	/* parse the mask if it has been specified, otherwise assume the mask is
	 * the biggest possible
	 */
	mask = 0xFFFFFFFF;
	mask_ptr = strchr(buff, '/');
	if (mask_ptr) {
		*mask_ptr = '\0';
		mask_ptr++;

		/* the mask must be entered in hex base as it is going to be a
		 * bitmask and not a prefix length
		 */
		if (kstrtou32(mask_ptr, 16, &mask) < 0)
			return -EINVAL;
	}

	/* the mark can be entered in any base */
	if (kstrtou32(buff, 0, &mark) < 0)
		return -EINVAL;

	bat_priv->isolation_mark_mask = mask;
	/* erase bits not covered by the mask */
	bat_priv->isolation_mark = mark & bat_priv->isolation_mark_mask;

	batadv_info(net_dev,
		    "New skb mark for extended isolation: %#.8x/%#.8x\n",
		    bat_priv->isolation_mark, bat_priv->isolation_mark_mask);

	return count;
}

556 557
BATADV_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL);
558
#ifdef CONFIG_BATMAN_ADV_BLA
559 560
BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR,
		     batadv_bla_status_update);
561
#endif
562
#ifdef CONFIG_BATMAN_ADV_DAT
563 564
BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR,
		     batadv_dat_status_update);
565
#endif
566 567 568 569
BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu);
static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL);
static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode,
		   batadv_store_gw_mode);
570 571 572 573 574 575
BATADV_ATTR_SIF_UINT(orig_interval, orig_interval, S_IRUGO | S_IWUSR,
		     2 * BATADV_JITTER, INT_MAX, NULL);
BATADV_ATTR_SIF_UINT(hop_penalty, hop_penalty, S_IRUGO | S_IWUSR, 0,
		     BATADV_TQ_MAX_VALUE, NULL);
BATADV_ATTR_SIF_UINT(gw_sel_class, gw_sel_class, S_IRUGO | S_IWUSR, 1,
		     BATADV_TQ_MAX_VALUE, batadv_post_gw_reselect);
576 577
static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
		   batadv_store_gw_bwidth);
578 579 580
#ifdef CONFIG_BATMAN_ADV_MCAST
BATADV_ATTR_SIF_BOOL(multicast_mode, S_IRUGO | S_IWUSR, NULL);
#endif
581
#ifdef CONFIG_BATMAN_ADV_DEBUG
582 583
BATADV_ATTR_SIF_UINT(log_level, log_level, S_IRUGO | S_IWUSR, 0,
		     BATADV_DBG_ALL, NULL);
584
#endif
585
#ifdef CONFIG_BATMAN_ADV_NC
586 587
BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR,
		     batadv_nc_status_update);
588
#endif
589 590
static BATADV_ATTR(isolation_mark, S_IRUGO | S_IWUSR,
		   batadv_show_isolation_mark, batadv_store_isolation_mark);
591

592
static struct batadv_attribute *batadv_mesh_attrs[] = {
593 594
	&batadv_attr_aggregated_ogms,
	&batadv_attr_bonding,
595
#ifdef CONFIG_BATMAN_ADV_BLA
596
	&batadv_attr_bridge_loop_avoidance,
597 598 599
#endif
#ifdef CONFIG_BATMAN_ADV_DAT
	&batadv_attr_distributed_arp_table,
600 601 602
#endif
#ifdef CONFIG_BATMAN_ADV_MCAST
	&batadv_attr_multicast_mode,
603
#endif
604 605 606 607 608 609 610
	&batadv_attr_fragmentation,
	&batadv_attr_routing_algo,
	&batadv_attr_gw_mode,
	&batadv_attr_orig_interval,
	&batadv_attr_hop_penalty,
	&batadv_attr_gw_sel_class,
	&batadv_attr_gw_bandwidth,
611
#ifdef CONFIG_BATMAN_ADV_DEBUG
612
	&batadv_attr_log_level,
613 614 615
#endif
#ifdef CONFIG_BATMAN_ADV_NC
	&batadv_attr_network_coding,
616
#endif
617
	&batadv_attr_isolation_mark,
618 619 620
	NULL,
};

621 622
BATADV_ATTR_VLAN_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);

623
/* array of vlan specific sysfs attributes */
624
static struct batadv_attribute *batadv_vlan_attrs[] = {
625
	&batadv_attr_vlan_ap_isolation,
626 627 628
	NULL,
};

629
int batadv_sysfs_add_meshif(struct net_device *dev)
630 631
{
	struct kobject *batif_kobject = &dev->dev.kobj;
632
	struct batadv_priv *bat_priv = netdev_priv(dev);
633
	struct batadv_attribute **bat_attr;
634 635
	int err;

636
	bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR,
637 638
						    batif_kobject);
	if (!bat_priv->mesh_obj) {
639
		batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
640
			   BATADV_SYSFS_IF_MESH_SUBDIR);
641 642 643
		goto out;
	}

644
	for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) {
645 646 647
		err = sysfs_create_file(bat_priv->mesh_obj,
					&((*bat_attr)->attr));
		if (err) {
648
			batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
649
				   dev->name, BATADV_SYSFS_IF_MESH_SUBDIR,
650
				   ((*bat_attr)->attr).name);
651 652 653 654 655 656 657
			goto rem_attr;
		}
	}

	return 0;

rem_attr:
658
	for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
659 660 661 662 663 664 665 666
		sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));

	kobject_put(bat_priv->mesh_obj);
	bat_priv->mesh_obj = NULL;
out:
	return -ENOMEM;
}

667
void batadv_sysfs_del_meshif(struct net_device *dev)
668
{
669
	struct batadv_priv *bat_priv = netdev_priv(dev);
670
	struct batadv_attribute **bat_attr;
671

672
	for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
673 674 675 676 677 678
		sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));

	kobject_put(bat_priv->mesh_obj);
	bat_priv->mesh_obj = NULL;
}

679 680 681 682 683
/**
 * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan
 * @dev: netdev of the mesh interface
 * @vlan: private data of the newly added VLAN interface
 *
684
 * Return: 0 on success and -ENOMEM if any of the structure allocations fails.
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752
 */
int batadv_sysfs_add_vlan(struct net_device *dev,
			  struct batadv_softif_vlan *vlan)
{
	char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
	struct batadv_priv *bat_priv = netdev_priv(dev);
	struct batadv_attribute **bat_attr;
	int err;

	if (vlan->vid & BATADV_VLAN_HAS_TAG) {
		sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
			vlan->vid & VLAN_VID_MASK);

		vlan->kobj = kobject_create_and_add(vlan_subdir,
						    bat_priv->mesh_obj);
		if (!vlan->kobj) {
			batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
				   dev->name, vlan_subdir);
			goto out;
		}
	} else {
		/* the untagged LAN uses the root folder to store its "VLAN
		 * specific attributes"
		 */
		vlan->kobj = bat_priv->mesh_obj;
		kobject_get(bat_priv->mesh_obj);
	}

	for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
		err = sysfs_create_file(vlan->kobj,
					&((*bat_attr)->attr));
		if (err) {
			batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
				   dev->name, vlan_subdir,
				   ((*bat_attr)->attr).name);
			goto rem_attr;
		}
	}

	return 0;

rem_attr:
	for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
		sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));

	kobject_put(vlan->kobj);
	vlan->kobj = NULL;
out:
	return -ENOMEM;
}

/**
 * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN
 * @bat_priv: the bat priv with all the soft interface information
 * @vlan: the private data of the VLAN to destroy
 */
void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
			   struct batadv_softif_vlan *vlan)
{
	struct batadv_attribute **bat_attr;

	for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
		sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));

	kobject_put(vlan->kobj);
	vlan->kobj = NULL;
}

753 754
static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
				      struct attribute *attr, char *buff)
755
{
756
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
757
	struct batadv_hard_iface *hard_iface;
758
	ssize_t length;
759
	const char *ifname;
760

761
	hard_iface = batadv_hardif_get_by_netdev(net_dev);
762
	if (!hard_iface)
763 764
		return 0;

765 766 767 768 769 770
	if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
		ifname =  "none";
	else
		ifname = hard_iface->soft_iface->name;

	length = sprintf(buff, "%s\n", ifname);
771

772
	batadv_hardif_free_ref(hard_iface);
773 774 775 776

	return length;
}

777 778 779
static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
				       struct attribute *attr, char *buff,
				       size_t count)
780
{
781
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
782
	struct batadv_hard_iface *hard_iface;
783
	int status_tmp = -1;
784
	int ret = count;
785

786
	hard_iface = batadv_hardif_get_by_netdev(net_dev);
787
	if (!hard_iface)
788 789 790 791 792 793
		return count;

	if (buff[count - 1] == '\n')
		buff[count - 1] = '\0';

	if (strlen(buff) >= IFNAMSIZ) {
794 795
		pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
		       buff);
796
		batadv_hardif_free_ref(hard_iface);
797 798 799 800
		return -EINVAL;
	}

	if (strncmp(buff, "none", 4) == 0)
801
		status_tmp = BATADV_IF_NOT_IN_USE;
802
	else
803
		status_tmp = BATADV_IF_I_WANT_YOU;
804

805 806 807 808 809
	if (hard_iface->if_status == status_tmp)
		goto out;

	if ((hard_iface->soft_iface) &&
	    (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
810
		goto out;
811

812
	rtnl_lock();
813

814
	if (status_tmp == BATADV_IF_NOT_IN_USE) {
815 816
		batadv_hardif_disable_interface(hard_iface,
						BATADV_IF_CLEANUP_AUTO);
817
		goto unlock;
818 819 820
	}

	/* if the interface already is in use */
821
	if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
822 823
		batadv_hardif_disable_interface(hard_iface,
						BATADV_IF_CLEANUP_AUTO);
824

825
	ret = batadv_hardif_enable_interface(hard_iface, buff);
826

827 828
unlock:
	rtnl_unlock();
829
out:
830
	batadv_hardif_free_ref(hard_iface);
831 832 833
	return ret;
}

834 835
static ssize_t batadv_show_iface_status(struct kobject *kobj,
					struct attribute *attr, char *buff)
836
{
837
	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
838
	struct batadv_hard_iface *hard_iface;
839 840
	ssize_t length;

841
	hard_iface = batadv_hardif_get_by_netdev(net_dev);
842
	if (!hard_iface)
843 844
		return 0;

845
	switch (hard_iface->if_status) {
846
	case BATADV_IF_TO_BE_REMOVED:
847 848
		length = sprintf(buff, "disabling\n");
		break;
849
	case BATADV_IF_INACTIVE:
850 851
		length = sprintf(buff, "inactive\n");
		break;
852
	case BATADV_IF_ACTIVE:
853 854
		length = sprintf(buff, "active\n");
		break;
855
	case BATADV_IF_TO_BE_ACTIVATED:
856 857
		length = sprintf(buff, "enabling\n");
		break;
858
	case BATADV_IF_NOT_IN_USE:
859 860 861 862 863
	default:
		length = sprintf(buff, "not in use\n");
		break;
	}

864
	batadv_hardif_free_ref(hard_iface);
865 866 867 868

	return length;
}

869 870 871
static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
		   batadv_store_mesh_iface);
static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
872

873
static struct batadv_attribute *batadv_batman_attrs[] = {
874 875
	&batadv_attr_mesh_iface,
	&batadv_attr_iface_status,
876 877 878
	NULL,
};

879
int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
880 881
{
	struct kobject *hardif_kobject = &dev->dev.kobj;
882
	struct batadv_attribute **bat_attr;
883 884
	int err;

885 886
	*hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR,
					     hardif_kobject);
887 888

	if (!*hardif_obj) {
889
		batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
890
			   BATADV_SYSFS_IF_BAT_SUBDIR);
891 892 893
		goto out;
	}

894
	for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) {
895 896
		err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
		if (err) {
897
			batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
898
				   dev->name, BATADV_SYSFS_IF_BAT_SUBDIR,
899
				   ((*bat_attr)->attr).name);
900 901 902 903 904 905 906
			goto rem_attr;
		}
	}

	return 0;

rem_attr:
907
	for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr)
908 909 910 911 912
		sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
out:
	return -ENOMEM;
}

913
void batadv_sysfs_del_hardif(struct kobject **hardif_obj)
914 915 916 917
{
	kobject_put(*hardif_obj);
	*hardif_obj = NULL;
}
918

919
int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
920
			enum batadv_uev_action action, const char *data)
921
{
922
	int ret = -ENOMEM;
923 924 925
	struct kobject *bat_kobj;
	char *uevent_env[4] = { NULL, NULL, NULL, NULL };

926
	bat_kobj = &bat_priv->soft_iface->dev.kobj;
927

H
Himangi Saraogi 已提交
928 929 930
	uevent_env[0] = kasprintf(GFP_ATOMIC,
				  "%s%s", BATADV_UEV_TYPE_VAR,
				  batadv_uev_type_str[type]);
931 932 933
	if (!uevent_env[0])
		goto out;

H
Himangi Saraogi 已提交
934 935 936
	uevent_env[1] = kasprintf(GFP_ATOMIC,
				  "%s%s", BATADV_UEV_ACTION_VAR,
				  batadv_uev_action_str[action]);
937 938 939 940
	if (!uevent_env[1])
		goto out;

	/* If the event is DEL, ignore the data field */
941
	if (action != BATADV_UEV_DEL) {
H
Himangi Saraogi 已提交
942 943
		uevent_env[2] = kasprintf(GFP_ATOMIC,
					  "%s%s", BATADV_UEV_DATA_VAR, data);
944 945 946 947 948 949 950 951 952 953 954
		if (!uevent_env[2])
			goto out;
	}

	ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
out:
	kfree(uevent_env[0]);
	kfree(uevent_env[1]);
	kfree(uevent_env[2]);

	if (ret)
955
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
956
			   "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
957 958
			   batadv_uev_type_str[type],
			   batadv_uev_action_str[action],
959
			   (action == BATADV_UEV_DEL ? "NULL" : data), ret);
960 961
	return ret;
}