INIT_HLIST_HEAD(&batadv_algo_list);
}
-static struct batadv_algo_ops *batadv_algo_get(char *name)
+/**
+ * batadv_algo_get() - Search for algorithm with specific name
+ * @name: algorithm name to find
+ *
+ * Return: Pointer to batadv_algo_ops on success, NULL otherwise
+ */
+struct batadv_algo_ops *batadv_algo_get(const char *name)
{
struct batadv_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp;
*
* Return: 0 on success or negative error number in case of failure
*/
-int batadv_algo_select(struct batadv_priv *bat_priv, char *name)
+int batadv_algo_select(struct batadv_priv *bat_priv, const char *name)
{
struct batadv_algo_ops *bat_algo_ops;
extern struct list_head batadv_hardif_list;
void batadv_algo_init(void);
+struct batadv_algo_ops *batadv_algo_get(const char *name);
int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops);
-int batadv_algo_select(struct batadv_priv *bat_priv, char *name);
+int batadv_algo_select(struct batadv_priv *bat_priv, const char *name);
int batadv_algo_seq_print_text(struct seq_file *seq, void *offset);
int batadv_algo_dump(struct sk_buff *msg, struct netlink_callback *cb);
batadv_nc_init_bat_priv(bat_priv);
- ret = batadv_algo_select(bat_priv, batadv_routing_algo);
- if (ret < 0)
- goto free_bat_counters;
+ if (!bat_priv->algo_ops) {
+ ret = batadv_algo_select(bat_priv, batadv_routing_algo);
+ if (ret < 0)
+ goto free_bat_counters;
+ }
ret = batadv_debugfs_add_meshif(dev);
if (ret < 0)
static int batadv_softif_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
+ struct batadv_algo_ops *algo_ops;
+
+ if (!data)
+ return 0;
+
+ if (data[IFLA_BATADV_ALGO_NAME]) {
+ algo_ops = batadv_algo_get(nla_data(data[IFLA_BATADV_ALGO_NAME]));
+ if (!algo_ops)
+ return -EINVAL;
+ }
+
return 0;
}
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
+ struct batadv_priv *bat_priv = netdev_priv(dev);
+ const char *algo_name;
+ int err;
+
+ if (data && data[IFLA_BATADV_ALGO_NAME]) {
+ algo_name = nla_data(data[IFLA_BATADV_ALGO_NAME]);
+ err = batadv_algo_select(bat_priv, algo_name);
+ if (err)
+ return -EINVAL;
+ }
+
return register_netdevice(dev);
}
}
static const struct nla_policy batadv_ifla_policy[IFLA_BATADV_MAX + 1] = {
+ [IFLA_BATADV_ALGO_NAME] = { .type = NLA_NUL_STRING },
};
struct rtnl_link_ops batadv_link_ops __read_mostly = {