aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/sysfs.c
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-07-02 05:04:35 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-19 11:28:42 -0400
commit90f4435da43191025712fdcf6b0dc09c018456e9 (patch)
tree6c74c3ad0053e06e3488282f1c39a2af38e88876 /net/batman-adv/sysfs.c
parent5d2c05b213377694a2aa8ce1ed9b23f7c39b0569 (diff)
batman-adv: add sysfs framework for VLAN
Each VLAN can now have its own set of attributes which are exported through a new subfolder in the sysfs tree. Each VLAN created on top of a soft_iface will have its own subfolder. The subfolder is named "vlan%VID" and it is created inside the "mesh" sysfs folder belonging to batman-adv. Attributes corresponding to the untagged LAN are stored in the root sysfs folder as before. This patch also creates all the needed macros and data structures to easily handle new VLAN spacific attributes. Signed-off-by: Antonio Quartulli <antonio@open-mesh.com> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv/sysfs.c')
-rw-r--r--net/batman-adv/sysfs.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 869eb46329cb..f419d218890d 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -24,6 +24,7 @@
24#include "network-coding.h" 24#include "network-coding.h"
25#include "originator.h" 25#include "originator.h"
26#include "hard-interface.h" 26#include "hard-interface.h"
27#include "soft-interface.h"
27#include "gateway_common.h" 28#include "gateway_common.h"
28#include "gateway_client.h" 29#include "gateway_client.h"
29 30
@@ -39,6 +40,53 @@ static struct batadv_priv *batadv_kobj_to_batpriv(struct kobject *obj)
39 return netdev_priv(net_dev); 40 return netdev_priv(net_dev);
40} 41}
41 42
43/**
44 * batadv_vlan_kobj_to_batpriv - convert a vlan kobj in the associated batpriv
45 * @obj: kobject to covert
46 *
47 * Returns the associated batadv_priv struct.
48 */
49static struct batadv_priv *batadv_vlan_kobj_to_batpriv(struct kobject *obj)
50{
51 /* VLAN specific attributes are located in the root sysfs folder if they
52 * refer to the untagged VLAN..
53 */
54 if (!strcmp(BATADV_SYSFS_IF_MESH_SUBDIR, obj->name))
55 return batadv_kobj_to_batpriv(obj);
56
57 /* ..while the attributes for the tagged vlans are located in
58 * the in the corresponding "vlan%VID" subfolder
59 */
60 return batadv_kobj_to_batpriv(obj->parent);
61}
62
63/**
64 * batadv_kobj_to_vlan - convert a kobj in the associated softif_vlan struct
65 * @obj: kobject to covert
66 *
67 * Returns the associated softif_vlan struct if found, NULL otherwise.
68 */
69static struct batadv_softif_vlan *
70batadv_kobj_to_vlan(struct batadv_priv *bat_priv, struct kobject *obj)
71{
72 struct batadv_softif_vlan *vlan_tmp, *vlan = NULL;
73
74 rcu_read_lock();
75 hlist_for_each_entry_rcu(vlan_tmp, &bat_priv->softif_vlan_list, list) {
76 if (vlan_tmp->kobj != obj)
77 continue;
78
79 if (!atomic_inc_not_zero(&vlan_tmp->refcount))
80 continue;
81
82 vlan = vlan_tmp;
83 break;
84 }
85 rcu_read_unlock();
86
87 return vlan;
88}
89
42#define BATADV_UEV_TYPE_VAR "BATTYPE=" 90#define BATADV_UEV_TYPE_VAR "BATTYPE="
43#define BATADV_UEV_ACTION_VAR "BATACTION=" 91#define BATADV_UEV_ACTION_VAR "BATACTION="
44#define BATADV_UEV_DATA_VAR "BATDATA=" 92#define BATADV_UEV_DATA_VAR "BATDATA="
@@ -53,6 +101,15 @@ static char *batadv_uev_type_str[] = {
53 "gw" 101 "gw"
54}; 102};
55 103
104/* Use this, if you have customized show and store functions for vlan attrs */
105#define BATADV_ATTR_VLAN(_name, _mode, _show, _store) \
106struct batadv_attribute batadv_attr_vlan_##_name = { \
107 .attr = {.name = __stringify(_name), \
108 .mode = _mode }, \
109 .show = _show, \
110 .store = _store, \
111};
112
56/* Use this, if you have customized show and store functions */ 113/* Use this, if you have customized show and store functions */
57#define BATADV_ATTR(_name, _mode, _show, _store) \ 114#define BATADV_ATTR(_name, _mode, _show, _store) \
58struct batadv_attribute batadv_attr_##_name = { \ 115struct batadv_attribute batadv_attr_##_name = { \
@@ -122,6 +179,41 @@ ssize_t batadv_show_##_name(struct kobject *kobj, \
122 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \ 179 static BATADV_ATTR(_name, _mode, batadv_show_##_name, \
123 batadv_store_##_name) 180 batadv_store_##_name)
124 181
182#define BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
183ssize_t batadv_store_vlan_##_name(struct kobject *kobj, \
184 struct attribute *attr, char *buff, \
185 size_t count) \
186{ \
187 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
188 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
189 kobj); \
190 size_t res = __batadv_store_bool_attr(buff, count, _post_func, \
191 attr, &vlan->_name, \
192 bat_priv->soft_iface); \
193 batadv_softif_vlan_free_ref(vlan); \
194 return res; \
195}
196
197#define BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
198ssize_t batadv_show_vlan_##_name(struct kobject *kobj, \
199 struct attribute *attr, char *buff) \
200{ \
201 struct batadv_priv *bat_priv = batadv_vlan_kobj_to_batpriv(kobj);\
202 struct batadv_softif_vlan *vlan = batadv_kobj_to_vlan(bat_priv, \
203 kobj); \
204 size_t res = sprintf(buff, "%s\n", \
205 atomic_read(&vlan->_name) == 0 ? \
206 "disabled" : "enabled"); \
207 batadv_softif_vlan_free_ref(vlan); \
208 return res; \
209}
210
211/* Use this, if you are going to turn a [name] in the vlan struct on or off */
212#define BATADV_ATTR_VLAN_BOOL(_name, _mode, _post_func) \
213 static BATADV_ATTR_VLAN_STORE_BOOL(_name, _post_func) \
214 static BATADV_ATTR_VLAN_SHOW_BOOL(_name) \
215 static BATADV_ATTR_VLAN(_name, _mode, batadv_show_vlan_##_name, \
216 batadv_store_vlan_##_name)
125 217
126static int batadv_store_bool_attr(char *buff, size_t count, 218static int batadv_store_bool_attr(char *buff, size_t count,
127 struct net_device *net_dev, 219 struct net_device *net_dev,
@@ -407,6 +499,13 @@ static struct batadv_attribute *batadv_mesh_attrs[] = {
407 NULL, 499 NULL,
408}; 500};
409 501
502/**
503 * batadv_vlan_attrs - array of vlan specific sysfs attributes
504 */
505static struct batadv_attribute *batadv_vlan_attrs[] = {
506 NULL,
507};
508
410int batadv_sysfs_add_meshif(struct net_device *dev) 509int batadv_sysfs_add_meshif(struct net_device *dev)
411{ 510{
412 struct kobject *batif_kobject = &dev->dev.kobj; 511 struct kobject *batif_kobject = &dev->dev.kobj;
@@ -457,6 +556,80 @@ void batadv_sysfs_del_meshif(struct net_device *dev)
457 bat_priv->mesh_obj = NULL; 556 bat_priv->mesh_obj = NULL;
458} 557}
459 558
559/**
560 * batadv_sysfs_add_vlan - add all the needed sysfs objects for the new vlan
561 * @dev: netdev of the mesh interface
562 * @vlan: private data of the newly added VLAN interface
563 *
564 * Returns 0 on success and -ENOMEM if any of the structure allocations fails.
565 */
566int batadv_sysfs_add_vlan(struct net_device *dev,
567 struct batadv_softif_vlan *vlan)
568{
569 char vlan_subdir[sizeof(BATADV_SYSFS_VLAN_SUBDIR_PREFIX) + 5];
570 struct batadv_priv *bat_priv = netdev_priv(dev);
571 struct batadv_attribute **bat_attr;
572 int err;
573
574 if (vlan->vid & BATADV_VLAN_HAS_TAG) {
575 sprintf(vlan_subdir, BATADV_SYSFS_VLAN_SUBDIR_PREFIX "%hu",
576 vlan->vid & VLAN_VID_MASK);
577
578 vlan->kobj = kobject_create_and_add(vlan_subdir,
579 bat_priv->mesh_obj);
580 if (!vlan->kobj) {
581 batadv_err(dev, "Can't add sysfs directory: %s/%s\n",
582 dev->name, vlan_subdir);
583 goto out;
584 }
585 } else {
586 /* the untagged LAN uses the root folder to store its "VLAN
587 * specific attributes"
588 */
589 vlan->kobj = bat_priv->mesh_obj;
590 kobject_get(bat_priv->mesh_obj);
591 }
592
593 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr) {
594 err = sysfs_create_file(vlan->kobj,
595 &((*bat_attr)->attr));
596 if (err) {
597 batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n",
598 dev->name, vlan_subdir,
599 ((*bat_attr)->attr).name);
600 goto rem_attr;
601 }
602 }
603
604 return 0;
605
606rem_attr:
607 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
608 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
609
610 kobject_put(vlan->kobj);
611 vlan->kobj = NULL;
612out:
613 return -ENOMEM;
614}
615
616/**
617 * batadv_sysfs_del_vlan - remove all the sysfs objects for a given VLAN
618 * @bat_priv: the bat priv with all the soft interface information
619 * @vlan: the private data of the VLAN to destroy
620 */
621void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
622 struct batadv_softif_vlan *vlan)
623{
624 struct batadv_attribute **bat_attr;
625
626 for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
627 sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));
628
629 kobject_put(vlan->kobj);
630 vlan->kobj = NULL;
631}
632
460static ssize_t batadv_show_mesh_iface(struct kobject *kobj, 633static ssize_t batadv_show_mesh_iface(struct kobject *kobj,
461 struct attribute *attr, char *buff) 634 struct attribute *attr, char *buff)
462{ 635{