static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, int *up, int *down) { int ret, multi = 1; char *slash_ptr, *tmp_ptr; long ldown, lup; slash_ptr = strchr(buff, '/'); if (slash_ptr) *slash_ptr = 0; if (strlen(buff) > 4) { tmp_ptr = buff + strlen(buff) - 4; if (strncasecmp(tmp_ptr, "mbit", 4) == 0) multi = 1024; if ((strncasecmp(tmp_ptr, "kbit", 4) == 0) || (multi > 1)) *tmp_ptr = '\0'; } ret = kstrtol(buff, 10, &ldown); if (ret) { batadv_err(net_dev, "Download speed of gateway mode invalid: %s\n", buff); return false; } *down = ldown * multi; /* we also got some upload info */ if (slash_ptr) { multi = 1; if (strlen(slash_ptr + 1) > 4) { tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); if (strncasecmp(tmp_ptr, "mbit", 4) == 0) multi = 1024; if ((strncasecmp(tmp_ptr, "kbit", 4) == 0) || (multi > 1)) *tmp_ptr = '\0'; } ret = kstrtol(slash_ptr + 1, 10, &lup); if (ret) { batadv_err(net_dev, "Upload speed of gateway mode invalid: %s\n", slash_ptr + 1); return false; } *up = lup * multi; } return true; }
int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) { struct kobject *hardif_kobject = &dev->dev.kobj; struct batadv_attribute **bat_attr; int err; *hardif_obj = kobject_create_and_add(BATADV_SYSFS_IF_BAT_SUBDIR, hardif_kobject); if (!*hardif_obj) { batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, BATADV_SYSFS_IF_BAT_SUBDIR); goto out; } for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) { err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); if (err) { batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", dev->name, BATADV_SYSFS_IF_BAT_SUBDIR, ((*bat_attr)->attr).name); goto rem_attr; } } return 0; rem_attr: for (bat_attr = batadv_batman_attrs; *bat_attr; ++bat_attr) sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); out: return -ENOMEM; }
/** * batadv_parse_throughput() - parse supplied string buffer to extract * throughput information * @net_dev: the soft interface net device * @buff: string buffer to parse * @description: text shown when throughput string cannot be parsed * @throughput: pointer holding the returned throughput information * * Return: false on parse error and true otherwise. */ bool batadv_parse_throughput(struct net_device *net_dev, char *buff, const char *description, u32 *throughput) { enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT; u64 lthroughput; char *tmp_ptr; int ret; if (strlen(buff) > 4) { tmp_ptr = buff + strlen(buff) - 4; if (strncasecmp(tmp_ptr, "mbit", 4) == 0) bw_unit_type = BATADV_BW_UNIT_MBIT; if (strncasecmp(tmp_ptr, "kbit", 4) == 0 || bw_unit_type == BATADV_BW_UNIT_MBIT) *tmp_ptr = '\0'; } ret = kstrtou64(buff, 10, <hroughput); if (ret) { batadv_err(net_dev, "Invalid throughput speed for %s: %s\n", description, buff); return false; } switch (bw_unit_type) { case BATADV_BW_UNIT_MBIT: /* prevent overflow */ if (U64_MAX / 10 < lthroughput) { batadv_err(net_dev, "Throughput speed for %s too large: %s\n", description, buff); return false; } lthroughput *= 10; break; case BATADV_BW_UNIT_KBIT: default: lthroughput = div_u64(lthroughput, 100); break; } if (lthroughput > U32_MAX) { batadv_err(net_dev, "Throughput speed for %s too large: %s\n", description, buff); return false; } *throughput = lthroughput; return true; }
int batadv_sysfs_add_meshif(struct net_device *dev) { struct kobject *batif_kobject = &dev->dev.kobj; struct batadv_priv *bat_priv = netdev_priv(dev); struct batadv_attribute **bat_attr; int err; bat_priv->mesh_obj = kobject_create_and_add(BATADV_SYSFS_IF_MESH_SUBDIR, batif_kobject); if (!bat_priv->mesh_obj) { batadv_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, BATADV_SYSFS_IF_MESH_SUBDIR); goto out; } for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) { err = sysfs_create_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); if (err) { batadv_err(dev, "Can't add sysfs file: %s/%s/%s\n", dev->name, BATADV_SYSFS_IF_MESH_SUBDIR, ((*bat_attr)->attr).name); goto rem_attr; } } return 0; rem_attr: for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr) sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); kobject_put(bat_priv->mesh_obj); bat_priv->mesh_obj = NULL; out: return -ENOMEM; }
int batadv_debugfs_add_meshif(struct net_device *dev) { struct batadv_priv *bat_priv = netdev_priv(dev); struct batadv_debuginfo **bat_debug; struct net *net = dev_net(dev); struct dentry *file; if (!batadv_debugfs) goto out; if (net != &init_net) return 0; bat_priv->debug_dir = debugfs_create_dir(dev->name, batadv_debugfs); if (!bat_priv->debug_dir) goto out; if (batadv_socket_setup(bat_priv) < 0) goto rem_attr; if (batadv_debug_log_setup(bat_priv) < 0) goto rem_attr; for (bat_debug = batadv_mesh_debuginfos; *bat_debug; ++bat_debug) { file = debugfs_create_file(((*bat_debug)->attr).name, S_IFREG | ((*bat_debug)->attr).mode, bat_priv->debug_dir, dev, &(*bat_debug)->fops); if (!file) { batadv_err(dev, "Can't add debugfs file: %s/%s\n", dev->name, ((*bat_debug)->attr).name); goto rem_attr; } } if (batadv_nc_init_debugfs(bat_priv) < 0) goto rem_attr; return 0; rem_attr: debugfs_remove_recursive(bat_priv->debug_dir); bat_priv->debug_dir = NULL; out: return -ENOMEM; }
/** * batadv_parse_gw_bandwidth - parse supplied string buffer to extract download * and upload bandwidth information * @net_dev: the soft interface net device * @buff: string buffer to parse * @down: pointer holding the returned download bandwidth information * @up: pointer holding the returned upload bandwidth information * * Returns false on parse error and true otherwise. */ static bool batadv_parse_gw_bandwidth(struct net_device *net_dev, char *buff, uint32_t *down, uint32_t *up) { enum batadv_bandwidth_units bw_unit_type = BATADV_BW_UNIT_KBIT; char *slash_ptr, *tmp_ptr; long ldown, lup; int ret; slash_ptr = strchr(buff, '/'); if (slash_ptr) *slash_ptr = 0; if (strlen(buff) > 4) { tmp_ptr = buff + strlen(buff) - 4; if (strncasecmp(tmp_ptr, "mbit", 4) == 0) bw_unit_type = BATADV_BW_UNIT_MBIT; if ((strncasecmp(tmp_ptr, "kbit", 4) == 0) || (bw_unit_type == BATADV_BW_UNIT_MBIT)) *tmp_ptr = '\0'; } ret = kstrtol(buff, 10, &ldown); if (ret) { batadv_err(net_dev, "Download speed of gateway mode invalid: %s\n", buff); return false; } switch (bw_unit_type) { case BATADV_BW_UNIT_MBIT: *down = ldown * 10; break; case BATADV_BW_UNIT_KBIT: default: *down = ldown / 100; break; } /* we also got some upload info */ if (slash_ptr) { bw_unit_type = BATADV_BW_UNIT_KBIT; if (strlen(slash_ptr + 1) > 4) { tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); if (strncasecmp(tmp_ptr, "mbit", 4) == 0) bw_unit_type = BATADV_BW_UNIT_MBIT; if ((strncasecmp(tmp_ptr, "kbit", 4) == 0) || (bw_unit_type == BATADV_BW_UNIT_MBIT)) *tmp_ptr = '\0'; } ret = kstrtol(slash_ptr + 1, 10, &lup); if (ret) { batadv_err(net_dev, "Upload speed of gateway mode invalid: %s\n", slash_ptr + 1); return false; } switch (bw_unit_type) { case BATADV_BW_UNIT_MBIT: *up = lup * 10; break; case BATADV_BW_UNIT_KBIT: default: *up = lup / 100; break; } } return true; }