aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r--net/batman-adv/routing.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 4fd2687b88c2..55e9aebcbc80 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -33,13 +33,32 @@
33static int batadv_route_unicast_packet(struct sk_buff *skb, 33static int batadv_route_unicast_packet(struct sk_buff *skb,
34 struct batadv_hard_iface *recv_if); 34 struct batadv_hard_iface *recv_if);
35 35
36/**
37 * _batadv_update_route - set the router for this originator
38 * @bat_priv: the bat priv with all the soft interface information
39 * @orig_node: orig node which is to be configured
40 * @recv_if: the receive interface for which this route is set
41 * @neigh_node: neighbor which should be the next router
42 *
43 * This function does not perform any error checks
44 */
36static void _batadv_update_route(struct batadv_priv *bat_priv, 45static void _batadv_update_route(struct batadv_priv *bat_priv,
37 struct batadv_orig_node *orig_node, 46 struct batadv_orig_node *orig_node,
47 struct batadv_hard_iface *recv_if,
38 struct batadv_neigh_node *neigh_node) 48 struct batadv_neigh_node *neigh_node)
39{ 49{
50 struct batadv_orig_ifinfo *orig_ifinfo;
40 struct batadv_neigh_node *curr_router; 51 struct batadv_neigh_node *curr_router;
41 52
42 curr_router = batadv_orig_node_get_router(orig_node); 53 orig_ifinfo = batadv_orig_ifinfo_get(orig_node, recv_if);
54 if (!orig_ifinfo)
55 return;
56
57 rcu_read_lock();
58 curr_router = rcu_dereference(orig_ifinfo->router);
59 if (curr_router && !atomic_inc_not_zero(&curr_router->refcount))
60 curr_router = NULL;
61 rcu_read_unlock();
43 62
44 /* route deleted */ 63 /* route deleted */
45 if ((curr_router) && (!neigh_node)) { 64 if ((curr_router) && (!neigh_node)) {
@@ -69,16 +88,25 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
69 neigh_node = NULL; 88 neigh_node = NULL;
70 89
71 spin_lock_bh(&orig_node->neigh_list_lock); 90 spin_lock_bh(&orig_node->neigh_list_lock);
72 rcu_assign_pointer(orig_node->router, neigh_node); 91 rcu_assign_pointer(orig_ifinfo->router, neigh_node);
73 spin_unlock_bh(&orig_node->neigh_list_lock); 92 spin_unlock_bh(&orig_node->neigh_list_lock);
93 batadv_orig_ifinfo_free_ref(orig_ifinfo);
74 94
75 /* decrease refcount of previous best neighbor */ 95 /* decrease refcount of previous best neighbor */
76 if (curr_router) 96 if (curr_router)
77 batadv_neigh_node_free_ref(curr_router); 97 batadv_neigh_node_free_ref(curr_router);
78} 98}
79 99
100/**
101 * batadv_update_route - set the router for this originator
102 * @bat_priv: the bat priv with all the soft interface information
103 * @orig_node: orig node which is to be configured
104 * @recv_if: the receive interface for which this route is set
105 * @neigh_node: neighbor which should be the next router
106 */
80void batadv_update_route(struct batadv_priv *bat_priv, 107void batadv_update_route(struct batadv_priv *bat_priv,
81 struct batadv_orig_node *orig_node, 108 struct batadv_orig_node *orig_node,
109 struct batadv_hard_iface *recv_if,
82 struct batadv_neigh_node *neigh_node) 110 struct batadv_neigh_node *neigh_node)
83{ 111{
84 struct batadv_neigh_node *router = NULL; 112 struct batadv_neigh_node *router = NULL;
@@ -86,10 +114,10 @@ void batadv_update_route(struct batadv_priv *bat_priv,
86 if (!orig_node) 114 if (!orig_node)
87 goto out; 115 goto out;
88 116
89 router = batadv_orig_node_get_router(orig_node); 117 router = batadv_orig_router_get(orig_node, recv_if);
90 118
91 if (router != neigh_node) 119 if (router != neigh_node)
92 _batadv_update_route(bat_priv, orig_node, neigh_node); 120 _batadv_update_route(bat_priv, orig_node, recv_if, neigh_node);
93 121
94out: 122out:
95 if (router) 123 if (router)
@@ -406,7 +434,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
406 if (!orig_node) 434 if (!orig_node)
407 return NULL; 435 return NULL;
408 436
409 router = batadv_orig_node_get_router(orig_node); 437 router = batadv_orig_router_get(orig_node, recv_if);
410 438
411 /* TODO: fill this later with new bonding mechanism */ 439 /* TODO: fill this later with new bonding mechanism */
412 440