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