Hi,
I massaged the RFC patches a little longer to integrate all the feedback received so far. They are ready to be considered 'real' patches now.
The 'dynamically load routing kernel module' feature has not found its way into my patchset. At this point I still see no benefit and only complications. The mentioned reasons (kernel folks might not like it / helps to better abstract) can be addressed in a different way (for example asking David if he is going to accept it or not). The only reason seems to be "because we can". That's not enough for me. This does not mean we can't add this feature at a later point in time when we have the feeling it actually brings some benefits.
Here the changelog:
* sysfs documentation added * changed batman iv function prefix to bat_iv * renamed struct bat_algo to struct bat_algo_ops * all bat_algo_ops callbacks are mandatory for now * added struct bat_algo_ops documentation * introduced bat_algo.h for the routing algo init calls * bat_algo_ops->name became a pointer * removed all (unnecessary) locking from bat_algo_*
Cheers, Marek
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_algo.h | 27 ++++++++++++++++++++ bat_debugfs.c | 8 ++++++ bat_iv_ogm.c | 10 +++++++ main.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.h | 3 ++ soft-interface.c | 4 +++ types.h | 6 ++++ 7 files changed, 129 insertions(+), 0 deletions(-) create mode 100644 bat_algo.h
diff --git a/bat_algo.h b/bat_algo.h new file mode 100644 index 0000000..755379f --- /dev/null +++ b/bat_algo.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2011 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_BAT_ALGO_H_ +#define _NET_BATMAN_ADV_BAT_ALGO_H_ + +int bat_iv_init(void); + +#endif /* _NET_BATMAN_ADV_BAT_ALGO_H_ */ diff --git a/bat_debugfs.c b/bat_debugfs.c index d0af9bf..05e2f1f 100644 --- a/bat_debugfs.c +++ b/bat_debugfs.c @@ -221,6 +221,12 @@ static void debug_log_cleanup(struct bat_priv *bat_priv) } #endif
+static int bat_algorithms_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, bat_algo_seq_print_text, net_dev); +} + static int originators_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; @@ -274,6 +280,7 @@ struct bat_debuginfo bat_debuginfo_##_name = { \ } \ };
+static BAT_DEBUGINFO(routing_algos, S_IRUGO, bat_algorithms_open); static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); @@ -282,6 +289,7 @@ static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open);
static struct bat_debuginfo *mesh_debuginfos[] = { + &bat_debuginfo_routing_algos, &bat_debuginfo_originators, &bat_debuginfo_gateways, &bat_debuginfo_softif_neigh, diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 3402fa5..1847efa 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -29,6 +29,7 @@ #include "gateway_client.h" #include "hard-interface.h" #include "send.h" +#include "bat_algo.h"
void bat_ogm_init(struct hard_iface *hard_iface) { @@ -1172,3 +1173,12 @@ void bat_ogm_receive(struct hard_iface *if_incoming, struct sk_buff *skb) } while (bat_ogm_aggr_packet(buff_pos, packet_len, batman_ogm_packet->tt_num_changes)); } + +static struct bat_algo_ops batman_iv __read_mostly = { + .name = "BATMAN IV", +}; + +int __init bat_iv_init(void) +{ + return bat_algo_register(&batman_iv); +} diff --git a/main.c b/main.c index fb87bdc..b554f63 100644 --- a/main.c +++ b/main.c @@ -32,11 +32,13 @@ #include "gateway_client.h" #include "vis.h" #include "hash.h" +#include "bat_algo.h"
/* List manipulations on hardif_list have to be rtnl_lock()'ed, * list traversals just rcu-locked */ struct list_head hardif_list; +static struct hlist_head bat_algo_list;
unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -45,6 +47,9 @@ struct workqueue_struct *bat_event_workqueue; static int __init batman_init(void) { INIT_LIST_HEAD(&hardif_list); + INIT_HLIST_HEAD(&bat_algo_list); + + bat_iv_init();
/* the name should not be longer than 10 chars - see * http://lwn.net/Articles/23634/ */ @@ -173,6 +178,72 @@ int is_my_mac(const uint8_t *addr)
}
+static struct bat_algo_ops *bat_algo_get(char *name) +{ + struct bat_algo_ops *bat_algo_ops = NULL, *bat_algo_ops_tmp; + struct hlist_node *node; + + hlist_for_each_entry(bat_algo_ops_tmp, node, &bat_algo_list, list) { + if (strcmp(bat_algo_ops_tmp->name, name) != 0) + continue; + + bat_algo_ops = bat_algo_ops_tmp; + break; + } + + return bat_algo_ops; +} + +int bat_algo_register(struct bat_algo_ops *bat_algo_ops) +{ + struct bat_algo_ops *bat_algo_ops_tmp; + int ret = -1; + + bat_algo_ops_tmp = bat_algo_get(bat_algo_ops->name); + if (bat_algo_ops_tmp) { + pr_info("Trying to register already registered routing " + "algorithm: %s\n", bat_algo_ops->name); + goto out; + } + + INIT_HLIST_NODE(&bat_algo_ops->list); + hlist_add_head(&bat_algo_ops->list, &bat_algo_list); + ret = 0; + +out: + return ret; +} + +int bat_algo_select(struct bat_priv *bat_priv, char *name) +{ + struct bat_algo_ops *bat_algo_ops; + int ret = -1; + + bat_algo_ops = bat_algo_get(name); + if (!bat_algo_ops) + goto out; + + bat_priv->bat_algo_ops = bat_algo_ops; + ret = 0; + +out: + return ret; +} + +int bat_algo_seq_print_text(struct seq_file *seq, void *offset) +{ + struct bat_algo_ops *bat_algo_ops; + struct hlist_node *node; + + seq_printf(seq, "Available routing algorithms:\n"); + + hlist_for_each_entry(bat_algo_ops, node, &bat_algo_list, list) { + seq_printf(seq, "%s\n", bat_algo_ops->name); + } + + return 0; +} + module_init(batman_init); module_exit(batman_exit);
diff --git a/main.h b/main.h index 464439f..8ad8f11 100644 --- a/main.h +++ b/main.h @@ -159,6 +159,9 @@ void mesh_free(struct net_device *soft_iface); void inc_module_count(void); void dec_module_count(void); int is_my_mac(const uint8_t *addr); +int bat_algo_register(struct bat_algo_ops *bat_algo_ops); +int bat_algo_select(struct bat_priv *bat_priv, char *name); +int bat_algo_seq_print_text(struct seq_file *seq, void *offset);
#ifdef CONFIG_BATMAN_ADV_DEBUG int debug_log(struct bat_priv *bat_priv, const char *fmt, ...) __printf(2, 3); diff --git a/soft-interface.c b/soft-interface.c index bd8c7cf..a0046ac 100644 --- a/soft-interface.c +++ b/soft-interface.c @@ -855,6 +855,10 @@ struct net_device *softif_create(const char *name) bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0;
+ ret = bat_algo_select(bat_priv, "BATMAN IV"); + if (ret < 0) + goto unreg_soft_iface; + ret = sysfs_add_meshif(soft_iface); if (ret < 0) goto unreg_soft_iface; diff --git a/types.h b/types.h index 35085f4..d21ff2c 100644 --- a/types.h +++ b/types.h @@ -206,6 +206,7 @@ struct bat_priv { atomic_t gw_reselect; struct hard_iface __rcu *primary_if; /* rcu protected pointer */ struct vis_info *my_vis_info; + struct bat_algo_ops *bat_algo_ops; };
struct socket_client { @@ -344,4 +345,9 @@ struct softif_neigh { struct rcu_head rcu; };
+struct bat_algo_ops { + struct hlist_node list; + char *name; +}; + #endif /* _NET_BATMAN_ADV_TYPES_H_ */
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_iv_ogm.c | 179 ++++++++++++++++++++++++++++-------------------------- bat_ogm.h | 34 ---------- hard-interface.c | 10 ++-- main.c | 12 ++++ routing.c | 4 +- send.c | 5 +- types.h | 14 ++++ 7 files changed, 129 insertions(+), 129 deletions(-) delete mode 100644 bat_ogm.h
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 1847efa..1c483a5 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -20,7 +20,6 @@ */
#include "main.h" -#include "bat_ogm.h" #include "translation-table.h" #include "ring_buffer.h" #include "originator.h" @@ -31,7 +30,7 @@ #include "send.h" #include "bat_algo.h"
-void bat_ogm_init(struct hard_iface *hard_iface) +static void bat_iv_ogm_init(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet;
@@ -48,7 +47,7 @@ void bat_ogm_init(struct hard_iface *hard_iface) batman_ogm_packet->ttvn = 0; }
-void bat_ogm_init_primary(struct hard_iface *hard_iface) +static void bat_iv_ogm_init_primary(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet;
@@ -57,7 +56,7 @@ void bat_ogm_init_primary(struct hard_iface *hard_iface) batman_ogm_packet->header.ttl = TTL; }
-void bat_ogm_update_mac(struct hard_iface *hard_iface) +static void bat_iv_ogm_update_mac(struct hard_iface *hard_iface) { struct batman_ogm_packet *batman_ogm_packet;
@@ -69,7 +68,7 @@ void bat_ogm_update_mac(struct hard_iface *hard_iface) }
/* when do we schedule our own ogm to be sent */ -static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv) +static unsigned long bat_iv_ogm_emit_send_time(const struct bat_priv *bat_priv) { return jiffies + msecs_to_jiffies( atomic_read(&bat_priv->orig_interval) - @@ -77,7 +76,7 @@ static unsigned long bat_ogm_emit_send_time(const struct bat_priv *bat_priv) }
/* when do we schedule a ogm packet to be sent */ -static unsigned long bat_ogm_fwd_send_time(void) +static unsigned long bat_iv_ogm_fwd_send_time(void) { return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); } @@ -90,8 +89,8 @@ static uint8_t hop_penalty(uint8_t tq, const struct bat_priv *bat_priv) }
/* is there another aggregated packet here? */ -static int bat_ogm_aggr_packet(int buff_pos, int packet_len, - int tt_num_changes) +static int bat_iv_ogm_aggr_packet(int buff_pos, int packet_len, + int tt_num_changes) { int next_buff_pos = buff_pos + BATMAN_OGM_LEN + tt_len(tt_num_changes);
@@ -100,8 +99,8 @@ static int bat_ogm_aggr_packet(int buff_pos, int packet_len, }
/* send a batman ogm to a given interface */ -static void bat_ogm_send_to_if(struct forw_packet *forw_packet, - struct hard_iface *hard_iface) +static void bat_iv_ogm_send_to_if(struct forw_packet *forw_packet, + struct hard_iface *hard_iface) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); char *fwd_str; @@ -118,8 +117,8 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet, batman_ogm_packet = (struct batman_ogm_packet *)forw_packet->skb->data;
/* adjust all flags and log packets */ - while (bat_ogm_aggr_packet(buff_pos, forw_packet->packet_len, - batman_ogm_packet->tt_num_changes)) { + while (bat_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, + batman_ogm_packet->tt_num_changes)) {
/* we might have aggregated direct link packets with an * ordinary base packet */ @@ -158,7 +157,7 @@ static void bat_ogm_send_to_if(struct forw_packet *forw_packet, }
/* send a batman ogm packet */ -void bat_ogm_emit(struct forw_packet *forw_packet) +static void bat_iv_ogm_emit(struct forw_packet *forw_packet) { struct hard_iface *hard_iface; struct net_device *soft_iface; @@ -217,7 +216,7 @@ void bat_ogm_emit(struct forw_packet *forw_packet) if (hard_iface->soft_iface != soft_iface) continue;
- bat_ogm_send_to_if(forw_packet, hard_iface); + bat_iv_ogm_send_to_if(forw_packet, hard_iface); } rcu_read_unlock();
@@ -227,13 +226,13 @@ out: }
/* return true if new_packet can be aggregated with forw_packet */ -static bool bat_ogm_can_aggregate(const struct batman_ogm_packet +static bool bat_iv_ogm_can_aggregate(const struct batman_ogm_packet *new_batman_ogm_packet, - struct bat_priv *bat_priv, - int packet_len, unsigned long send_time, - bool directlink, - const struct hard_iface *if_incoming, - const struct forw_packet *forw_packet) + struct bat_priv *bat_priv, + int packet_len, unsigned long send_time, + bool directlink, + const struct hard_iface *if_incoming, + const struct forw_packet *forw_packet) { struct batman_ogm_packet *batman_ogm_packet; int aggregated_bytes = forw_packet->packet_len + packet_len; @@ -307,11 +306,11 @@ out: }
/* create a new aggregated packet and add this packet to it */ -static void bat_ogm_aggregate_new(const unsigned char *packet_buff, - int packet_len, unsigned long send_time, - bool direct_link, - struct hard_iface *if_incoming, - int own_packet) +static void bat_iv_ogm_aggregate_new(const unsigned char *packet_buff, + int packet_len, unsigned long send_time, + bool direct_link, + struct hard_iface *if_incoming, + int own_packet) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct forw_packet *forw_packet_aggr; @@ -386,9 +385,9 @@ out: }
/* aggregate a new packet into the existing ogm packet */ -static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr, - const unsigned char *packet_buff, - int packet_len, bool direct_link) +static void bat_iv_ogm_aggregate(struct forw_packet *forw_packet_aggr, + const unsigned char *packet_buff, + int packet_len, bool direct_link) { unsigned char *skb_buff;
@@ -403,10 +402,10 @@ static void bat_ogm_aggregate(struct forw_packet *forw_packet_aggr, (1 << forw_packet_aggr->num_packets); }
-static void bat_ogm_queue_add(struct bat_priv *bat_priv, - unsigned char *packet_buff, - int packet_len, struct hard_iface *if_incoming, - int own_packet, unsigned long send_time) +static void bat_iv_ogm_queue_add(struct bat_priv *bat_priv, + unsigned char *packet_buff, + int packet_len, struct hard_iface *if_incoming, + int own_packet, unsigned long send_time) { /** * _aggr -> pointer to the packet we want to aggregate with @@ -426,11 +425,11 @@ static void bat_ogm_queue_add(struct bat_priv *bat_priv, if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, &bat_priv->forw_bat_list, list) { - if (bat_ogm_can_aggregate(batman_ogm_packet, - bat_priv, packet_len, - send_time, direct_link, - if_incoming, - forw_packet_pos)) { + if (bat_iv_ogm_can_aggregate(batman_ogm_packet, + bat_priv, packet_len, + send_time, direct_link, + if_incoming, + forw_packet_pos)) { forw_packet_aggr = forw_packet_pos; break; } @@ -452,20 +451,20 @@ static void bat_ogm_queue_add(struct bat_priv *bat_priv, (atomic_read(&bat_priv->aggregated_ogms))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS);
- bat_ogm_aggregate_new(packet_buff, packet_len, - send_time, direct_link, - if_incoming, own_packet); + bat_iv_ogm_aggregate_new(packet_buff, packet_len, + send_time, direct_link, + if_incoming, own_packet); } else { - bat_ogm_aggregate(forw_packet_aggr, packet_buff, packet_len, - direct_link); + bat_iv_ogm_aggregate(forw_packet_aggr, packet_buff, + packet_len, direct_link); spin_unlock_bh(&bat_priv->forw_bat_list_lock); } }
-static void bat_ogm_forward(struct orig_node *orig_node, - const struct ethhdr *ethhdr, - struct batman_ogm_packet *batman_ogm_packet, - int directlink, struct hard_iface *if_incoming) +static void bat_iv_ogm_forward(struct orig_node *orig_node, + const struct ethhdr *ethhdr, + struct batman_ogm_packet *batman_ogm_packet, + int directlink, struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct neigh_node *router; @@ -524,12 +523,13 @@ static void bat_ogm_forward(struct orig_node *orig_node, else batman_ogm_packet->flags &= ~DIRECTLINK;
- bat_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, - BATMAN_OGM_LEN + tt_len(tt_num_changes), - if_incoming, 0, bat_ogm_fwd_send_time()); + bat_iv_ogm_queue_add(bat_priv, (unsigned char *)batman_ogm_packet, + BATMAN_OGM_LEN + tt_len(tt_num_changes), + if_incoming, 0, bat_iv_ogm_fwd_send_time()); }
-void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes) +static void bat_iv_ogm_schedule(struct hard_iface *hard_iface, + int tt_num_changes) { struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batman_ogm_packet *batman_ogm_packet; @@ -566,21 +566,22 @@ void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes) atomic_inc(&hard_iface->seqno);
slide_own_bcast_window(hard_iface); - bat_ogm_queue_add(bat_priv, hard_iface->packet_buff, - hard_iface->packet_len, hard_iface, 1, - bat_ogm_emit_send_time(bat_priv)); + bat_iv_ogm_queue_add(bat_priv, hard_iface->packet_buff, + hard_iface->packet_len, hard_iface, 1, + bat_iv_ogm_emit_send_time(bat_priv));
if (primary_if) hardif_free_ref(primary_if); }
-static void bat_ogm_orig_update(struct bat_priv *bat_priv, - struct orig_node *orig_node, - const struct ethhdr *ethhdr, - const struct batman_ogm_packet +static void bat_iv_ogm_orig_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, + const struct ethhdr *ethhdr, + const struct batman_ogm_packet *batman_ogm_packet, - struct hard_iface *if_incoming, - const unsigned char *tt_buff, int is_duplicate) + struct hard_iface *if_incoming, + const unsigned char *tt_buff, + int is_duplicate) { struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; struct neigh_node *router = NULL; @@ -715,10 +716,10 @@ out: neigh_node_free_ref(router); }
-static int bat_ogm_calc_tq(struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - struct batman_ogm_packet *batman_ogm_packet, - struct hard_iface *if_incoming) +static int bat_iv_ogm_calc_tq(struct orig_node *orig_node, + struct orig_node *orig_neigh_node, + struct batman_ogm_packet *batman_ogm_packet, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct neigh_node *neigh_node = NULL, *tmp_neigh_node; @@ -827,10 +828,10 @@ out: * -1 the packet is old and has been received while the seqno window * was protected. Caller should drop it. */ -static int bat_ogm_update_seqnos(const struct ethhdr *ethhdr, - const struct batman_ogm_packet +static int bat_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, + const struct batman_ogm_packet *batman_ogm_packet, - const struct hard_iface *if_incoming) + const struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct orig_node *orig_node; @@ -892,10 +893,10 @@ out: return ret; }
-static void bat_ogm_process(const struct ethhdr *ethhdr, - struct batman_ogm_packet *batman_ogm_packet, - const unsigned char *tt_buff, - struct hard_iface *if_incoming) +static void bat_iv_ogm_process(const struct ethhdr *ethhdr, + struct batman_ogm_packet *batman_ogm_packet, + const unsigned char *tt_buff, + struct hard_iface *if_incoming) { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct hard_iface *hard_iface; @@ -1033,8 +1034,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr, if (!orig_node) return;
- is_duplicate = bat_ogm_update_seqnos(ethhdr, batman_ogm_packet, - if_incoming); + is_duplicate = bat_iv_ogm_update_seqnos(ethhdr, batman_ogm_packet, + if_incoming);
if (is_duplicate == -1) { bat_dbg(DBG_BATMAN, bat_priv, @@ -1083,8 +1084,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr, goto out_neigh; }
- is_bidirectional = bat_ogm_calc_tq(orig_node, orig_neigh_node, - batman_ogm_packet, if_incoming); + is_bidirectional = bat_iv_ogm_calc_tq(orig_node, orig_neigh_node, + batman_ogm_packet, if_incoming);
bonding_save_primary(orig_node, orig_neigh_node, batman_ogm_packet);
@@ -1094,16 +1095,16 @@ static void bat_ogm_process(const struct ethhdr *ethhdr, (!is_duplicate || ((orig_node->last_real_seqno == batman_ogm_packet->seqno) && (orig_node->last_ttl - 3 <= batman_ogm_packet->header.ttl)))) - bat_ogm_orig_update(bat_priv, orig_node, ethhdr, - batman_ogm_packet, if_incoming, - tt_buff, is_duplicate); + bat_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, + batman_ogm_packet, if_incoming, + tt_buff, is_duplicate);
/* is single hop (direct) neighbor */ if (is_single_hop_neigh) {
/* mark direct link on incoming interface */ - bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, - 1, if_incoming); + bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, + 1, if_incoming);
bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " "rebroadcast neighbor packet with direct link flag\n"); @@ -1125,7 +1126,8 @@ static void bat_ogm_process(const struct ethhdr *ethhdr,
bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: rebroadcast originator packet\n"); - bat_ogm_forward(orig_node, ethhdr, batman_ogm_packet, 0, if_incoming); + bat_iv_ogm_forward(orig_node, ethhdr, batman_ogm_packet, + 0, if_incoming);
out_neigh: if ((orig_neigh_node) && (!is_single_hop_neigh)) @@ -1141,7 +1143,8 @@ out: orig_node_free_ref(orig_node); }
-void bat_ogm_receive(struct hard_iface *if_incoming, struct sk_buff *skb) +static void bat_iv_ogm_receive(struct hard_iface *if_incoming, + struct sk_buff *skb) { struct batman_ogm_packet *batman_ogm_packet; struct ethhdr *ethhdr; @@ -1162,20 +1165,26 @@ void bat_ogm_receive(struct hard_iface *if_incoming, struct sk_buff *skb)
tt_buff = packet_buff + buff_pos + BATMAN_OGM_LEN;
- bat_ogm_process(ethhdr, batman_ogm_packet, - tt_buff, if_incoming); + bat_iv_ogm_process(ethhdr, batman_ogm_packet, + tt_buff, if_incoming);
buff_pos += BATMAN_OGM_LEN + tt_len(batman_ogm_packet->tt_num_changes);
batman_ogm_packet = (struct batman_ogm_packet *) (packet_buff + buff_pos); - } while (bat_ogm_aggr_packet(buff_pos, packet_len, - batman_ogm_packet->tt_num_changes)); + } while (bat_iv_ogm_aggr_packet(buff_pos, packet_len, + batman_ogm_packet->tt_num_changes)); }
static struct bat_algo_ops batman_iv __read_mostly = { .name = "BATMAN IV", + .bat_ogm_init = bat_iv_ogm_init, + .bat_ogm_init_primary = bat_iv_ogm_init_primary, + .bat_ogm_update_mac = bat_iv_ogm_update_mac, + .bat_ogm_schedule = bat_iv_ogm_schedule, + .bat_ogm_emit = bat_iv_ogm_emit, + .bat_ogm_receive = bat_iv_ogm_receive, };
int __init bat_iv_init(void) diff --git a/bat_ogm.h b/bat_ogm.h deleted file mode 100644 index 47edfde..0000000 --- a/bat_ogm.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007-2011 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_OGM_H_ -#define _NET_BATMAN_ADV_OGM_H_ - -#include "main.h" - -void bat_ogm_init(struct hard_iface *hard_iface); -void bat_ogm_init_primary(struct hard_iface *hard_iface); -void bat_ogm_update_mac(struct hard_iface *hard_iface); -void bat_ogm_schedule(struct hard_iface *hard_iface, int tt_num_changes); -void bat_ogm_emit(struct forw_packet *forw_packet); -void bat_ogm_receive(struct hard_iface *if_incoming, struct sk_buff *skb); - -#endif /* _NET_BATMAN_ADV_OGM_H_ */ diff --git a/hard-interface.c b/hard-interface.c index d3e0e32..e66d8d6 100644 --- a/hard-interface.c +++ b/hard-interface.c @@ -28,7 +28,6 @@ #include "bat_sysfs.h" #include "originator.h" #include "hash.h" -#include "bat_ogm.h"
#include <linux/if_arp.h>
@@ -147,7 +146,7 @@ static void primary_if_select(struct bat_priv *bat_priv, if (!new_hard_iface) return;
- bat_ogm_init_primary(new_hard_iface); + bat_priv->bat_algo_ops->bat_ogm_init_primary(new_hard_iface); primary_if_update_addr(bat_priv); }
@@ -233,7 +232,7 @@ static void hardif_activate_interface(struct hard_iface *hard_iface)
bat_priv = netdev_priv(hard_iface->soft_iface);
- bat_ogm_update_mac(hard_iface); + bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); hard_iface->if_status = IF_TO_BE_ACTIVATED;
/** @@ -307,7 +306,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface, hard_iface->soft_iface = soft_iface; bat_priv = netdev_priv(hard_iface->soft_iface);
- bat_ogm_init(hard_iface); + bat_priv->bat_algo_ops->bat_ogm_init(hard_iface);
if (!hard_iface->packet_buff) { bat_err(hard_iface->soft_iface, "Can't add interface packet " @@ -527,9 +526,10 @@ static int hard_if_event(struct notifier_block *this, goto hardif_put;
check_known_mac_addr(hard_iface->net_dev); - bat_ogm_update_mac(hard_iface);
bat_priv = netdev_priv(hard_iface->soft_iface); + bat_priv->bat_algo_ops->bat_ogm_update_mac(hard_iface); + primary_if = primary_if_get_selected(bat_priv); if (!primary_if) goto hardif_put; diff --git a/main.c b/main.c index b554f63..b7bfa38 100644 --- a/main.c +++ b/main.c @@ -206,6 +206,18 @@ int bat_algo_register(struct bat_algo_ops *bat_algo_ops) goto out; }
+ /* all algorithms must implement all ops (for now) */ + if (!bat_algo_ops->bat_ogm_init || + !bat_algo_ops->bat_ogm_init_primary || + !bat_algo_ops->bat_ogm_update_mac || + !bat_algo_ops->bat_ogm_schedule || + !bat_algo_ops->bat_ogm_emit || + !bat_algo_ops->bat_ogm_receive) { + pr_info("Routing algo '%s' does not implement required ops\n", + bat_algo_ops->name); + goto out; + } + INIT_HLIST_NODE(&bat_algo_ops->list); hlist_add_head(&bat_algo_ops->list, &bat_algo_list); ret = 0; diff --git a/routing.c b/routing.c index 5bc41c8..b72d7f3 100644 --- a/routing.c +++ b/routing.c @@ -29,7 +29,6 @@ #include "originator.h" #include "vis.h" #include "unicast.h" -#include "bat_ogm.h"
void slide_own_bcast_window(struct hard_iface *hard_iface) { @@ -248,6 +247,7 @@ int window_protected(struct bat_priv *bat_priv, int32_t seq_num_diff,
int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface) { + struct bat_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct ethhdr *ethhdr;
/* drop packet if it has not necessary minimum size */ @@ -272,7 +272,7 @@ int recv_bat_ogm_packet(struct sk_buff *skb, struct hard_iface *hard_iface) if (skb_linearize(skb) < 0) return NET_RX_DROP;
- bat_ogm_receive(hard_iface, skb); + bat_priv->bat_algo_ops->bat_ogm_receive(hard_iface, skb);
kfree_skb(skb); return NET_RX_SUCCESS; diff --git a/send.c b/send.c index b00a0f5..019337e 100644 --- a/send.c +++ b/send.c @@ -28,7 +28,6 @@ #include "vis.h" #include "gateway_common.h" #include "originator.h" -#include "bat_ogm.h"
static void send_outstanding_bcast_packet(struct work_struct *work);
@@ -168,7 +167,7 @@ void schedule_bat_ogm(struct hard_iface *hard_iface) if (primary_if) hardif_free_ref(primary_if);
- bat_ogm_schedule(hard_iface, tt_num_changes); + bat_priv->bat_algo_ops->bat_ogm_schedule(hard_iface, tt_num_changes); }
static void forw_packet_free(struct forw_packet *forw_packet) @@ -318,7 +317,7 @@ void send_outstanding_bat_ogm_packet(struct work_struct *work) if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) goto out;
- bat_ogm_emit(forw_packet); + bat_priv->bat_algo_ops->bat_ogm_emit(forw_packet);
/** * we have to have at least one packet in the queue diff --git a/types.h b/types.h index d21ff2c..650ce5f 100644 --- a/types.h +++ b/types.h @@ -348,6 +348,20 @@ struct softif_neigh { struct bat_algo_ops { struct hlist_node list; char *name; + /* init OGM when hard-interface is enabled */ + void (*bat_ogm_init)(struct hard_iface *hard_iface); + /* init primary OGM when primary interface is selected */ + void (*bat_ogm_init_primary)(struct hard_iface *hard_iface); + /* init mac addresses of the OGM belonging to this hard-interface */ + void (*bat_ogm_update_mac)(struct hard_iface *hard_iface); + /* prepare a new outgoing OGM for the send queue */ + void (*bat_ogm_schedule)(struct hard_iface *hard_iface, + int tt_num_changes); + /* send scheduled OGM */ + void (*bat_ogm_emit)(struct forw_packet *forw_packet); + /* receive incoming OGM */ + void (*bat_ogm_receive)(struct hard_iface *if_incoming, + struct sk_buff *skb); };
#endif /* _NET_BATMAN_ADV_TYPES_H_ */
Signed-off-by: Marek Lindner lindner_marek@yahoo.de --- bat_sysfs.c | 35 +++++++++++++++++++++++++++++++++++ sysfs-class-net-mesh | 7 +++++++ 2 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/bat_sysfs.c b/bat_sysfs.c index c25492f..af8dd58 100644 --- a/bat_sysfs.c +++ b/bat_sysfs.c @@ -272,6 +272,39 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, return count; }
+static ssize_t show_bat_algo(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + return sprintf(buff, "%s\n", bat_priv->bat_algo_ops->name); +} + +static ssize_t store_bat_algo(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct bat_priv *bat_priv = netdev_priv(net_dev); + int ret; + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + else + buff[count] = '\0'; + + if (strcmp(bat_priv->bat_algo_ops->name, buff) == 0) + return count; + + ret = bat_algo_select(bat_priv, buff); + if (ret < 0) + bat_info(net_dev, + "Invalid parameter for 'routing algorithm' setting " + "received: %s\n", buff); + else + bat_info(net_dev, "Changing routing algorithm to: %s\n", buff); + + return count; +} + static void post_gw_deselect(struct net_device *net_dev) { struct bat_priv *bat_priv = netdev_priv(net_dev); @@ -382,6 +415,7 @@ BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); +static BAT_ATTR(routing_algo, S_IRUGO | S_IWUSR, show_bat_algo, store_bat_algo); static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); @@ -399,6 +433,7 @@ static struct bat_attribute *mesh_attrs[] = { &bat_attr_fragmentation, &bat_attr_ap_isolation, &bat_attr_vis_mode, + &bat_attr_routing_algo, &bat_attr_gw_mode, &bat_attr_orig_interval, &bat_attr_hop_penalty, diff --git a/sysfs-class-net-mesh b/sysfs-class-net-mesh index b020014..b218e0f 100644 --- a/sysfs-class-net-mesh +++ b/sysfs-class-net-mesh @@ -65,6 +65,13 @@ Description: Defines the penalty which will be applied to an originator message's tq-field on every hop.
+What: /sys/class/net/<mesh_iface>/mesh/routing_algo +Date: Dec 2011 +Contact: Marek Lindner lindner_marek@yahoo.de +Description: + Defines the routing procotol this mesh instance + uses to find the optimal paths through the mesh. + What: /sys/class/net/<mesh_iface>/mesh/vis_mode Date: May 2010 Contact: Marek Lindner lindner_marek@yahoo.de
On Mon, Dec 05, 2011 at 05:56:22PM +0800, Marek Lindner wrote:
Hi,
I massaged the RFC patches a little longer to integrate all the feedback received so far. They are ready to be considered 'real' patches now.
Hi Marek
If i'm reading the patches correctly, it looks like you can change the algorithm at any time. Rather than making one algorithm deal with what ever state the previous algorithm left behind, would it not be better to only allow algorithm change when the soft interface is down and there is no local state?
Andrew
On Monday, December 05, 2011 19:27:26 Andrew Lunn wrote:
If i'm reading the patches correctly, it looks like you can change the algorithm at any time. Rather than making one algorithm deal with what ever state the previous algorithm left behind, would it not be better to only allow algorithm change when the soft interface is down and there is no local state?
Good point. Alternatively, we could add a cleanup call ?
Cheers, Marek
On Mon, Dec 05, 2011 at 07:35:06PM +0800, Marek Lindner wrote:
On Monday, December 05, 2011 19:27:26 Andrew Lunn wrote:
If i'm reading the patches correctly, it looks like you can change the algorithm at any time. Rather than making one algorithm deal with what ever state the previous algorithm left behind, would it not be better to only allow algorithm change when the soft interface is down and there is no local state?
Good point. Alternatively, we could add a cleanup call ?
Hi Marek
Changing routing protocol is something you don't want to accidentally do. So i think it should be reasonably hard to do, so you don't get any surprises. I would limit it to when the soft interface is down, and at other times return EBUSY. EBUSY seems like a reasonable good way to indicate the mesh is busy.
However, i think a cleanup call probably is needed, since the routing protocol will probably have its own internal state, memory allocations, etc which needs freeing when the mesh is going down.
Andrew
On Monday, December 05, 2011 20:13:42 Andrew Lunn wrote:
Changing routing protocol is something you don't want to accidentally do. So i think it should be reasonably hard to do, so you don't get any surprises. I would limit it to when the soft interface is down, and at other times return EBUSY. EBUSY seems like a reasonable good way to indicate the mesh is busy.
However, i think a cleanup call probably is needed, since the routing protocol will probably have its own internal state, memory allocations, etc which needs freeing when the mesh is going down.
The mesh is not going down when you bring down bat0. You can do whatever you want with bat0 - the mesh continues to operate normally. Only when a hard- interface goes down the routing information relying on that very interface are purged.
Here comes the chicken & egg problem: We can't have bat0 and its routing algorithm selection before we did not add at least one hard-interface.
Cheers, Marek
On Mon, Dec 05, 2011 at 09:38:54 +0800, Marek Lindner wrote:
On Monday, December 05, 2011 20:13:42 Andrew Lunn wrote:
Changing routing protocol is something you don't want to accidentally do. So i think it should be reasonably hard to do, so you don't get any surprises. I would limit it to when the soft interface is down, and at other times return EBUSY. EBUSY seems like a reasonable good way to indicate the mesh is busy.
However, i think a cleanup call probably is needed, since the routing protocol will probably have its own internal state, memory allocations, etc which needs freeing when the mesh is going down.
The mesh is not going down when you bring down bat0. You can do whatever you want with bat0 - the mesh continues to operate normally. Only when a hard- interface goes down the routing information relying on that very interface are purged.
Here comes the chicken & egg problem: We can't have bat0 and its routing algorithm selection before we did not add at least one hard-interface.
What about specifying the routing algorithm directly on "soft-iface creation" and deny any further change?
I discussed a little bit about this with Marek on IRC and we figured out that the soft-iface is created after writing "bat0" (or any other name) in to the sysfs. At this point the routing algorithm has not been specified yet, but the soft-iface has already been created...
As solution I would suggest about splitting the soft-iface creation into two steps:
1) specify the soft-iface name => create the interface and allocate all the structure (that are not dependant on the routing algo)
1.1) the interface is in ALGO-WAITING state, any action that tries to enable it is denied and EBUSY (?) is returned.
2) specify the routing algo => launch the routing algo init function and create all the needed strctures.
2.1) the interface is now READY
I don't exclude that I wrote something totally wrong :-)
Cheers,
What about specifying the routing algorithm directly on "soft-iface creation" and deny any further change?
Emails crossed in the post....
- specify the soft-iface name => create the interface and allocate all the
structure (that are not dependant on the routing algo)
1.1) the interface is in ALGO-WAITING state, any action that tries to enable it is denied and EBUSY (?) is returned.
We should try to keep backwards compatibility. So rather than having ALGO-WAITING, i would suggest using the first available routing algorithm as the default.
So the backwards compatible way would be:
1) Add a hard interface, which automagically creates the soft interface with the first available routing algorithm.
For those who want to play with new routing algorithms:
1) Create the soft interface 2) Change the routing algorithm away from the default 3) Add the first hard interface.
batctl could be extended to hide some of this, eg.
batctl if add -a ix eth1 eth42
i.e. use routing algorithm ix while adding interfaces eth1 and eth42. batctl could check if the soft interface already exists and throw an error if -a is passed, or at least, if the algorithm is different to the one currently in use.
Andrew
On Mon, Dec 05, 2011 at 03:38:48 +0100, Andrew Lunn wrote:
What about specifying the routing algorithm directly on "soft-iface creation" and deny any further change?
Emails crossed in the post....
- specify the soft-iface name => create the interface and allocate all the
structure (that are not dependant on the routing algo)
1.1) the interface is in ALGO-WAITING state, any action that tries to enable it is denied and EBUSY (?) is returned.
We should try to keep backwards compatibility. So rather than having ALGO-WAITING, i would suggest using the first available routing algorithm as the default.
So the backwards compatible way would be:
- Add a hard interface, which automagically creates the soft interface with the first available routing algorithm.
For those who want to play with new routing algorithms:
- Create the soft interface
- Change the routing algorithm away from the default
- Add the first hard interface.
I think that currently point 1) and 3) are joint. So adding something in between means redesign the initialisation part.
Cheers,
The mesh is not going down when you bring down bat0. You can do whatever you want with bat0 - the mesh continues to operate normally. Only when a hard- interface goes down the routing information relying on that very interface are purged.
Ah, O.K. My understanding was wrong.
Here comes the chicken & egg problem: We can't have bat0 and its routing algorithm selection before we did not add at least one hard-interface.
Lets see if i have the call chain correct:
store_mesh_iface()->hardif_enable_interface()->softif_create()->mesh_init()
It is mesh_init() that really starts the mesh going, but there is no real need to start it until the first hard interface is added.
So maybe we could spit this into two separate operations.
1) Create the software interface 2) Add a hard interface and start the mesh, if not already started.
So maybe two new sysfs files are needed:
/sys/class/net/batman_adv/add_mesh /sys/class/net/batman_adv/rm_mesh
echo the name of a soft interface, bat0, into the add_mesh file and the softif_create() function would be called for it, but not mesh_init().
hardif_enable_interface() would see if the soft interface exists, as it currently does, so keeping backwards compatibility. If it does not exist, call softif_create. Then check if the soft interface has been started. Maybe add another atomic to priv, started, which mesh_init() can increment.
Andrew
Hey there,
On Mon, Dec 05, 2011 at 03:25:53PM +0100, Andrew Lunn wrote:
Here comes the chicken & egg problem: We can't have bat0 and its routing algorithm selection before we did not add at least one hard-interface.
an alternative we may consider:
We could just write the name of the algorithm in a debugfs file called "routing_algorithm". It is filled with batmanIV as the default algorithm to start with, and whatever is written there is used for the next soft interface to be created.
This would be backward compatible and changes are only made upon creation of a soft interface. It would also allow different soft interfaces using different routing algorithms (if someone really needs it). Putting it into debugfs may be not the worst idea, as changing routing algorithms is (currently) only done for debugging purposes anyway.
What do you think?
Cheers Simon
On Tue, Dec 06, 2011 at 04:01:34PM +0100, Simon Wunderlich wrote:
Hey there,
On Mon, Dec 05, 2011 at 03:25:53PM +0100, Andrew Lunn wrote:
Here comes the chicken & egg problem: We can't have bat0 and its routing algorithm selection before we did not add at least one hard-interface.
an alternative we may consider:
We could just write the name of the algorithm in a debugfs file called "routing_algorithm". It is filled with batmanIV as the default algorithm to start with, and whatever is written there is used for the next soft interface to be created.
sounds good IMHO! I think this would be a really nice solution.
This would be backward compatible and changes are only made upon creation of a soft interface. It would also allow different soft interfaces using different routing algorithms (if someone really needs it). Putting it into debugfs may be not the worst idea, as changing routing algorithms is (currently) only done for debugging purposes anyway.
What do you think?
I agree on this solution...it merges nearly all the ideas we discussed so far.
Cheers,
On Tue, Dec 06, 2011 at 04:01:34PM +0100, Simon Wunderlich wrote:
Hey there,
On Mon, Dec 05, 2011 at 03:25:53PM +0100, Andrew Lunn wrote:
Here comes the chicken & egg problem: We can't have bat0 and its routing algorithm selection before we did not add at least one hard-interface.
an alternative we may consider:
We could just write the name of the algorithm in a debugfs file called "routing_algorithm". It is filled with batmanIV as the default algorithm to start with, and whatever is written there is used for the next soft interface to be created.
This would be backward compatible and changes are only made upon creation of a soft interface. It would also allow different soft interfaces using different routing algorithms (if someone really needs it). Putting it into debugfs may be not the worst idea, as changing routing algorithms is (currently) only done for debugging purposes anyway.
Hi Simon
When it is in debugfs, it implies that the user has no choice, it is a debug tool only. So when the development is finished, one day batman will just swap from IV to V, and the user gets no choice?
For the moment, i think it is O.K. in debugfs. However, there should be some sort of idea how this is going to work when it comes to actually mainstream use of V. Is it simply that IV is dead, you need to use V now. Or do we give the user a choice and some file under /sys to make this choice?
Also, i would suggest not adding batctl support for this file in /debugfs, since then routing_algorithm is on the first steps towards becoming part of the ABI, even thought it is in debugfs and should not be part of an ABI.
Andrew
Hi,
When it is in debugfs, it implies that the user has no choice, it is a debug tool only. So when the development is finished, one day batman will just swap from IV to V, and the user gets no choice?
For the moment, i think it is O.K. in debugfs. However, there should be some sort of idea how this is going to work when it comes to actually mainstream use of V. Is it simply that IV is dead, you need to use V now. Or do we give the user a choice and some file under /sys to make this choice?
the idea of using debugfs instead of sysfs was to avoid the chicken & egg problem (I guess). However, looking at my batman-adv debugfs entry tells me that we have the same problem there. Unless we want to move this file into the debugfs batman-adv root folder (/sys/kernel/debug/batman_adv) we can't move forward either. The whole init/config structure has been designed for "create bat0 first".
If we don't want to rewrite this whole part I only see 2 options: * compile or module parameter * changing the routing algo on the fly
Regards, Marek
Hey there,
On Tue, Dec 06, 2011 at 11:30:54PM +0800, Marek Lindner wrote:
Hi,
When it is in debugfs, it implies that the user has no choice, it is a debug tool only. So when the development is finished, one day batman will just swap from IV to V, and the user gets no choice?
For the moment, i think it is O.K. in debugfs. However, there should be some sort of idea how this is going to work when it comes to actually mainstream use of V. Is it simply that IV is dead, you need to use V now. Or do we give the user a choice and some file under /sys to make this choice?
the idea of using debugfs instead of sysfs was to avoid the chicken & egg problem (I guess). However, looking at my batman-adv debugfs entry tells me that we have the same problem there. Unless we want to move this file into the debugfs batman-adv root folder (/sys/kernel/debug/batman_adv) we can't move forward either. The whole init/config structure has been designed for "create bat0 first".
If we don't want to rewrite this whole part I only see 2 options:
- compile or module parameter
- changing the routing algo on the fly
Yeah, we would have to move it into /sys/kernel/debug/batman_adv in the root, but Andrew may be right about future "non-debug" algorithm selection.
Maybe we go back to Antonios idea with the module parameter, but make it changeable in runtime. Haven't done that yet, but it seems to be possible [1]:
''Loadable modules, after being loaded into the running kernel, also reveal their parameters in /sys/module/${modulename}/parameters/. Some of these parameters may be changed at runtime by the command "echo -n ${value} > /sys/module/${modulename}/parameters/${parm}" ''
The rest would work as described: having a default value, allow user changes in runtime and use the configured algorithm value for the next soft interface creation.
How about this? Simon
[1] http://www.kernel.org/doc/Documentation/kernel-parameters.txt
b.a.t.m.a.n@lists.open-mesh.org