1 /* Copyright (C) 2013-2016 B.A.T.M.A.N. contributors: 2 * 3 * Linus Lüssing, Marek Lindner 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of version 2 of the GNU General Public 7 * License as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include "bat_algo.h" 19 #include "main.h" 20 21 #include <linux/atomic.h> 22 #include <linux/bug.h> 23 #include <linux/cache.h> 24 #include <linux/init.h> 25 #include <linux/jiffies.h> 26 #include <linux/netdevice.h> 27 #include <linux/rculist.h> 28 #include <linux/rcupdate.h> 29 #include <linux/seq_file.h> 30 #include <linux/types.h> 31 #include <linux/workqueue.h> 32 33 #include "bat_v_elp.h" 34 #include "bat_v_ogm.h" 35 #include "hard-interface.h" 36 #include "hash.h" 37 #include "originator.h" 38 #include "packet.h" 39 40 static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface) 41 { 42 /* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can 43 * set the interface as ACTIVE right away, without any risk of race 44 * condition 45 */ 46 if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED) 47 hard_iface->if_status = BATADV_IF_ACTIVE; 48 } 49 50 static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface) 51 { 52 int ret; 53 54 ret = batadv_v_elp_iface_enable(hard_iface); 55 if (ret < 0) 56 return ret; 57 58 ret = batadv_v_ogm_iface_enable(hard_iface); 59 if (ret < 0) 60 batadv_v_elp_iface_disable(hard_iface); 61 62 /* enable link throughput auto-detection by setting the throughput 63 * override to zero 64 */ 65 atomic_set(&hard_iface->bat_v.throughput_override, 0); 66 67 return ret; 68 } 69 70 static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface) 71 { 72 batadv_v_elp_iface_disable(hard_iface); 73 } 74 75 static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface) 76 { 77 } 78 79 static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface) 80 { 81 batadv_v_elp_primary_iface_set(hard_iface); 82 batadv_v_ogm_primary_iface_set(hard_iface); 83 } 84 85 static void 86 batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh) 87 { 88 ewma_throughput_init(&hardif_neigh->bat_v.throughput); 89 INIT_WORK(&hardif_neigh->bat_v.metric_work, 90 batadv_v_elp_throughput_metric_update); 91 } 92 93 static void batadv_v_ogm_schedule(struct batadv_hard_iface *hard_iface) 94 { 95 } 96 97 static void batadv_v_ogm_emit(struct batadv_forw_packet *forw_packet) 98 { 99 } 100 101 /** 102 * batadv_v_orig_print_neigh - print neighbors for the originator table 103 * @orig_node: the orig_node for which the neighbors are printed 104 * @if_outgoing: outgoing interface for these entries 105 * @seq: debugfs table seq_file struct 106 * 107 * Must be called while holding an rcu lock. 108 */ 109 static void 110 batadv_v_orig_print_neigh(struct batadv_orig_node *orig_node, 111 struct batadv_hard_iface *if_outgoing, 112 struct seq_file *seq) 113 { 114 struct batadv_neigh_node *neigh_node; 115 struct batadv_neigh_ifinfo *n_ifinfo; 116 117 hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) { 118 n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing); 119 if (!n_ifinfo) 120 continue; 121 122 seq_printf(seq, " %pM (%9u.%1u)", 123 neigh_node->addr, 124 n_ifinfo->bat_v.throughput / 10, 125 n_ifinfo->bat_v.throughput % 10); 126 127 batadv_neigh_ifinfo_put(n_ifinfo); 128 } 129 } 130 131 /** 132 * batadv_v_hardif_neigh_print - print a single ELP neighbour node 133 * @seq: neighbour table seq_file struct 134 * @hardif_neigh: hardif neighbour information 135 */ 136 static void 137 batadv_v_hardif_neigh_print(struct seq_file *seq, 138 struct batadv_hardif_neigh_node *hardif_neigh) 139 { 140 int last_secs, last_msecs; 141 u32 throughput; 142 143 last_secs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) / 1000; 144 last_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen) % 1000; 145 throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput); 146 147 seq_printf(seq, "%pM %4i.%03is (%9u.%1u) [%10s]\n", 148 hardif_neigh->addr, last_secs, last_msecs, throughput / 10, 149 throughput % 10, hardif_neigh->if_incoming->net_dev->name); 150 } 151 152 /** 153 * batadv_v_neigh_print - print the single hop neighbour list 154 * @bat_priv: the bat priv with all the soft interface information 155 * @seq: neighbour table seq_file struct 156 */ 157 static void batadv_v_neigh_print(struct batadv_priv *bat_priv, 158 struct seq_file *seq) 159 { 160 struct net_device *net_dev = (struct net_device *)seq->private; 161 struct batadv_hardif_neigh_node *hardif_neigh; 162 struct batadv_hard_iface *hard_iface; 163 int batman_count = 0; 164 165 seq_printf(seq, " %-15s %s (%11s) [%10s]\n", "Neighbor", 166 "last-seen", "throughput", "IF"); 167 168 rcu_read_lock(); 169 list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { 170 if (hard_iface->soft_iface != net_dev) 171 continue; 172 173 hlist_for_each_entry_rcu(hardif_neigh, 174 &hard_iface->neigh_list, list) { 175 batadv_v_hardif_neigh_print(seq, hardif_neigh); 176 batman_count++; 177 } 178 } 179 rcu_read_unlock(); 180 181 if (batman_count == 0) 182 seq_puts(seq, "No batman nodes in range ...\n"); 183 } 184 185 /** 186 * batadv_v_orig_print - print the originator table 187 * @bat_priv: the bat priv with all the soft interface information 188 * @seq: debugfs table seq_file struct 189 * @if_outgoing: the outgoing interface for which this should be printed 190 */ 191 static void batadv_v_orig_print(struct batadv_priv *bat_priv, 192 struct seq_file *seq, 193 struct batadv_hard_iface *if_outgoing) 194 { 195 struct batadv_neigh_node *neigh_node; 196 struct batadv_hashtable *hash = bat_priv->orig_hash; 197 int last_seen_msecs, last_seen_secs; 198 struct batadv_orig_node *orig_node; 199 struct batadv_neigh_ifinfo *n_ifinfo; 200 unsigned long last_seen_jiffies; 201 struct hlist_head *head; 202 int batman_count = 0; 203 u32 i; 204 205 seq_printf(seq, " %-15s %s (%11s) %17s [%10s]: %20s ...\n", 206 "Originator", "last-seen", "throughput", "Nexthop", 207 "outgoingIF", "Potential nexthops"); 208 209 for (i = 0; i < hash->size; i++) { 210 head = &hash->table[i]; 211 212 rcu_read_lock(); 213 hlist_for_each_entry_rcu(orig_node, head, hash_entry) { 214 neigh_node = batadv_orig_router_get(orig_node, 215 if_outgoing); 216 if (!neigh_node) 217 continue; 218 219 n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, 220 if_outgoing); 221 if (!n_ifinfo) 222 goto next; 223 224 last_seen_jiffies = jiffies - orig_node->last_seen; 225 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies); 226 last_seen_secs = last_seen_msecs / 1000; 227 last_seen_msecs = last_seen_msecs % 1000; 228 229 seq_printf(seq, "%pM %4i.%03is (%9u.%1u) %pM [%10s]:", 230 orig_node->orig, last_seen_secs, 231 last_seen_msecs, 232 n_ifinfo->bat_v.throughput / 10, 233 n_ifinfo->bat_v.throughput % 10, 234 neigh_node->addr, 235 neigh_node->if_incoming->net_dev->name); 236 237 batadv_v_orig_print_neigh(orig_node, if_outgoing, seq); 238 seq_puts(seq, "\n"); 239 batman_count++; 240 241 next: 242 batadv_neigh_node_put(neigh_node); 243 if (n_ifinfo) 244 batadv_neigh_ifinfo_put(n_ifinfo); 245 } 246 rcu_read_unlock(); 247 } 248 249 if (batman_count == 0) 250 seq_puts(seq, "No batman nodes in range ...\n"); 251 } 252 253 static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1, 254 struct batadv_hard_iface *if_outgoing1, 255 struct batadv_neigh_node *neigh2, 256 struct batadv_hard_iface *if_outgoing2) 257 { 258 struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; 259 260 ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); 261 ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); 262 263 if (WARN_ON(!ifinfo1 || !ifinfo2)) 264 return 0; 265 266 return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; 267 } 268 269 static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, 270 struct batadv_hard_iface *if_outgoing1, 271 struct batadv_neigh_node *neigh2, 272 struct batadv_hard_iface *if_outgoing2) 273 { 274 struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; 275 u32 threshold; 276 277 ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); 278 ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); 279 280 threshold = ifinfo1->bat_v.throughput / 4; 281 threshold = ifinfo1->bat_v.throughput - threshold; 282 283 return ifinfo2->bat_v.throughput > threshold; 284 } 285 286 static struct batadv_algo_ops batadv_batman_v __read_mostly = { 287 .name = "BATMAN_V", 288 .bat_iface_activate = batadv_v_iface_activate, 289 .bat_iface_enable = batadv_v_iface_enable, 290 .bat_iface_disable = batadv_v_iface_disable, 291 .bat_iface_update_mac = batadv_v_iface_update_mac, 292 .bat_primary_iface_set = batadv_v_primary_iface_set, 293 .bat_hardif_neigh_init = batadv_v_hardif_neigh_init, 294 .bat_ogm_emit = batadv_v_ogm_emit, 295 .bat_ogm_schedule = batadv_v_ogm_schedule, 296 .bat_orig_print = batadv_v_orig_print, 297 .bat_neigh_cmp = batadv_v_neigh_cmp, 298 .bat_neigh_is_similar_or_better = batadv_v_neigh_is_sob, 299 .bat_neigh_print = batadv_v_neigh_print, 300 }; 301 302 /** 303 * batadv_v_mesh_init - initialize the B.A.T.M.A.N. V private resources for a 304 * mesh 305 * @bat_priv: the object representing the mesh interface to initialise 306 * 307 * Return: 0 on success or a negative error code otherwise 308 */ 309 int batadv_v_mesh_init(struct batadv_priv *bat_priv) 310 { 311 return batadv_v_ogm_init(bat_priv); 312 } 313 314 /** 315 * batadv_v_mesh_free - free the B.A.T.M.A.N. V private resources for a mesh 316 * @bat_priv: the object representing the mesh interface to free 317 */ 318 void batadv_v_mesh_free(struct batadv_priv *bat_priv) 319 { 320 batadv_v_ogm_free(bat_priv); 321 } 322 323 /** 324 * batadv_v_init - B.A.T.M.A.N. V initialization function 325 * 326 * Description: Takes care of initializing all the subcomponents. 327 * It is invoked upon module load only. 328 * 329 * Return: 0 on success or a negative error code otherwise 330 */ 331 int __init batadv_v_init(void) 332 { 333 int ret; 334 335 /* B.A.T.M.A.N. V echo location protocol packet */ 336 ret = batadv_recv_handler_register(BATADV_ELP, 337 batadv_v_elp_packet_recv); 338 if (ret < 0) 339 return ret; 340 341 ret = batadv_recv_handler_register(BATADV_OGM2, 342 batadv_v_ogm_packet_recv); 343 if (ret < 0) 344 goto elp_unregister; 345 346 ret = batadv_algo_register(&batadv_batman_v); 347 if (ret < 0) 348 goto ogm_unregister; 349 350 return ret; 351 352 ogm_unregister: 353 batadv_recv_handler_unregister(BATADV_OGM2); 354 355 elp_unregister: 356 batadv_recv_handler_unregister(BATADV_ELP); 357 358 return ret; 359 } 360