1/* Copyright (C) 2010-2014 B.A.T.M.A.N. contributors: 2 * 3 * Marek Lindner 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * 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 "main.h" 19#include "sysfs.h" 20#include "translation-table.h" 21#include "distributed-arp-table.h" 22#include "network-coding.h" 23#include "originator.h" 24#include "hard-interface.h" 25#include "soft-interface.h" 26#include "gateway_common.h" 27#include "gateway_client.h" 28 29static struct net_device *batadv_kobj_to_netdev(struct kobject *obj) 30{ 31 struct device *dev = container_of(obj->parent, struct device, kobj); 32 33 return to_net_dev(dev); 34} 35 36static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj) 37{ 38 struct net_device *net_dev = batadv_kobj_to_netdev(obj); 39 40 return netdev_priv(net_dev); 41} 42 43/** 44 * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv 45 * @obj: kobject to covert 46 * 47 * Returns the associated batadv_priv struct. 48 */ 49static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj) 50{ 51 /* VLAN specific attributes are located in the root sysfs folder if they 52 * refer to the untagged VLAN.. 53 */ 54 if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name)) 55 return batadv_kobj_to_batpriv(obj); 56 57 /* ..while the attributes for the tagged vlans are located in 58 * the in the corresponding "vlan%VID" subfolder 59 */ 60 return batadv_kobj_to_batpriv(obj->parent); 61} 62 63/** 64 * batadv_kobj_to_vlan - convert a kobj in the associated softif_vlan struct 65 * @obj: kobject to covert 66 * 67 * Returns the associated softif_vlan struct if found, NULL otherwise. 68 */ 69static struct batadv_softif_vlan * 70batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj) 71{ 72 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL; 73 74 rcu_read_lock(); 75 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) { 76 if (vlan_tmp->kobj != obj) 77 continue; 78 79 if (!atomic_inc_not_zero(&vlan_tmp->refcount)) 80 continue; 81 82 vlan = vlan_tmp; 83 break; 84 } 85 rcu_read_unlock(); 86 87 return vlan; 88} 89 90#define BATADV_UEV_TYPE_VAR "BATTYPE=" 91#define BATADV_UEV_ACTION_VAR "BATACTION=" 92#define BATADV_UEV_DATA_VAR "BATDATA=" 93 94static char *batadv_uev_action_str[] = { 95 "add", 96 "del", 97 "change" 98}; 99 100static char *batadv_uev_type_str[] = { 101 "gw" 102}; 103 104/* Use this, if you have customized show and store functions for vlan attrs */ 105#define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \ 106struct batadv_attribute batadv_attr_vlan_##_name = { \ 107 .attr = {.name = __stringify(_name), \ 108 .mode = _mode }, \ 109 .show = _show, \ 110 .store = _store, \ 111} 112 113/* Use this, if you have customized show and store functions */ 114#define BATADV_ATTR(_name, _mode, _show, _store) \ 115struct batadv_attribute batadv_attr_##_name = { \ 116 .attr = {.name = __stringify(_name), \ 117 .mode = _mode }, \ 118 .show = _show, \ 119 .store = _store, \ 120} 121 122#define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \ 123ssize_t batadv_store_##_name(struct kobject *kobj, \ 124 struct attribute *attr, char *buff, \ 125 size_t count) \ 126{ \ 127 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ 128 struct batadv_priv *bat_priv = netdev_priv(net_dev); \ 129 \ 130 return __batadv_store_bool_attr(buff, count, _post_func, attr, \ 131 &bat_priv->_name, net_dev); \ 132} 133 134#define BATADV_ATTR_SIF_SHOW_BOOL(_name) \ 135ssize_t batadv_show_##_name(struct kobject *kobj, \ 136 struct attribute *attr, char *buff) \ 137{ \ 138 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \ 139 \ 140 return sprintf(buff, "%s\n", \ 141 atomic_read(&bat_priv->_name) == 0 ? \ 142 "disabled" : "enabled"); \ 143} \ 144 145/* Use this, if you are going to turn a [name] in the soft-interface 146 * (bat_priv) on or off 147 */ 148#define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func) \ 149 static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \ 150 static BATADV_ATTR_SIF_SHOW_BOOL(_name) \ 151 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 152 batadv_store_##_name) 153 154#define BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \ 155ssize_t batadv_store_##_name(struct kobject *kobj, \ 156 struct attribute *attr, char *buff, \ 157 size_t count) \ 158{ \ 159 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \ 160 struct batadv_priv *bat_priv = netdev_priv(net_dev); \ 161 \ 162 return __batadv_store_uint_attr(buff, count, _min, _max, \ 163 _post_func, attr, \ 164 &bat_priv->_name, net_dev); \ 165} 166 167#define BATADV_ATTR_SIF_SHOW_UINT(_name) \ 168ssize_t batadv_show_##_name(struct kobject *kobj, \ 169 struct attribute *attr, char *buff) \ 170{ \ 171 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \ 172 \ 173 return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ 174} \ 175 176/* Use this, if you are going to set [name] in the soft-interface 177 * (bat_priv) to an unsigned integer value 178 */ 179#define BATADV_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \ 180 static BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func)\ 181 static BATADV_ATTR_SIF_SHOW_UINT(_name) \ 182 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 183 batadv_store_##_name) 184 185#define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \ 186ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \ 187 struct attribute *attr, char *buff, \ 188 size_t count) \ 189{ \ 190 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\ 191 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \ 192 kobj); \ 193 size_t res = __batadv_store_bool_attr(buff, count, _post_func, \ 194 attr, &vlan->_name, \ 195 bat_priv->soft_iface); \ 196 \ 197 batadv_softif_vlan_free_ref(vlan); \ 198 return res; \ 199} 200 201#define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \ 202ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \ 203 struct attribute *attr, char *buff) \ 204{ \ 205 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\ 206 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \ 207 kobj); \ 208 size_t res = sprintf(buff, "%s\n", \ 209 atomic_read(&vlan->_name) == 0 ? \ 210 "disabled" : "enabled"); \ 211 \ 212 batadv_softif_vlan_free_ref(vlan); \ 213 return res; \ 214} 215 216/* Use this, if you are going to turn a [name] in the vlan struct on or off */ 217#define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \ 218 static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \ 219 static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \ 220 static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \ 221 batadv_store_vlan_##_name) 222 223static int batadv_store_bool_attr(char *buff, size_t count, 224 struct net_device *net_dev, 225 const char *attr_name, atomic_t *attr) 226{ 227 int enabled = -1; 228 229 if (buff[count - 1] == '\n') 230 buff[count - 1] = '\0'; 231 232 if ((strncmp(buff, "1", 2) == 0) || 233 (strncmp(buff, "enable", 7) == 0) || 234 (strncmp(buff, "enabled", 8) == 0)) 235 enabled = 1; 236 237 if ((strncmp(buff, "0", 2) == 0) || 238 (strncmp(buff, "disable", 8) == 0) || 239 (strncmp(buff, "disabled", 9) == 0)) 240 enabled = 0; 241 242 if (enabled < 0) { 243 batadv_info(net_dev, "%s: Invalid parameter received: %s\n", 244 attr_name, buff); 245 return -EINVAL; 246 } 247 248 if (atomic_read(attr) == enabled) 249 return count; 250 251 batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, 252 atomic_read(attr) == 1 ? "enabled" : "disabled", 253 enabled == 1 ? "enabled" : "disabled"); 254 255 atomic_set(attr, (unsigned int)enabled); 256 return count; 257} 258 259static inline ssize_t 260__batadv_store_bool_attr(char *buff, size_t count, 261 void (*post_func)(struct net_device *), 262 struct attribute *attr, 263 atomic_t *attr_store, struct net_device *net_dev) 264{ 265 int ret; 266 267 ret = batadv_store_bool_attr(buff, count, net_dev, attr->name, 268 attr_store); 269 if (post_func && ret) 270 post_func(net_dev); 271 272 return ret; 273} 274 275static int batadv_store_uint_attr(const char *buff, size_t count, 276 struct net_device *net_dev, 277 const char *attr_name, 278 unsigned int min, unsigned int max, 279 atomic_t *attr) 280{ 281 unsigned long uint_val; 282 int ret; 283 284 ret = kstrtoul(buff, 10, &uint_val); 285 if (ret) { 286 batadv_info(net_dev, "%s: Invalid parameter received: %s\n", 287 attr_name, buff); 288 return -EINVAL; 289 } 290 291 if (uint_val < min) { 292 batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n", 293 attr_name, uint_val, min); 294 return -EINVAL; 295 } 296 297 if (uint_val > max) { 298 batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n", 299 attr_name, uint_val, max); 300 return -EINVAL; 301 } 302 303 if (atomic_read(attr) == uint_val) 304 return count; 305 306 batadv_info(net_dev, "%s: Changing from: %i to: %lu\n", 307 attr_name, atomic_read(attr), uint_val); 308 309 atomic_set(attr, uint_val); 310 return count; 311} 312 313static inline ssize_t 314__batadv_store_uint_attr(const char *buff, size_t count, 315 int min, int max, 316 void (*post_func)(struct net_device *), 317 const struct attribute *attr, 318 atomic_t *attr_store, struct net_device *net_dev) 319{ 320 int ret; 321 322 ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max, 323 attr_store); 324 if (post_func && ret) 325 post_func(net_dev); 326 327 return ret; 328} 329 330static ssize_t batadv_show_bat_algo(struct kobject *kobj, 331 struct attribute *attr, char *buff) 332{ 333 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 334 335 return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name); 336} 337 338static void batadv_post_gw_reselect(struct net_device *net_dev) 339{ 340 struct batadv_priv *bat_priv = netdev_priv(net_dev); 341 342 batadv_gw_reselect(bat_priv); 343} 344 345static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr, 346 char *buff) 347{ 348 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 349 int bytes_written; 350 351 switch (atomic_read(&bat_priv->gw_mode)) { 352 case BATADV_GW_MODE_CLIENT: 353 bytes_written = sprintf(buff, "%s\n", 354 BATADV_GW_MODE_CLIENT_NAME); 355 break; 356 case BATADV_GW_MODE_SERVER: 357 bytes_written = sprintf(buff, "%s\n", 358 BATADV_GW_MODE_SERVER_NAME); 359 break; 360 default: 361 bytes_written = sprintf(buff, "%s\n", 362 BATADV_GW_MODE_OFF_NAME); 363 break; 364 } 365 366 return bytes_written; 367} 368 369static ssize_t batadv_store_gw_mode(struct kobject *kobj, 370 struct attribute *attr, char *buff, 371 size_t count) 372{ 373 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 374 struct batadv_priv *bat_priv = netdev_priv(net_dev); 375 char *curr_gw_mode_str; 376 int gw_mode_tmp = -1; 377 378 if (buff[count - 1] == '\n') 379 buff[count - 1] = '\0'; 380 381 if (strncmp(buff, BATADV_GW_MODE_OFF_NAME, 382 strlen(BATADV_GW_MODE_OFF_NAME)) == 0) 383 gw_mode_tmp = BATADV_GW_MODE_OFF; 384 385 if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME, 386 strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0) 387 gw_mode_tmp = BATADV_GW_MODE_CLIENT; 388 389 if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME, 390 strlen(BATADV_GW_MODE_SERVER_NAME)) == 0) 391 gw_mode_tmp = BATADV_GW_MODE_SERVER; 392 393 if (gw_mode_tmp < 0) { 394 batadv_info(net_dev, 395 "Invalid parameter for 'gw mode' setting received: %s\n", 396 buff); 397 return -EINVAL; 398 } 399 400 if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) 401 return count; 402 403 switch (atomic_read(&bat_priv->gw_mode)) { 404 case BATADV_GW_MODE_CLIENT: 405 curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME; 406 break; 407 case BATADV_GW_MODE_SERVER: 408 curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME; 409 break; 410 default: 411 curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME; 412 break; 413 } 414 415 batadv_info(net_dev, "Changing gw mode from: %s to: %s\n", 416 curr_gw_mode_str, buff); 417 418 /* Invoking batadv_gw_reselect() is not enough to really de-select the 419 * current GW. It will only instruct the gateway client code to perform 420 * a re-election the next time that this is needed. 421 * 422 * When gw client mode is being switched off the current GW must be 423 * de-selected explicitly otherwise no GW_ADD uevent is thrown on 424 * client mode re-activation. This is operation is performed in 425 * batadv_gw_check_client_stop(). 426 */ 427 batadv_gw_reselect(bat_priv); 428 /* always call batadv_gw_check_client_stop() before changing the gateway 429 * state 430 */ 431 batadv_gw_check_client_stop(bat_priv); 432 atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); 433 batadv_gw_tvlv_container_update(bat_priv); 434 return count; 435} 436 437static ssize_t batadv_show_gw_bwidth(struct kobject *kobj, 438 struct attribute *attr, char *buff) 439{ 440 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 441 uint32_t down, up; 442 443 down = atomic_read(&bat_priv->gw.bandwidth_down); 444 up = atomic_read(&bat_priv->gw.bandwidth_up); 445 446 return sprintf(buff, "%u.%u/%u.%u MBit\n", down / 10, 447 down % 10, up / 10, up % 10); 448} 449 450static ssize_t batadv_store_gw_bwidth(struct kobject *kobj, 451 struct attribute *attr, char *buff, 452 size_t count) 453{ 454 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 455 456 if (buff[count - 1] == '\n') 457 buff[count - 1] = '\0'; 458 459 return batadv_gw_bandwidth_set(net_dev, buff, count); 460} 461 462/** 463 * batadv_show_isolation_mark - print the current isolation mark/mask 464 * @kobj: kobject representing the private mesh sysfs directory 465 * @attr: the batman-adv attribute the user is interacting with 466 * @buff: the buffer that will contain the data to send back to the user 467 * 468 * Returns the number of bytes written into 'buff' on success or a negative 469 * error code in case of failure 470 */ 471static ssize_t batadv_show_isolation_mark(struct kobject *kobj, 472 struct attribute *attr, char *buff) 473{ 474 struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); 475 476 return sprintf(buff, "%#.8x/%#.8x\n", bat_priv->isolation_mark, 477 bat_priv->isolation_mark_mask); 478} 479 480/** 481 * batadv_store_isolation_mark - parse and store the isolation mark/mask entered 482 * by the user 483 * @kobj: kobject representing the private mesh sysfs directory 484 * @attr: the batman-adv attribute the user is interacting with 485 * @buff: the buffer containing the user data 486 * @count: number of bytes in the buffer 487 * 488 * Returns 'count' on success or a negative error code in case of failure 489 */ 490static ssize_t batadv_store_isolation_mark(struct kobject *kobj, 491 struct attribute *attr, char *buff, 492 size_t count) 493{ 494 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 495 struct batadv_priv *bat_priv = netdev_priv(net_dev); 496 uint32_t mark, mask; 497 char *mask_ptr; 498 499 /* parse the mask if it has been specified, otherwise assume the mask is 500 * the biggest possible 501 */ 502 mask = 0xFFFFFFFF; 503 mask_ptr = strchr(buff, '/'); 504 if (mask_ptr) { 505 *mask_ptr = '\0'; 506 mask_ptr++; 507 508 /* the mask must be entered in hex base as it is going to be a 509 * bitmask and not a prefix length 510 */ 511 if (kstrtou32(mask_ptr, 16, &mask) < 0) 512 return -EINVAL; 513 } 514 515 /* the mark can be entered in any base */ 516 if (kstrtou32(buff, 0, &mark) < 0) 517 return -EINVAL; 518 519 bat_priv->isolation_mark_mask = mask; 520 /* erase bits not covered by the mask */ 521 bat_priv->isolation_mark = mark & bat_priv->isolation_mark_mask; 522 523 batadv_info(net_dev, 524 "New skb mark for extended isolation: %#.8x/%#.8x\n", 525 bat_priv->isolation_mark, bat_priv->isolation_mark_mask); 526 527 return count; 528} 529 530BATADV_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); 531BATADV_ATTR_SIF_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); 532#ifdef CONFIG_BATMAN_ADV_BLA 533BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL); 534#endif 535#ifdef CONFIG_BATMAN_ADV_DAT 536BATADV_ATTR_SIF_BOOL(distributed_arp_table, S_IRUGO | S_IWUSR, 537 batadv_dat_status_update); 538#endif 539BATADV_ATTR_SIF_BOOL(fragmentation, S_IRUGO | S_IWUSR, batadv_update_min_mtu); 540static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL); 541static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode, 542 batadv_store_gw_mode); 543BATADV_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * BATADV_JITTER, 544 INT_MAX, NULL); 545BATADV_ATTR_SIF_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, BATADV_TQ_MAX_VALUE, 546 NULL); 547BATADV_ATTR_SIF_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, BATADV_TQ_MAX_VALUE, 548 batadv_post_gw_reselect); 549static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth, 550 batadv_store_gw_bwidth); 551#ifdef CONFIG_BATMAN_ADV_MCAST 552BATADV_ATTR_SIF_BOOL(multicast_mode, S_IRUGO | S_IWUSR, NULL); 553#endif 554#ifdef CONFIG_BATMAN_ADV_DEBUG 555BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL); 556#endif 557#ifdef CONFIG_BATMAN_ADV_NC 558BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR, 559 batadv_nc_status_update); 560#endif 561static BATADV_ATTR(isolation_mark, S_IRUGO | S_IWUSR, 562 batadv_show_isolation_mark, batadv_store_isolation_mark); 563 564static struct batadv_attribute *batadv_mesh_attrs[] = { 565 &batadv_attr_aggregated_ogms, 566 &batadv_attr_bonding, 567#ifdef CONFIG_BATMAN_ADV_BLA 568 &batadv_attr_bridge_loop_avoidance, 569#endif 570#ifdef CONFIG_BATMAN_ADV_DAT 571 &batadv_attr_distributed_arp_table, 572#endif 573#ifdef CONFIG_BATMAN_ADV_MCAST 574 &batadv_attr_multicast_mode, 575#endif 576 &batadv_attr_fragmentation, 577 &batadv_attr_routing_algo, 578 &batadv_attr_gw_mode, 579 &batadv_attr_orig_interval, 580 &batadv_attr_hop_penalty, 581 &batadv_attr_gw_sel_class, 582 &batadv_attr_gw_bandwidth, 583#ifdef CONFIG_BATMAN_ADV_DEBUG 584 &batadv_attr_log_level, 585#endif 586#ifdef CONFIG_BATMAN_ADV_NC 587 &batadv_attr_network_coding, 588#endif 589 &batadv_attr_isolation_mark, 590 NULL, 591}; 592 593BATADV_ATTR_VLAN_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); 594 595/** 596 * batadv_vlan_attrs - array of vlan specific sysfs attributes 597 */ 598static struct batadv_attribute *batadv_vlan_attrs[] = { 599 &batadv_attr_vlan_ap_isolation, 600 NULL, 601}; 602 603int batadv_sysfs_add_meshif(struct net_device *dev) 604{ 605 struct kobject *batif_kobject = &dev->dev.kobj; 606 struct batadv_priv *bat_priv = netdev_priv(dev); 607 struct batadv_attribute **bat_attr; 608 int err; 609 610 bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR, 611 batif_kobject); 612 if (!bat_priv->mesh_obj) { 613 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, 614 BATADV_SYSFS_IF_MESH_SUBDIR); 615 goto out; 616 } 617 618 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) { 619 err = sysfs_create_file(bat_priv->mesh_obj, 620 &((*bat_attr)->attr)); 621 if (err) { 622 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", 623 dev->name, BATADV_SYSFS_IF_MESH_SUBDIR, 624 ((*bat_attr)->attr).name); 625 goto rem_attr; 626 } 627 } 628 629 return 0; 630 631rem_attr: 632 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) 633 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); 634 635 kobject_put(bat_priv->mesh_obj); 636 bat_priv->mesh_obj = NULL; 637out: 638 return -ENOMEM; 639} 640 641void batadv_sysfs_del_meshif(struct net_device *dev) 642{ 643 struct batadv_priv *bat_priv = netdev_priv(dev); 644 struct batadv_attribute **bat_attr; 645 646 for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) 647 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); 648 649 kobject_put(bat_priv->mesh_obj); 650 bat_priv->mesh_obj = NULL; 651} 652 653/** 654 * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan 655 * @dev: netdev of the mesh interface 656 * @vlan: private data of the newly added VLAN interface 657 * 658 * Returns 0 on success and -ENOMEM if any of the structure allocations fails. 659 */ 660int batadv_sysfs_add_vlan(struct net_device *dev, 661 struct batadv_softif_vlan *vlan) 662{ 663 char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5]; 664 struct batadv_priv *bat_priv = netdev_priv(dev); 665 struct batadv_attribute **bat_attr; 666 int err; 667 668 if (vlan->vid & BATADV_VLAN_HAS_TAG) { 669 sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu", 670 vlan->vid & VLAN_VID_MASK); 671 672 vlan->kobj = kobject_create_and_add(vlan_subdir, 673 bat_priv->mesh_obj); 674 if (!vlan->kobj) { 675 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", 676 dev->name, vlan_subdir); 677 goto out; 678 } 679 } else { 680 /* the untagged LAN uses the root folder to store its "VLAN 681 * specific attributes" 682 */ 683 vlan->kobj = bat_priv->mesh_obj; 684 kobject_get(bat_priv->mesh_obj); 685 } 686 687 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) { 688 err = sysfs_create_file(vlan->kobj, 689 &((*bat_attr)->attr)); 690 if (err) { 691 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", 692 dev->name, vlan_subdir, 693 ((*bat_attr)->attr).name); 694 goto rem_attr; 695 } 696 } 697 698 return 0; 699 700rem_attr: 701 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) 702 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr)); 703 704 kobject_put(vlan->kobj); 705 vlan->kobj = NULL; 706out: 707 return -ENOMEM; 708} 709 710/** 711 * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN 712 * @bat_priv: the bat priv with all the soft interface information 713 * @vlan: the private data of the VLAN to destroy 714 */ 715void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv, 716 struct batadv_softif_vlan *vlan) 717{ 718 struct batadv_attribute **bat_attr; 719 720 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) 721 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr)); 722 723 kobject_put(vlan->kobj); 724 vlan->kobj = NULL; 725} 726 727static ssize_t batadv_show_mesh_iface(struct kobject *kobj, 728 struct attribute *attr, char *buff) 729{ 730 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 731 struct batadv_hard_iface *hard_iface; 732 ssize_t length; 733 const char *ifname; 734 735 hard_iface = batadv_hardif_get_by_netdev(net_dev); 736 if (!hard_iface) 737 return 0; 738 739 if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) 740 ifname = "none"; 741 else 742 ifname = hard_iface->soft_iface->name; 743 744 length = sprintf(buff, "%s\n", ifname); 745 746 batadv_hardif_free_ref(hard_iface); 747 748 return length; 749} 750 751static ssize_t batadv_store_mesh_iface(struct kobject *kobj, 752 struct attribute *attr, char *buff, 753 size_t count) 754{ 755 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 756 struct batadv_hard_iface *hard_iface; 757 int status_tmp = -1; 758 int ret = count; 759 760 hard_iface = batadv_hardif_get_by_netdev(net_dev); 761 if (!hard_iface) 762 return count; 763 764 if (buff[count - 1] == '\n') 765 buff[count - 1] = '\0'; 766 767 if (strlen(buff) >= IFNAMSIZ) { 768 pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n", 769 buff); 770 batadv_hardif_free_ref(hard_iface); 771 return -EINVAL; 772 } 773 774 if (strncmp(buff, "none", 4) == 0) 775 status_tmp = BATADV_IF_NOT_IN_USE; 776 else 777 status_tmp = BATADV_IF_I_WANT_YOU; 778 779 if (hard_iface->if_status == status_tmp) 780 goto out; 781 782 if ((hard_iface->soft_iface) && 783 (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0)) 784 goto out; 785 786 rtnl_lock(); 787 788 if (status_tmp == BATADV_IF_NOT_IN_USE) { 789 batadv_hardif_disable_interface(hard_iface, 790 BATADV_IF_CLEANUP_AUTO); 791 goto unlock; 792 } 793 794 /* if the interface already is in use */ 795 if (hard_iface->if_status != BATADV_IF_NOT_IN_USE) 796 batadv_hardif_disable_interface(hard_iface, 797 BATADV_IF_CLEANUP_AUTO); 798 799 ret = batadv_hardif_enable_interface(hard_iface, buff); 800 801unlock: 802 rtnl_unlock(); 803out: 804 batadv_hardif_free_ref(hard_iface); 805 return ret; 806} 807 808static ssize_t batadv_show_iface_status(struct kobject *kobj, 809 struct attribute *attr, char *buff) 810{ 811 struct net_device *net_dev = batadv_kobj_to_netdev(kobj); 812 struct batadv_hard_iface *hard_iface; 813 ssize_t length; 814 815 hard_iface = batadv_hardif_get_by_netdev(net_dev); 816 if (!hard_iface) 817 return 0; 818 819 switch (hard_iface->if_status) { 820 case BATADV_IF_TO_BE_REMOVED: 821 length = sprintf(buff, "disabling\n"); 822 break; 823 case BATADV_IF_INACTIVE: 824 length = sprintf(buff, "inactive\n"); 825 break; 826 case BATADV_IF_ACTIVE: 827 length = sprintf(buff, "active\n"); 828 break; 829 case BATADV_IF_TO_BE_ACTIVATED: 830 length = sprintf(buff, "enabling\n"); 831 break; 832 case BATADV_IF_NOT_IN_USE: 833 default: 834 length = sprintf(buff, "not in use\n"); 835 break; 836 } 837 838 batadv_hardif_free_ref(hard_iface); 839 840 return length; 841} 842 843static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface, 844 batadv_store_mesh_iface); 845static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL); 846 847static struct batadv_attribute *batadv_batman_attrs[] = { 848 &batadv_attr_mesh_iface, 849 &batadv_attr_iface_status, 850 NULL, 851}; 852 853int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) 854{ 855 struct kobject *hardif_kobject = &dev->dev.kobj; 856 struct batadv_attribute **bat_attr; 857 int err; 858 859 *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR, 860 hardif_kobject); 861 862 if (!*hardif_obj) { 863 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, 864 BATADV_SYSFS_IF_BAT_SUBDIR); 865 goto out; 866 } 867 868 for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) { 869 err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); 870 if (err) { 871 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", 872 dev->name, BATADV_SYSFS_IF_BAT_SUBDIR, 873 ((*bat_attr)->attr).name); 874 goto rem_attr; 875 } 876 } 877 878 return 0; 879 880rem_attr: 881 for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) 882 sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); 883out: 884 return -ENOMEM; 885} 886 887void batadv_sysfs_del_hardif(struct kobject **hardif_obj) 888{ 889 kobject_put(*hardif_obj); 890 *hardif_obj = NULL; 891} 892 893int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type, 894 enum batadv_uev_action action, const char *data) 895{ 896 int ret = -ENOMEM; 897 struct kobject *bat_kobj; 898 char *uevent_env[4] = { NULL, NULL, NULL, NULL }; 899 900 bat_kobj = &bat_priv->soft_iface->dev.kobj; 901 902 uevent_env[0] = kasprintf(GFP_ATOMIC, 903 "%s%s", BATADV_UEV_TYPE_VAR, 904 batadv_uev_type_str[type]); 905 if (!uevent_env[0]) 906 goto out; 907 908 uevent_env[1] = kasprintf(GFP_ATOMIC, 909 "%s%s", BATADV_UEV_ACTION_VAR, 910 batadv_uev_action_str[action]); 911 if (!uevent_env[1]) 912 goto out; 913 914 /* If the event is DEL, ignore the data field */ 915 if (action != BATADV_UEV_DEL) { 916 uevent_env[2] = kasprintf(GFP_ATOMIC, 917 "%s%s", BATADV_UEV_DATA_VAR, data); 918 if (!uevent_env[2]) 919 goto out; 920 } 921 922 ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env); 923out: 924 kfree(uevent_env[0]); 925 kfree(uevent_env[1]); 926 kfree(uevent_env[2]); 927 928 if (ret) 929 batadv_dbg(BATADV_DBG_BATMAN, bat_priv, 930 "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n", 931 batadv_uev_type_str[type], 932 batadv_uev_action_str[action], 933 (action == BATADV_UEV_DEL ? "NULL" : data), ret); 934 return ret; 935} 936