static int batadv_store_bool_attr(char *buff, size_t count, struct net_device *net_dev, const char *attr_name, atomic_t *attr) { int enabled = -1; if (buff[count - 1] == '\n') buff[count - 1] = '\0'; if ((strncmp(buff, "1", 2) == 0) || (strncmp(buff, "enable", 7) == 0) || (strncmp(buff, "enabled", 8) == 0)) enabled = 1; if ((strncmp(buff, "0", 2) == 0) || (strncmp(buff, "disable", 8) == 0) || (strncmp(buff, "disabled", 9) == 0)) enabled = 0; if (enabled < 0) { batadv_info(net_dev, "%s: Invalid parameter received: %s\n", attr_name, buff); return -EINVAL; } if (atomic_read(attr) == enabled) return count; batadv_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, atomic_read(attr) == 1 ? "enabled" : "disabled", enabled == 1 ? "enabled" : "disabled"); atomic_set(attr, (unsigned int)enabled); return count; }
static ssize_t batadv_store_gw_mode(struct kobject *kobj, struct attribute *attr, char *buff, size_t count) { struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct batadv_priv *bat_priv = netdev_priv(net_dev); char *curr_gw_mode_str; int gw_mode_tmp = -1; if (buff[count - 1] == '\n') buff[count - 1] = '\0'; if (strncmp(buff, BATADV_GW_MODE_OFF_NAME, strlen(BATADV_GW_MODE_OFF_NAME)) == 0) gw_mode_tmp = BATADV_GW_MODE_OFF; if (strncmp(buff, BATADV_GW_MODE_CLIENT_NAME, strlen(BATADV_GW_MODE_CLIENT_NAME)) == 0) gw_mode_tmp = BATADV_GW_MODE_CLIENT; if (strncmp(buff, BATADV_GW_MODE_SERVER_NAME, strlen(BATADV_GW_MODE_SERVER_NAME)) == 0) gw_mode_tmp = BATADV_GW_MODE_SERVER; if (gw_mode_tmp < 0) { batadv_info(net_dev, "Invalid parameter for 'gw mode' setting received: %s\n", buff); return -EINVAL; } if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) return count; switch (atomic_read(&bat_priv->gw_mode)) { case BATADV_GW_MODE_CLIENT: curr_gw_mode_str = BATADV_GW_MODE_CLIENT_NAME; break; case BATADV_GW_MODE_SERVER: curr_gw_mode_str = BATADV_GW_MODE_SERVER_NAME; break; default: curr_gw_mode_str = BATADV_GW_MODE_OFF_NAME; break; } batadv_info(net_dev, "Changing gw mode from: %s to: %s\n", curr_gw_mode_str, buff); batadv_gw_deselect(bat_priv); atomic_set(&bat_priv->gw_mode, (unsigned int)gw_mode_tmp); return count; }
static ssize_t batadv_store_vis_mode(struct kobject *kobj, struct attribute *attr, char *buff, size_t count) { struct net_device *net_dev = batadv_kobj_to_netdev(kobj); struct batadv_priv *bat_priv = netdev_priv(net_dev); unsigned long val; int ret, vis_mode_tmp = -1; const char *old_mode, *new_mode; ret = kstrtoul(buff, 10, &val); if (((count == 2) && (!ret) && (val == BATADV_VIS_TYPE_CLIENT_UPDATE)) || (strncmp(buff, "client", 6) == 0) || (strncmp(buff, "off", 3) == 0)) vis_mode_tmp = BATADV_VIS_TYPE_CLIENT_UPDATE; if (((count == 2) && (!ret) && (val == BATADV_VIS_TYPE_SERVER_SYNC)) || (strncmp(buff, "server", 6) == 0)) vis_mode_tmp = BATADV_VIS_TYPE_SERVER_SYNC; if (vis_mode_tmp < 0) { if (buff[count - 1] == '\n') buff[count - 1] = '\0'; batadv_info(net_dev, "Invalid parameter for 'vis mode' setting received: %s\n", buff); return -EINVAL; } if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) return count; if (atomic_read(&bat_priv->vis_mode) == BATADV_VIS_TYPE_CLIENT_UPDATE) old_mode = "client"; else old_mode = "server"; if (vis_mode_tmp == BATADV_VIS_TYPE_CLIENT_UPDATE) new_mode = "client"; else new_mode = "server"; batadv_info(net_dev, "Changing vis mode from: %s to: %s\n", old_mode, new_mode); atomic_set(&bat_priv->vis_mode, (unsigned int)vis_mode_tmp); return count; }
static int batadv_store_uint_attr(const char *buff, size_t count, struct net_device *net_dev, const char *attr_name, unsigned int min, unsigned int max, atomic_t *attr) { unsigned long uint_val; int ret; ret = kstrtoul(buff, 10, &uint_val); if (ret) { batadv_info(net_dev, "%s: Invalid parameter received: %s\n", attr_name, buff); return -EINVAL; } if (uint_val < min) { batadv_info(net_dev, "%s: Value is too small: %lu min: %u\n", attr_name, uint_val, min); return -EINVAL; } if (uint_val > max) { batadv_info(net_dev, "%s: Value is too big: %lu max: %u\n", attr_name, uint_val, max); return -EINVAL; } if (atomic_read(attr) == uint_val) return count; batadv_info(net_dev, "%s: Changing from: %i to: %lu\n", attr_name, atomic_read(attr), uint_val); atomic_set(attr, uint_val); return count; }
ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) { struct batadv_priv *bat_priv = netdev_priv(net_dev); long gw_bandwidth_tmp = 0; int up = 0, down = 0; bool ret; ret = batadv_parse_gw_bandwidth(net_dev, buff, &up, &down); if (!ret) goto end; if ((!down) || (down < 256)) down = 2000; if (!up) up = down / 5; batadv_kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); /* the gw bandwidth we guessed above might not match the given * speeds, hence we need to calculate it back to show the number * that is going to be propagated */ batadv_gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, &down, &up); if (atomic_read(&bat_priv->gw_bandwidth) == gw_bandwidth_tmp) return count; batadv_gw_deselect(bat_priv); batadv_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' (propagating: %d%s/%d%s)\n", atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, (down > 2048 ? down / 1024 : down), (down > 2048 ? "MBit" : "KBit"), (up > 2048 ? up / 1024 : up), (up > 2048 ? "MBit" : "KBit")); atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); end: return count; }
/** * batadv_gw_bandwidth_set() - Parse and set download/upload gateway bandwidth * from supplied string buffer * @net_dev: netdev struct of the soft interface * @buff: the buffer containing the user data * @count: number of bytes in the buffer * * Return: 'count' on success or a negative error code in case of failure */ ssize_t batadv_gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) { struct batadv_priv *bat_priv = netdev_priv(net_dev); u32 down_curr; u32 up_curr; u32 down_new = 0; u32 up_new = 0; bool ret; down_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_down); up_curr = (unsigned int)atomic_read(&bat_priv->gw.bandwidth_up); ret = batadv_parse_gw_bandwidth(net_dev, buff, &down_new, &up_new); if (!ret) return -EINVAL; if (!down_new) down_new = 1; if (!up_new) up_new = down_new / 5; if (!up_new) up_new = 1; if (down_curr == down_new && up_curr == up_new) return count; batadv_gw_reselect(bat_priv); batadv_info(net_dev, "Changing gateway bandwidth from: '%u.%u/%u.%u MBit' to: '%u.%u/%u.%u MBit'\n", down_curr / 10, down_curr % 10, up_curr / 10, up_curr % 10, down_new / 10, down_new % 10, up_new / 10, up_new % 10); atomic_set(&bat_priv->gw.bandwidth_down, down_new); atomic_set(&bat_priv->gw.bandwidth_up, up_new); batadv_gw_tvlv_container_update(bat_priv); return count; }