Hello list,
with this RFC I'd like to introduce some new routing API functions meant to improve the routing protocol abstraction.
This changes have been written while developing batman V. The latter helped me in understanding what batman iv and v have in common and what not.
The main problem was the metric: the two protocols use different metric domains and different semantics. Therefore all the functions handling/printing the metric needed to be generalised and rearranged to let the protocols decide what to do.
Another issue was the way routing protocols handle the orig and neigh node structures. Also these two have been changed and some small APIs have been provided as well.
Moreover, after Simon's RFC about the new multi-interface optimisation, we saw the need for a better abstraction so that mechanisms like that could easily be re-used by new algorithms (like batman v) with little effort.
This is the second version of this RFC where I introduced some changes to the names of some functions and some other minor changes discussed in the previous RFC thread.
The new API functions are the following: + metric related: - bat_metric_get - bat_metric_is_similar - bat_metric_compare
+ orig_node related: - bat_orig_print: print the originator table - bat_orig_add_if - bat_orig_del_if - bat_orig_free
Any feedback will surely be welcome :-)
Cheers,
Antonio Quartulli (10): batman-adv: make struct batadv_neigh_node algorithm agnostic batman-adv: make struct batadv_orig_node algorithm agnostic batman-adv: add bat_orig_print function API batman-adv: add bat_metric_get API function batman-adv: add bat_metric_is_equiv_or_better API function batman-adv: add bat_metric_compare API function batman-adv: adapt bonding to use the new API functions batman-adv: adapt the neighbor purging routine to use the new API functions batman-adv: provide orig_node routing API batman-adv: adapt the TT component to use the new API functions
bat_iv_ogm.c | 359 +++++++++++++++++++++++++++++++++++++++++++--------- gateway_client.c | 16 +-- main.c | 5 +- main.h | 6 + network-coding.c | 8 +- originator.c | 230 +++++++-------------------------- originator.h | 5 +- routing.c | 37 ++++-- routing.h | 3 +- translation-table.c | 31 +++-- types.h | 86 +++++++++---- 11 files changed, 480 insertions(+), 306 deletions(-)
From: Antonio Quartulli antonio@open-mesh.com
some of the fields in struct batadv_neigh_node are strictly related to the B.A.T.M.A.N. IV algorithm. In order to make the struct usable by any routing algorithm it has to be split and made more generic
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 64 +++++++++++++++++++++++++++-------------------------- gateway_client.c | 16 +++++++------- network-coding.c | 8 ++++--- originator.c | 28 ++++++++++++----------- originator.h | 3 ++- routing.c | 9 ++++---- translation-table.c | 4 ++-- types.h | 40 +++++++++++++++++++-------------- 8 files changed, 94 insertions(+), 78 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 5ff1a6b..cfa3b1f 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -93,20 +93,18 @@ batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_neigh) { + struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_neigh_node *neigh_node;
- neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr); + neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, orig_node); if (!neigh_node) goto out;
- INIT_LIST_HEAD(&neigh_node->bonding_list); - - neigh_node->orig_node = orig_neigh; - neigh_node->if_incoming = hard_iface; + spin_lock_init(&neigh_node->bat_iv.lq_update_lock);
- spin_lock_bh(&orig_node->neigh_list_lock); - hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); - spin_unlock_bh(&orig_node->neigh_list_lock); + batadv_dbg(BATADV_DBG_BATMAN, bat_priv, + "Creating new neighbor %pM for orig_node %pM on interface %s\n", + neigh_addr, orig_node->orig, hard_iface->net_dev->name);
out: return neigh_node; @@ -754,12 +752,12 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, if (dup_status != BATADV_NO_DUP) continue;
- spin_lock_bh(&tmp_neigh_node->lq_update_lock); - batadv_ring_buffer_set(tmp_neigh_node->tq_recv, - &tmp_neigh_node->tq_index, 0); - tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->tq_recv); - tmp_neigh_node->tq_avg = tq_avg; - spin_unlock_bh(&tmp_neigh_node->lq_update_lock); + spin_lock_bh(&tmp_neigh_node->bat_iv.lq_update_lock); + batadv_ring_buffer_set(tmp_neigh_node->bat_iv.tq_recv, + &tmp_neigh_node->bat_iv.tq_index, 0); + tq_avg = batadv_ring_buffer_avg(tmp_neigh_node->bat_iv.tq_recv); + tmp_neigh_node->bat_iv.tq_avg = tq_avg; + spin_unlock_bh(&tmp_neigh_node->bat_iv.lq_update_lock); }
if (!neigh_node) { @@ -784,12 +782,13 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
neigh_node->last_seen = jiffies;
- spin_lock_bh(&neigh_node->lq_update_lock); - batadv_ring_buffer_set(neigh_node->tq_recv, - &neigh_node->tq_index, + spin_lock_bh(&neigh_node->bat_iv.lq_update_lock); + batadv_ring_buffer_set(neigh_node->bat_iv.tq_recv, + &neigh_node->bat_iv.tq_index, batadv_ogm_packet->tq); - neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); - spin_unlock_bh(&neigh_node->lq_update_lock); + tq_avg = batadv_ring_buffer_avg(neigh_node->bat_iv.tq_recv); + neigh_node->bat_iv.tq_avg = tq_avg; + spin_unlock_bh(&neigh_node->bat_iv.lq_update_lock);
if (dup_status == BATADV_NO_DUP) { orig_node->last_ttl = batadv_ogm_packet->header.ttl; @@ -806,13 +805,13 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, goto out;
/* if this neighbor does not offer a better TQ we won't consider it */ - if (router && (router->tq_avg > neigh_node->tq_avg)) + if (router && (router->bat_iv.tq_avg > neigh_node->bat_iv.tq_avg)) goto out;
/* if the TQ is the same and the link not more symmetric we * won't consider it either */ - if (router && (neigh_node->tq_avg == router->tq_avg)) { + if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) { orig_node_tmp = router->orig_node; spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); if_num = router->if_incoming->if_num; @@ -891,7 +890,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, /* find packet count of corresponding one hop neighbor */ spin_lock_bh(&orig_node->ogm_cnt_lock); orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; - neigh_rq_count = neigh_node->real_packet_count; + neigh_rq_count = neigh_node->bat_iv.real_packet_count; spin_unlock_bh(&orig_node->ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */ @@ -974,6 +973,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, uint32_t seqno = ntohl(batadv_ogm_packet->seqno); uint8_t *neigh_addr; uint8_t packet_count; + unsigned long (*bitmap)[];
orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); if (!orig_node) @@ -994,7 +994,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, hlist_for_each_entry_rcu(tmp_neigh_node, &orig_node->neigh_list, list) { neigh_addr = tmp_neigh_node->addr; - is_dup = batadv_test_bit(tmp_neigh_node->real_bits, + is_dup = batadv_test_bit(tmp_neigh_node->bat_iv.real_bits, orig_node->last_real_seqno, seqno);
@@ -1010,13 +1010,13 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, }
/* if the window moved, set the update flag. */ - need_update |= batadv_bit_get_packet(bat_priv, - tmp_neigh_node->real_bits, + bitmap = &tmp_neigh_node->bat_iv.real_bits; + need_update |= batadv_bit_get_packet(bat_priv, *bitmap, seq_diff, set_mark);
- packet_count = bitmap_weight(tmp_neigh_node->real_bits, + packet_count = bitmap_weight(tmp_neigh_node->bat_iv.real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); - tmp_neigh_node->real_packet_count = packet_count; + tmp_neigh_node->bat_iv.real_packet_count = packet_count; } rcu_read_unlock();
@@ -1040,7 +1040,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, { struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct batadv_hard_iface *hard_iface; - struct batadv_orig_node *orig_neigh_node, *orig_node; + struct batadv_orig_node *orig_neigh_node, *orig_node, *orig_node_tmp; struct batadv_neigh_node *router = NULL, *router_router = NULL; struct batadv_neigh_node *orig_neigh_router = NULL; int has_directlink_flag; @@ -1191,10 +1191,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, }
router = batadv_orig_node_get_router(orig_node); - if (router) - router_router = batadv_orig_node_get_router(router->orig_node); + if (router) { + orig_node_tmp = router->orig_node; + router_router = batadv_orig_node_get_router(orig_node_tmp); + }
- if ((router && router->tq_avg != 0) && + if ((router && router->bat_iv.tq_avg != 0) && (batadv_compare_eth(router->addr, ethhdr->h_source))) is_from_best_next_hop = true;
diff --git a/gateway_client.c b/gateway_client.c index edf61da..bb3b060 100644 --- a/gateway_client.c +++ b/gateway_client.c @@ -137,7 +137,7 @@ batadv_gw_get_best_gw_node(struct batadv_priv *bat_priv) if (!atomic_inc_not_zero(&gw_node->refcount)) goto next;
- tq_avg = router->tq_avg; + tq_avg = router->bat_iv.tq_avg;
switch (atomic_read(&bat_priv->gw_sel_class)) { case 1: /* fast connection */ @@ -256,7 +256,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv) next_gw->bandwidth_down / 10, next_gw->bandwidth_down % 10, next_gw->bandwidth_up / 10, - next_gw->bandwidth_up % 10, router->tq_avg); + next_gw->bandwidth_up % 10, router->bat_iv.tq_avg); batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_ADD, gw_addr); } else { @@ -266,7 +266,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv) next_gw->bandwidth_down / 10, next_gw->bandwidth_down % 10, next_gw->bandwidth_up / 10, - next_gw->bandwidth_up % 10, router->tq_avg); + next_gw->bandwidth_up % 10, router->bat_iv.tq_avg); batadv_throw_uevent(bat_priv, BATADV_UEV_GW, BATADV_UEV_CHANGE, gw_addr); } @@ -305,8 +305,8 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv, if (!router_orig) goto out;
- gw_tq_avg = router_gw->tq_avg; - orig_tq_avg = router_orig->tq_avg; + gw_tq_avg = router_gw->bat_iv.tq_avg; + orig_tq_avg = router_orig->bat_iv.tq_avg;
/* the TQ value has to be better */ if (orig_tq_avg < gw_tq_avg) @@ -528,7 +528,7 @@ static int batadv_write_buffer_text(struct batadv_priv *bat_priv, ret = seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %u.%u/%u.%u MBit\n", (curr_gw == gw_node ? "=>" : " "), gw_node->orig_node->orig, - router->tq_avg, router->addr, + router->bat_iv.tq_avg, router->addr, router->if_incoming->net_dev->name, gw_node->bandwidth_down / 10, gw_node->bandwidth_down % 10, @@ -781,7 +781,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, if (!neigh_curr) goto out;
- curr_tq_avg = neigh_curr->tq_avg; + curr_tq_avg = neigh_curr->bat_iv.tq_avg; break; case BATADV_GW_MODE_OFF: default: @@ -792,7 +792,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, if (!neigh_old) goto out;
- if (curr_tq_avg - neigh_old->tq_avg > BATADV_GW_THRESHOLD) + if (curr_tq_avg - neigh_old->bat_iv.tq_avg > BATADV_GW_THRESHOLD) out_of_range = true;
out: diff --git a/network-coding.c b/network-coding.c index ef88a1f..173a96e 100644 --- a/network-coding.c +++ b/network-coding.c @@ -994,7 +994,7 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv, struct batadv_nc_packet *nc_packet, struct batadv_neigh_node *neigh_node) { - uint8_t tq_weighted_neigh, tq_weighted_coding; + uint8_t tq_weighted_neigh, tq_weighted_coding, tq_tmp; struct sk_buff *skb_dest, *skb_src; struct batadv_unicast_packet *packet1; struct batadv_unicast_packet *packet2; @@ -1019,8 +1019,10 @@ static bool batadv_nc_code_packets(struct batadv_priv *bat_priv, if (!router_coding) goto out;
- tq_weighted_neigh = batadv_nc_random_weight_tq(router_neigh->tq_avg); - tq_weighted_coding = batadv_nc_random_weight_tq(router_coding->tq_avg); + tq_tmp = batadv_nc_random_weight_tq(router_neigh->bat_iv.tq_avg); + tq_weighted_neigh = tq_tmp; + tq_tmp = batadv_nc_random_weight_tq(router_coding->bat_iv.tq_avg); + tq_weighted_coding = tq_tmp;
/* Select one destination for the MAC-header dst-field based on * weighted TQ-values. diff --git a/originator.c b/originator.c index ee1d847..3837195 100644 --- a/originator.c +++ b/originator.c @@ -174,27 +174,28 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
struct batadv_neigh_node * batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, - const uint8_t *neigh_addr) + const uint8_t *neigh_addr, + struct batadv_orig_node *orig_node) { - struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_neigh_node *neigh_node;
neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); if (!neigh_node) goto out;
- INIT_HLIST_NODE(&neigh_node->list); - memcpy(neigh_node->addr, neigh_addr, ETH_ALEN); - spin_lock_init(&neigh_node->lq_update_lock); + neigh_node->if_incoming = hard_iface; + neigh_node->orig_node = orig_node; + + spin_lock_bh(&orig_node->neigh_list_lock); + hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); + spin_unlock_bh(&orig_node->neigh_list_lock); + + INIT_LIST_HEAD(&neigh_node->bonding_list);
/* extra reference for return */ atomic_set(&neigh_node->refcount, 2);
- batadv_dbg(BATADV_DBG_BATMAN, bat_priv, - "Creating new neighbor %pM on interface %s\n", neigh_addr, - hard_iface->net_dev->name); - out: return neigh_node; } @@ -436,7 +437,8 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, batadv_neigh_node_free_ref(neigh_node); } else { if ((!*best_neigh_node) || - (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) + (neigh_node->bat_iv.tq_avg > + (*best_neigh_node)->bat_iv.tq_avg)) *best_neigh_node = neigh_node; } } @@ -557,7 +559,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) if (!neigh_node) continue;
- if (neigh_node->tq_avg == 0) + if (neigh_node->bat_iv.tq_avg == 0) goto next;
last_seen_jiffies = jiffies - orig_node->last_seen; @@ -567,7 +569,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", orig_node->orig, last_seen_secs, - last_seen_msecs, neigh_node->tq_avg, + last_seen_msecs, neigh_node->bat_iv.tq_avg, neigh_node->addr, neigh_node->if_incoming->net_dev->name);
@@ -575,7 +577,7 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) &orig_node->neigh_list, list) { seq_printf(seq, " %pM (%3i)", neigh_node_tmp->addr, - neigh_node_tmp->tq_avg); + neigh_node_tmp->bat_iv.tq_avg); }
seq_puts(seq, "\n"); diff --git a/originator.h b/originator.h index cc6d686..06e5a68 100644 --- a/originator.h +++ b/originator.h @@ -31,7 +31,8 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, const uint8_t *addr); struct batadv_neigh_node * batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, - const uint8_t *neigh_addr); + const uint8_t *neigh_addr, + struct batadv_orig_node *orig_node); void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node); struct batadv_neigh_node * batadv_orig_node_get_router(struct batadv_orig_node *orig_node); diff --git a/routing.c b/routing.c index 2b35205..99f6844 100644 --- a/routing.c +++ b/routing.c @@ -133,7 +133,8 @@ void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node, goto candidate_del;
/* ... and is good enough to be considered */ - if (neigh_node->tq_avg < router->tq_avg - BATADV_BONDING_TQ_THRESHOLD) + if (neigh_node->bat_iv.tq_avg < + router->bat_iv.tq_avg - BATADV_BONDING_TQ_THRESHOLD) goto candidate_del;
/* check if we have another candidate with the same mac address or @@ -470,8 +471,7 @@ batadv_find_bond_router(struct batadv_orig_node *primary_orig, * does not exist as rcu version */ list_del_rcu(&primary_orig->bond_list); - list_add_rcu(&primary_orig->bond_list, - &router->bonding_list); + list_add_rcu(&primary_orig->bond_list, &router->bonding_list); spin_unlock_bh(&primary_orig->neigh_list_lock);
out: @@ -502,7 +502,8 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, if (tmp_neigh_node->if_incoming == recv_if) continue;
- if (router && tmp_neigh_node->tq_avg <= router->tq_avg) + if (router && + tmp_neigh_node->bat_iv.tq_avg <= router->bat_iv.tq_avg) continue;
if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) diff --git a/translation-table.c b/translation-table.c index b6f8a9a..0064423 100644 --- a/translation-table.c +++ b/translation-table.c @@ -1299,9 +1299,9 @@ batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry) if (!router) continue;
- if (router->tq_avg > best_tq) { + if (router->bat_iv.tq_avg > best_tq) { best_entry = orig_entry; - best_tq = router->tq_avg; + best_tq = router->bat_iv.tq_avg; }
batadv_neigh_node_free_ref(router); diff --git a/types.h b/types.h index 0f938c2..0088a53 100644 --- a/types.h +++ b/types.h @@ -263,40 +263,48 @@ struct batadv_gw_node { };
/** - * struct batadv_neigh_node - structure for single hop neighbors - * @list: list node for batadv_orig_node::neigh_list - * @addr: mac address of neigh node + * struct batadv_neigh_bat_iv - structure for single hop neighbors * @tq_recv: ring buffer of received TQ values from this neigh node * @tq_index: ring buffer index * @tq_avg: averaged tq of all tq values in the ring buffer (tq_recv) - * @last_ttl: last received ttl from this neigh node - * @bonding_list: list node for batadv_orig_node::bond_list - * @last_seen: when last packet via this neighbor was received * @real_bits: bitfield containing the number of OGMs received from this neigh * node (relative to orig_node->last_real_seqno) * @real_packet_count: counted result of real_bits - * @orig_node: pointer to corresponding orig_node - * @if_incoming: pointer to incoming hard interface * @lq_update_lock: lock protecting tq_recv & tq_index * @refcount: number of contexts the object is used - * @rcu: struct used for freeing in an RCU-safe manner */ -struct batadv_neigh_node { - struct hlist_node list; - uint8_t addr[ETH_ALEN]; +struct batadv_neigh_bat_iv { uint8_t tq_recv[BATADV_TQ_GLOBAL_WINDOW_SIZE]; uint8_t tq_index; uint8_t tq_avg; - uint8_t last_ttl; - struct list_head bonding_list; - unsigned long last_seen; DECLARE_BITMAP(real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); uint8_t real_packet_count; + spinlock_t lq_update_lock; /* protects tq_recv & tq_index */ +}; + +/** + * struct batadv_neigh_node - structure for single hops neighbors + * @list: list node for batadv_orig_node::neigh_list + * @orig_node: pointer to corresponding orig_node + * @addr: the MAC address of the neighboring interface + * @if_incoming: pointer to incoming hard interface + * @last_seen: when last packet via this neighbor was received + * @last_ttl: last received ttl from this neigh node + * @bonding_list: list node for batadv_orig_node::bond_list + * @rcu: struct used for freeing in an RCU-safe manner + * @priv: pointer to the routing algorithm private data + */ +struct batadv_neigh_node { + struct hlist_node list; struct batadv_orig_node *orig_node; + uint8_t addr[ETH_ALEN]; struct batadv_hard_iface *if_incoming; - spinlock_t lq_update_lock; /* protects tq_recv & tq_index */ + unsigned long last_seen; + uint8_t last_ttl; + struct list_head bonding_list; atomic_t refcount; struct rcu_head rcu; + struct batadv_neigh_bat_iv bat_iv; };
/**
On Wed, Jul 31, 2013 at 10:47:38PM +0200, Antonio Quartulli wrote:
@@ -974,6 +973,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, uint32_t seqno = ntohl(batadv_ogm_packet->seqno); uint8_t *neigh_addr; uint8_t packet_count;
- unsigned long (*bitmap)[];
[...] @@ -1010,13 +1010,13 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, }
/* if the window moved, set the update flag. */
need_update |= batadv_bit_get_packet(bat_priv,
tmp_neigh_node->real_bits,
bitmap = &tmp_neigh_node->bat_iv.real_bits;
need_update |= batadv_bit_get_packet(bat_priv, *bitmap, seq_diff, set_mark);
Why referencing and derefencing here? That looks odd, you don't use the bitmap after that, do you?
packet_count = bitmap_weight(tmp_neigh_node->real_bits,
packet_count = bitmap_weight(tmp_neigh_node->bat_iv.real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
tmp_neigh_node->real_packet_count = packet_count;
tmp_neigh_node->bat_iv.real_packet_count = packet_count;
} rcu_read_unlock();
/* ... and is good enough to be considered */
- if (neigh_node->tq_avg < router->tq_avg - BATADV_BONDING_TQ_THRESHOLD)
- if (neigh_node->bat_iv.tq_avg <
goto candidate_del;router->bat_iv.tq_avg - BATADV_BONDING_TQ_THRESHOLD)
alignment looks a little weird, although this will probably replaced anyway in the later patches?
/**
- struct batadv_neigh_node - structure for single hop neighbors
- @list: list node for batadv_orig_node::neigh_list
- @addr: mac address of neigh node
- struct batadv_neigh_bat_iv - structure for single hop neighbors
- @tq_recv: ring buffer of received TQ values from this neigh node
- @tq_index: ring buffer index
- @tq_avg: averaged tq of all tq values in the ring buffer (tq_recv)
- @last_ttl: last received ttl from this neigh node
- @bonding_list: list node for batadv_orig_node::bond_list
- @last_seen: when last packet via this neighbor was received
- @real_bits: bitfield containing the number of OGMs received from this neigh
- node (relative to orig_node->last_real_seqno)
- @real_packet_count: counted result of real_bits
- @orig_node: pointer to corresponding orig_node
- @if_incoming: pointer to incoming hard interface
- @lq_update_lock: lock protecting tq_recv & tq_index
- @refcount: number of contexts the object is used
*/
- @rcu: struct used for freeing in an RCU-safe manner
-struct batadv_neigh_node {
- struct hlist_node list;
- uint8_t addr[ETH_ALEN];
+struct batadv_neigh_bat_iv { uint8_t tq_recv[BATADV_TQ_GLOBAL_WINDOW_SIZE]; uint8_t tq_index; uint8_t tq_avg;
- uint8_t last_ttl;
- struct list_head bonding_list;
- unsigned long last_seen; DECLARE_BITMAP(real_bits, BATADV_TQ_LOCAL_WINDOW_SIZE); uint8_t real_packet_count;
- spinlock_t lq_update_lock; /* protects tq_recv & tq_index */
I'd like to suggest to split out struct batadv_neigh_bat_iv in an own struct instead of keeping it in batadv_neigh_node. If you want to keep it there, you should at least do some indendation for the bat_iv specific parts (and maybe also the kernel doc?)
Cheers, Simon
From: Antonio Quartulli antonio@open-mesh.com
some of the struct batadv_orig_node members are B.A.T.M.A.N. IV specific and therefore they are moved in a algorithm specific substruct in order to make batadv_orig_node routing algorithm agnostic
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 93 ++++++++++++++++++++++++++++++++++++++++++------------------ originator.c | 77 ++++++++++++++++++------------------------------- originator.h | 2 +- routing.c | 10 +++++-- types.h | 30 +++++++++++++------- 5 files changed, 121 insertions(+), 91 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index cfa3b1f..595fcb0 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -87,6 +87,42 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) return (uint8_t)(sum / count); }
+static struct batadv_orig_node * +batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr) +{ + struct batadv_orig_node *orig_node; + int size; + + orig_node = batadv_orig_hash_find(bat_priv, addr); + if (orig_node) + return orig_node; + + orig_node = batadv_orig_node_new(bat_priv, addr); + if (!orig_node) + return NULL; + + spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock); + + size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS; + orig_node->bat_iv.bcast_own = kzalloc(size, GFP_ATOMIC); + if (!orig_node->bat_iv.bcast_own) + goto free_orig_node; + + size = bat_priv->num_ifaces * sizeof(uint8_t); + orig_node->bat_iv.bcast_own_sum = kzalloc(size, GFP_ATOMIC); + if (!orig_node->bat_iv.bcast_own_sum) + goto free_bcast_own; + + return orig_node; + +free_bcast_own: + kfree(orig_node->bat_iv.bcast_own); +free_orig_node: + batadv_orig_node_free_ref(orig_node); + + return NULL; +} + static struct batadv_neigh_node * batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, const uint8_t *neigh_addr, @@ -658,20 +694,22 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface) uint32_t i; size_t word_index; uint8_t *w; + int if_num;
for (i = 0; i < hash->size; i++) { head = &hash->table[i];
rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, head, hash_entry) { - spin_lock_bh(&orig_node->ogm_cnt_lock); + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); word_index = hard_iface->if_num * BATADV_NUM_WORDS; - word = &(orig_node->bcast_own[word_index]); + word = &(orig_node->bat_iv.bcast_own[word_index]);
batadv_bit_get_packet(bat_priv, word, 1, 0); - w = &orig_node->bcast_own_sum[hard_iface->if_num]; + if_num = hard_iface->if_num; + w = &orig_node->bat_iv.bcast_own_sum[if_num]; *w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE); - spin_unlock_bh(&orig_node->ogm_cnt_lock); + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); } rcu_read_unlock(); } @@ -763,7 +801,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, if (!neigh_node) { struct batadv_orig_node *orig_tmp;
- orig_tmp = batadv_get_orig_node(bat_priv, ethhdr->h_source); + orig_tmp = batadv_iv_ogm_orig_get(bat_priv, ethhdr->h_source); if (!orig_tmp) goto unlock;
@@ -813,16 +851,16 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, */ if (router && (neigh_node->bat_iv.tq_avg == router->bat_iv.tq_avg)) { orig_node_tmp = router->orig_node; - spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); + spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock); if_num = router->if_incoming->if_num; - sum_orig = orig_node_tmp->bcast_own_sum[if_num]; - spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); + sum_orig = orig_node_tmp->bat_iv.bcast_own_sum[if_num]; + spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
orig_node_tmp = neigh_node->orig_node; - spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); + spin_lock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock); if_num = neigh_node->if_incoming->if_num; - sum_neigh = orig_node_tmp->bcast_own_sum[if_num]; - spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); + sum_neigh = orig_node_tmp->bat_iv.bcast_own_sum[if_num]; + spin_unlock_bh(&orig_node_tmp->bat_iv.ogm_cnt_lock);
if (sum_orig >= sum_neigh) goto out; @@ -850,7 +888,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, uint8_t total_count; uint8_t orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own; unsigned int neigh_rq_inv_cube, neigh_rq_max_cube; - int tq_asym_penalty, inv_asym_penalty, ret = 0; + int tq_asym_penalty, inv_asym_penalty, if_num, ret = 0; unsigned int combined_tq;
/* find corresponding one hop neighbor */ @@ -888,10 +926,11 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, orig_node->last_seen = jiffies;
/* find packet count of corresponding one hop neighbor */ - spin_lock_bh(&orig_node->ogm_cnt_lock); - orig_eq_count = orig_neigh_node->bcast_own_sum[if_incoming->if_num]; + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); + if_num = if_incoming->if_num; + orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; neigh_rq_count = neigh_node->bat_iv.real_packet_count; - spin_unlock_bh(&orig_node->ogm_cnt_lock); + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
/* pay attention to not get a value bigger than 100 % */ if (orig_eq_count > neigh_rq_count) @@ -975,11 +1014,11 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, uint8_t packet_count; unsigned long (*bitmap)[];
- orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); + orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig); if (!orig_node) return BATADV_NO_DUP;
- spin_lock_bh(&orig_node->ogm_cnt_lock); + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); seq_diff = seqno - orig_node->last_real_seqno;
/* signalize caller that the packet is to be dropped. */ @@ -1028,7 +1067,7 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, }
out: - spin_unlock_bh(&orig_node->ogm_cnt_lock); + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); batadv_orig_node_free_ref(orig_node); return ret; } @@ -1124,8 +1163,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, int16_t if_num; uint8_t *weight;
- orig_neigh_node = batadv_get_orig_node(bat_priv, - ethhdr->h_source); + orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, + ethhdr->h_source); if (!orig_neigh_node) return;
@@ -1139,15 +1178,15 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, if_num = if_incoming->if_num; offset = if_num * BATADV_NUM_WORDS;
- spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); - word = &(orig_neigh_node->bcast_own[offset]); + spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); + word = &(orig_neigh_node->bat_iv.bcast_own[offset]); bit_pos = if_incoming_seqno - 2; bit_pos -= ntohl(batadv_ogm_packet->seqno); batadv_set_bit(word, bit_pos); - weight = &orig_neigh_node->bcast_own_sum[if_num]; + weight = &orig_neigh_node->bat_iv.bcast_own_sum[if_num]; *weight = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE); - spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); + spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); }
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, @@ -1170,7 +1209,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, return; }
- orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); + orig_node = batadv_iv_ogm_orig_get(bat_priv, batadv_ogm_packet->orig); if (!orig_node) return;
@@ -1220,8 +1259,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, if (is_single_hop_neigh) orig_neigh_node = orig_node; else - orig_neigh_node = batadv_get_orig_node(bat_priv, - ethhdr->h_source); + orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv, + ethhdr->h_source);
if (!orig_neigh_node) goto out; diff --git a/originator.c b/originator.c index 3837195..ccdb246 100644 --- a/originator.c +++ b/originator.c @@ -235,8 +235,8 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) "originator timed out");
kfree(orig_node->tt_buff); - kfree(orig_node->bcast_own); - kfree(orig_node->bcast_own_sum); + kfree(orig_node->bat_iv.bcast_own); + kfree(orig_node->bat_iv.bcast_own_sum); kfree(orig_node); }
@@ -297,18 +297,13 @@ void batadv_originator_free(struct batadv_priv *bat_priv) /* this function finds or creates an originator entry for the given * address if it does not exits */ -struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, +struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, const uint8_t *addr) { struct batadv_orig_node *orig_node; struct batadv_orig_node_vlan *vlan; - int size, i; - int hash_added; unsigned long reset_time; - - orig_node = batadv_orig_hash_find(bat_priv, addr); - if (orig_node) - return orig_node; + int i, hash_added;
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Creating new originator: %pM\n", addr); @@ -320,7 +315,6 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, INIT_HLIST_HEAD(&orig_node->neigh_list); INIT_LIST_HEAD(&orig_node->bond_list); INIT_LIST_HEAD(&orig_node->vlan_list); - spin_lock_init(&orig_node->ogm_cnt_lock); spin_lock_init(&orig_node->bcast_seqno_lock); spin_lock_init(&orig_node->neigh_list_lock); spin_lock_init(&orig_node->tt_buff_lock); @@ -356,37 +350,21 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, */ batadv_orig_node_vlan_free_ref(vlan);
- size = bat_priv->num_ifaces * sizeof(unsigned long) * BATADV_NUM_WORDS; - - orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); - if (!orig_node->bcast_own) - goto free_vlan; - - size = bat_priv->num_ifaces * sizeof(uint8_t); - orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); - for (i = 0; i < BATADV_FRAG_BUFFER_COUNT; i++) { INIT_HLIST_HEAD(&orig_node->fragments[i].head); spin_lock_init(&orig_node->fragments[i].lock); orig_node->fragments[i].size = 0; }
- if (!orig_node->bcast_own_sum) - goto free_bcast_own; - hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig, batadv_choose_orig, orig_node, &orig_node->hash_entry); - if (hash_added != 0) - goto free_bcast_own_sum; + if (hash_added != 0) { + kfree(orig_node); + return NULL; + }
return orig_node; -free_bcast_own_sum: - kfree(orig_node->bcast_own_sum); -free_bcast_own: - kfree(orig_node->bcast_own); -free_vlan: - batadv_orig_node_vlan_free_ref(vlan); free_orig_node: kfree(orig_node); return NULL; @@ -610,18 +588,18 @@ static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, if (!data_ptr) return -ENOMEM;
- memcpy(data_ptr, orig_node->bcast_own, old_size); - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; + memcpy(data_ptr, orig_node->bat_iv.bcast_own, old_size); + kfree(orig_node->bat_iv.bcast_own); + orig_node->bat_iv.bcast_own = data_ptr;
data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); if (!data_ptr) return -ENOMEM;
- memcpy(data_ptr, orig_node->bcast_own_sum, + memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, (max_if_num - 1) * sizeof(uint8_t)); - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; + kfree(orig_node->bat_iv.bcast_own_sum); + orig_node->bat_iv.bcast_own_sum = data_ptr;
return 0; } @@ -644,9 +622,9 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, head, hash_entry) { - spin_lock_bh(&orig_node->ogm_cnt_lock); + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); ret = batadv_orig_node_add_if(orig_node, max_if_num); - spin_unlock_bh(&orig_node->ogm_cnt_lock); + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
if (ret == -ENOMEM) goto err; @@ -664,8 +642,8 @@ err: static int batadv_orig_node_del_if(struct batadv_orig_node *orig_node, int max_if_num, int del_if_num) { + int chunk_size, if_offset; void *data_ptr = NULL; - int chunk_size;
/* last interface was removed */ if (max_if_num == 0) @@ -677,16 +655,16 @@ static int batadv_orig_node_del_if(struct batadv_orig_node *orig_node, return -ENOMEM;
/* copy first part */ - memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); + memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size);
/* copy second part */ memcpy((char *)data_ptr + del_if_num * chunk_size, - orig_node->bcast_own + ((del_if_num + 1) * chunk_size), + orig_node->bat_iv.bcast_own + ((del_if_num + 1) * chunk_size), (max_if_num - del_if_num) * chunk_size);
free_bcast_own: - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; + kfree(orig_node->bat_iv.bcast_own); + orig_node->bat_iv.bcast_own = data_ptr;
if (max_if_num == 0) goto free_own_sum; @@ -695,16 +673,17 @@ free_bcast_own: if (!data_ptr) return -ENOMEM;
- memcpy(data_ptr, orig_node->bcast_own_sum, + memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, del_if_num * sizeof(uint8_t));
+ if_offset = ((del_if_num + 1) * sizeof(uint8_t)); memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t), - orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), + orig_node->bat_iv.bcast_own_sum + if_offset, (max_if_num - del_if_num) * sizeof(uint8_t));
free_own_sum: - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; + kfree(orig_node->bat_iv.bcast_own_sum); + orig_node->bat_iv.bcast_own_sum = data_ptr;
return 0; } @@ -728,10 +707,10 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, head, hash_entry) { - spin_lock_bh(&orig_node->ogm_cnt_lock); + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); ret = batadv_orig_node_del_if(orig_node, max_if_num, hard_iface->if_num); - spin_unlock_bh(&orig_node->ogm_cnt_lock); + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
if (ret == -ENOMEM) goto err; diff --git a/originator.h b/originator.h index 06e5a68..a765a2f 100644 --- a/originator.h +++ b/originator.h @@ -27,7 +27,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv); void batadv_purge_orig_ref(struct batadv_priv *bat_priv); void batadv_orig_node_free_ref(struct batadv_orig_node *orig_node); void batadv_orig_node_free_ref_now(struct batadv_orig_node *orig_node); -struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, +struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, const uint8_t *addr); struct batadv_neigh_node * batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, diff --git a/routing.c b/routing.c index 99f6844..46de5c7 100644 --- a/routing.c +++ b/routing.c @@ -1075,6 +1075,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, int hdr_size = sizeof(*bcast_packet); int ret = NET_RX_DROP; int32_t seq_diff; + uint32_t seqno;
/* drop packet if it has not necessary minimum size */ if (unlikely(!pskb_may_pull(skb, hdr_size))) @@ -1111,11 +1112,13 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, spin_lock_bh(&orig_node->bcast_seqno_lock);
/* check whether the packet is a duplicate */ - if (batadv_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno, + if (batadv_test_bit(orig_node->bcast_bits, + orig_node->last_bcast_seqno, ntohl(bcast_packet->seqno))) goto spin_unlock;
- seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; + seqno = orig_node->last_bcast_seqno; + seq_diff = ntohl(bcast_packet->seqno) - seqno;
/* check whether the packet is old and the host just restarted. */ if (batadv_window_protected(bat_priv, seq_diff, @@ -1125,7 +1128,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, /* mark broadcast in flood history, update window position * if required. */ - if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) + if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, + seq_diff, 1)) orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
spin_unlock_bh(&orig_node->bcast_seqno_lock); diff --git a/types.h b/types.h index 0088a53..0c0d999 100644 --- a/types.h +++ b/types.h @@ -133,14 +133,28 @@ struct batadv_orig_node_vlan { };
/** + * struct batadv_orig_bat_iv - B.A.T.M.A.N. IV private orig_node members + * @bcast_own: bitfield containing the number of our OGMs this orig_node + * rebroadcasted "back" to us (relative to last_real_seqno) + * @bcast_own_sum: counted result of bcast_own + * @ogm_cnt_lock: lock protecting bcast_own, bcast_own_sum, + * neigh_node->real_bits & neigh_node->real_packet_count + */ +struct batadv_orig_bat_iv { + unsigned long *bcast_own; + uint8_t *bcast_own_sum; + /* ogm_cnt_lock protects: bcast_own, bcast_own_sum, + * neigh_node->real_bits & neigh_node->real_packet_count + */ + spinlock_t ogm_cnt_lock; +}; + +/** * struct batadv_orig_node - structure for orig_list maintaining nodes of mesh * @orig: originator ethernet address * @primary_addr: hosts primary interface address * @router: router that should be used to reach this originator * @batadv_dat_addr_t: address of the orig node in the distributed hash - * @bcast_own: bitfield containing the number of our OGMs this orig_node - * rebroadcasted "back" to us (relative to last_real_seqno) - * @bcast_own_sum: counted result of bcast_own * @last_seen: time when last packet from this node was received * @bcast_seqno_reset: time when the broadcast seqno window was reset * @batman_seqno_reset: time when the batman seqno window was reset @@ -166,8 +180,6 @@ struct batadv_orig_node_vlan { * @neigh_list_lock: lock protecting neigh_list, router and bonding_list * @hash_entry: hlist node for batadv_priv::orig_hash * @bat_priv: pointer to soft_iface this orig node belongs to - * @ogm_cnt_lock: lock protecting bcast_own, bcast_own_sum, - * neigh_node->real_bits & neigh_node->real_packet_count * @bcast_seqno_lock: lock protecting bcast_bits & last_bcast_seqno * @bond_candidates: how many candidates are available * @bond_list: list of bonding candidates @@ -181,6 +193,7 @@ struct batadv_orig_node_vlan { * @vlan_list: a list of orig_node_vlan structs, one per VLAN served by the * originator represented by this object * @vlan_list_lock: lock protecting vlan_list + * @bat_iv: B.A.T.M.A.N. IV private structure */ struct batadv_orig_node { uint8_t orig[ETH_ALEN]; @@ -189,8 +202,6 @@ struct batadv_orig_node { #ifdef CONFIG_BATMAN_ADV_DAT batadv_dat_addr_t dat_addr; #endif - unsigned long *bcast_own; - uint8_t *bcast_own_sum; unsigned long last_seen; unsigned long bcast_seqno_reset; unsigned long batman_seqno_reset; @@ -211,10 +222,6 @@ struct batadv_orig_node { spinlock_t neigh_list_lock; struct hlist_node hash_entry; struct batadv_priv *bat_priv; - /* ogm_cnt_lock protects: bcast_own, bcast_own_sum, - * neigh_node->real_bits & neigh_node->real_packet_count - */ - spinlock_t ogm_cnt_lock; /* bcast_seqno_lock protects: bcast_bits & last_bcast_seqno */ spinlock_t bcast_seqno_lock; atomic_t bond_candidates; @@ -230,6 +237,7 @@ struct batadv_orig_node { struct batadv_frag_table_entry fragments[BATADV_FRAG_BUFFER_COUNT]; struct list_head vlan_list; spinlock_t vlan_list_lock; /* protects vlan_list */ + struct batadv_orig_bat_iv bat_iv; };
/**
On Wed, Jul 31, 2013 at 10:47:39PM +0200, Antonio Quartulli wrote:
/* check whether the packet is a duplicate */
- if (batadv_test_bit(orig_node->bcast_bits, orig_node->last_bcast_seqno,
- if (batadv_test_bit(orig_node->bcast_bits,
orig_node->last_bcast_seqno,
Is this change really neccesary? Looks rather random to me. :)
ntohl(bcast_packet->seqno))) goto spin_unlock;
- seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
- seqno = orig_node->last_bcast_seqno;
- seq_diff = ntohl(bcast_packet->seqno) - seqno;
Same here ... you are not using the seqno variable below, are you?
/* check whether the packet is old and the host just restarted. */ if (batadv_window_protected(bat_priv, seq_diff, @@ -1125,7 +1128,8 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, /* mark broadcast in flood history, update window position * if required. */
- if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1))
- if (batadv_bit_get_packet(bat_priv, orig_node->bcast_bits,
seq_diff, 1))
... same here.
orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
spin_unlock_bh(&orig_node->bcast_seqno_lock); diff --git a/types.h b/types.h index 0088a53..0c0d999 100644 --- a/types.h +++ b/types.h @@ -133,14 +133,28 @@ struct batadv_orig_node_vlan { };
/**
- struct batadv_orig_bat_iv - B.A.T.M.A.N. IV private orig_node members
- @bcast_own: bitfield containing the number of our OGMs this orig_node
- rebroadcasted "back" to us (relative to last_real_seqno)
- @bcast_own_sum: counted result of bcast_own
- @ogm_cnt_lock: lock protecting bcast_own, bcast_own_sum,
- neigh_node->real_bits & neigh_node->real_packet_count
Hmm, neigh_node is not part of this structure, please change the reference (if it's actually still protecting things).
From: Antonio Quartulli antonio@open-mesh.com
Each routing protocol has its own metric and private variables, therefore it is useful to introduce a new API for originator information printing.
This API needs to be implemented by each protocol in order to provide its specific originator table output.
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ originator.c | 66 +++++++++-------------------------------------------------- types.h | 3 +++ 3 files changed, 80 insertions(+), 56 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 595fcb0..605c954 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1391,6 +1391,72 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, return NET_RX_SUCCESS; }
+/** + * batadv_iv_ogm_orig_print - print the originator table + * @bat_priv: the bat priv with all the soft interface information + * @seq: debugfs table seq_file struct + */ +static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv, + struct seq_file *seq) +{ + struct batadv_hashtable *hash = bat_priv->orig_hash; + struct hlist_head *head; + struct batadv_orig_node *orig_node; + struct batadv_neigh_node *neigh_node, *neigh_node_tmp; + int batman_count = 0; + int last_seen_secs; + int last_seen_msecs; + unsigned long last_seen_jiffies; + uint32_t i; + + + seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", + "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE, + "Nexthop", "outgoingIF", "Potential nexthops"); + + for (i = 0; i < hash->size; i++) { + head = &hash->table[i]; + + rcu_read_lock(); + hlist_for_each_entry_rcu(orig_node, head, hash_entry) { + neigh_node = batadv_orig_node_get_router(orig_node); + if (!neigh_node) + continue; + + if (neigh_node->bat_iv.tq_avg == 0) + goto next; + + last_seen_jiffies = jiffies - orig_node->last_seen; + last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); + last_seen_secs = last_seen_msecs / 1000; + last_seen_msecs = last_seen_msecs % 1000; + + seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", + orig_node->orig, last_seen_secs, + last_seen_msecs, neigh_node->bat_iv.tq_avg, + neigh_node->addr, + neigh_node->if_incoming->net_dev->name); + + hlist_for_each_entry_rcu(neigh_node_tmp, + &orig_node->neigh_list, list) { + seq_printf(seq, " %pM (%3i)", + neigh_node_tmp->addr, + neigh_node_tmp->bat_iv.tq_avg); + } + + seq_puts(seq, "\n"); + batman_count++; + +next: + batadv_neigh_node_free_ref(neigh_node); + } + rcu_read_unlock(); + } + + if (batman_count == 0) + seq_puts(seq, "No batman nodes in range ...\n"); +} + static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", .bat_iface_enable = batadv_iv_ogm_iface_enable, @@ -1399,6 +1465,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set, .bat_ogm_schedule = batadv_iv_ogm_schedule, .bat_ogm_emit = batadv_iv_ogm_emit, + .bat_orig_print = batadv_iv_ogm_orig_print, };
int __init batadv_iv_init(void) diff --git a/originator.c b/originator.c index ccdb246..b3f6910 100644 --- a/originator.c +++ b/originator.c @@ -506,73 +506,27 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) { struct net_device *net_dev = (struct net_device *)seq->private; struct batadv_priv *bat_priv = netdev_priv(net_dev); - struct batadv_hashtable *hash = bat_priv->orig_hash; - struct hlist_head *head; struct batadv_hard_iface *primary_if; - struct batadv_orig_node *orig_node; - struct batadv_neigh_node *neigh_node, *neigh_node_tmp; - int batman_count = 0; - int last_seen_secs; - int last_seen_msecs; - unsigned long last_seen_jiffies; - uint32_t i;
primary_if = batadv_seq_print_text_primary_if_get(seq); if (!primary_if) - goto out; + return 0;
- seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s)]\n", + seq_printf(seq, "[B.A.T.M.A.N. adv %s, MainIF/MAC: %s/%pM (%s %s)]\n", BATADV_SOURCE_VERSION, primary_if->net_dev->name, - primary_if->net_dev->dev_addr, net_dev->name); - seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", - "Originator", "last-seen", "#", BATADV_TQ_MAX_VALUE, - "Nexthop", "outgoingIF", "Potential nexthops"); - - for (i = 0; i < hash->size; i++) { - head = &hash->table[i]; - - rcu_read_lock(); - hlist_for_each_entry_rcu(orig_node, head, hash_entry) { - neigh_node = batadv_orig_node_get_router(orig_node); - if (!neigh_node) - continue; - - if (neigh_node->bat_iv.tq_avg == 0) - goto next; - - last_seen_jiffies = jiffies - orig_node->last_seen; - last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); - last_seen_secs = last_seen_msecs / 1000; - last_seen_msecs = last_seen_msecs % 1000; - - seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", - orig_node->orig, last_seen_secs, - last_seen_msecs, neigh_node->bat_iv.tq_avg, - neigh_node->addr, - neigh_node->if_incoming->net_dev->name); - - hlist_for_each_entry_rcu(neigh_node_tmp, - &orig_node->neigh_list, list) { - seq_printf(seq, " %pM (%3i)", - neigh_node_tmp->addr, - neigh_node_tmp->bat_iv.tq_avg); - } + primary_if->net_dev->dev_addr, net_dev->name, + bat_priv->bat_algo_ops->name);
- seq_puts(seq, "\n"); - batman_count++; + batadv_hardif_free_ref(primary_if);
-next: - batadv_neigh_node_free_ref(neigh_node); - } - rcu_read_unlock(); + if (!bat_priv->bat_algo_ops->bat_orig_print) { + seq_puts(seq, + "No printing function for this routing protocol\n"); + return 0; }
- if (batman_count == 0) - seq_puts(seq, "No batman nodes in range ...\n"); + bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq);
-out: - if (primary_if) - batadv_hardif_free_ref(primary_if); return 0; }
diff --git a/types.h b/types.h index 0c0d999..bff1668 100644 --- a/types.h +++ b/types.h @@ -991,6 +991,7 @@ struct batadv_forw_packet { * @bat_primary_iface_set: called when primary interface is selected / changed * @bat_ogm_schedule: prepare a new outgoing OGM for the send queue * @bat_ogm_emit: send scheduled OGM + * @bat_orig_print: print the originator table */ struct batadv_algo_ops { struct hlist_node list; @@ -1001,6 +1002,8 @@ struct batadv_algo_ops { void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface); void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface); void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); + /* orig_node handling API */ + void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq); };
/**
On Wed, Jul 31, 2013 at 10:47:40PM +0200, Antonio Quartulli wrote:
From: Antonio Quartulli antonio@open-mesh.com
Each routing protocol has its own metric and private variables, therefore it is useful to introduce a new API for originator information printing.
This API needs to be implemented by each protocol in order to provide its specific originator table output.
Signed-off-by: Antonio Quartulli antonio@open-mesh.com
bat_iv_ogm.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ originator.c | 66 +++++++++-------------------------------------------------- types.h | 3 +++ 3 files changed, 80 insertions(+), 56 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 595fcb0..605c954 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1391,6 +1391,72 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, return NET_RX_SUCCESS; }
+/**
- batadv_iv_ogm_orig_print - print the originator table
- @bat_priv: the bat priv with all the soft interface information
- @seq: debugfs table seq_file struct
- */
+static void batadv_iv_ogm_orig_print(struct batadv_priv *bat_priv,
struct seq_file *seq)
+{
- struct batadv_hashtable *hash = bat_priv->orig_hash;
- struct hlist_head *head;
- struct batadv_orig_node *orig_node;
- struct batadv_neigh_node *neigh_node, *neigh_node_tmp;
- int batman_count = 0;
- int last_seen_secs;
- int last_seen_msecs;
- unsigned long last_seen_jiffies;
- uint32_t i;
unneccesary double newline?
Rest looks good.
From: Antonio Quartulli antonio@open-mesh.com
Each routing algorithm may store its metric value in a different place, therefore a new API function is needed in order to ask the algorithm to return the metric of a given originator
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 9 +++++++++ main.c | 3 ++- types.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 605c954..32e0321 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1457,6 +1457,14 @@ next: seq_puts(seq, "No batman nodes in range ...\n"); }
+static uint32_t batadv_iv_ogm_metric_get(struct batadv_neigh_node *neigh_node) +{ + if (!neigh_node) + return 0; + + return neigh_node->bat_iv.tq_avg; +} + static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", .bat_iface_enable = batadv_iv_ogm_iface_enable, @@ -1465,6 +1473,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .bat_primary_iface_set = batadv_iv_ogm_primary_iface_set, .bat_ogm_schedule = batadv_iv_ogm_schedule, .bat_ogm_emit = batadv_iv_ogm_emit, + .bat_metric_get = batadv_iv_ogm_metric_get, .bat_orig_print = batadv_iv_ogm_orig_print, };
diff --git a/main.c b/main.c index 46adf68..cc75126 100644 --- a/main.c +++ b/main.c @@ -445,7 +445,8 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops) !bat_algo_ops->bat_iface_update_mac || !bat_algo_ops->bat_primary_iface_set || !bat_algo_ops->bat_ogm_schedule || - !bat_algo_ops->bat_ogm_emit) { + !bat_algo_ops->bat_ogm_emit || + !bat_algo_ops->bat_metric_get) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); ret = -EINVAL; diff --git a/types.h b/types.h index bff1668..e994fe0 100644 --- a/types.h +++ b/types.h @@ -1002,6 +1002,7 @@ struct batadv_algo_ops { void (*bat_primary_iface_set)(struct batadv_hard_iface *hard_iface); void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface); void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); + uint32_t (*bat_metric_get)(struct batadv_neigh_node *neigh_node); /* orig_node handling API */ void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq); };
From: Antonio Quartulli antonio@open-mesh.com
Each routing protocol has its own metric semantic and therefore is the protocol itself the only component able to compare two metrics to check similarity similarity.
This new API allows each routing protocol to implement its own logic and make the external code protocol agnostic.
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 6 ++++++ main.c | 3 ++- main.h | 6 ++++++ types.h | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 32e0321..2e03fdb 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1465,6 +1465,11 @@ static uint32_t batadv_iv_ogm_metric_get(struct batadv_neigh_node *neigh_node) return neigh_node->bat_iv.tq_avg; }
+static bool batadv_iv_ogm_metric_is_eob(uint32_t metric, uint32_t new_metric) +{ + return (metric - new_metric < BATADV_TQ_SIMILARITY_THRESHOLD); +} + static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", .bat_iface_enable = batadv_iv_ogm_iface_enable, @@ -1474,6 +1479,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .bat_ogm_schedule = batadv_iv_ogm_schedule, .bat_ogm_emit = batadv_iv_ogm_emit, .bat_metric_get = batadv_iv_ogm_metric_get, + .bat_metric_is_equiv_or_better = batadv_iv_ogm_metric_is_eob, .bat_orig_print = batadv_iv_ogm_orig_print, };
diff --git a/main.c b/main.c index cc75126..d263a42 100644 --- a/main.c +++ b/main.c @@ -446,7 +446,8 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops) !bat_algo_ops->bat_primary_iface_set || !bat_algo_ops->bat_ogm_schedule || !bat_algo_ops->bat_ogm_emit || - !bat_algo_ops->bat_metric_get) { + !bat_algo_ops->bat_metric_get || + !bat_algo_ops->bat_metric_is_equiv_or_better) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); ret = -EINVAL; diff --git a/main.h b/main.h index 7b68db9..9b365ad 100644 --- a/main.h +++ b/main.h @@ -86,6 +86,12 @@ /* numbers of originator to contact for any PUT/GET DHT operation */ #define BATADV_DAT_CANDIDATES_NUM 3
+/** + * BATADV_TQ_SIMILARITY_THRESHOLD - TQ points that a secondary metric can differ + * at most from the primary one in order to be still considered acceptable + */ +#define BATADV_TQ_SIMILARITY_THRESHOLD 50 + /* how much worse secondary interfaces may be to be considered as bonding * candidates */ diff --git a/types.h b/types.h index e994fe0..8885dc0 100644 --- a/types.h +++ b/types.h @@ -991,6 +991,8 @@ struct batadv_forw_packet { * @bat_primary_iface_set: called when primary interface is selected / changed * @bat_ogm_schedule: prepare a new outgoing OGM for the send queue * @bat_ogm_emit: send scheduled OGM + * @bat_metric_is_equiv_or_better: check if new_metric is good enough to be + * comparable with metric * @bat_orig_print: print the originator table */ struct batadv_algo_ops { @@ -1003,6 +1005,8 @@ struct batadv_algo_ops { void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface); void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); uint32_t (*bat_metric_get)(struct batadv_neigh_node *neigh_node); + bool (*bat_metric_is_equiv_or_better)(uint32_t metric, + uint32_t new_metric); /* orig_node handling API */ void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq); };
On Wed, Jul 31, 2013 at 10:47:42PM +0200, Antonio Quartulli wrote:
From: Antonio Quartulli antonio@open-mesh.com
Each routing protocol has its own metric semantic and therefore is the protocol itself the only component able to compare two metrics to check similarity similarity.
This new API allows each routing protocol to implement its own logic and make the external code protocol agnostic.
Signed-off-by: Antonio Quartulli antonio@open-mesh.com
bat_iv_ogm.c | 6 ++++++ main.c | 3 ++- main.h | 6 ++++++ types.h | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 32e0321..2e03fdb 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1465,6 +1465,11 @@ static uint32_t batadv_iv_ogm_metric_get(struct batadv_neigh_node *neigh_node) return neigh_node->bat_iv.tq_avg; }
+static bool batadv_iv_ogm_metric_is_eob(uint32_t metric, uint32_t new_metric) +{
- return (metric - new_metric < BATADV_TQ_SIMILARITY_THRESHOLD);
+}
Since it's static anyway, maybe call this function batadv_iv_ogm_metric_is_equiv_or_better instead? eob looks so ... random. :) Also, maybe use BATADV_IV_TQ_SIMILARITY_THRESHOLD? Although TQ somehow implies BATADV_IV ...
static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", .bat_iface_enable = batadv_iv_ogm_iface_enable, @@ -1474,6 +1479,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .bat_ogm_schedule = batadv_iv_ogm_schedule, .bat_ogm_emit = batadv_iv_ogm_emit, .bat_metric_get = batadv_iv_ogm_metric_get,
- .bat_metric_is_equiv_or_better = batadv_iv_ogm_metric_is_eob, .bat_orig_print = batadv_iv_ogm_orig_print,
};
diff --git a/main.c b/main.c index cc75126..d263a42 100644 --- a/main.c +++ b/main.c @@ -446,7 +446,8 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops) !bat_algo_ops->bat_primary_iface_set || !bat_algo_ops->bat_ogm_schedule || !bat_algo_ops->bat_ogm_emit ||
!bat_algo_ops->bat_metric_get) {
!bat_algo_ops->bat_metric_get ||
pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); ret = -EINVAL;!bat_algo_ops->bat_metric_is_equiv_or_better) {
diff --git a/main.h b/main.h index 7b68db9..9b365ad 100644 --- a/main.h +++ b/main.h @@ -86,6 +86,12 @@ /* numbers of originator to contact for any PUT/GET DHT operation */ #define BATADV_DAT_CANDIDATES_NUM 3
+/**
- BATADV_TQ_SIMILARITY_THRESHOLD - TQ points that a secondary metric can differ
- at most from the primary one in order to be still considered acceptable
- */
+#define BATADV_TQ_SIMILARITY_THRESHOLD 50
/* how much worse secondary interfaces may be to be considered as bonding
- candidates
*/ diff --git a/types.h b/types.h index e994fe0..8885dc0 100644 --- a/types.h +++ b/types.h @@ -991,6 +991,8 @@ struct batadv_forw_packet {
- @bat_primary_iface_set: called when primary interface is selected / changed
- @bat_ogm_schedule: prepare a new outgoing OGM for the send queue
- @bat_ogm_emit: send scheduled OGM
- @bat_metric_is_equiv_or_better: check if new_metric is good enough to be
*/
- comparable with metric
- @bat_orig_print: print the originator table
struct batadv_algo_ops { @@ -1003,6 +1005,8 @@ struct batadv_algo_ops { void (*bat_ogm_schedule)(struct batadv_hard_iface *hard_iface); void (*bat_ogm_emit)(struct batadv_forw_packet *forw_packet); uint32_t (*bat_metric_get)(struct batadv_neigh_node *neigh_node);
- bool (*bat_metric_is_equiv_or_better)(uint32_t metric,
/* orig_node handling API */ void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq);uint32_t new_metric);
};
1.8.1.5
On Sat, Aug 03, 2013 at 11:10:07PM +0200, Simon Wunderlich wrote:
+static bool batadv_iv_ogm_metric_is_eob(uint32_t metric, uint32_t new_metric) +{
- return (metric - new_metric < BATADV_TQ_SIMILARITY_THRESHOLD);
+}
Since it's static anyway, maybe call this function batadv_iv_ogm_metric_is_equiv_or_better instead? eob
if I use batadv_iv_ogm_metric_is_equiv_or_better than I have problems wit hthe assignment of the ops member later...line toooo long :) This is why I chose that name.
looks so ... random. :) Also, maybe use BATADV_IV_TQ_SIMILARITY_THRESHOLD? Although TQ somehow implies BATADV_IV ...
I don't think it is correct. Metric is separated from the algorithm and and this define belongs to the metric. In the future we may have B.A.T.M.A.N. X which wants to use the TQ again..at that point it should (re-)use all the constants we already have.
Cheers,
From: Antonio Quartulli antonio@open-mesh.com
Add an API function to allow the routing protocol to implement its own metric sorting logic.
In this way each routing protocol can play with its metric semantic without exposing any detail to the rest of the code.
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 14 ++++++++++++++ main.c | 3 ++- types.h | 3 +++ 3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index 2e03fdb..a05dd3a 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -1470,6 +1470,19 @@ static bool batadv_iv_ogm_metric_is_eob(uint32_t metric, uint32_t new_metric) return (metric - new_metric < BATADV_TQ_SIMILARITY_THRESHOLD); }
+/** + * batadv_iv_ogm_metric_compare - implement the bat_metric_compare API + * @metric1: the first metric to compare + * @metric2: the second metric to compare + * + * Return a value smaller, equal or greater than zero if metric1 is respectively + * smaller, equal or greater than metric2 + */ +static int batadv_iv_ogm_metric_compare(uint32_t metric1, uint32_t metric2) +{ + return metric1 - metric2; +} + static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .name = "BATMAN_IV", .bat_iface_enable = batadv_iv_ogm_iface_enable, @@ -1480,6 +1493,7 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .bat_ogm_emit = batadv_iv_ogm_emit, .bat_metric_get = batadv_iv_ogm_metric_get, .bat_metric_is_equiv_or_better = batadv_iv_ogm_metric_is_eob, + .bat_metric_compare = batadv_iv_ogm_metric_compare, .bat_orig_print = batadv_iv_ogm_orig_print, };
diff --git a/main.c b/main.c index d263a42..8bc353b 100644 --- a/main.c +++ b/main.c @@ -447,7 +447,8 @@ int batadv_algo_register(struct batadv_algo_ops *bat_algo_ops) !bat_algo_ops->bat_ogm_schedule || !bat_algo_ops->bat_ogm_emit || !bat_algo_ops->bat_metric_get || - !bat_algo_ops->bat_metric_is_equiv_or_better) { + !bat_algo_ops->bat_metric_is_equiv_or_better || + !bat_algo_ops->bat_metric_compare) { pr_info("Routing algo '%s' does not implement required ops\n", bat_algo_ops->name); ret = -EINVAL; diff --git a/types.h b/types.h index 8885dc0..516d30d 100644 --- a/types.h +++ b/types.h @@ -993,6 +993,8 @@ struct batadv_forw_packet { * @bat_ogm_emit: send scheduled OGM * @bat_metric_is_equiv_or_better: check if new_metric is good enough to be * comparable with metric + * with metric + * @bat_metric_compare: compare two metric values * @bat_orig_print: print the originator table */ struct batadv_algo_ops { @@ -1007,6 +1009,7 @@ struct batadv_algo_ops { uint32_t (*bat_metric_get)(struct batadv_neigh_node *neigh_node); bool (*bat_metric_is_equiv_or_better)(uint32_t metric, uint32_t new_metric); + int (*bat_metric_compare)(uint32_t metric, uint32_t new_metric); /* orig_node handling API */ void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq); };
On Wed, Jul 31, 2013 at 10:47:43PM +0200, Antonio Quartulli wrote:
diff --git a/types.h b/types.h index 8885dc0..516d30d 100644 --- a/types.h +++ b/types.h @@ -993,6 +993,8 @@ struct batadv_forw_packet {
- @bat_ogm_emit: send scheduled OGM
- @bat_metric_is_equiv_or_better: check if new_metric is good enough to be
- comparable with metric
- with metric
???
*/
- @bat_metric_compare: compare two metric values
- @bat_orig_print: print the originator table
struct batadv_algo_ops { @@ -1007,6 +1009,7 @@ struct batadv_algo_ops { uint32_t (*bat_metric_get)(struct batadv_neigh_node *neigh_node); bool (*bat_metric_is_equiv_or_better)(uint32_t metric, uint32_t new_metric);
- int (*bat_metric_compare)(uint32_t metric, uint32_t new_metric); /* orig_node handling API */ void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq);
};
1.8.1.5
From: Antonio Quartulli antonio@open-mesh.com
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 2 +- routing.c | 24 +++++++++++++++++------- routing.h | 3 ++- 3 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index a05dd3a..dc31039 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -833,7 +833,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, neigh_node->last_ttl = batadv_ogm_packet->header.ttl; }
- batadv_bonding_candidate_add(orig_node, neigh_node); + batadv_bonding_candidate_add(bat_priv, orig_node, neigh_node);
/* if this neighbor already is our next hop there is nothing * to change diff --git a/routing.c b/routing.c index 46de5c7..e06045f 100644 --- a/routing.c +++ b/routing.c @@ -115,11 +115,14 @@ out: return; }
-void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node, +void batadv_bonding_candidate_add(struct batadv_priv *bat_priv, + struct batadv_orig_node *orig_node, struct batadv_neigh_node *neigh_node) { + struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; struct batadv_neigh_node *tmp_neigh_node, *router = NULL; uint8_t interference_candidate = 0; + uint32_t router_metric, neigh_metric;
spin_lock_bh(&orig_node->neigh_list_lock);
@@ -133,8 +136,9 @@ void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node, goto candidate_del;
/* ... and is good enough to be considered */ - if (neigh_node->bat_iv.tq_avg < - router->bat_iv.tq_avg - BATADV_BONDING_TQ_THRESHOLD) + router_metric = bao->bat_metric_get(router); + neigh_metric = bao->bat_metric_get(neigh_node); + if (bao->bat_metric_is_equiv_or_better(neigh_metric, router_metric)) goto candidate_del;
/* check if we have another candidate with the same mac address or @@ -486,11 +490,14 @@ out: * Increases the returned router's refcount */ static struct batadv_neigh_node * -batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, +batadv_find_ifalter_router(struct batadv_priv *bat_priv, + struct batadv_orig_node *primary_orig, const struct batadv_hard_iface *recv_if) { - struct batadv_neigh_node *tmp_neigh_node; struct batadv_neigh_node *router = NULL, *first_candidate = NULL; + struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; + struct batadv_neigh_node *tmp_neigh_node; + uint32_t tmp_metric, router_metric;
rcu_read_lock(); list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list, @@ -502,8 +509,9 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, if (tmp_neigh_node->if_incoming == recv_if) continue;
+ tmp_metric = bao->bat_metric_get(tmp_neigh_node); if (router && - tmp_neigh_node->bat_iv.tq_avg <= router->bat_iv.tq_avg) + bao->bat_metric_compare(tmp_metric, router_metric) <= 0) continue;
if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) @@ -515,6 +523,7 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig,
/* we found a better router (or at least one valid router) */ router = tmp_neigh_node; + router_metric = bao->bat_metric_get(router); }
/* use the first candidate if nothing was found. */ @@ -637,7 +646,8 @@ batadv_find_router(struct batadv_priv *bat_priv, if (bonding_enabled) router = batadv_find_bond_router(primary_orig_node, recv_if); else - router = batadv_find_ifalter_router(primary_orig_node, recv_if); + router = batadv_find_ifalter_router(bat_priv, primary_orig_node, + recv_if);
return_router: if (router && router->if_incoming->if_status != BATADV_IF_ACTIVE) diff --git a/routing.h b/routing.h index 55d637a..19544dd 100644 --- a/routing.h +++ b/routing.h @@ -48,7 +48,8 @@ batadv_find_router(struct batadv_priv *bat_priv, const struct batadv_hard_iface *recv_if); void batadv_bonding_candidate_del(struct batadv_orig_node *orig_node, struct batadv_neigh_node *neigh_node); -void batadv_bonding_candidate_add(struct batadv_orig_node *orig_node, +void batadv_bonding_candidate_add(struct batadv_priv *bat_priv, + struct batadv_orig_node *orig_node, struct batadv_neigh_node *neigh_node); void batadv_bonding_save_primary(const struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_neigh_node,
From: Antonio Quartulli antonio@open-mesh.com
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- originator.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/originator.c b/originator.c index b3f6910..8f96041 100644 --- a/originator.c +++ b/originator.c @@ -380,6 +380,8 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, bool neigh_purged = false; unsigned long last_seen; struct batadv_hard_iface *if_incoming; + struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; + uint32_t neigh_metric, best_metric;
*best_neigh_node = NULL;
@@ -414,10 +416,13 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv, batadv_bonding_candidate_del(orig_node, neigh_node); batadv_neigh_node_free_ref(neigh_node); } else { - if ((!*best_neigh_node) || - (neigh_node->bat_iv.tq_avg > - (*best_neigh_node)->bat_iv.tq_avg)) + neigh_metric = bao->bat_metric_get(neigh_node); + if (!*best_neigh_node || + bao->bat_metric_compare(neigh_metric, + best_metric) > 0) { *best_neigh_node = neigh_node; + best_metric = bao->bat_metric_get(neigh_node); + } } }
From: Antonio Quartulli antonio@open-mesh.com
Some operations executed on an orig_node depends on the current routing algorithm being used. To easily make this mechanism routing algorithm agnostic add a orig_node specific API that each algorithm can populate with its own routines.
Such routines are then invoked by the code when needed, without knowing which routing algorithm is currently in use
With this patch 3 API functions are added: - orig_free (to free routing depending internal structs) - orig_add_if (to change the inner state of an orig_node when a new hard interface is added) - orig_del_if (to change the inner state of an orig_node when an hard interface is removed)
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- bat_iv_ogm.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ originator.c | 102 ++++++++------------------------------------------------- types.h | 5 +++ 3 files changed, 123 insertions(+), 88 deletions(-)
diff --git a/bat_iv_ogm.c b/bat_iv_ogm.c index dc31039..fa1eee5 100644 --- a/bat_iv_ogm.c +++ b/bat_iv_ogm.c @@ -87,6 +87,107 @@ static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]) return (uint8_t)(sum / count); }
+static void batadv_iv_ogm_orig_free(struct batadv_orig_node *orig_node) +{ + kfree(orig_node->bat_iv.bcast_own); + kfree(orig_node->bat_iv.bcast_own_sum); +} + +static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node, + int max_if_num) +{ + void *data_ptr; + size_t data_size, old_size; + int ret = -ENOMEM; + + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); + + data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS; + old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS; + data_ptr = kmalloc(data_size, GFP_ATOMIC); + if (!data_ptr) + goto unlock; + + memcpy(data_ptr, orig_node->bat_iv.bcast_own, old_size); + kfree(orig_node->bat_iv.bcast_own); + orig_node->bat_iv.bcast_own = data_ptr; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + kfree(orig_node->bat_iv.bcast_own); + goto unlock; + } + + memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, + (max_if_num - 1) * sizeof(uint8_t)); + kfree(orig_node->bat_iv.bcast_own_sum); + orig_node->bat_iv.bcast_own_sum = data_ptr; + + ret = 0; + +unlock: + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); + + return ret; +} + +static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node, + int max_if_num, int del_if_num) +{ + int chunk_size, ret = -ENOMEM, if_offset; + void *data_ptr = NULL; + + spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); + + /* last interface was removed */ + if (max_if_num == 0) + goto free_bcast_own; + + chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS; + data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); + if (!data_ptr) + goto unlock; + + /* copy first part */ + memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size); + + /* copy second part */ + memcpy((char *)data_ptr + del_if_num * chunk_size, + orig_node->bat_iv.bcast_own + ((del_if_num + 1) * chunk_size), + (max_if_num - del_if_num) * chunk_size); + +free_bcast_own: + kfree(orig_node->bat_iv.bcast_own); + orig_node->bat_iv.bcast_own = data_ptr; + + if (max_if_num == 0) + goto free_own_sum; + + data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); + if (!data_ptr) { + kfree(orig_node->bat_iv.bcast_own); + goto unlock; + } + + memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, + del_if_num * sizeof(uint8_t)); + + if_offset = ((del_if_num + 1) * sizeof(uint8_t)); + memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t), + orig_node->bat_iv.bcast_own_sum + if_offset, + (max_if_num - del_if_num) * sizeof(uint8_t)); + +free_own_sum: + kfree(orig_node->bat_iv.bcast_own_sum); + orig_node->bat_iv.bcast_own_sum = data_ptr; + + ret = 0; +unlock: + spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); + + return ret; +} + static struct batadv_orig_node * batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const uint8_t *addr) { @@ -1495,6 +1596,9 @@ static struct batadv_algo_ops batadv_batman_iv __read_mostly = { .bat_metric_is_equiv_or_better = batadv_iv_ogm_metric_is_eob, .bat_metric_compare = batadv_iv_ogm_metric_compare, .bat_orig_print = batadv_iv_ogm_orig_print, + .bat_orig_free = batadv_iv_ogm_orig_free, + .bat_orig_add_if = batadv_iv_ogm_orig_add_if, + .bat_orig_del_if = batadv_iv_ogm_orig_del_if, };
int __init batadv_iv_init(void) diff --git a/originator.c b/originator.c index 8f96041..3a8fd4f 100644 --- a/originator.c +++ b/originator.c @@ -234,9 +234,10 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu) batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1, "originator timed out");
+ if (orig_node->bat_priv->bat_algo_ops->bat_orig_free) + orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node); + kfree(orig_node->tt_buff); - kfree(orig_node->bat_iv.bcast_own); - kfree(orig_node->bat_iv.bcast_own_sum); kfree(orig_node); }
@@ -535,38 +536,11 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset) return 0; }
-static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node, - int max_if_num) -{ - void *data_ptr; - size_t data_size, old_size; - - data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS; - old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS; - data_ptr = kmalloc(data_size, GFP_ATOMIC); - if (!data_ptr) - return -ENOMEM; - - memcpy(data_ptr, orig_node->bat_iv.bcast_own, old_size); - kfree(orig_node->bat_iv.bcast_own); - orig_node->bat_iv.bcast_own = data_ptr; - - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) - return -ENOMEM; - - memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, - (max_if_num - 1) * sizeof(uint8_t)); - kfree(orig_node->bat_iv.bcast_own_sum); - orig_node->bat_iv.bcast_own_sum = data_ptr; - - return 0; -} - int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, int max_if_num) { struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); + struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; struct batadv_hashtable *hash = bat_priv->orig_hash; struct hlist_head *head; struct batadv_orig_node *orig_node; @@ -581,10 +555,10 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, head, hash_entry) { - spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); - ret = batadv_orig_node_add_if(orig_node, max_if_num); - spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); - + ret = 0; + if (bao->bat_orig_add_if) + ret = bao->bat_orig_add_if(orig_node, + max_if_num); if (ret == -ENOMEM) goto err; } @@ -598,55 +572,6 @@ err: return -ENOMEM; }
-static int batadv_orig_node_del_if(struct batadv_orig_node *orig_node, - int max_if_num, int del_if_num) -{ - int chunk_size, if_offset; - void *data_ptr = NULL; - - /* last interface was removed */ - if (max_if_num == 0) - goto free_bcast_own; - - chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS; - data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); - if (!data_ptr) - return -ENOMEM; - - /* copy first part */ - memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size); - - /* copy second part */ - memcpy((char *)data_ptr + del_if_num * chunk_size, - orig_node->bat_iv.bcast_own + ((del_if_num + 1) * chunk_size), - (max_if_num - del_if_num) * chunk_size); - -free_bcast_own: - kfree(orig_node->bat_iv.bcast_own); - orig_node->bat_iv.bcast_own = data_ptr; - - if (max_if_num == 0) - goto free_own_sum; - - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) - return -ENOMEM; - - memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum, - del_if_num * sizeof(uint8_t)); - - if_offset = ((del_if_num + 1) * sizeof(uint8_t)); - memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t), - orig_node->bat_iv.bcast_own_sum + if_offset, - (max_if_num - del_if_num) * sizeof(uint8_t)); - -free_own_sum: - kfree(orig_node->bat_iv.bcast_own_sum); - orig_node->bat_iv.bcast_own_sum = data_ptr; - - return 0; -} - int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, int max_if_num) { @@ -655,6 +580,7 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, struct hlist_head *head; struct batadv_hard_iface *hard_iface_tmp; struct batadv_orig_node *orig_node; + struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; uint32_t i; int ret;
@@ -666,11 +592,11 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
rcu_read_lock(); hlist_for_each_entry_rcu(orig_node, head, hash_entry) { - spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); - ret = batadv_orig_node_del_if(orig_node, max_if_num, - hard_iface->if_num); - spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); - + ret = 0; + if (bao->bat_orig_del_if) + ret = bao->bat_orig_del_if(orig_node, + max_if_num, + hard_iface->if_num); if (ret == -ENOMEM) goto err; } diff --git a/types.h b/types.h index 516d30d..ee08193 100644 --- a/types.h +++ b/types.h @@ -1012,6 +1012,11 @@ struct batadv_algo_ops { int (*bat_metric_compare)(uint32_t metric, uint32_t new_metric); /* orig_node handling API */ void (*bat_orig_print)(struct batadv_priv *priv, struct seq_file *seq); + void (*bat_orig_free)(struct batadv_orig_node *orig_node); + int (*bat_orig_add_if)(struct batadv_orig_node *orig_node, + int max_if_num); + int (*bat_orig_del_if)(struct batadv_orig_node *orig_node, + int max_if_num, int del_if_num); };
/**
From: Antonio Quartulli antonio@open-mesh.com
Signed-off-by: Antonio Quartulli antonio@open-mesh.com --- translation-table.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/translation-table.c b/translation-table.c index 0064423..abbc0fe 100644 --- a/translation-table.c +++ b/translation-table.c @@ -1280,18 +1280,21 @@ out: }
/* batadv_transtable_best_orig - Get best originator list entry from tt entry + * @bat_priv: the bat priv with all the soft interface information * @tt_global_entry: global translation table entry to be analyzed * * This functon assumes the caller holds rcu_read_lock(). * Returns best originator list entry or NULL on errors. */ static struct batadv_tt_orig_list_entry * -batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry) +batadv_transtable_best_orig(struct batadv_priv *bat_priv, + struct batadv_tt_global_entry *tt_global_entry) { - struct batadv_neigh_node *router = NULL; + struct batadv_neigh_node *router; + struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; struct hlist_head *head; struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL; - int best_tq = 0; + uint16_t metric, best_metric = 0;
head = &tt_global_entry->orig_list; hlist_for_each_entry_rcu(orig_entry, head, list) { @@ -1299,12 +1302,14 @@ batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry) if (!router) continue;
- if (router->bat_iv.tq_avg > best_tq) { - best_entry = orig_entry; - best_tq = router->bat_iv.tq_avg; - } - + metric = bao->bat_metric_get(router); batadv_neigh_node_free_ref(router); + + if (metric <= best_metric) + continue; + + best_entry = orig_entry; + best_metric = metric; }
return best_entry; @@ -1312,13 +1317,15 @@ batadv_transtable_best_orig(struct batadv_tt_global_entry *tt_global_entry)
/* batadv_tt_global_print_entry - print all orig nodes who announce the address * for this global entry + * @bat_priv: the bat priv with all the soft interface information * @tt_global_entry: global translation table entry to be printed * @seq: debugfs table seq_file struct * * This functon assumes the caller holds rcu_read_lock(). */ static void -batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, +batadv_tt_global_print_entry(struct batadv_priv *bat_priv, + struct batadv_tt_global_entry *tt_global_entry, struct seq_file *seq) { struct batadv_tt_orig_list_entry *orig_entry, *best_entry; @@ -1331,7 +1338,7 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry, tt_common_entry = &tt_global_entry->common; flags = tt_common_entry->flags;
- best_entry = batadv_transtable_best_orig(tt_global_entry); + best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry); if (best_entry) { vlan = batadv_orig_node_vlan_get(best_entry->orig_node, tt_common_entry->vid); @@ -1420,7 +1427,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset) tt_global = container_of(tt_common_entry, struct batadv_tt_global_entry, common); - batadv_tt_global_print_entry(tt_global, seq); + batadv_tt_global_print_entry(bat_priv, tt_global, seq); } rcu_read_unlock(); } @@ -1808,7 +1815,7 @@ struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv, goto out;
rcu_read_lock(); - best_entry = batadv_transtable_best_orig(tt_global_entry); + best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry); /* found anything? */ if (best_entry) orig_node = best_entry->orig_node;
On Wed, Jul 31, 2013 at 10:47:47PM +0200, Antonio Quartulli wrote:
if (metric <= best_metric)
continue;
best_entry = orig_entry;
best_metric = metric;
Why don't you use the bat_metric_compare() function here?
BTW, do we need bat_metric_compare() anyway? I think both TQ and the metric in BATMAN V can work with integer comparison, so as long as we don't add some other "special" metrics we might not need this bat_metric_compare() at all?
Simon
On Wed, Jul 31, 2013 at 10:47:37PM +0200, Antonio Quartulli wrote:
Hello list,
with this RFC I'd like to introduce some new routing API functions meant to improve the routing protocol abstraction.
This changes have been written while developing batman V. The latter helped me in understanding what batman iv and v have in common and what not.
The main problem was the metric: the two protocols use different metric domains and different semantics. Therefore all the functions handling/printing the metric needed to be generalised and rearranged to let the protocols decide what to do.
Another issue was the way routing protocols handle the orig and neigh node structures. Also these two have been changed and some small APIs have been provided as well.
Moreover, after Simon's RFC about the new multi-interface optimisation, we saw the need for a better abstraction so that mechanisms like that could easily be re-used by new algorithms (like batman v) with little effort.
This is the second version of this RFC where I introduced some changes to the names of some functions and some other minor changes discussed in the previous RFC thread.
The new API functions are the following:
- metric related: - bat_metric_get - bat_metric_is_similar
copy + paste?! :P
- bat_metric_compare
- orig_node related: - bat_orig_print: print the originator table - bat_orig_add_if - bat_orig_del_if - bat_orig_free
Any feedback will surely be welcome :-)
Looks pretty good to me, see a few questions inline of the patches for detail. I'd love to see the real patches soon. :)
Cheers, Simon
b.a.t.m.a.n@lists.open-mesh.org