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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
/**
 * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv
 * @obj: kobject to covert
 *
 * Returns the associated batadv_priv struct.
 */
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
 *
 * Returns the associated softif_vlan struct if found, NULL otherwise.
 */
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 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
/**
 * 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
 *
 * Returns the number of bytes written into 'buff' on success or a negative
 * 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
 *
 * Returns 'count' on success or a negative error code in case of failure
 */
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 624 625 626
/**
 * batadv_vlan_attrs - array of vlan specific sysfs attributes
 */
static struct batadv_attribute *batadv_vlan_attrs[] = {
627
	&batadv_attr_vlan_ap_isolation,
628 629 630
	NULL,
};

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

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

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

	return 0;

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

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

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

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

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

681 682 683 684 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 753 754
/**
 * 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
 *
 * Returns 0 on success and -ENOMEM if any of the structure allocations fails.
 */
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;
}

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

763
	hard_iface = batadv_hardif_get_by_netdev(net_dev);
764
	if (!hard_iface)
765 766
		return 0;

767 768 769 770 771 772
	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);
773

774
	batadv_hardif_free_ref(hard_iface);
775 776 777 778

	return length;
}

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

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

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

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

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

807 808 809 810 811
	if (hard_iface->if_status == status_tmp)
		goto out;

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

814
	rtnl_lock();
815

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

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

827
	ret = batadv_hardif_enable_interface(hard_iface, buff);
828

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

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

843
	hard_iface = batadv_hardif_get_by_netdev(net_dev);
844
	if (!hard_iface)
845 846
		return 0;

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

866
	batadv_hardif_free_ref(hard_iface);
867 868 869 870

	return length;
}

871 872 873
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);
874

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

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

887 888
	*hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR,
					     hardif_kobject);
889 890

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

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

	return 0;

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

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

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

928
	bat_kobj = &bat_priv->soft_iface->dev.kobj;
929

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

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

	/* If the event is DEL, ignore the data field */
943
	if (action != BATADV_UEV_DEL) {
H
Himangi Saraogi 已提交
944 945
		uevent_env[2] = kasprintf(GFP_ATOMIC,
					  "%s%s", BATADV_UEV_DATA_VAR, data);
946 947 948 949 950 951 952 953 954 955 956
		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)
957
		batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
958
			   "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
959 960
			   batadv_uev_type_str[type],
			   batadv_uev_action_str[action],
961
			   (action == BATADV_UEV_DEL ? "NULL" : data), ret);
962 963
	return ret;
}