diff options
author | Simon Wunderlich <simon@open-mesh.com> | 2013-11-13 13:14:45 -0500 |
---|---|---|
committer | Antonio Quartulli <antonio@meshcoding.com> | 2014-01-12 08:41:10 -0500 |
commit | f6c8b71173ad50e48e6569a1ef5d7d4486268b4d (patch) | |
tree | ece15dadcb5973de5eb11c0f4f2b9031d90462f4 /net/batman-adv/routing.c | |
parent | f9577a376e28d7b8367319e103d6511d41c1c5fa (diff) |
batman-adv: remove bonding and interface alternating
Remove bonding and interface alternating code - it will be replaced
by a new, network-wide multi interface optimization which enables
both bonding and interface alternating in a better way.
Keep the sysfs and find router function though, this will be needed
later.
Signed-off-by: Simon Wunderlich <simon@open-mesh.com>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r-- | net/batman-adv/routing.c | 300 |
1 files changed, 9 insertions, 291 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 7e8aa177eb1d..4fd2687b88c2 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -96,115 +96,6 @@ out: | |||
96 | batadv_neigh_node_free_ref(router); | 96 | batadv_neigh_node_free_ref(router); |
97 | } | 97 | } |
98 | 98 | ||
99 | /* caller must hold the neigh_list_lock */ | ||
100 | void batadv_bonding_candidate_del(struct batadv_orig_node *orig_node, | ||
101 | struct batadv_neigh_node *neigh_node) | ||
102 | { | ||
103 | /* this neighbor is not part of our candidate list */ | ||
104 | if (list_empty(&neigh_node->bonding_list)) | ||
105 | goto out; | ||
106 | |||
107 | list_del_rcu(&neigh_node->bonding_list); | ||
108 | INIT_LIST_HEAD(&neigh_node->bonding_list); | ||
109 | batadv_neigh_node_free_ref(neigh_node); | ||
110 | atomic_dec(&orig_node->bond_candidates); | ||
111 | |||
112 | out: | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * batadv_bonding_candidate_add - consider a new link for bonding mode towards | ||
118 | * the given originator | ||
119 | * @bat_priv: the bat priv with all the soft interface information | ||
120 | * @orig_node: the target node | ||
121 | * @neigh_node: the neighbor representing the new link to consider for bonding | ||
122 | * mode | ||
123 | */ | ||
124 | void batadv_bonding_candidate_add(struct batadv_priv *bat_priv, | ||
125 | struct batadv_orig_node *orig_node, | ||
126 | struct batadv_neigh_node *neigh_node) | ||
127 | { | ||
128 | struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; | ||
129 | struct batadv_neigh_node *tmp_neigh_node, *router = NULL; | ||
130 | uint8_t interference_candidate = 0; | ||
131 | |||
132 | spin_lock_bh(&orig_node->neigh_list_lock); | ||
133 | |||
134 | /* only consider if it has the same primary address ... */ | ||
135 | if (!batadv_compare_eth(orig_node->orig, | ||
136 | neigh_node->orig_node->primary_addr)) | ||
137 | goto candidate_del; | ||
138 | |||
139 | router = batadv_orig_node_get_router(orig_node); | ||
140 | if (!router) | ||
141 | goto candidate_del; | ||
142 | |||
143 | |||
144 | /* ... and is good enough to be considered */ | ||
145 | if (bao->bat_neigh_is_equiv_or_better(neigh_node, router)) | ||
146 | goto candidate_del; | ||
147 | |||
148 | /* check if we have another candidate with the same mac address or | ||
149 | * interface. If we do, we won't select this candidate because of | ||
150 | * possible interference. | ||
151 | */ | ||
152 | hlist_for_each_entry_rcu(tmp_neigh_node, | ||
153 | &orig_node->neigh_list, list) { | ||
154 | if (tmp_neigh_node == neigh_node) | ||
155 | continue; | ||
156 | |||
157 | /* we only care if the other candidate is even | ||
158 | * considered as candidate. | ||
159 | */ | ||
160 | if (list_empty(&tmp_neigh_node->bonding_list)) | ||
161 | continue; | ||
162 | |||
163 | if ((neigh_node->if_incoming == tmp_neigh_node->if_incoming) || | ||
164 | (batadv_compare_eth(neigh_node->addr, | ||
165 | tmp_neigh_node->addr))) { | ||
166 | interference_candidate = 1; | ||
167 | break; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | /* don't care further if it is an interference candidate */ | ||
172 | if (interference_candidate) | ||
173 | goto candidate_del; | ||
174 | |||
175 | /* this neighbor already is part of our candidate list */ | ||
176 | if (!list_empty(&neigh_node->bonding_list)) | ||
177 | goto out; | ||
178 | |||
179 | if (!atomic_inc_not_zero(&neigh_node->refcount)) | ||
180 | goto out; | ||
181 | |||
182 | list_add_rcu(&neigh_node->bonding_list, &orig_node->bond_list); | ||
183 | atomic_inc(&orig_node->bond_candidates); | ||
184 | goto out; | ||
185 | |||
186 | candidate_del: | ||
187 | batadv_bonding_candidate_del(orig_node, neigh_node); | ||
188 | |||
189 | out: | ||
190 | spin_unlock_bh(&orig_node->neigh_list_lock); | ||
191 | |||
192 | if (router) | ||
193 | batadv_neigh_node_free_ref(router); | ||
194 | } | ||
195 | |||
196 | /* copy primary address for bonding */ | ||
197 | void | ||
198 | batadv_bonding_save_primary(const struct batadv_orig_node *orig_node, | ||
199 | struct batadv_orig_node *orig_neigh_node, | ||
200 | const struct batadv_ogm_packet *batman_ogm_packet) | ||
201 | { | ||
202 | if (!(batman_ogm_packet->flags & BATADV_PRIMARIES_FIRST_HOP)) | ||
203 | return; | ||
204 | |||
205 | memcpy(orig_neigh_node->primary_addr, orig_node->orig, ETH_ALEN); | ||
206 | } | ||
207 | |||
208 | /* checks whether the host restarted and is in the protection time. | 99 | /* checks whether the host restarted and is in the protection time. |
209 | * returns: | 100 | * returns: |
210 | * 0 if the packet is to be accepted | 101 | * 0 if the packet is to be accepted |
@@ -459,114 +350,6 @@ out: | |||
459 | return ret; | 350 | return ret; |
460 | } | 351 | } |
461 | 352 | ||
462 | /* In the bonding case, send the packets in a round | ||
463 | * robin fashion over the remaining interfaces. | ||
464 | * | ||
465 | * This method rotates the bonding list and increases the | ||
466 | * returned router's refcount. | ||
467 | */ | ||
468 | static struct batadv_neigh_node * | ||
469 | batadv_find_bond_router(struct batadv_orig_node *primary_orig, | ||
470 | const struct batadv_hard_iface *recv_if) | ||
471 | { | ||
472 | struct batadv_neigh_node *tmp_neigh_node; | ||
473 | struct batadv_neigh_node *router = NULL, *first_candidate = NULL; | ||
474 | |||
475 | rcu_read_lock(); | ||
476 | list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list, | ||
477 | bonding_list) { | ||
478 | if (!first_candidate) | ||
479 | first_candidate = tmp_neigh_node; | ||
480 | |||
481 | /* recv_if == NULL on the first node. */ | ||
482 | if (tmp_neigh_node->if_incoming == recv_if) | ||
483 | continue; | ||
484 | |||
485 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) | ||
486 | continue; | ||
487 | |||
488 | router = tmp_neigh_node; | ||
489 | break; | ||
490 | } | ||
491 | |||
492 | /* use the first candidate if nothing was found. */ | ||
493 | if (!router && first_candidate && | ||
494 | atomic_inc_not_zero(&first_candidate->refcount)) | ||
495 | router = first_candidate; | ||
496 | |||
497 | if (!router) | ||
498 | goto out; | ||
499 | |||
500 | /* selected should point to the next element | ||
501 | * after the current router | ||
502 | */ | ||
503 | spin_lock_bh(&primary_orig->neigh_list_lock); | ||
504 | /* this is a list_move(), which unfortunately | ||
505 | * does not exist as rcu version | ||
506 | */ | ||
507 | list_del_rcu(&primary_orig->bond_list); | ||
508 | list_add_rcu(&primary_orig->bond_list, | ||
509 | &router->bonding_list); | ||
510 | spin_unlock_bh(&primary_orig->neigh_list_lock); | ||
511 | |||
512 | out: | ||
513 | rcu_read_unlock(); | ||
514 | return router; | ||
515 | } | ||
516 | |||
517 | /** | ||
518 | * batadv_find_ifalter_router - find the best of the remaining candidates which | ||
519 | * are not using this interface | ||
520 | * @bat_priv: the bat priv with all the soft interface information | ||
521 | * @primary_orig: the destination | ||
522 | * @recv_if: the interface that the router returned by this function has to not | ||
523 | * use | ||
524 | * | ||
525 | * Returns the best candidate towards primary_orig that is not using recv_if. | ||
526 | * Increases the returned neighbor's refcount | ||
527 | */ | ||
528 | static struct batadv_neigh_node * | ||
529 | batadv_find_ifalter_router(struct batadv_priv *bat_priv, | ||
530 | struct batadv_orig_node *primary_orig, | ||
531 | const struct batadv_hard_iface *recv_if) | ||
532 | { | ||
533 | struct batadv_neigh_node *router = NULL, *first_candidate = NULL; | ||
534 | struct batadv_algo_ops *bao = bat_priv->bat_algo_ops; | ||
535 | struct batadv_neigh_node *tmp_neigh_node; | ||
536 | |||
537 | rcu_read_lock(); | ||
538 | list_for_each_entry_rcu(tmp_neigh_node, &primary_orig->bond_list, | ||
539 | bonding_list) { | ||
540 | if (!first_candidate) | ||
541 | first_candidate = tmp_neigh_node; | ||
542 | |||
543 | /* recv_if == NULL on the first node. */ | ||
544 | if (tmp_neigh_node->if_incoming == recv_if) | ||
545 | continue; | ||
546 | |||
547 | if (router && bao->bat_neigh_cmp(tmp_neigh_node, router)) | ||
548 | continue; | ||
549 | |||
550 | if (!atomic_inc_not_zero(&tmp_neigh_node->refcount)) | ||
551 | continue; | ||
552 | |||
553 | /* decrement refcount of previously selected router */ | ||
554 | if (router) | ||
555 | batadv_neigh_node_free_ref(router); | ||
556 | |||
557 | /* we found a better router (or at least one valid router) */ | ||
558 | router = tmp_neigh_node; | ||
559 | } | ||
560 | |||
561 | /* use the first candidate if nothing was found. */ | ||
562 | if (!router && first_candidate && | ||
563 | atomic_inc_not_zero(&first_candidate->refcount)) | ||
564 | router = first_candidate; | ||
565 | |||
566 | rcu_read_unlock(); | ||
567 | return router; | ||
568 | } | ||
569 | |||
570 | /** | 353 | /** |
571 | * batadv_check_unicast_packet - Check for malformed unicast packets | 354 | * batadv_check_unicast_packet - Check for malformed unicast packets |
572 | * @bat_priv: the bat priv with all the soft interface information | 355 | * @bat_priv: the bat priv with all the soft interface information |
@@ -604,95 +387,30 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, | |||
604 | return 0; | 387 | return 0; |
605 | } | 388 | } |
606 | 389 | ||
607 | /* find a suitable router for this originator, and use | 390 | /** |
608 | * bonding if possible. increases the found neighbors | 391 | * batadv_find_router - find a suitable router for this originator |
609 | * refcount. | 392 | * @bat_priv: the bat priv with all the soft interface information |
393 | * @orig_node: the destination node | ||
394 | * @recv_if: pointer to interface this packet was received on | ||
395 | * | ||
396 | * Returns the router which should be used for this orig_node on | ||
397 | * this interface, or NULL if not available. | ||
610 | */ | 398 | */ |
611 | struct batadv_neigh_node * | 399 | struct batadv_neigh_node * |
612 | batadv_find_router(struct batadv_priv *bat_priv, | 400 | batadv_find_router(struct batadv_priv *bat_priv, |
613 | struct batadv_orig_node *orig_node, | 401 | struct batadv_orig_node *orig_node, |
614 | const struct batadv_hard_iface *recv_if) | 402 | const struct batadv_hard_iface *recv_if) |
615 | { | 403 | { |
616 | struct batadv_orig_node *primary_orig_node; | ||
617 | struct batadv_orig_node *router_orig; | ||
618 | struct batadv_neigh_node *router; | 404 | struct batadv_neigh_node *router; |
619 | static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; | ||
620 | int bonding_enabled; | ||
621 | uint8_t *primary_addr; | ||
622 | 405 | ||
623 | if (!orig_node) | 406 | if (!orig_node) |
624 | return NULL; | 407 | return NULL; |
625 | 408 | ||
626 | router = batadv_orig_node_get_router(orig_node); | 409 | router = batadv_orig_node_get_router(orig_node); |
627 | if (!router) | ||
628 | goto err; | ||
629 | |||
630 | /* without bonding, the first node should | ||
631 | * always choose the default router. | ||
632 | */ | ||
633 | bonding_enabled = atomic_read(&bat_priv->bonding); | ||
634 | |||
635 | rcu_read_lock(); | ||
636 | /* select default router to output */ | ||
637 | router_orig = router->orig_node; | ||
638 | if (!router_orig) | ||
639 | goto err_unlock; | ||
640 | |||
641 | if ((!recv_if) && (!bonding_enabled)) | ||
642 | goto return_router; | ||
643 | |||
644 | primary_addr = router_orig->primary_addr; | ||
645 | |||
646 | /* if we have something in the primary_addr, we can search | ||
647 | * for a potential bonding candidate. | ||
648 | */ | ||
649 | if (batadv_compare_eth(primary_addr, zero_mac)) | ||
650 | goto return_router; | ||
651 | |||
652 | /* find the orig_node which has the primary interface. might | ||
653 | * even be the same as our router_orig in many cases | ||
654 | */ | ||
655 | if (batadv_compare_eth(primary_addr, router_orig->orig)) { | ||
656 | primary_orig_node = router_orig; | ||
657 | } else { | ||
658 | primary_orig_node = batadv_orig_hash_find(bat_priv, | ||
659 | primary_addr); | ||
660 | if (!primary_orig_node) | ||
661 | goto return_router; | ||
662 | 410 | ||
663 | batadv_orig_node_free_ref(primary_orig_node); | 411 | /* TODO: fill this later with new bonding mechanism */ |
664 | } | ||
665 | |||
666 | /* with less than 2 candidates, we can't do any | ||
667 | * bonding and prefer the original router. | ||
668 | */ | ||
669 | if (atomic_read(&primary_orig_node->bond_candidates) < 2) | ||
670 | goto return_router; | ||
671 | 412 | ||
672 | /* all nodes between should choose a candidate which | ||
673 | * is is not on the interface where the packet came | ||
674 | * in. | ||
675 | */ | ||
676 | batadv_neigh_node_free_ref(router); | ||
677 | |||
678 | if (bonding_enabled) | ||
679 | router = batadv_find_bond_router(primary_orig_node, recv_if); | ||
680 | else | ||
681 | router = batadv_find_ifalter_router(bat_priv, primary_orig_node, | ||
682 | recv_if); | ||
683 | |||
684 | return_router: | ||
685 | if (router && router->if_incoming->if_status != BATADV_IF_ACTIVE) | ||
686 | goto err_unlock; | ||
687 | |||
688 | rcu_read_unlock(); | ||
689 | return router; | 413 | return router; |
690 | err_unlock: | ||
691 | rcu_read_unlock(); | ||
692 | err: | ||
693 | if (router) | ||
694 | batadv_neigh_node_free_ref(router); | ||
695 | return NULL; | ||
696 | } | 414 | } |
697 | 415 | ||
698 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 416 | static int batadv_route_unicast_packet(struct sk_buff *skb, |