diff options
Diffstat (limited to 'net/batman-adv/routing.c')
-rw-r--r-- | net/batman-adv/routing.c | 38 |
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 @@ | |||
33 | static int batadv_route_unicast_packet(struct sk_buff *skb, | 33 | static 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 | */ | ||
36 | static void _batadv_update_route(struct batadv_priv *bat_priv, | 45 | static 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 | */ | ||
80 | void batadv_update_route(struct batadv_priv *bat_priv, | 107 | void 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 | ||
94 | out: | 122 | out: |
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 | ||