Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[sfrench/cifs-2.6.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_MCAST
543 BATADV_ATTR_SIF_BOOL(multicast_mode, S_IRUGO | S_IWUSR, NULL);
544 #endif
545 #ifdef CONFIG_BATMAN_ADV_DEBUG
546 BATADV_ATTR_SIF_UINT(log_level, S_IRUGO | S_IWUSR, 0, BATADV_DBG_ALL, NULL);
547 #endif
548 #ifdef CONFIG_BATMAN_ADV_NC
549 BATADV_ATTR_SIF_BOOL(network_coding, S_IRUGO | S_IWUSR,
550                      batadv_nc_status_update);
551 #endif
552 static BATADV_ATTR(isolation_mark, S_IRUGO | S_IWUSR,
553                    batadv_show_isolation_mark, batadv_store_isolation_mark);
554
555 static struct batadv_attribute *batadv_mesh_attrs[] = {
556         &batadv_attr_aggregated_ogms,
557         &batadv_attr_bonding,
558 #ifdef CONFIG_BATMAN_ADV_BLA
559         &batadv_attr_bridge_loop_avoidance,
560 #endif
561 #ifdef CONFIG_BATMAN_ADV_DAT
562         &batadv_attr_distributed_arp_table,
563 #endif
564 #ifdef CONFIG_BATMAN_ADV_MCAST
565         &batadv_attr_multicast_mode,
566 #endif
567         &batadv_attr_fragmentation,
568         &batadv_attr_routing_algo,
569         &batadv_attr_gw_mode,
570         &batadv_attr_orig_interval,
571         &batadv_attr_hop_penalty,
572         &batadv_attr_gw_sel_class,
573         &batadv_attr_gw_bandwidth,
574 #ifdef CONFIG_BATMAN_ADV_DEBUG
575         &batadv_attr_log_level,
576 #endif
577 #ifdef CONFIG_BATMAN_ADV_NC
578         &batadv_attr_network_coding,
579 #endif
580         &batadv_attr_isolation_mark,
581         NULL,
582 };
583
584 BATADV_ATTR_VLAN_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL);
585
586 /**
587  * batadv_vlan_attrs - array of vlan specific sysfs attributes
588  */
589 static struct batadv_attribute *batadv_vlan_attrs[] = {
590         &batadv_attr_vlan_ap_isolation,
591         NULL,
592 };
593
594 int batadv_sysfs_add_meshif(struct net_device *dev)
595 {
596         struct kobject *batif_kobject = &dev->dev.kobj;
597         struct batadv_priv *bat_priv = netdev_priv(dev);
598         struct batadv_attribute **bat_attr;
599         int err;
600
601         bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR,
602                                                     batif_kobject);
603         if (!bat_priv->mesh_obj) {
604                 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
605                            BATADV_SYSFS_IF_MESH_SUBDIR);
606                 goto out;
607         }
608
609         for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) {
610                 err = sysfs_create_file(bat_priv->mesh_obj,
611                                         &((*bat_attr)->attr));
612                 if (err) {
613                         batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
614                                    dev->name, BATADV_SYSFS_IF_MESH_SUBDIR,
615                                    ((*bat_attr)->attr).name);
616                         goto rem_attr;
617                 }
618         }
619
620         return 0;
621
622 rem_attr:
623         for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
624                 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
625
626         kobject_put(bat_priv->mesh_obj);
627         bat_priv->mesh_obj = NULL;
628 out:
629         return -ENOMEM;
630 }
631
632 void batadv_sysfs_del_meshif(struct net_device *dev)
633 {
634         struct batadv_priv *bat_priv = netdev_priv(dev);
635         struct batadv_attribute **bat_attr;
636
637         for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
638                 sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));
639
640         kobject_put(bat_priv->mesh_obj);
641         bat_priv->mesh_obj = NULL;
642 }
643
644 /**
645  * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan
646  * @dev: netdev of the mesh interface
647  * @vlan: private data of the newly added VLAN interface
648  *
649  * Returns 0 on success and -ENOMEM if any of the structure allocations fails.
650  */
651 int batadv_sysfs_add_vlan(struct net_device *dev,
652                           struct batadv_softif_vlan *vlan)
653 {
654         char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
655         struct batadv_priv *bat_priv = netdev_priv(dev);
656         struct batadv_attribute **bat_attr;
657         int err;
658
659         if (vlan->vid & BATADV_VLAN_HAS_TAG) {
660                 sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
661                         vlan->vid & VLAN_VID_MASK);
662
663                 vlan->kobj = kobject_create_and_add(vlan_subdir,
664                                                     bat_priv->mesh_obj);
665                 if (!vlan->kobj) {
666                         batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
667                                    dev->name, vlan_subdir);
668                         goto out;
669                 }
670         } else {
671                 /* the untagged LAN uses the root folder to store its "VLAN
672                  * specific attributes"
673                  */
674                 vlan->kobj = bat_priv->mesh_obj;
675                 kobject_get(bat_priv->mesh_obj);
676         }
677
678         for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
679                 err = sysfs_create_file(vlan->kobj,
680                                         &((*bat_attr)->attr));
681                 if (err) {
682                         batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
683                                    dev->name, vlan_subdir,
684                                    ((*bat_attr)->attr).name);
685                         goto rem_attr;
686                 }
687         }
688
689         return 0;
690
691 rem_attr:
692         for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
693                 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
694
695         kobject_put(vlan->kobj);
696         vlan->kobj = NULL;
697 out:
698         return -ENOMEM;
699 }
700
701 /**
702  * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN
703  * @bat_priv: the bat priv with all the soft interface information
704  * @vlan: the private data of the VLAN to destroy
705  */
706 void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
707                            struct batadv_softif_vlan *vlan)
708 {
709         struct batadv_attribute **bat_attr;
710
711         for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
712                 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
713
714         kobject_put(vlan->kobj);
715         vlan->kobj = NULL;
716 }
717
718 static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
719                                       struct attribute *attr, char *buff)
720 {
721         struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
722         struct batadv_hard_iface *hard_iface;
723         ssize_t length;
724         const char *ifname;
725
726         hard_iface = batadv_hardif_get_by_netdev(net_dev);
727         if (!hard_iface)
728                 return 0;
729
730         if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
731                 ifname =  "none";
732         else
733                 ifname = hard_iface->soft_iface->name;
734
735         length = sprintf(buff, "%s\n", ifname);
736
737         batadv_hardif_free_ref(hard_iface);
738
739         return length;
740 }
741
742 static ssize_t batadv_store_mesh_iface(struct kobject *kobj,
743                                        struct attribute *attr, char *buff,
744                                        size_t count)
745 {
746         struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
747         struct batadv_hard_iface *hard_iface;
748         int status_tmp = -1;
749         int ret = count;
750
751         hard_iface = batadv_hardif_get_by_netdev(net_dev);
752         if (!hard_iface)
753                 return count;
754
755         if (buff[count - 1] == '\n')
756                 buff[count - 1] = '\0';
757
758         if (strlen(buff) >= IFNAMSIZ) {
759                 pr_err("Invalid parameter for 'mesh_iface' setting received: interface name too long '%s'\n",
760                        buff);
761                 batadv_hardif_free_ref(hard_iface);
762                 return -EINVAL;
763         }
764
765         if (strncmp(buff, "none", 4) == 0)
766                 status_tmp = BATADV_IF_NOT_IN_USE;
767         else
768                 status_tmp = BATADV_IF_I_WANT_YOU;
769
770         if (hard_iface->if_status == status_tmp)
771                 goto out;
772
773         if ((hard_iface->soft_iface) &&
774             (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0))
775                 goto out;
776
777         rtnl_lock();
778
779         if (status_tmp == BATADV_IF_NOT_IN_USE) {
780                 batadv_hardif_disable_interface(hard_iface,
781                                                 BATADV_IF_CLEANUP_AUTO);
782                 goto unlock;
783         }
784
785         /* if the interface already is in use */
786         if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
787                 batadv_hardif_disable_interface(hard_iface,
788                                                 BATADV_IF_CLEANUP_AUTO);
789
790         ret = batadv_hardif_enable_interface(hard_iface, buff);
791
792 unlock:
793         rtnl_unlock();
794 out:
795         batadv_hardif_free_ref(hard_iface);
796         return ret;
797 }
798
799 static ssize_t batadv_show_iface_status(struct kobject *kobj,
800                                         struct attribute *attr, char *buff)
801 {
802         struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
803         struct batadv_hard_iface *hard_iface;
804         ssize_t length;
805
806         hard_iface = batadv_hardif_get_by_netdev(net_dev);
807         if (!hard_iface)
808                 return 0;
809
810         switch (hard_iface->if_status) {
811         case BATADV_IF_TO_BE_REMOVED:
812                 length = sprintf(buff, "disabling\n");
813                 break;
814         case BATADV_IF_INACTIVE:
815                 length = sprintf(buff, "inactive\n");
816                 break;
817         case BATADV_IF_ACTIVE:
818                 length = sprintf(buff, "active\n");
819                 break;
820         case BATADV_IF_TO_BE_ACTIVATED:
821                 length = sprintf(buff, "enabling\n");
822                 break;
823         case BATADV_IF_NOT_IN_USE:
824         default:
825                 length = sprintf(buff, "not in use\n");
826                 break;
827         }
828
829         batadv_hardif_free_ref(hard_iface);
830
831         return length;
832 }
833
834 static BATADV_ATTR(mesh_iface, S_IRUGO | S_IWUSR, batadv_show_mesh_iface,
835                    batadv_store_mesh_iface);
836 static BATADV_ATTR(iface_status, S_IRUGO, batadv_show_iface_status, NULL);
837
838 static struct batadv_attribute *batadv_batman_attrs[] = {
839         &batadv_attr_mesh_iface,
840         &batadv_attr_iface_status,
841         NULL,
842 };
843
844 int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)
845 {
846         struct kobject *hardif_kobject = &dev->dev.kobj;
847         struct batadv_attribute **bat_attr;
848         int err;
849
850         *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR,
851                                              hardif_kobject);
852
853         if (!*hardif_obj) {
854                 batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name,
855                            BATADV_SYSFS_IF_BAT_SUBDIR);
856                 goto out;
857         }
858
859         for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) {
860                 err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr));
861                 if (err) {
862                         batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
863                                    dev->name, BATADV_SYSFS_IF_BAT_SUBDIR,
864                                    ((*bat_attr)->attr).name);
865                         goto rem_attr;
866                 }
867         }
868
869         return 0;
870
871 rem_attr:
872         for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr)
873                 sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr));
874 out:
875         return -ENOMEM;
876 }
877
878 void batadv_sysfs_del_hardif(struct kobject **hardif_obj)
879 {
880         kobject_put(*hardif_obj);
881         *hardif_obj = NULL;
882 }
883
884 int batadv_throw_uevent(struct batadv_priv *bat_priv, enum batadv_uev_type type,
885                         enum batadv_uev_action action, const char *data)
886 {
887         int ret = -ENOMEM;
888         struct kobject *bat_kobj;
889         char *uevent_env[4] = { NULL, NULL, NULL, NULL };
890
891         bat_kobj = &bat_priv->soft_iface->dev.kobj;
892
893         uevent_env[0] = kmalloc(strlen(BATADV_UEV_TYPE_VAR) +
894                                 strlen(batadv_uev_type_str[type]) + 1,
895                                 GFP_ATOMIC);
896         if (!uevent_env[0])
897                 goto out;
898
899         sprintf(uevent_env[0], "%s%s", BATADV_UEV_TYPE_VAR,
900                 batadv_uev_type_str[type]);
901
902         uevent_env[1] = kmalloc(strlen(BATADV_UEV_ACTION_VAR) +
903                                 strlen(batadv_uev_action_str[action]) + 1,
904                                 GFP_ATOMIC);
905         if (!uevent_env[1])
906                 goto out;
907
908         sprintf(uevent_env[1], "%s%s", BATADV_UEV_ACTION_VAR,
909                 batadv_uev_action_str[action]);
910
911         /* If the event is DEL, ignore the data field */
912         if (action != BATADV_UEV_DEL) {
913                 uevent_env[2] = kmalloc(strlen(BATADV_UEV_DATA_VAR) +
914                                         strlen(data) + 1, GFP_ATOMIC);
915                 if (!uevent_env[2])
916                         goto out;
917
918                 sprintf(uevent_env[2], "%s%s", BATADV_UEV_DATA_VAR, data);
919         }
920
921         ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
922 out:
923         kfree(uevent_env[0]);
924         kfree(uevent_env[1]);
925         kfree(uevent_env[2]);
926
927         if (ret)
928                 batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
929                            "Impossible to send uevent for (%s,%s,%s) event (err: %d)\n",
930                            batadv_uev_type_str[type],
931                            batadv_uev_action_str[action],
932                            (action == BATADV_UEV_DEL ? "NULL" : data), ret);
933         return ret;
934 }