batman-adv: add wrapper function to throw uevent in userspace
authorAntonio Quartulli <ordex@autistici.org>
Tue, 26 Apr 2011 16:26:01 +0000 (18:26 +0200)
committerSven Eckelmann <sven@narfation.org>
Mon, 20 Jun 2011 09:37:33 +0000 (11:37 +0200)
Using throw_uevent() is now possible to trigger uevent signal that can
be recognised in userspace. Uevents will be triggered through the
/devices/virtual/net/{MESH_IFACE} kobject.

A triggered uevent has three properties:
- type: the event class. Who generates the event (only 'gw' is currently
  defined). Corresponds to the BATTYPE uevent variable.
- action: the associated action with the event ('add'/'change'/'del' are
  currently defined). Corresponds to the BATACTION uevent variable.
- data: any useful data for the userspace. Corresponds to the BATDATA
  uevent variable.

Signed-off-by: Antonio Quartulli <ordex@autistici.org>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
net/batman-adv/bat_sysfs.c
net/batman-adv/bat_sysfs.h
net/batman-adv/main.h

index 63738ec1051112e34b2ccf7d772fdf65ad1c06e0..cd15deba60a15ad188b5bf445ee744639856e43c 100644 (file)
@@ -40,6 +40,20 @@ static struct bat_priv *kobj_to_batpriv(struct kobject *obj)
        return netdev_priv(net_dev);
 }
 
+#define UEV_TYPE_VAR   "BATTYPE="
+#define UEV_ACTION_VAR "BATACTION="
+#define UEV_DATA_VAR   "BATDATA="
+
+static char *uev_action_str[] = {
+       "add",
+       "del",
+       "change"
+};
+
+static char *uev_type_str[] = {
+       "gw"
+};
+
 /* Use this, if you have customized show and store functions */
 #define BAT_ATTR(_name, _mode, _show, _store)  \
 struct bat_attribute bat_attr_##_name = {      \
@@ -601,3 +615,60 @@ void sysfs_del_hardif(struct kobject **hardif_obj)
        kobject_put(*hardif_obj);
        *hardif_obj = NULL;
 }
+
+int throw_uevent(struct bat_priv *bat_priv, enum uev_type type,
+                enum uev_action action, const char *data)
+{
+       int ret = -1;
+       struct hard_iface *primary_if = NULL;
+       struct kobject *bat_kobj;
+       char *uevent_env[4] = { NULL, NULL, NULL, NULL };
+
+       primary_if = primary_if_get_selected(bat_priv);
+       if (!primary_if)
+               goto out;
+
+       bat_kobj = &primary_if->soft_iface->dev.kobj;
+
+       uevent_env[0] = kmalloc(strlen(UEV_TYPE_VAR) +
+                               strlen(uev_type_str[type]) + 1,
+                               GFP_ATOMIC);
+       if (!uevent_env[0])
+               goto out;
+
+       sprintf(uevent_env[0], "%s%s", UEV_TYPE_VAR, uev_type_str[type]);
+
+       uevent_env[1] = kmalloc(strlen(UEV_ACTION_VAR) +
+                               strlen(uev_action_str[action]) + 1,
+                               GFP_ATOMIC);
+       if (!uevent_env[1])
+               goto out;
+
+       sprintf(uevent_env[1], "%s%s", UEV_ACTION_VAR, uev_action_str[action]);
+
+       /* If the event is DEL, ignore the data field */
+       if (action != UEV_DEL) {
+               uevent_env[2] = kmalloc(strlen(UEV_DATA_VAR) +
+                                       strlen(data) + 1, GFP_ATOMIC);
+               if (!uevent_env[2])
+                       goto out;
+
+               sprintf(uevent_env[2], "%s%s", UEV_DATA_VAR, data);
+       }
+
+       ret = kobject_uevent_env(bat_kobj, KOBJ_CHANGE, uevent_env);
+out:
+       kfree(uevent_env[0]);
+       kfree(uevent_env[1]);
+       kfree(uevent_env[2]);
+
+       if (primary_if)
+               hardif_free_ref(primary_if);
+
+       if (ret)
+               bat_dbg(DBG_BATMAN, bat_priv, "Impossible to send "
+                       "uevent for (%s,%s,%s) event (err: %d)\n",
+                       uev_type_str[type], uev_action_str[action],
+                       (action == UEV_DEL ? "NULL" : data), ret);
+       return ret;
+}
index 02f1fa7aadfa768f6b2298a3591f2819fb331b46..a3f75a723c568e21a7554117584d80098b2f50af 100644 (file)
@@ -38,5 +38,7 @@ int sysfs_add_meshif(struct net_device *dev);
 void sysfs_del_meshif(struct net_device *dev);
 int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev);
 void sysfs_del_hardif(struct kobject **hardif_obj);
+int throw_uevent(struct bat_priv *bat_priv, enum uev_type type,
+                enum uev_action action, const char *data);
 
 #endif /* _NET_BATMAN_ADV_SYSFS_H_ */
index 8eae05e4dc1bb0d06a1727e8132a7987ee94333f..f9e0e174b3f6efc9ebadb631968f85971226d1ad 100644 (file)
@@ -91,6 +91,17 @@ enum mesh_state {
 #define BCAST_QUEUE_LEN                256
 #define BATMAN_QUEUE_LEN       256
 
+
+enum uev_action {
+       UEV_ADD = 0,
+       UEV_DEL,
+       UEV_CHANGE
+};
+
+enum uev_type {
+       UEV_GW = 0
+};
+
 /*
  * Debug Messages
  */