Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sysfs.c
Go to the documentation of this file.
1 /* Copyright (C) 2010-2012 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA
18  */
19 
20 #include "main.h"
21 #include "sysfs.h"
22 #include "translation-table.h"
23 #include "originator.h"
24 #include "hard-interface.h"
25 #include "gateway_common.h"
26 #include "gateway_client.h"
27 #include "vis.h"
28 
29 static struct net_device *batadv_kobj_to_netdev(struct kobject *obj)
30 {
31  struct device *dev = container_of(obj->parent, struct device, kobj);
32  return to_net_dev(dev);
33 }
34 
35 static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
36 {
37  struct net_device *net_dev = batadv_kobj_to_netdev(obj);
38  return netdev_priv(net_dev);
39 }
40 
41 #define BATADV_UEV_TYPE_VAR "BATTYPE="
42 #define BATADV_UEV_ACTION_VAR "BATACTION="
43 #define BATADV_UEV_DATA_VAR "BATDATA="
44 
45 static char *batadv_uev_action_str[] = {
46  "add",
47  "del",
48  "change"
49 };
50 
51 static char *batadv_uev_type_str[] = {
52  "gw"
53 };
54 
55 /* Use this, if you have customized show and store functions */
56 #define BATADV_ATTR(_name, _mode, _show, _store) \
57 struct batadv_attribute batadv_attr_##_name = { \
58  .attr = {.name = __stringify(_name), \
59  .mode = _mode }, \
60  .show = _show, \
61  .store = _store, \
62 };
63 
64 #define BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \
65 ssize_t batadv_store_##_name(struct kobject *kobj, \
66  struct attribute *attr, char *buff, \
67  size_t count) \
68 { \
69  struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
70  struct batadv_priv *bat_priv = netdev_priv(net_dev); \
71  return __batadv_store_bool_attr(buff, count, _post_func, attr, \
72  &bat_priv->_name, net_dev); \
73 }
74 
75 #define BATADV_ATTR_SIF_SHOW_BOOL(_name) \
76 ssize_t batadv_show_##_name(struct kobject *kobj, \
77  struct attribute *attr, char *buff) \
78 { \
79  struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \
80  return sprintf(buff, "%s\n", \
81  atomic_read(&bat_priv->_name) == 0 ? \
82  "disabled" : "enabled"); \
83 } \
84 
85 /* Use this, if you are going to turn a [name] in the soft-interface
86  * (bat_priv) on or off
87  */
88 #define BATADV_ATTR_SIF_BOOL(_name, _mode, _post_func) \
89  static BATADV_ATTR_SIF_STORE_BOOL(_name, _post_func) \
90  static BATADV_ATTR_SIF_SHOW_BOOL(_name) \
91  static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
92  batadv_store_##_name)
93 
94 
95 #define BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func) \
96 ssize_t batadv_store_##_name(struct kobject *kobj, \
97  struct attribute *attr, char *buff, \
98  size_t count) \
99 { \
100  struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
101  struct batadv_priv *bat_priv = netdev_priv(net_dev); \
102  return __batadv_store_uint_attr(buff, count, _min, _max, \
103  _post_func, attr, \
104  &bat_priv->_name, net_dev); \
105 }
106 
107 #define BATADV_ATTR_SIF_SHOW_UINT(_name) \
108 ssize_t batadv_show_##_name(struct kobject *kobj, \
109  struct attribute *attr, char *buff) \
110 { \
111  struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj); \
112  return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \
113 } \
114 
115 /* Use this, if you are going to set [name] in the soft-interface
116  * (bat_priv) to an unsigned integer value
117  */
118 #define BATADV_ATTR_SIF_UINT(_name, _mode, _min, _max, _post_func) \
119  static BATADV_ATTR_SIF_STORE_UINT(_name, _min, _max, _post_func)\
120  static BATADV_ATTR_SIF_SHOW_UINT(_name) \
121  static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
122  batadv_store_##_name)
123 
124 
125 #define BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func) \
126 ssize_t batadv_store_##_name(struct kobject *kobj, \
127  struct attribute *attr, char *buff, \
128  size_t count) \
129 { \
130  struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
131  struct batadv_hard_iface *hard_iface; \
132  ssize_t length; \
133  \
134  hard_iface = batadv_hardif_get_by_netdev(net_dev); \
135  if (!hard_iface) \
136  return 0; \
137  \
138  length = __batadv_store_uint_attr(buff, count, _min, _max, \
139  _post_func, attr, \
140  &hard_iface->_name, net_dev); \
141  \
142  batadv_hardif_free_ref(hard_iface); \
143  return length; \
144 }
145 
146 #define BATADV_ATTR_HIF_SHOW_UINT(_name) \
147 ssize_t batadv_show_##_name(struct kobject *kobj, \
148  struct attribute *attr, char *buff) \
149 { \
150  struct net_device *net_dev = batadv_kobj_to_netdev(kobj); \
151  struct batadv_hard_iface *hard_iface; \
152  ssize_t length; \
153  \
154  hard_iface = batadv_hardif_get_by_netdev(net_dev); \
155  if (!hard_iface) \
156  return 0; \
157  \
158  length = sprintf(buff, "%i\n", atomic_read(&hard_iface->_name));\
159  \
160  batadv_hardif_free_ref(hard_iface); \
161  return length; \
162 }
163 
164 /* Use this, if you are going to set [name] in hard_iface to an
165  * unsigned integer value
166  */
167 #define BATADV_ATTR_HIF_UINT(_name, _mode, _min, _max, _post_func) \
168  static BATADV_ATTR_HIF_STORE_UINT(_name, _min, _max, _post_func)\
169  static BATADV_ATTR_HIF_SHOW_UINT(_name) \
170  static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
171  batadv_store_##_name)
172 
173 
174 static int batadv_store_bool_attr(char *buff, size_t count,
175  struct net_device *net_dev,
176  const char *attr_name, atomic_t *attr)
177 {
178  int enabled = -1;
179 
180  if (buff[count - 1] == '\n')
181  buff[count - 1] = '\0';
182 
183  if ((strncmp(buff, "1", 2) == 0) ||
184  (strncmp(buff, "enable", 7) == 0) ||
185  (strncmp(buff, "enabled", 8) == 0))
186  enabled = 1;
187 
188  if ((strncmp(buff, "0", 2) == 0) ||
189  (strncmp(buff, "disable", 8) == 0) ||
190  (strncmp(buff, "disabled", 9) == 0))
191  enabled = 0;
192 
193  if (enabled < 0) {
194  batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
195  attr_name, buff);
196  return -EINVAL;
197  }
198 
199  if (atomic_read(attr) == enabled)
200  return count;
201 
202  batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name,
203  atomic_read(attr) == 1 ? "enabled" : "disabled",
204  enabled == 1 ? "enabled" : "disabled");
205 
206  atomic_set(attr, (unsigned int)enabled);
207  return count;
208 }
209 
210 static inline ssize_t
211 __batadv_store_bool_attr(char *buff, size_t count,
212  void (*post_func)(struct net_device *),
213  struct attribute *attr,
214  atomic_t *attr_store, struct net_device *net_dev)
215 {
216  int ret;
217 
218  ret = batadv_store_bool_attr(buff, count, net_dev, attr->name,
219  attr_store);
220  if (post_func && ret)
221  post_func(net_dev);
222 
223  return ret;
224 }
225 
226 static int batadv_store_uint_attr(const char *buff, size_t count,
227  struct net_device *net_dev,
228  const char *attr_name,
229  unsigned int min, unsigned int max,
230  atomic_t *attr)
231 {
232  unsigned long uint_val;
233  int ret;
234 
235  ret = kstrtoul(buff, 10, &uint_val);
236  if (ret) {
237  batadv_info(net_dev, "%s: Invalid parameter received: %s\n",
238  attr_name, buff);
239  return -EINVAL;
240  }
241 
242  if (uint_val < min) {
243  batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n",
244  attr_name, uint_val, min);
245  return -EINVAL;
246  }
247 
248  if (uint_val > max) {
249  batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n",
250  attr_name, uint_val, max);
251  return -EINVAL;
252  }
253 
254  if (atomic_read(attr) == uint_val)
255  return count;
256 
257  batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
258  attr_name, atomic_read(attr), uint_val);
259 
260  atomic_set(attr, uint_val);
261  return count;
262 }
263 
264 static inline ssize_t
265 __batadv_store_uint_attr(const char *buff, size_t count,
266  int min, int max,
267  void (*post_func)(struct net_device *),
268  const struct attribute *attr,
269  atomic_t *attr_store, struct net_device *net_dev)
270 {
271  int ret;
272 
273  ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
274  attr_store);
275  if (post_func && ret)
276  post_func(net_dev);
277 
278  return ret;
279 }
280 
281 static ssize_t batadv_show_vis_mode(struct kobject *kobj,
282  struct attribute *attr, char *buff)
283 {
284  struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
285  int vis_mode = atomic_read(&bat_priv->vis_mode);
286  const char *mode;
287 
288  if (vis_mode == BATADV_VIS_TYPE_CLIENT_UPDATE)
289  mode = "client";
290  else
291  mode = "server";
292 
293  return sprintf(buff, "%s\n", mode);
294 }
295 
296 static ssize_t batadv_store_vis_mode(struct kobject *kobj,
297  struct attribute *attr, char *buff,
298  size_t count)
299 {
300  struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
301  struct batadv_priv *bat_priv = netdev_priv(net_dev);
302  unsigned long val;
303  int ret, vis_mode_tmp = -1;
304  const char *old_mode, *new_mode;
305 
306  ret = kstrtoul(buff, 10, &val);
307 
308  if (((count == 2) && (!ret) &&
309  (val == BATADV_VIS_TYPE_CLIENT_UPDATE)) ||
310  (strncmp(buff, "client", 6) == 0) ||
311  (strncmp(buff, "off", 3) == 0))
312  vis_mode_tmp = BATADV_VIS_TYPE_CLIENT_UPDATE;
313 
314  if (((count == 2) && (!ret) &&
315  (val == BATADV_VIS_TYPE_SERVER_SYNC)) ||
316  (strncmp(buff, "server", 6) == 0))
317  vis_mode_tmp = BATADV_VIS_TYPE_SERVER_SYNC;
318 
319  if (vis_mode_tmp < 0) {
320  if (buff[count - 1] == '\n')
321  buff[count - 1] = '\0';
322 
323  batadv_info(net_dev,
324  "Invalid parameter for 'vis mode' setting received: %s\n",
325  buff);
326  return -EINVAL;
327  }
328 
329  if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp)
330  return count;
331 
333  old_mode = "client";
334  else
335  old_mode = "server";
336 
337  if (vis_mode_tmp == BATADV_VIS_TYPE_CLIENT_UPDATE)
338  new_mode = "client";
339  else
340  new_mode = "server";
341 
342  batadv_info(net_dev, "Changing vis mode from: %s to: %s\n", old_mode,
343  new_mode);
344 
345  atomic_set(&bat_priv->vis_mode, (unsigned int)vis_mode_tmp);
346  return count;
347 }
348 
349 static ssize_t batadv_show_bat_algo(struct kobject *kobj,
350  struct attribute *attr, char *buff)
351 {
352  struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
353  return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name);
354 }
355 
356 static void batadv_post_gw_deselect(struct net_device *net_dev)
357 {
358  struct batadv_priv *bat_priv = netdev_priv(net_dev);
359  batadv_gw_deselect(bat_priv);
360 }
361 
362 static ssize_t batadv_show_gw_mode(struct kobject *kobj, struct attribute *attr,
363  char *buff)
364 {
365  struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
366  int bytes_written;
367 
368  switch (atomic_read(&bat_priv->gw_mode)) {
370  bytes_written = sprintf(buff, "%s\n",
372  break;
374  bytes_written = sprintf(buff, "%s\n",
376  break;
377  default:
378  bytes_written = sprintf(buff, "%s\n",
380  break;
381  }
382 
383  return bytes_written;
384 }
385 
386 static ssize_t batadv_store_gw_mode(struct kobject *kobj,
387  struct attribute *attr, char *buff,
388  size_t count)
389 {
390  struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
391  struct batadv_priv *bat_priv = netdev_priv(net_dev);
392  char *curr_gw_mode_str;
393  int gw_mode_tmp = -1;
394 
395  if (buff[count - 1] == '\n')
396  buff[count - 1] = '\0';
397 
400  gw_mode_tmp = BATADV_GW_MODE_OFF;
401 
404  gw_mode_tmp = BATADV_GW_MODE_CLIENT;
405 
408  gw_mode_tmp = BATADV_GW_MODE_SERVER;
409 
410  if (gw_mode_tmp < 0) {
411  batadv_info(net_dev,
412  "Invalid parameter for 'gw mode' setting received: %s\n",
413  buff);
414  return -EINVAL;
415  }
416 
417  if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp)
418  return count;
419 
420  switch (atomic_read(&bat_priv->gw_mode)) {
422  curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME;
423  break;
425  curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME;
426  break;
427  default:
428  curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME;
429  break;
430  }
431 
432  batadv_info(net_dev, "Changing gw mode from: %s to: %s\n",
433  curr_gw_mode_str, buff);
434 
435  batadv_gw_deselect(bat_priv);
436  atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp);
437  return count;
438 }
439 
440 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
441  struct attribute *attr, char *buff)
442 {
443  struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
444  int down, up;
445  int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth);
446 
447  batadv_gw_bandwidth_to_kbit(gw_bandwidth, &down, &up);
448  return sprintf(buff, "%i%s/%i%s\n",
449  (down > 2048 ? down / 1024 : down),
450  (down > 2048 ? "MBit" : "KBit"),
451  (up > 2048 ? up / 1024 : up),
452  (up > 2048 ? "MBit" : "KBit"));
453 }
454 
455 static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
456  struct attribute *attr, char *buff,
457  size_t count)
458 {
459  struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
460 
461  if (buff[count - 1] == '\n')
462  buff[count - 1] = '\0';
463 
464  return batadv_gw_bandwidth_set(net_dev, buff, count);
465 }
466 
467 BATADV_ATTR_SIF_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL);
469 #ifdef CONFIG_BATMAN_ADV_BLA
470 BATADV_ATTR_SIF_BOOL(bridge_loop_avoidance, S_IRUGO | S_IWUSR, NULL);
471 #endif
473 BATADV_ATTR_SIF_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
474 static BATADV_ATTR(vis_mode, S_IRUGO | S_IWUSR, batadv_show_vis_mode,
475  batadv_store_vis_mode);
476 static BATADV_ATTR(routing_algo, S_IRUGO, batadv_show_bat_algo, NULL);
477 static BATADV_ATTR(gw_mode, S_IRUGO | S_IWUSR, batadv_show_gw_mode,
478  batadv_store_gw_mode);
479 BATADV_ATTR_SIF_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * BATADV_JITTER,
480  INT_MAX, NULL);
482  NULL);
484  batadv_post_gw_deselect);
485 static BATADV_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, batadv_show_gw_bwidth,
486  batadv_store_gw_bwidth);
487 #ifdef CONFIG_BATMAN_ADV_DEBUG
489 #endif
490 
491 static struct batadv_attribute *batadv_mesh_attrs[] = {
492  &batadv_attr_aggregated_ogms,
493  &batadv_attr_bonding,
494 #ifdef CONFIG_BATMAN_ADV_BLA
495  &batadv_attr_bridge_loop_avoidance,
496 #endif
497  &batadv_attr_fragmentation,
498  &batadv_attr_ap_isolation,
499  &batadv_attr_vis_mode,
500  &batadv_attr_routing_algo,
501  &batadv_attr_gw_mode,
502  &batadv_attr_orig_interval,
503  &batadv_attr_hop_penalty,
504  &batadv_attr_gw_sel_class,
505  &batadv_attr_gw_bandwidth,
506 #ifdef CONFIG_BATMAN_ADV_DEBUG
507  &batadv_attr_log_level,
508 #endif
509  NULL,
510 };
511 
513 {
514  struct kobject *batif_kobject = &dev->dev.kobj;
515  struct batadv_priv *bat_priv = netdev_priv(dev);
516  struct batadv_attribute **bat_attr;
517  int err;
518 
520  batif_kobject);
521  if (!bat_priv->mesh_obj) {
522  batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
524  goto out;
525  }
526 
527  for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) {
528  err = sysfs_create_file(bat_priv->mesh_obj,
529  &((*bat_attr)->attr));
530  if (err) {
531  batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
533  ((*bat_attr)->attr).name);
534  goto rem_attr;
535  }
536  }
537 
538  return 0;
539 
540 rem_attr:
541  for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
542  sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
543 
544  kobject_put(bat_priv->mesh_obj);
545  bat_priv->mesh_obj = NULL;
546 out:
547  return -ENOMEM;
548 }
549 
551 {
552  struct batadv_priv *bat_priv = netdev_priv(dev);
553  struct batadv_attribute **bat_attr;
554 
555  for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
556  sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
557 
558  kobject_put(bat_priv->mesh_obj);
559  bat_priv->mesh_obj = NULL;
560 }
561 
562 static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
563  struct attribute *attr, char *buff)
564 {
565  struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
566  struct batadv_hard_iface *hard_iface;
567  ssize_t length;
568  const char *ifname;
569 
570  hard_iface = batadv_hardif_get_by_netdev(net_dev);
571  if (!hard_iface)
572  return 0;
573 
574  if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
575  ifname = "none";
576  else
577  ifname = hard_iface->soft_iface->name;
578 
579  length = sprintf(buff, "%s\n", ifname);
580 
581  batadv_hardif_free_ref(hard_iface);
582 
583  return length;
584 }
585 
586 static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
587  struct attribute *attr, char *buff,
588  size_t count)
589 {
590  struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
591  struct batadv_hard_iface *hard_iface;
592  int status_tmp = -1;
593  int ret = count;
594 
595  hard_iface = batadv_hardif_get_by_netdev(net_dev);
596  if (!hard_iface)
597  return count;
598 
599  if (buff[count - 1] == '\n')
600  buff[count - 1] = '\0';
601 
602  if (strlen(buff) >= IFNAMSIZ) {
603  pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
604  buff);
605  batadv_hardif_free_ref(hard_iface);
606  return -EINVAL;
607  }
608 
609  if (strncmp(buff, "none", 4) == 0)
610  status_tmp = BATADV_IF_NOT_IN_USE;
611  else
612  status_tmp = BATADV_IF_I_WANT_YOU;
613 
614  if (hard_iface->if_status == status_tmp)
615  goto out;
616 
617  if ((hard_iface->soft_iface) &&
618  (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
619  goto out;
620 
621  if (!rtnl_trylock()) {
622  ret = -ERESTARTSYS;
623  goto out;
624  }
625 
626  if (status_tmp == BATADV_IF_NOT_IN_USE) {
628  goto unlock;
629  }
630 
631  /* if the interface already is in use */
632  if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
634 
635  ret = batadv_hardif_enable_interface(hard_iface, buff);
636 
637 unlock:
638  rtnl_unlock();
639 out:
640  batadv_hardif_free_ref(hard_iface);
641  return ret;
642 }
643 
644 static ssize_t batadv_show_iface_status(struct kobject *kobj,
645  struct attribute *attr, char *buff)
646 {
647  struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
648  struct batadv_hard_iface *hard_iface;
649  ssize_t length;
650 
651  hard_iface = batadv_hardif_get_by_netdev(net_dev);
652  if (!hard_iface)
653  return 0;
654 
655  switch (hard_iface->if_status) {
657  length = sprintf(buff, "disabling\n");
658  break;
659  case BATADV_IF_INACTIVE:
660  length = sprintf(buff, "inactive\n");
661  break;
662  case BATADV_IF_ACTIVE:
663  length = sprintf(buff, "active\n");
664  break;
666  length = sprintf(buff, "enabling\n");
667  break;
669  default:
670  length = sprintf(buff, "not in use\n");
671  break;
672  }
673 
674  batadv_hardif_free_ref(hard_iface);
675 
676  return length;
677 }
678 
679 static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
680  batadv_store_mesh_iface);
681 static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
682 
683 static struct batadv_attribute *batadv_batman_attrs[] = {
684  &batadv_attr_mesh_iface,
685  &batadv_attr_iface_status,
686  NULL,
687 };
688 
689 int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
690 {
691  struct kobject *hardif_kobject = &dev->dev.kobj;
692  struct batadv_attribute **bat_attr;
693  int err;
694 
696  hardif_kobject);
697 
698  if (!*hardif_obj) {
699  batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
701  goto out;
702  }
703 
704  for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) {
705  err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
706  if (err) {
707  batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
709  ((*bat_attr)->attr).name);
710  goto rem_attr;
711  }
712  }
713 
714  return 0;
715 
716 rem_attr:
717  for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr)
718  sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
719 out:
720  return -ENOMEM;
721 }
722 
723 void batadv_sysfs_del_hardif(struct kobject **hardif_obj)
724 {
725  kobject_put(*hardif_obj);
726  *hardif_obj = NULL;
727 }
728 
730  enum batadv_uev_action action, const char *data)
731 {
732  int ret = -ENOMEM;
733  struct batadv_hard_iface *primary_if = NULL;
734  struct kobject *bat_kobj;
735  char *uevent_env[4] = { NULL, NULL, NULL, NULL };
736 
737  primary_if = batadv_primary_if_get_selected(bat_priv);
738  if (!primary_if)
739  goto out;
740 
741  bat_kobj = &primary_if->soft_iface->dev.kobj;
742 
743  uevent_env[0] = kmalloc(strlen(BATADV_UEV_TYPE_VAR) +
744  strlen(batadv_uev_type_str[type]) + 1,
745  GFP_ATOMIC);
746  if (!uevent_env[0])
747  goto out;
748 
749  sprintf(uevent_env[0], "%s%s", BATADV_UEV_TYPE_VAR,
750  batadv_uev_type_str[type]);
751 
752  uevent_env[1] = kmalloc(strlen(BATADV_UEV_ACTION_VAR) +
753  strlen(batadv_uev_action_str[action]) + 1,
754  GFP_ATOMIC);
755  if (!uevent_env[1])
756  goto out;
757 
758  sprintf(uevent_env[1], "%s%s", BATADV_UEV_ACTION_VAR,
759  batadv_uev_action_str[action]);
760 
761  /* If the event is DEL, ignore the data field */
762  if (action != BATADV_UEV_DEL) {
763  uevent_env[2] = kmalloc(strlen(BATADV_UEV_DATA_VAR) +
764  strlen(data) + 1, GFP_ATOMIC);
765  if (!uevent_env[2])
766  goto out;
767 
768  sprintf(uevent_env[2], "%s%s", BATADV_UEV_DATA_VAR, data);
769  }
770 
771  ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
772 out:
773  kfree(uevent_env[0]);
774  kfree(uevent_env[1]);
775  kfree(uevent_env[2]);
776 
777  if (primary_if)
778  batadv_hardif_free_ref(primary_if);
779 
780  if (ret)
781  batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
782  "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
783  batadv_uev_type_str[type],
784  batadv_uev_action_str[action],
785  (action == BATADV_UEV_DEL ? "NULL" : data), ret);
786  return ret;
787 }