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