xref: /linux/net/batman-adv/bat_v.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3  *
4  * Linus Lüssing, Marek Lindner
5  */
6 
7 #include "bat_v.h"
8 #include "main.h"
9 
10 #include <linux/cache.h>
11 #include <linux/compiler.h>
12 #include <linux/errno.h>
13 #include <linux/if_ether.h>
14 #include <linux/init.h>
15 #include <linux/jiffies.h>
16 #include <linux/kref.h>
17 #include <linux/limits.h>
18 #include <linux/list.h>
19 #include <linux/minmax.h>
20 #include <linux/netdevice.h>
21 #include <linux/netlink.h>
22 #include <linux/rculist.h>
23 #include <linux/rcupdate.h>
24 #include <linux/skbuff.h>
25 #include <linux/spinlock.h>
26 #include <linux/stddef.h>
27 #include <linux/types.h>
28 #include <linux/workqueue.h>
29 #include <net/genetlink.h>
30 #include <net/netlink.h>
31 #include <uapi/linux/batadv_packet.h>
32 #include <uapi/linux/batman_adv.h>
33 
34 #include "bat_algo.h"
35 #include "bat_v_elp.h"
36 #include "bat_v_ogm.h"
37 #include "gateway_client.h"
38 #include "hard-interface.h"
39 #include "hash.h"
40 #include "log.h"
41 #include "netlink.h"
42 #include "originator.h"
43 
44 /**
45  * batadv_v_iface_activate() - finalise the activation of a hard interface
46  * @hard_iface: interface to activate
47  *
48  * Reuse the currently selected primary interface to seed the ELP packet.
49  * Immediately activate the interface.
50  */
batadv_v_iface_activate(struct batadv_hard_iface * hard_iface)51 static void batadv_v_iface_activate(struct batadv_hard_iface *hard_iface)
52 {
53 	struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
54 	struct batadv_hard_iface *primary_if;
55 
56 	primary_if = batadv_primary_if_get_selected(bat_priv);
57 
58 	if (primary_if) {
59 		batadv_v_elp_iface_activate(primary_if, hard_iface);
60 		batadv_hardif_put(primary_if);
61 	}
62 
63 	/* B.A.T.M.A.N. V does not use any queuing mechanism, therefore it can
64 	 * set the interface as ACTIVE right away, without any risk of race
65 	 * condition
66 	 */
67 	if (hard_iface->if_status == BATADV_IF_TO_BE_ACTIVATED)
68 		hard_iface->if_status = BATADV_IF_ACTIVE;
69 }
70 
71 /**
72  * batadv_v_iface_enable() - enable the B.A.T.M.A.N. V protocol on an
73  *  interface
74  * @hard_iface: interface to enable
75  *
76  * Enable the ELP and OGM components for @hard_iface. On error, the partially
77  * enabled state is rolled back before returning.
78  *
79  * Return: 0 on success or negative error number in case of failure
80  */
batadv_v_iface_enable(struct batadv_hard_iface * hard_iface)81 static int batadv_v_iface_enable(struct batadv_hard_iface *hard_iface)
82 {
83 	int ret;
84 
85 	ret = batadv_v_elp_iface_enable(hard_iface);
86 	if (ret < 0)
87 		return ret;
88 
89 	ret = batadv_v_ogm_iface_enable(hard_iface);
90 	if (ret < 0)
91 		batadv_v_elp_iface_disable(hard_iface);
92 
93 	return ret;
94 }
95 
96 /**
97  * batadv_v_iface_disable() - disable the B.A.T.M.A.N. V protocol on an
98  *  interface
99  * @hard_iface: interface to disable
100  */
batadv_v_iface_disable(struct batadv_hard_iface * hard_iface)101 static void batadv_v_iface_disable(struct batadv_hard_iface *hard_iface)
102 {
103 	batadv_v_ogm_iface_disable(hard_iface);
104 	batadv_v_elp_iface_disable(hard_iface);
105 }
106 
107 /**
108  * batadv_v_primary_iface_set() - apply primary interface state
109  * @hard_iface: interface which just became the primary
110  */
batadv_v_primary_iface_set(struct batadv_hard_iface * hard_iface)111 static void batadv_v_primary_iface_set(struct batadv_hard_iface *hard_iface)
112 {
113 	batadv_v_elp_primary_iface_set(hard_iface);
114 	batadv_v_ogm_primary_iface_set(hard_iface);
115 }
116 
117 /**
118  * batadv_v_iface_update_mac() - react to hard-interface MAC address change
119  * @hard_iface: the modified interface
120  *
121  * If the modified interface is the primary one, update the originator
122  * address in the ELP and OGM messages to reflect the new MAC address.
123  */
batadv_v_iface_update_mac(struct batadv_hard_iface * hard_iface)124 static void batadv_v_iface_update_mac(struct batadv_hard_iface *hard_iface)
125 {
126 	struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
127 	struct batadv_hard_iface *primary_if;
128 
129 	primary_if = batadv_primary_if_get_selected(bat_priv);
130 	if (primary_if != hard_iface)
131 		goto out;
132 
133 	batadv_v_primary_iface_set(hard_iface);
134 out:
135 	batadv_hardif_put(primary_if);
136 }
137 
138 /**
139  * batadv_v_hardif_neigh_init() - initialise the B.A.T.M.A.N. V state of a
140  *  hard interface neighbour
141  * @hardif_neigh: hard interface neighbour to initialise
142  */
143 static void
batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node * hardif_neigh)144 batadv_v_hardif_neigh_init(struct batadv_hardif_neigh_node *hardif_neigh)
145 {
146 	ewma_throughput_init(&hardif_neigh->bat_v.throughput);
147 }
148 
149 /**
150  * batadv_v_neigh_dump_neigh() - Dump a neighbour into a message
151  * @msg: Netlink message to dump into
152  * @portid: Port making netlink request
153  * @seq: Sequence number of netlink message
154  * @hardif_neigh: Neighbour to dump
155  *
156  * Return: Error code, or 0 on success
157  */
158 static int
batadv_v_neigh_dump_neigh(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_hardif_neigh_node * hardif_neigh)159 batadv_v_neigh_dump_neigh(struct sk_buff *msg, u32 portid, u32 seq,
160 			  struct batadv_hardif_neigh_node *hardif_neigh)
161 {
162 	unsigned int last_seen_msecs;
163 	u32 throughput;
164 	void *hdr;
165 
166 	last_seen_msecs = jiffies_to_msecs(jiffies - hardif_neigh->last_seen);
167 	throughput = ewma_throughput_read(&hardif_neigh->bat_v.throughput);
168 	throughput = throughput * 100;
169 
170 	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI,
171 			  BATADV_CMD_GET_NEIGHBORS);
172 	if (!hdr)
173 		return -ENOBUFS;
174 
175 	if (nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
176 		    hardif_neigh->addr) ||
177 	    nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
178 			   hardif_neigh->if_incoming->net_dev->name) ||
179 	    nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
180 			hardif_neigh->if_incoming->net_dev->ifindex) ||
181 	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
182 			last_seen_msecs) ||
183 	    nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput))
184 		goto nla_put_failure;
185 
186 	genlmsg_end(msg, hdr);
187 	return 0;
188 
189  nla_put_failure:
190 	genlmsg_cancel(msg, hdr);
191 	return -EMSGSIZE;
192 }
193 
194 /**
195  * batadv_v_neigh_dump_hardif() - Dump the  neighbours of a hard interface into
196  *  a message
197  * @msg: Netlink message to dump into
198  * @portid: Port making netlink request
199  * @seq: Sequence number of netlink message
200  * @bat_priv: The bat priv with all the mesh interface information
201  * @hard_iface: The hard interface to be dumped
202  * @idx_s: Entries to be skipped
203  *
204  * This function assumes the caller holds rcu_read_lock().
205  *
206  * Return: Error code, or 0 on success
207  */
208 static int
batadv_v_neigh_dump_hardif(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * hard_iface,int * idx_s)209 batadv_v_neigh_dump_hardif(struct sk_buff *msg, u32 portid, u32 seq,
210 			   struct batadv_priv *bat_priv,
211 			   struct batadv_hard_iface *hard_iface,
212 			   int *idx_s)
213 {
214 	struct batadv_hardif_neigh_node *hardif_neigh;
215 	int idx = 0;
216 
217 	hlist_for_each_entry_rcu(hardif_neigh,
218 				 &hard_iface->neigh_list, list) {
219 		if (idx++ < *idx_s)
220 			continue;
221 
222 		if (batadv_v_neigh_dump_neigh(msg, portid, seq, hardif_neigh)) {
223 			*idx_s = idx - 1;
224 			return -EMSGSIZE;
225 		}
226 	}
227 
228 	*idx_s = 0;
229 	return 0;
230 }
231 
232 /**
233  * batadv_v_neigh_dump() - Dump the neighbours of a hard interface  into a
234  *  message
235  * @msg: Netlink message to dump into
236  * @cb: Control block containing additional options
237  * @bat_priv: The bat priv with all the mesh interface information
238  * @single_hardif: Limit dumping to this hard interface
239  */
240 static void
batadv_v_neigh_dump(struct sk_buff * msg,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_hard_iface * single_hardif)241 batadv_v_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
242 		    struct batadv_priv *bat_priv,
243 		    struct batadv_hard_iface *single_hardif)
244 {
245 	int portid = NETLINK_CB(cb->skb).portid;
246 	struct batadv_hard_iface *hard_iface;
247 	int i_hardif_s = cb->args[0];
248 	struct list_head *iter;
249 	int idx = cb->args[1];
250 	int i_hardif = 0;
251 
252 	rcu_read_lock();
253 	if (single_hardif) {
254 		if (i_hardif_s == 0) {
255 			if (batadv_v_neigh_dump_hardif(msg, portid,
256 						       cb->nlh->nlmsg_seq,
257 						       bat_priv, single_hardif,
258 						       &idx) == 0)
259 				i_hardif++;
260 		}
261 	} else {
262 		netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
263 			if (i_hardif++ < i_hardif_s)
264 				continue;
265 
266 			if (batadv_v_neigh_dump_hardif(msg, portid,
267 						       cb->nlh->nlmsg_seq,
268 						       bat_priv, hard_iface,
269 						       &idx)) {
270 				i_hardif--;
271 				break;
272 			}
273 		}
274 	}
275 	rcu_read_unlock();
276 
277 	cb->args[0] = i_hardif;
278 	cb->args[1] = idx;
279 }
280 
281 /**
282  * batadv_v_orig_dump_subentry() - Dump an originator subentry into a message
283  * @msg: Netlink message to dump into
284  * @portid: Port making netlink request
285  * @seq: Sequence number of netlink message
286  * @bat_priv: The bat priv with all the mesh interface information
287  * @if_outgoing: Limit dump to entries with this outgoing interface
288  * @orig_node: Originator to dump
289  * @neigh_node: Single hops neighbour
290  * @best: Is the best originator
291  *
292  * Return: Error code, or 0 on success
293  */
294 static int
batadv_v_orig_dump_subentry(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing,struct batadv_orig_node * orig_node,struct batadv_neigh_node * neigh_node,bool best)295 batadv_v_orig_dump_subentry(struct sk_buff *msg, u32 portid, u32 seq,
296 			    struct batadv_priv *bat_priv,
297 			    struct batadv_hard_iface *if_outgoing,
298 			    struct batadv_orig_node *orig_node,
299 			    struct batadv_neigh_node *neigh_node,
300 			    bool best)
301 {
302 	struct batadv_neigh_ifinfo *n_ifinfo;
303 	unsigned int last_seen_msecs;
304 	u32 throughput;
305 	void *hdr;
306 
307 	n_ifinfo = batadv_neigh_ifinfo_get(neigh_node, if_outgoing);
308 	if (!n_ifinfo)
309 		return 0;
310 
311 	throughput = n_ifinfo->bat_v.throughput * 100;
312 
313 	batadv_neigh_ifinfo_put(n_ifinfo);
314 
315 	last_seen_msecs = jiffies_to_msecs(jiffies - orig_node->last_seen);
316 
317 	if (if_outgoing != BATADV_IF_DEFAULT &&
318 	    if_outgoing != neigh_node->if_incoming)
319 		return 0;
320 
321 	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, NLM_F_MULTI,
322 			  BATADV_CMD_GET_ORIGINATORS);
323 	if (!hdr)
324 		return -ENOBUFS;
325 
326 	if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, orig_node->orig) ||
327 	    nla_put(msg, BATADV_ATTR_NEIGH_ADDRESS, ETH_ALEN,
328 		    neigh_node->addr) ||
329 	    nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
330 			   neigh_node->if_incoming->net_dev->name) ||
331 	    nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
332 			neigh_node->if_incoming->net_dev->ifindex) ||
333 	    nla_put_u32(msg, BATADV_ATTR_THROUGHPUT, throughput) ||
334 	    nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS,
335 			last_seen_msecs))
336 		goto nla_put_failure;
337 
338 	if (best && nla_put_flag(msg, BATADV_ATTR_FLAG_BEST))
339 		goto nla_put_failure;
340 
341 	genlmsg_end(msg, hdr);
342 	return 0;
343 
344  nla_put_failure:
345 	genlmsg_cancel(msg, hdr);
346 	return -EMSGSIZE;
347 }
348 
349 /**
350  * batadv_v_orig_dump_entry() - Dump an originator entry into a message
351  * @msg: Netlink message to dump into
352  * @portid: Port making netlink request
353  * @seq: Sequence number of netlink message
354  * @bat_priv: The bat priv with all the mesh interface information
355  * @if_outgoing: Limit dump to entries with this outgoing interface
356  * @orig_node: Originator to dump
357  * @sub_s: Number of sub entries to skip
358  *
359  * This function assumes the caller holds rcu_read_lock().
360  *
361  * Return: Error code, or 0 on success
362  */
363 static int
batadv_v_orig_dump_entry(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing,struct batadv_orig_node * orig_node,int * sub_s)364 batadv_v_orig_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
365 			 struct batadv_priv *bat_priv,
366 			 struct batadv_hard_iface *if_outgoing,
367 			 struct batadv_orig_node *orig_node, int *sub_s)
368 {
369 	struct batadv_neigh_node *neigh_node_best;
370 	struct batadv_neigh_node *neigh_node;
371 	int sub = 0;
372 	bool best;
373 
374 	neigh_node_best = batadv_orig_router_get(orig_node, if_outgoing);
375 	if (!neigh_node_best)
376 		goto out;
377 
378 	hlist_for_each_entry_rcu(neigh_node, &orig_node->neigh_list, list) {
379 		if (sub++ < *sub_s)
380 			continue;
381 
382 		best = (neigh_node == neigh_node_best);
383 
384 		if (batadv_v_orig_dump_subentry(msg, portid, seq, bat_priv,
385 						if_outgoing, orig_node,
386 						neigh_node, best)) {
387 			batadv_neigh_node_put(neigh_node_best);
388 
389 			*sub_s = sub - 1;
390 			return -EMSGSIZE;
391 		}
392 	}
393 
394  out:
395 	batadv_neigh_node_put(neigh_node_best);
396 
397 	*sub_s = 0;
398 	return 0;
399 }
400 
401 /**
402  * batadv_v_orig_dump_bucket() - Dump an originator bucket into a message
403  * @msg: Netlink message to dump into
404  * @portid: Port making netlink request
405  * @seq: Sequence number of netlink message
406  * @bat_priv: The bat priv with all the mesh interface information
407  * @if_outgoing: Limit dump to entries with this outgoing interface
408  * @head: Bucket to be dumped
409  * @idx_s: Number of entries to be skipped
410  * @sub: Number of sub entries to be skipped
411  *
412  * Return: Error code, or 0 on success
413  */
414 static int
batadv_v_orig_dump_bucket(struct sk_buff * msg,u32 portid,u32 seq,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing,struct hlist_head * head,int * idx_s,int * sub)415 batadv_v_orig_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq,
416 			  struct batadv_priv *bat_priv,
417 			  struct batadv_hard_iface *if_outgoing,
418 			  struct hlist_head *head, int *idx_s, int *sub)
419 {
420 	struct batadv_orig_node *orig_node;
421 	int idx = 0;
422 
423 	rcu_read_lock();
424 	hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
425 		if (idx++ < *idx_s)
426 			continue;
427 
428 		if (batadv_v_orig_dump_entry(msg, portid, seq, bat_priv,
429 					     if_outgoing, orig_node, sub)) {
430 			rcu_read_unlock();
431 			*idx_s = idx - 1;
432 			return -EMSGSIZE;
433 		}
434 	}
435 	rcu_read_unlock();
436 
437 	*idx_s = 0;
438 	*sub = 0;
439 	return 0;
440 }
441 
442 /**
443  * batadv_v_orig_dump() - Dump the originators into a message
444  * @msg: Netlink message to dump into
445  * @cb: Control block containing additional options
446  * @bat_priv: The bat priv with all the mesh interface information
447  * @if_outgoing: Limit dump to entries with this outgoing interface
448  */
449 static void
batadv_v_orig_dump(struct sk_buff * msg,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_hard_iface * if_outgoing)450 batadv_v_orig_dump(struct sk_buff *msg, struct netlink_callback *cb,
451 		   struct batadv_priv *bat_priv,
452 		   struct batadv_hard_iface *if_outgoing)
453 {
454 	struct batadv_hashtable *hash = bat_priv->orig_hash;
455 	int portid = NETLINK_CB(cb->skb).portid;
456 	int bucket = cb->args[0];
457 	struct hlist_head *head;
458 	int idx = cb->args[1];
459 	int sub = cb->args[2];
460 
461 	while (bucket < hash->size) {
462 		head = &hash->table[bucket];
463 
464 		if (batadv_v_orig_dump_bucket(msg, portid,
465 					      cb->nlh->nlmsg_seq,
466 					      bat_priv, if_outgoing, head, &idx,
467 					      &sub))
468 			break;
469 
470 		bucket++;
471 	}
472 
473 	cb->args[0] = bucket;
474 	cb->args[1] = idx;
475 	cb->args[2] = sub;
476 }
477 
478 /**
479  * batadv_v_neigh_cmp() - compare two B.A.T.M.A.N. V neighbours by throughput
480  * @neigh1: first neighbour to compare
481  * @if_outgoing1: outgoing interface to use for @neigh1
482  * @neigh2: second neighbour to compare
483  * @if_outgoing2: outgoing interface to use for @neigh2
484  *
485  * Return: a positive value if @neigh1 is better, a negative value if @neigh2
486  *  is better and 0 if both have equal throughput
487  */
batadv_v_neigh_cmp(struct batadv_neigh_node * neigh1,struct batadv_hard_iface * if_outgoing1,struct batadv_neigh_node * neigh2,struct batadv_hard_iface * if_outgoing2)488 static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
489 			      struct batadv_hard_iface *if_outgoing1,
490 			      struct batadv_neigh_node *neigh2,
491 			      struct batadv_hard_iface *if_outgoing2)
492 {
493 	struct batadv_neigh_ifinfo *ifinfo1;
494 	struct batadv_neigh_ifinfo *ifinfo2;
495 	int ret = 0;
496 
497 	ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
498 	if (!ifinfo1)
499 		goto err_ifinfo1;
500 
501 	ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
502 	if (!ifinfo2)
503 		goto err_ifinfo2;
504 
505 	ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
506 
507 	batadv_neigh_ifinfo_put(ifinfo2);
508 err_ifinfo2:
509 	batadv_neigh_ifinfo_put(ifinfo1);
510 err_ifinfo1:
511 	return ret;
512 }
513 
514 /**
515  * batadv_v_neigh_is_sob() - check whether two B.A.T.M.A.N. V neighbours have
516  *  a similar or better throughput
517  * @neigh1: first neighbour to compare
518  * @if_outgoing1: outgoing interface to use for @neigh1
519  * @neigh2: second neighbour to compare
520  * @if_outgoing2: outgoing interface to use for @neigh2
521  *
522  * Return: true if the throughput of @neigh2 is at least 3/4 of the
523  *  @neigh1 throughput
524  */
batadv_v_neigh_is_sob(struct batadv_neigh_node * neigh1,struct batadv_hard_iface * if_outgoing1,struct batadv_neigh_node * neigh2,struct batadv_hard_iface * if_outgoing2)525 static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
526 				  struct batadv_hard_iface *if_outgoing1,
527 				  struct batadv_neigh_node *neigh2,
528 				  struct batadv_hard_iface *if_outgoing2)
529 {
530 	struct batadv_neigh_ifinfo *ifinfo1;
531 	struct batadv_neigh_ifinfo *ifinfo2;
532 	bool ret = false;
533 	u32 threshold;
534 
535 	ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
536 	if (!ifinfo1)
537 		goto err_ifinfo1;
538 
539 	ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
540 	if (!ifinfo2)
541 		goto err_ifinfo2;
542 
543 	threshold = ifinfo1->bat_v.throughput / 4;
544 	threshold = ifinfo1->bat_v.throughput - threshold;
545 
546 	ret = ifinfo2->bat_v.throughput > threshold;
547 
548 	batadv_neigh_ifinfo_put(ifinfo2);
549 err_ifinfo2:
550 	batadv_neigh_ifinfo_put(ifinfo1);
551 err_ifinfo1:
552 	return ret;
553 }
554 
555 /**
556  * batadv_v_init_sel_class() - initialize GW selection class
557  * @bat_priv: the bat priv with all the mesh interface information
558  */
batadv_v_init_sel_class(struct batadv_priv * bat_priv)559 static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
560 {
561 	/* set default throughput difference threshold to 5Mbps */
562 	WRITE_ONCE(bat_priv->gw.sel_class, 50);
563 }
564 
565 /**
566  * batadv_v_gw_throughput_get() - retrieve the GW-bandwidth for a given GW
567  * @gw_node: the GW to retrieve the metric for
568  * @bw: the pointer where the metric will be stored. The metric is computed as
569  *  the minimum between the GW advertised throughput and the path throughput to
570  *  it in the mesh
571  *
572  * Return: 0 on success, -1 on failure
573  */
batadv_v_gw_throughput_get(struct batadv_gw_node * gw_node,u32 * bw)574 static int batadv_v_gw_throughput_get(struct batadv_gw_node *gw_node, u32 *bw)
575 {
576 	struct batadv_neigh_ifinfo *router_ifinfo = NULL;
577 	struct batadv_orig_node *orig_node;
578 	struct batadv_neigh_node *router;
579 	int ret = -1;
580 
581 	orig_node = gw_node->orig_node;
582 	router = batadv_orig_router_get(orig_node, BATADV_IF_DEFAULT);
583 	if (!router)
584 		goto out;
585 
586 	router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
587 	if (!router_ifinfo)
588 		goto out;
589 
590 	/* the GW metric is computed as the minimum between the path throughput
591 	 * to reach the GW itself and the advertised bandwidth.
592 	 * This gives us an approximation of the effective throughput that the
593 	 * client can expect via this particular GW node
594 	 */
595 	*bw = router_ifinfo->bat_v.throughput;
596 	*bw = min_t(u32, *bw, gw_node->bandwidth_down);
597 
598 	ret = 0;
599 out:
600 	batadv_neigh_node_put(router);
601 	batadv_neigh_ifinfo_put(router_ifinfo);
602 
603 	return ret;
604 }
605 
606 /**
607  * batadv_v_gw_get_best_gw_node() - retrieve the best GW node
608  * @bat_priv: the bat priv with all the mesh interface information
609  *
610  * Return: the GW node having the best GW-metric, NULL if no GW is known
611  */
612 static struct batadv_gw_node *
batadv_v_gw_get_best_gw_node(struct batadv_priv * bat_priv)613 batadv_v_gw_get_best_gw_node(struct batadv_priv *bat_priv)
614 {
615 	struct batadv_gw_node *curr_gw = NULL;
616 	struct batadv_gw_node *gw_node;
617 	u32 max_bw = 0;
618 	u32 bw;
619 
620 	rcu_read_lock();
621 	hlist_for_each_entry_rcu(gw_node, &bat_priv->gw.gateway_list, list) {
622 		if (!kref_get_unless_zero(&gw_node->refcount))
623 			continue;
624 
625 		if (batadv_v_gw_throughput_get(gw_node, &bw) < 0)
626 			goto next;
627 
628 		if (curr_gw && bw <= max_bw)
629 			goto next;
630 
631 		batadv_gw_node_put(curr_gw);
632 
633 		curr_gw = gw_node;
634 		kref_get(&curr_gw->refcount);
635 		max_bw = bw;
636 
637 next:
638 		batadv_gw_node_put(gw_node);
639 	}
640 	rcu_read_unlock();
641 
642 	return curr_gw;
643 }
644 
645 /**
646  * batadv_v_gw_is_eligible() - check if an originator would be selected as GW
647  * @bat_priv: the bat priv with all the mesh interface information
648  * @curr_gw_orig: originator representing the currently selected GW
649  * @orig_node: the originator representing the new candidate
650  *
651  * Return: true if orig_node can be selected as current GW, false otherwise
652  */
batadv_v_gw_is_eligible(struct batadv_priv * bat_priv,struct batadv_orig_node * curr_gw_orig,struct batadv_orig_node * orig_node)653 static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
654 				    struct batadv_orig_node *curr_gw_orig,
655 				    struct batadv_orig_node *orig_node)
656 {
657 	struct batadv_gw_node *orig_gw = NULL;
658 	struct batadv_gw_node *curr_gw;
659 	u32 orig_throughput;
660 	u32 gw_throughput;
661 	bool ret = false;
662 	u32 threshold;
663 
664 	threshold = READ_ONCE(bat_priv->gw.sel_class);
665 
666 	curr_gw = batadv_gw_node_get(bat_priv, curr_gw_orig);
667 	if (!curr_gw) {
668 		ret = true;
669 		goto out;
670 	}
671 
672 	if (batadv_v_gw_throughput_get(curr_gw, &gw_throughput) < 0) {
673 		ret = true;
674 		goto out;
675 	}
676 
677 	orig_gw = batadv_gw_node_get(bat_priv, orig_node);
678 	if (!orig_gw)
679 		goto out;
680 
681 	if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)
682 		goto out;
683 
684 	if (orig_throughput < gw_throughput)
685 		goto out;
686 
687 	if ((orig_throughput - gw_throughput) < threshold)
688 		goto out;
689 
690 	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
691 		   "Restarting gateway selection: better gateway found (throughput curr: %u, throughput new: %u)\n",
692 		   gw_throughput, orig_throughput);
693 
694 	ret = true;
695 out:
696 	batadv_gw_node_put(curr_gw);
697 	batadv_gw_node_put(orig_gw);
698 
699 	return ret;
700 }
701 
702 /**
703  * batadv_v_gw_dump_entry() - Dump a gateway into a message
704  * @msg: Netlink message to dump into
705  * @portid: Port making netlink request
706  * @cb: Control block containing additional options
707  * @bat_priv: The bat priv with all the mesh interface information
708  * @gw_node: Gateway to be dumped
709  *
710  * Return: Error code, or 0 on success
711  */
batadv_v_gw_dump_entry(struct sk_buff * msg,u32 portid,struct netlink_callback * cb,struct batadv_priv * bat_priv,struct batadv_gw_node * gw_node)712 static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid,
713 				  struct netlink_callback *cb,
714 				  struct batadv_priv *bat_priv,
715 				  struct batadv_gw_node *gw_node)
716 {
717 	struct batadv_neigh_ifinfo *router_ifinfo = NULL;
718 	struct batadv_gw_node *curr_gw = NULL;
719 	struct batadv_neigh_node *router;
720 	int ret = 0;
721 	void *hdr;
722 
723 	router = batadv_orig_router_get(gw_node->orig_node, BATADV_IF_DEFAULT);
724 	if (!router)
725 		goto out;
726 
727 	router_ifinfo = batadv_neigh_ifinfo_get(router, BATADV_IF_DEFAULT);
728 	if (!router_ifinfo)
729 		goto out;
730 
731 	curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
732 
733 	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
734 			  &batadv_netlink_family, NLM_F_MULTI,
735 			  BATADV_CMD_GET_GATEWAYS);
736 	if (!hdr) {
737 		ret = -ENOBUFS;
738 		goto out;
739 	}
740 
741 	genl_dump_check_consistent(cb, hdr);
742 
743 	ret = -EMSGSIZE;
744 
745 	if (curr_gw == gw_node) {
746 		if (nla_put_flag(msg, BATADV_ATTR_FLAG_BEST)) {
747 			genlmsg_cancel(msg, hdr);
748 			goto out;
749 		}
750 	}
751 
752 	if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN,
753 		    gw_node->orig_node->orig)) {
754 		genlmsg_cancel(msg, hdr);
755 		goto out;
756 	}
757 
758 	if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT,
759 			router_ifinfo->bat_v.throughput)) {
760 		genlmsg_cancel(msg, hdr);
761 		goto out;
762 	}
763 
764 	if (nla_put(msg, BATADV_ATTR_ROUTER, ETH_ALEN, router->addr)) {
765 		genlmsg_cancel(msg, hdr);
766 		goto out;
767 	}
768 
769 	if (nla_put_string(msg, BATADV_ATTR_HARD_IFNAME,
770 			   router->if_incoming->net_dev->name)) {
771 		genlmsg_cancel(msg, hdr);
772 		goto out;
773 	}
774 
775 	if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
776 			router->if_incoming->net_dev->ifindex)) {
777 		genlmsg_cancel(msg, hdr);
778 		goto out;
779 	}
780 
781 	if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_DOWN,
782 			gw_node->bandwidth_down)) {
783 		genlmsg_cancel(msg, hdr);
784 		goto out;
785 	}
786 
787 	if (nla_put_u32(msg, BATADV_ATTR_BANDWIDTH_UP, gw_node->bandwidth_up)) {
788 		genlmsg_cancel(msg, hdr);
789 		goto out;
790 	}
791 
792 	genlmsg_end(msg, hdr);
793 	ret = 0;
794 
795 out:
796 	batadv_gw_node_put(curr_gw);
797 	batadv_neigh_ifinfo_put(router_ifinfo);
798 	batadv_neigh_node_put(router);
799 	return ret;
800 }
801 
802 /**
803  * batadv_v_gw_dump() - Dump gateways into a message
804  * @msg: Netlink message to dump into
805  * @cb: Control block containing additional options
806  * @bat_priv: The bat priv with all the mesh interface information
807  */
batadv_v_gw_dump(struct sk_buff * msg,struct netlink_callback * cb,struct batadv_priv * bat_priv)808 static void batadv_v_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
809 			     struct batadv_priv *bat_priv)
810 {
811 	int portid = NETLINK_CB(cb->skb).portid;
812 	struct batadv_gw_node *gw_node;
813 	int idx_skip = cb->args[0];
814 	int idx = 0;
815 
816 	spin_lock_bh(&bat_priv->gw.list_lock);
817 	cb->seq = bat_priv->gw.generation << 1 | 1;
818 
819 	hlist_for_each_entry(gw_node, &bat_priv->gw.gateway_list, list) {
820 		if (idx++ < idx_skip)
821 			continue;
822 
823 		if (batadv_v_gw_dump_entry(msg, portid, cb, bat_priv,
824 					   gw_node)) {
825 			idx_skip = idx - 1;
826 			goto unlock;
827 		}
828 	}
829 
830 	idx_skip = idx;
831 unlock:
832 	spin_unlock_bh(&bat_priv->gw.list_lock);
833 
834 	cb->args[0] = idx_skip;
835 }
836 
837 static struct batadv_algo_ops batadv_batman_v __read_mostly = {
838 	.name = "BATMAN_V",
839 	.iface = {
840 		.activate = batadv_v_iface_activate,
841 		.enable = batadv_v_iface_enable,
842 		.disable = batadv_v_iface_disable,
843 		.update_mac = batadv_v_iface_update_mac,
844 		.primary_set = batadv_v_primary_iface_set,
845 	},
846 	.neigh = {
847 		.hardif_init = batadv_v_hardif_neigh_init,
848 		.cmp = batadv_v_neigh_cmp,
849 		.is_similar_or_better = batadv_v_neigh_is_sob,
850 		.dump = batadv_v_neigh_dump,
851 	},
852 	.orig = {
853 		.dump = batadv_v_orig_dump,
854 	},
855 	.gw = {
856 		.init_sel_class = batadv_v_init_sel_class,
857 		.sel_class_max = U32_MAX,
858 		.get_best_gw_node = batadv_v_gw_get_best_gw_node,
859 		.is_eligible = batadv_v_gw_is_eligible,
860 		.dump = batadv_v_gw_dump,
861 	},
862 };
863 
864 /**
865  * batadv_v_hardif_init() - initialize the algorithm specific fields in the
866  *  hard-interface object
867  * @hard_iface: the hard-interface to initialize
868  */
batadv_v_hardif_init(struct batadv_hard_iface * hard_iface)869 void batadv_v_hardif_init(struct batadv_hard_iface *hard_iface)
870 {
871 	/* enable link throughput auto-detection by setting the throughput
872 	 * override to zero
873 	 */
874 	WRITE_ONCE(hard_iface->bat_v.throughput_override, 0);
875 	WRITE_ONCE(hard_iface->bat_v.elp_interval, 500);
876 
877 	hard_iface->bat_v.aggr_len = 0;
878 	skb_queue_head_init(&hard_iface->bat_v.aggr_list);
879 	hard_iface->bat_v.aggr_list_enabled = false;
880 	INIT_DELAYED_WORK(&hard_iface->bat_v.aggr_wq,
881 			  batadv_v_ogm_aggr_work);
882 	/* make sure it doesn't run until interface gets enabled */
883 	disable_delayed_work(&hard_iface->bat_v.aggr_wq);
884 }
885 
886 /**
887  * batadv_v_mesh_init() - initialize the B.A.T.M.A.N. V private resources for a
888  *  mesh
889  * @bat_priv: the object representing the mesh interface to initialise
890  *
891  * Return: 0 on success or a negative error code otherwise
892  */
batadv_v_mesh_init(struct batadv_priv * bat_priv)893 int batadv_v_mesh_init(struct batadv_priv *bat_priv)
894 {
895 	int ret = 0;
896 
897 	ret = batadv_v_ogm_init(bat_priv);
898 	if (ret < 0)
899 		return ret;
900 
901 	return 0;
902 }
903 
904 /**
905  * batadv_v_mesh_free() - free the B.A.T.M.A.N. V private resources for a mesh
906  * @bat_priv: the object representing the mesh interface to free
907  */
batadv_v_mesh_free(struct batadv_priv * bat_priv)908 void batadv_v_mesh_free(struct batadv_priv *bat_priv)
909 {
910 	batadv_v_ogm_free(bat_priv);
911 }
912 
913 /**
914  * batadv_v_init() - B.A.T.M.A.N. V initialization function
915  *
916  * Description: Takes care of initializing all the subcomponents.
917  * It is invoked upon module load only.
918  *
919  * Return: 0 on success or a negative error code otherwise
920  */
batadv_v_init(void)921 int __init batadv_v_init(void)
922 {
923 	int ret;
924 
925 	/* B.A.T.M.A.N. V echo location protocol packet  */
926 	ret = batadv_recv_handler_register(BATADV_ELP,
927 					   batadv_v_elp_packet_recv);
928 	if (ret < 0)
929 		return ret;
930 
931 	ret = batadv_recv_handler_register(BATADV_OGM2,
932 					   batadv_v_ogm_packet_recv);
933 	if (ret < 0)
934 		goto elp_unregister;
935 
936 	ret = batadv_algo_register(&batadv_batman_v);
937 	if (ret < 0)
938 		goto ogm_unregister;
939 
940 	return ret;
941 
942 ogm_unregister:
943 	batadv_recv_handler_unregister(BATADV_OGM2);
944 
945 elp_unregister:
946 	batadv_recv_handler_unregister(BATADV_ELP);
947 
948 	return ret;
949 }
950 
951 /**
952  * batadv_v_deinit() - B.A.T.M.A.N. V deinitialization function
953  */
batadv_v_deinit(void)954 void batadv_v_deinit(void)
955 {
956 	batadv_recv_handler_unregister(BATADV_OGM2);
957 	batadv_recv_handler_unregister(BATADV_ELP);
958 }
959