aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/originator.c
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-09-03 05:10:23 -0400
committerAntonio Quartulli <antonio@meshcoding.com>2013-10-23 11:03:21 -0400
commitd0015fdd3d2c9cc5927637c74a66d85e8bcacf1c (patch)
tree541340ef841baf985b4f14268ebd9a7536df2a07 /net/batman-adv/originator.c
parent81e26b1a1c0ad32a3c80e31024b5c4ff4842299a (diff)
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.c102
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)
241 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1, 241 batadv_tt_global_del_orig(orig_node->bat_priv, orig_node, -1,
242 "originator timed out"); 242 "originator timed out");
243 243
244 if (orig_node->bat_priv->bat_algo_ops->bat_orig_free)
245 orig_node->bat_priv->bat_algo_ops->bat_orig_free(orig_node);
246
244 kfree(orig_node->tt_buff); 247 kfree(orig_node->tt_buff);
245 kfree(orig_node->bat_iv.bcast_own);
246 kfree(orig_node->bat_iv.bcast_own_sum);
247 kfree(orig_node); 248 kfree(orig_node);
248} 249}
249 250
@@ -538,38 +539,11 @@ int batadv_orig_seq_print_text(struct seq_file *seq, void *offset)
538 return 0; 539 return 0;
539} 540}
540 541
541static int batadv_orig_node_add_if(struct batadv_orig_node *orig_node,
542 int max_if_num)
543{
544 void *data_ptr;
545 size_t data_size, old_size;
546
547 data_size = max_if_num * sizeof(unsigned long) * BATADV_NUM_WORDS;
548 old_size = (max_if_num - 1) * sizeof(unsigned long) * BATADV_NUM_WORDS;
549 data_ptr = kmalloc(data_size, GFP_ATOMIC);
550 if (!data_ptr)
551 return -ENOMEM;
552
553 memcpy(data_ptr, orig_node->bat_iv.bcast_own, old_size);
554 kfree(orig_node->bat_iv.bcast_own);
555 orig_node->bat_iv.bcast_own = data_ptr;
556
557 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
558 if (!data_ptr)
559 return -ENOMEM;
560
561 memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
562 (max_if_num - 1) * sizeof(uint8_t));
563 kfree(orig_node->bat_iv.bcast_own_sum);
564 orig_node->bat_iv.bcast_own_sum = data_ptr;
565
566 return 0;
567}
568
569int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface, 542int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
570 int max_if_num) 543 int max_if_num)
571{ 544{
572 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 545 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
546 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
573 struct batadv_hashtable *hash = bat_priv->orig_hash; 547 struct batadv_hashtable *hash = bat_priv->orig_hash;
574 struct hlist_head *head; 548 struct hlist_head *head;
575 struct batadv_orig_node *orig_node; 549 struct batadv_orig_node *orig_node;
@@ -584,10 +558,10 @@ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
584 558
585 rcu_read_lock(); 559 rcu_read_lock();
586 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 560 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
587 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); 561 ret = 0;
588 ret = batadv_orig_node_add_if(orig_node, max_if_num); 562 if (bao->bat_orig_add_if)
589 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); 563 ret = bao->bat_orig_add_if(orig_node,
590 564 max_if_num);
591 if (ret == -ENOMEM) 565 if (ret == -ENOMEM)
592 goto err; 566 goto err;
593 } 567 }
@@ -601,55 +575,6 @@ err:
601 return -ENOMEM; 575 return -ENOMEM;
602} 576}
603 577
604static int batadv_orig_node_del_if(struct batadv_orig_node *orig_node,
605 int max_if_num, int del_if_num)
606{
607 int chunk_size, if_offset;
608 void *data_ptr = NULL;
609
610 /* last interface was removed */
611 if (max_if_num == 0)
612 goto free_bcast_own;
613
614 chunk_size = sizeof(unsigned long) * BATADV_NUM_WORDS;
615 data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC);
616 if (!data_ptr)
617 return -ENOMEM;
618
619 /* copy first part */
620 memcpy(data_ptr, orig_node->bat_iv.bcast_own, del_if_num * chunk_size);
621
622 /* copy second part */
623 memcpy((char *)data_ptr + del_if_num * chunk_size,
624 orig_node->bat_iv.bcast_own + ((del_if_num + 1) * chunk_size),
625 (max_if_num - del_if_num) * chunk_size);
626
627free_bcast_own:
628 kfree(orig_node->bat_iv.bcast_own);
629 orig_node->bat_iv.bcast_own = data_ptr;
630
631 if (max_if_num == 0)
632 goto free_own_sum;
633
634 data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC);
635 if (!data_ptr)
636 return -ENOMEM;
637
638 memcpy(data_ptr, orig_node->bat_iv.bcast_own_sum,
639 del_if_num * sizeof(uint8_t));
640
641 if_offset = (del_if_num + 1) * sizeof(uint8_t);
642 memcpy((char *)data_ptr + del_if_num * sizeof(uint8_t),
643 orig_node->bat_iv.bcast_own_sum + if_offset,
644 (max_if_num - del_if_num) * sizeof(uint8_t));
645
646free_own_sum:
647 kfree(orig_node->bat_iv.bcast_own_sum);
648 orig_node->bat_iv.bcast_own_sum = data_ptr;
649
650 return 0;
651}
652
653int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface, 578int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
654 int max_if_num) 579 int max_if_num)
655{ 580{
@@ -658,6 +583,7 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
658 struct hlist_head *head; 583 struct hlist_head *head;
659 struct batadv_hard_iface *hard_iface_tmp; 584 struct batadv_hard_iface *hard_iface_tmp;
660 struct batadv_orig_node *orig_node; 585 struct batadv_orig_node *orig_node;
586 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
661 uint32_t i; 587 uint32_t i;
662 int ret; 588 int ret;
663 589
@@ -669,11 +595,11 @@ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
669 595
670 rcu_read_lock(); 596 rcu_read_lock();
671 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 597 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
672 spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); 598 ret = 0;
673 ret = batadv_orig_node_del_if(orig_node, max_if_num, 599 if (bao->bat_orig_del_if)
674 hard_iface->if_num); 600 ret = bao->bat_orig_del_if(orig_node,
675 spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); 601 max_if_num,
676 602 hard_iface->if_num);
677 if (ret == -ENOMEM) 603 if (ret == -ENOMEM)
678 goto err; 604 goto err;
679 } 605 }