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