diff options
author | Antonio Quartulli <antonio@open-mesh.com> | 2013-09-03 11:10:23 +0200 |
---|---|---|
committer | Antonio Quartulli <antonio@meshcoding.com> | 2013-10-23 17:03:21 +0200 |
commit | d0015fdd3d2c9cc5927637c74a66d85e8bcacf1c (patch) | |
tree | 541340ef841baf985b4f14268ebd9a7536df2a07 /net/batman-adv/originator.c | |
parent | batman-adv: adapt the neighbor purging routine to use the new API functions (diff) | |
download | linux-d0015fdd3d2c9cc5927637c74a66d85e8bcacf1c.tar.xz linux-d0015fdd3d2c9cc5927637c74a66d85e8bcacf1c.zip |
batman-adv: provide orig_node routing API
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>
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv/originator.c')
-rw-r--r-- | net/batman-adv/originator.c | 102 |
1 files changed, 14 insertions, 88 deletions
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index 9cee053f6a5c..8ab14340d10f 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -241,9 +241,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); } @@ -538,38 +539,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; @@ -584,10 +558,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; } @@ -601,55 +575,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) { @@ -658,6 +583,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; @@ -669,11 +595,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; } |