1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) B.A.T.M.A.N. contributors:
3 *
4 * Linus Lüssing
5 */
6
7 #include "multicast.h"
8 #include "main.h"
9
10 #include <linux/bug.h>
11 #include <linux/build_bug.h>
12 #include <linux/byteorder/generic.h>
13 #include <linux/compiler.h>
14 #include <linux/errno.h>
15 #include <linux/etherdevice.h>
16 #include <linux/gfp.h>
17 #include <linux/if_ether.h>
18 #include <linux/if_vlan.h>
19 #include <linux/ipv6.h>
20 #include <linux/limits.h>
21 #include <linux/netdevice.h>
22 #include <linux/rculist.h>
23 #include <linux/rcupdate.h>
24 #include <linux/skbuff.h>
25 #include <linux/stddef.h>
26 #include <linux/string.h>
27 #include <linux/types.h>
28 #include <uapi/linux/batadv_packet.h>
29
30 #include "bridge_loop_avoidance.h"
31 #include "originator.h"
32 #include "send.h"
33 #include "translation-table.h"
34
35 #define batadv_mcast_forw_tracker_for_each_dest(dest, num_dests) \
36 for (; num_dests; num_dests--, (dest) += ETH_ALEN)
37
38 #define batadv_mcast_forw_tracker_for_each_dest2(dest1, dest2, num_dests) \
39 for (; num_dests; num_dests--, (dest1) += ETH_ALEN, (dest2) += ETH_ALEN)
40
41 /**
42 * batadv_mcast_forw_skb_push() - skb_push and memorize amount of pushed bytes
43 * @skb: the skb to push onto
44 * @size: the amount of bytes to push
45 * @len: stores the total amount of bytes pushed
46 *
47 * Performs an skb_push() onto the given skb and adds the amount of pushed bytes
48 * to the given len pointer.
49 *
50 * Return: the return value of the skb_push() call.
51 */
batadv_mcast_forw_skb_push(struct sk_buff * skb,size_t size,unsigned short * len)52 static void *batadv_mcast_forw_skb_push(struct sk_buff *skb, size_t size,
53 unsigned short *len)
54 {
55 *len += size;
56 return skb_push(skb, size);
57 }
58
59 /**
60 * batadv_mcast_forw_push_padding() - push 2 padding bytes to skb's front
61 * @skb: the skb to push onto
62 * @tvlv_len: stores the amount of currently pushed TVLV bytes
63 *
64 * Pushes two padding bytes to the front of the given skb.
65 *
66 * Return: On success a pointer to the first byte of the two pushed padding
67 * bytes within the skb. NULL otherwise.
68 */
69 static char *
batadv_mcast_forw_push_padding(struct sk_buff * skb,unsigned short * tvlv_len)70 batadv_mcast_forw_push_padding(struct sk_buff *skb, unsigned short *tvlv_len)
71 {
72 const int pad_len = 2;
73 char *padding;
74
75 if (skb_headroom(skb) < pad_len)
76 return NULL;
77
78 padding = batadv_mcast_forw_skb_push(skb, pad_len, tvlv_len);
79 memset(padding, 0, pad_len);
80
81 return padding;
82 }
83
84 /**
85 * batadv_mcast_forw_push_est_padding() - push padding bytes if necessary
86 * @skb: the skb to potentially push the padding onto
87 * @count: the (estimated) number of originators the multicast packet needs to
88 * be sent to
89 * @tvlv_len: stores the amount of currently pushed TVLV bytes
90 *
91 * If the number of destination entries is even then this adds two
92 * padding bytes to the end of the tracker TVLV.
93 *
94 * Return: true on success or if no padding is needed, false otherwise.
95 */
96 static bool
batadv_mcast_forw_push_est_padding(struct sk_buff * skb,int count,unsigned short * tvlv_len)97 batadv_mcast_forw_push_est_padding(struct sk_buff *skb, int count,
98 unsigned short *tvlv_len)
99 {
100 if (!(count % 2) && !batadv_mcast_forw_push_padding(skb, tvlv_len))
101 return false;
102
103 return true;
104 }
105
106 /**
107 * batadv_mcast_forw_orig_entry() - get orig_node from an hlist node
108 * @node: the hlist node to get the orig_node from
109 * @entry_offset: the offset of the hlist node within the orig_node struct
110 *
111 * Return: The orig_node containing the hlist node on success, NULL on error.
112 */
113 static struct batadv_orig_node *
batadv_mcast_forw_orig_entry(struct hlist_node * node,size_t entry_offset)114 batadv_mcast_forw_orig_entry(struct hlist_node *node,
115 size_t entry_offset)
116 {
117 /* sanity check */
118 switch (entry_offset) {
119 case offsetof(struct batadv_orig_node, mcast_want_all_ipv4_node):
120 case offsetof(struct batadv_orig_node, mcast_want_all_ipv6_node):
121 case offsetof(struct batadv_orig_node, mcast_want_all_rtr4_node):
122 case offsetof(struct batadv_orig_node, mcast_want_all_rtr6_node):
123 break;
124 default:
125 WARN_ON(1);
126 return NULL;
127 }
128
129 return (struct batadv_orig_node *)((void *)node - entry_offset);
130 }
131
132 /**
133 * batadv_mcast_forw_push_dest() - push an originator MAC address onto an skb
134 * @bat_priv: the bat priv with all the mesh interface information
135 * @skb: the skb to push the destination address onto
136 * @vid: the vlan identifier
137 * @orig_node: the originator node to get the MAC address from
138 * @num_dests: a pointer to store the number of pushed addresses in
139 * @tvlv_len: stores the amount of currently pushed TVLV bytes
140 *
141 * If the orig_node is a BLA backbone gateway, if there is not enough skb
142 * headroom available or if num_dests is already at its maximum (65535) then
143 * neither the skb nor num_dests is changed. Otherwise the originator's MAC
144 * address is pushed onto the given skb and num_dests incremented by one.
145 *
146 * Return: true if the orig_node is a backbone gateway or if an orig address
147 * was pushed successfully, false otherwise.
148 */
batadv_mcast_forw_push_dest(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,struct batadv_orig_node * orig_node,unsigned short * num_dests,unsigned short * tvlv_len)149 static bool batadv_mcast_forw_push_dest(struct batadv_priv *bat_priv,
150 struct sk_buff *skb, unsigned short vid,
151 struct batadv_orig_node *orig_node,
152 unsigned short *num_dests,
153 unsigned short *tvlv_len)
154 {
155 BUILD_BUG_ON(sizeof_field(struct batadv_tvlv_mcast_tracker, num_dests)
156 != sizeof(__be16));
157
158 /* Avoid sending to other BLA gateways - they already got the frame from
159 * the LAN side we share with them.
160 * TODO: Refactor to take BLA into account earlier in mode check.
161 */
162 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid))
163 return true;
164
165 if (skb_headroom(skb) < ETH_ALEN || *num_dests == U16_MAX)
166 return false;
167
168 batadv_mcast_forw_skb_push(skb, ETH_ALEN, tvlv_len);
169 ether_addr_copy(skb->data, orig_node->orig);
170 (*num_dests)++;
171
172 return true;
173 }
174
175 /**
176 * batadv_mcast_forw_push_dests_list() - push originators from list onto an skb
177 * @bat_priv: the bat priv with all the mesh interface information
178 * @skb: the skb to push the destination addresses onto
179 * @vid: the vlan identifier
180 * @head: the list to gather originators from
181 * @entry_offset: offset of an hlist node in an orig_node structure
182 * @num_dests: a pointer to store the number of pushed addresses in
183 * @tvlv_len: stores the amount of currently pushed TVLV bytes
184 *
185 * Push the MAC addresses of all originators in the given list onto the given
186 * skb.
187 *
188 * Return: true on success, false otherwise.
189 */
batadv_mcast_forw_push_dests_list(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,struct hlist_head * head,size_t entry_offset,unsigned short * num_dests,unsigned short * tvlv_len)190 static int batadv_mcast_forw_push_dests_list(struct batadv_priv *bat_priv,
191 struct sk_buff *skb,
192 unsigned short vid,
193 struct hlist_head *head,
194 size_t entry_offset,
195 unsigned short *num_dests,
196 unsigned short *tvlv_len)
197 {
198 struct batadv_orig_node *orig_node;
199 struct hlist_node *node;
200
201 rcu_read_lock();
202 __hlist_for_each_rcu(node, head) {
203 orig_node = batadv_mcast_forw_orig_entry(node, entry_offset);
204 if (!orig_node ||
205 !batadv_mcast_forw_push_dest(bat_priv, skb, vid, orig_node,
206 num_dests, tvlv_len)) {
207 rcu_read_unlock();
208 return false;
209 }
210 }
211 rcu_read_unlock();
212
213 return true;
214 }
215
216 /**
217 * batadv_mcast_forw_push_tt() - push originators with interest through TT
218 * @bat_priv: the bat priv with all the mesh interface information
219 * @skb: the skb to push the destination addresses onto
220 * @vid: the vlan identifier
221 * @num_dests: a pointer to store the number of pushed addresses in
222 * @tvlv_len: stores the amount of currently pushed TVLV bytes
223 *
224 * Push the MAC addresses of all originators which have indicated interest in
225 * this multicast packet through the translation table onto the given skb.
226 *
227 * Return: true on success, false otherwise.
228 */
229 static bool
batadv_mcast_forw_push_tt(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,unsigned short * num_dests,unsigned short * tvlv_len)230 batadv_mcast_forw_push_tt(struct batadv_priv *bat_priv, struct sk_buff *skb,
231 unsigned short vid, unsigned short *num_dests,
232 unsigned short *tvlv_len)
233 {
234 struct batadv_tt_orig_list_entry *orig_entry;
235 struct batadv_tt_global_entry *tt_global;
236 const u8 *addr = eth_hdr(skb)->h_dest;
237 int ret = true; /* ok */
238
239 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
240 if (!tt_global)
241 goto out;
242
243 rcu_read_lock();
244 hlist_for_each_entry_rcu(orig_entry, &tt_global->orig_list, list) {
245 if (!batadv_mcast_forw_push_dest(bat_priv, skb, vid,
246 orig_entry->orig_node,
247 num_dests, tvlv_len)) {
248 ret = false;
249 break;
250 }
251 }
252 rcu_read_unlock();
253
254 batadv_tt_global_entry_put(tt_global);
255
256 out:
257 return ret;
258 }
259
260 /**
261 * batadv_mcast_forw_push_want_all() - push originators with want-all flag
262 * @bat_priv: the bat priv with all the mesh interface information
263 * @skb: the skb to push the destination addresses onto
264 * @vid: the vlan identifier
265 * @num_dests: a pointer to store the number of pushed addresses in
266 * @tvlv_len: stores the amount of currently pushed TVLV bytes
267 *
268 * Push the MAC addresses of all originators which have indicated interest in
269 * this multicast packet through the want-all flag onto the given skb.
270 *
271 * Return: true on success, false otherwise.
272 */
batadv_mcast_forw_push_want_all(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,unsigned short * num_dests,unsigned short * tvlv_len)273 static bool batadv_mcast_forw_push_want_all(struct batadv_priv *bat_priv,
274 struct sk_buff *skb,
275 unsigned short vid,
276 unsigned short *num_dests,
277 unsigned short *tvlv_len)
278 {
279 struct hlist_head *head = NULL;
280 size_t offset;
281 int ret;
282
283 switch (eth_hdr(skb)->h_proto) {
284 case htons(ETH_P_IP):
285 head = &bat_priv->mcast.want_all_ipv4_list;
286 offset = offsetof(struct batadv_orig_node,
287 mcast_want_all_ipv4_node);
288 break;
289 case htons(ETH_P_IPV6):
290 head = &bat_priv->mcast.want_all_ipv6_list;
291 offset = offsetof(struct batadv_orig_node,
292 mcast_want_all_ipv6_node);
293 break;
294 default:
295 return false;
296 }
297
298 ret = batadv_mcast_forw_push_dests_list(bat_priv, skb, vid, head,
299 offset, num_dests, tvlv_len);
300 if (!ret)
301 return false;
302
303 return true;
304 }
305
306 /**
307 * batadv_mcast_forw_push_want_rtr() - push originators with want-router flag
308 * @bat_priv: the bat priv with all the mesh interface information
309 * @skb: the skb to push the destination addresses onto
310 * @vid: the vlan identifier
311 * @num_dests: a pointer to store the number of pushed addresses in
312 * @tvlv_len: stores the amount of currently pushed TVLV bytes
313 *
314 * Push the MAC addresses of all originators which have indicated interest in
315 * this multicast packet through the want-all-rtr flag onto the given skb.
316 *
317 * Return: true on success, false otherwise.
318 */
batadv_mcast_forw_push_want_rtr(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,unsigned short * num_dests,unsigned short * tvlv_len)319 static bool batadv_mcast_forw_push_want_rtr(struct batadv_priv *bat_priv,
320 struct sk_buff *skb,
321 unsigned short vid,
322 unsigned short *num_dests,
323 unsigned short *tvlv_len)
324 {
325 struct hlist_head *head = NULL;
326 size_t offset;
327 int ret;
328
329 switch (eth_hdr(skb)->h_proto) {
330 case htons(ETH_P_IP):
331 head = &bat_priv->mcast.want_all_rtr4_list;
332 offset = offsetof(struct batadv_orig_node,
333 mcast_want_all_rtr4_node);
334 break;
335 case htons(ETH_P_IPV6):
336 head = &bat_priv->mcast.want_all_rtr6_list;
337 offset = offsetof(struct batadv_orig_node,
338 mcast_want_all_rtr6_node);
339 break;
340 default:
341 return false;
342 }
343
344 ret = batadv_mcast_forw_push_dests_list(bat_priv, skb, vid, head,
345 offset, num_dests, tvlv_len);
346 if (!ret)
347 return false;
348
349 return true;
350 }
351
352 /**
353 * batadv_mcast_forw_scrape() - remove bytes within skb data
354 * @skb: the skb to remove bytes from
355 * @offset: the offset from the skb data from which to scrape
356 * @len: the amount of bytes to scrape starting from the offset
357 *
358 * Scrapes/removes len bytes from the given skb at the given offset from the
359 * skb data.
360 *
361 * Caller needs to ensure that the region from the skb data's start up
362 * to/including the to be removed bytes are linearized.
363 */
batadv_mcast_forw_scrape(struct sk_buff * skb,unsigned short offset,unsigned short len)364 static void batadv_mcast_forw_scrape(struct sk_buff *skb,
365 unsigned short offset,
366 unsigned short len)
367 {
368 char *from;
369 char *to;
370
371 SKB_LINEAR_ASSERT(skb);
372
373 to = skb_pull(skb, len);
374 from = to - len;
375
376 memmove(to, from, offset);
377 }
378
379 /**
380 * batadv_mcast_forw_push_scrape_padding() - remove TVLV padding
381 * @skb: the skb to potentially adjust the TVLV's padding on
382 * @tvlv_len: stores the amount of currently pushed TVLV bytes
383 *
384 * Remove two padding bytes from the end of the multicast tracker TVLV,
385 * from before the payload data.
386 *
387 * Caller needs to ensure that the TVLV bytes are linearized.
388 */
batadv_mcast_forw_push_scrape_padding(struct sk_buff * skb,unsigned short * tvlv_len)389 static void batadv_mcast_forw_push_scrape_padding(struct sk_buff *skb,
390 unsigned short *tvlv_len)
391 {
392 const int pad_len = 2;
393
394 batadv_mcast_forw_scrape(skb, *tvlv_len - pad_len, pad_len);
395 *tvlv_len -= pad_len;
396 }
397
398 /**
399 * batadv_mcast_forw_push_insert_padding() - insert TVLV padding
400 * @skb: the skb to potentially adjust the TVLV's padding on
401 * @tvlv_len: stores the amount of currently pushed TVLV bytes
402 *
403 * Inserts two padding bytes at the end of the multicast tracker TVLV,
404 * before the payload data in the given skb.
405 *
406 * Return: true on success, false otherwise.
407 */
batadv_mcast_forw_push_insert_padding(struct sk_buff * skb,unsigned short * tvlv_len)408 static bool batadv_mcast_forw_push_insert_padding(struct sk_buff *skb,
409 unsigned short *tvlv_len)
410 {
411 unsigned short offset = *tvlv_len;
412 char *from = skb->data;
413 char *to;
414
415 to = batadv_mcast_forw_push_padding(skb, tvlv_len);
416 if (!to)
417 return false;
418
419 memmove(to, from, offset);
420 memset(to + offset, 0, *tvlv_len - offset);
421 return true;
422 }
423
424 /**
425 * batadv_mcast_forw_push_adjust_padding() - adjust padding if necessary
426 * @skb: the skb to potentially adjust the TVLV's padding on
427 * @count: the estimated number of originators the multicast packet needs to
428 * be sent to
429 * @num_dests_pushed: the number of originators that were actually added to the
430 * multicast packet's tracker TVLV
431 * @tvlv_len: stores the amount of currently pushed TVLV bytes
432 *
433 * Adjusts the padding in the multicast packet's tracker TVLV depending on the
434 * initially estimated amount of destinations versus the amount of destinations
435 * that were actually added to the tracker TVLV.
436 *
437 * If the initial estimate was correct or at least the oddness was the same then
438 * no padding adjustment is performed.
439 * If the initially estimated number was even, so padding was initially added,
440 * but it turned out to be odd then padding is removed.
441 * If the initially estimated number was odd, so no padding was initially added,
442 * but it turned out to be even then padding is added.
443 *
444 * Return: true if no padding adjustment is needed or the adjustment was
445 * successful, false otherwise.
446 */
447 static bool
batadv_mcast_forw_push_adjust_padding(struct sk_buff * skb,int * count,unsigned short num_dests_pushed,unsigned short * tvlv_len)448 batadv_mcast_forw_push_adjust_padding(struct sk_buff *skb, int *count,
449 unsigned short num_dests_pushed,
450 unsigned short *tvlv_len)
451 {
452 int ret = true;
453
454 if (likely((num_dests_pushed % 2) == (*count % 2)))
455 goto out;
456
457 /**
458 * estimated even number of destinations, but turned out to be odd
459 * -> remove padding
460 */
461 if (!(*count % 2) && (num_dests_pushed % 2))
462 batadv_mcast_forw_push_scrape_padding(skb, tvlv_len);
463 /**
464 * estimated odd number of destinations, but turned out to be even
465 * -> add padding
466 */
467 else if ((*count % 2) && (!(num_dests_pushed % 2)))
468 ret = batadv_mcast_forw_push_insert_padding(skb, tvlv_len);
469
470 out:
471 *count = num_dests_pushed;
472 return ret;
473 }
474
475 /**
476 * batadv_mcast_forw_push_dests() - push originator addresses onto an skb
477 * @bat_priv: the bat priv with all the mesh interface information
478 * @skb: the skb to push the destination addresses onto
479 * @vid: the vlan identifier
480 * @is_routable: indicates whether the destination is routable
481 * @count: the number of originators the multicast packet needs to be sent to
482 * @tvlv_len: stores the amount of currently pushed TVLV bytes
483 *
484 * Push the MAC addresses of all originators which have indicated interest in
485 * this multicast packet onto the given skb.
486 *
487 * Return: -ENOMEM if there is not enough skb headroom available. Otherwise, on
488 * success 0.
489 */
490 static int
batadv_mcast_forw_push_dests(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,int is_routable,int * count,unsigned short * tvlv_len)491 batadv_mcast_forw_push_dests(struct batadv_priv *bat_priv, struct sk_buff *skb,
492 unsigned short vid, int is_routable, int *count,
493 unsigned short *tvlv_len)
494 {
495 unsigned short num_dests = 0;
496
497 if (!batadv_mcast_forw_push_est_padding(skb, *count, tvlv_len))
498 goto err;
499
500 if (!batadv_mcast_forw_push_tt(bat_priv, skb, vid, &num_dests,
501 tvlv_len))
502 goto err;
503
504 if (!batadv_mcast_forw_push_want_all(bat_priv, skb, vid, &num_dests,
505 tvlv_len))
506 goto err;
507
508 if (is_routable &&
509 !batadv_mcast_forw_push_want_rtr(bat_priv, skb, vid, &num_dests,
510 tvlv_len))
511 goto err;
512
513 if (!batadv_mcast_forw_push_adjust_padding(skb, count, num_dests,
514 tvlv_len))
515 goto err;
516
517 return 0;
518 err:
519 return -ENOMEM;
520 }
521
522 /**
523 * batadv_mcast_forw_push_tracker() - push a multicast tracker TVLV header
524 * @skb: the skb to push the tracker TVLV onto
525 * @num_dests: the number of destination addresses to set in the header
526 * @tvlv_len: stores the amount of currently pushed TVLV bytes
527 *
528 * Pushes a multicast tracker TVLV header onto the given skb, including the
529 * generic TVLV header but excluding the destination MAC addresses.
530 *
531 * The provided num_dests value is taken into consideration to set the
532 * num_dests field in the tracker header and to set the appropriate TVLV length
533 * value fields.
534 *
535 * Return: -ENOMEM if there is not enough skb headroom available. Otherwise, on
536 * success 0.
537 */
batadv_mcast_forw_push_tracker(struct sk_buff * skb,int num_dests,unsigned short * tvlv_len)538 static int batadv_mcast_forw_push_tracker(struct sk_buff *skb, int num_dests,
539 unsigned short *tvlv_len)
540 {
541 struct batadv_tvlv_mcast_tracker *mcast_tracker;
542 struct batadv_tvlv_hdr *tvlv_hdr;
543 unsigned int tvlv_value_len;
544
545 if (skb_headroom(skb) < sizeof(*mcast_tracker) + sizeof(*tvlv_hdr))
546 return -ENOMEM;
547
548 tvlv_value_len = sizeof(*mcast_tracker) + *tvlv_len;
549 if (tvlv_value_len + sizeof(*tvlv_hdr) > U16_MAX)
550 return -ENOMEM;
551
552 batadv_mcast_forw_skb_push(skb, sizeof(*mcast_tracker), tvlv_len);
553 mcast_tracker = (struct batadv_tvlv_mcast_tracker *)skb->data;
554 mcast_tracker->num_dests = htons(num_dests);
555
556 skb_reset_network_header(skb);
557
558 batadv_mcast_forw_skb_push(skb, sizeof(*tvlv_hdr), tvlv_len);
559 tvlv_hdr = (struct batadv_tvlv_hdr *)skb->data;
560 tvlv_hdr->type = BATADV_TVLV_MCAST_TRACKER;
561 tvlv_hdr->version = 1;
562 tvlv_hdr->len = htons(tvlv_value_len);
563
564 return 0;
565 }
566
567 /**
568 * batadv_mcast_forw_push_tvlvs() - push a multicast tracker TVLV onto an skb
569 * @bat_priv: the bat priv with all the mesh interface information
570 * @skb: the skb to push the tracker TVLV onto
571 * @vid: the vlan identifier
572 * @is_routable: indicates whether the destination is routable
573 * @count: the number of originators the multicast packet needs to be sent to
574 * @tvlv_len: stores the amount of currently pushed TVLV bytes
575 *
576 * Pushes a multicast tracker TVLV onto the given skb, including the collected
577 * destination MAC addresses and the generic TVLV header.
578 *
579 * Return: -ENOMEM if there is not enough skb headroom available. Otherwise, on
580 * success 0.
581 */
582 static int
batadv_mcast_forw_push_tvlvs(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,int is_routable,int count,unsigned short * tvlv_len)583 batadv_mcast_forw_push_tvlvs(struct batadv_priv *bat_priv, struct sk_buff *skb,
584 unsigned short vid, int is_routable, int count,
585 unsigned short *tvlv_len)
586 {
587 int ret;
588
589 ret = batadv_mcast_forw_push_dests(bat_priv, skb, vid, is_routable,
590 &count, tvlv_len);
591 if (ret < 0)
592 return ret;
593
594 ret = batadv_mcast_forw_push_tracker(skb, count, tvlv_len);
595 if (ret < 0)
596 return ret;
597
598 return 0;
599 }
600
601 /**
602 * batadv_mcast_forw_push_hdr() - push a multicast packet header onto an skb
603 * @skb: the skb to push the header onto
604 * @tvlv_len: the total TVLV length value to set in the header
605 *
606 * Pushes a batman-adv multicast packet header onto the given skb and sets
607 * the provided total TVLV length value in it.
608 *
609 * Caller needs to ensure enough skb headroom is available.
610 *
611 * Return: -ENOMEM if there is not enough skb headroom available. Otherwise, on
612 * success 0.
613 */
614 static int
batadv_mcast_forw_push_hdr(struct sk_buff * skb,unsigned short tvlv_len)615 batadv_mcast_forw_push_hdr(struct sk_buff *skb, unsigned short tvlv_len)
616 {
617 struct batadv_mcast_packet *mcast_packet;
618
619 if (skb_headroom(skb) < sizeof(*mcast_packet))
620 return -ENOMEM;
621
622 skb_push(skb, sizeof(*mcast_packet));
623
624 mcast_packet = (struct batadv_mcast_packet *)skb->data;
625 mcast_packet->version = BATADV_COMPAT_VERSION;
626 mcast_packet->ttl = BATADV_TTL;
627 mcast_packet->packet_type = BATADV_MCAST;
628 mcast_packet->reserved = 0;
629 mcast_packet->tvlv_len = htons(tvlv_len);
630
631 return 0;
632 }
633
634 /**
635 * batadv_mcast_forw_scrub_dests() - scrub destinations in a tracker TVLV
636 * @bat_priv: the bat priv with all the mesh interface information
637 * @comp_neigh: next hop neighbor to scrub+collect destinations for
638 * @dest: start MAC entry in original skb's tracker TVLV
639 * @next_dest: start MAC entry in to be sent skb's tracker TVLV
640 * @num_dests: number of remaining destination MAC entries to iterate over
641 *
642 * This sorts destination entries into either the original batman-adv
643 * multicast packet or the skb (copy) that is going to be sent to comp_neigh
644 * next.
645 *
646 * In preparation for the next, to be (unicast) transmitted batman-adv multicast
647 * packet skb to be sent to the given neighbor node, tries to collect all
648 * originator MAC addresses that have the given neighbor node as their next hop
649 * in the to be transmitted skb (copy), which next_dest points into. That is we
650 * zero all destination entries in next_dest which do not have comp_neigh as
651 * their next hop. And zero all destination entries in the original skb that
652 * would have comp_neigh as their next hop (to avoid redundant transmissions and
653 * duplicated payload later).
654 */
655 static void
batadv_mcast_forw_scrub_dests(struct batadv_priv * bat_priv,struct batadv_neigh_node * comp_neigh,u8 * dest,u8 * next_dest,u16 num_dests)656 batadv_mcast_forw_scrub_dests(struct batadv_priv *bat_priv,
657 struct batadv_neigh_node *comp_neigh, u8 *dest,
658 u8 *next_dest, u16 num_dests)
659 {
660 struct batadv_neigh_node *next_neigh;
661
662 /* skip first entry, this is what we are comparing with */
663 eth_zero_addr(dest);
664 dest += ETH_ALEN;
665 next_dest += ETH_ALEN;
666 num_dests--;
667
668 batadv_mcast_forw_tracker_for_each_dest2(dest, next_dest, num_dests) {
669 if (is_zero_ether_addr(next_dest))
670 continue;
671
672 /* sanity check, we expect unicast destinations */
673 if (is_multicast_ether_addr(next_dest)) {
674 eth_zero_addr(dest);
675 eth_zero_addr(next_dest);
676 continue;
677 }
678
679 next_neigh = batadv_orig_to_router(bat_priv, next_dest, NULL);
680 if (!next_neigh) {
681 eth_zero_addr(next_dest);
682 continue;
683 }
684
685 if (!batadv_compare_eth(next_neigh->addr, comp_neigh->addr)) {
686 eth_zero_addr(next_dest);
687 batadv_neigh_node_put(next_neigh);
688 continue;
689 }
690
691 /* found an entry for our next packet to transmit, so remove it
692 * from the original packet
693 */
694 eth_zero_addr(dest);
695 batadv_neigh_node_put(next_neigh);
696 }
697 }
698
699 /**
700 * batadv_mcast_forw_shrink_fill() - swap slot with next non-zero destination
701 * @slot: the to be filled zero-MAC destination entry in a tracker TVLV
702 * @num_dests_slot: remaining entries in tracker TVLV from/including slot
703 *
704 * Searches for the next non-zero-MAC destination entry in a tracker TVLV after
705 * the given slot pointer. And if found, swaps it with the zero-MAC destination
706 * entry which the slot points to.
707 *
708 * Return: true if slot was swapped/filled successfully, false otherwise.
709 */
batadv_mcast_forw_shrink_fill(u8 * slot,u16 num_dests_slot)710 static bool batadv_mcast_forw_shrink_fill(u8 *slot, u16 num_dests_slot)
711 {
712 u16 num_dests_filler;
713 u8 *filler;
714
715 /* sanity check, should not happen */
716 if (!num_dests_slot)
717 return false;
718
719 num_dests_filler = num_dests_slot - 1;
720 filler = slot + ETH_ALEN;
721
722 /* find a candidate to fill the empty slot */
723 batadv_mcast_forw_tracker_for_each_dest(filler, num_dests_filler) {
724 if (is_zero_ether_addr(filler))
725 continue;
726
727 ether_addr_copy(slot, filler);
728 eth_zero_addr(filler);
729 return true;
730 }
731
732 return false;
733 }
734
735 /**
736 * batadv_mcast_forw_shrink_pack_dests() - pack destinations of a tracker TVLV
737 * @skb: the batman-adv multicast packet to compact destinations in
738 *
739 * Compacts the originator destination MAC addresses in the multicast tracker
740 * TVLV of the given multicast packet. This is done by moving all non-zero
741 * MAC addresses in direction of the skb head and all zero MAC addresses in skb
742 * tail direction, within the multicast tracker TVLV.
743 *
744 * Return: The number of consecutive zero MAC address destinations which are
745 * now at the end of the multicast tracker TVLV.
746 */
batadv_mcast_forw_shrink_pack_dests(struct sk_buff * skb)747 static int batadv_mcast_forw_shrink_pack_dests(struct sk_buff *skb)
748 {
749 struct batadv_tvlv_mcast_tracker *mcast_tracker;
750 unsigned char *skb_net_hdr;
751 u16 num_dests_slot;
752 u8 *slot;
753
754 skb_net_hdr = skb_network_header(skb);
755 mcast_tracker = (struct batadv_tvlv_mcast_tracker *)skb_net_hdr;
756 num_dests_slot = ntohs(mcast_tracker->num_dests);
757
758 slot = (u8 *)mcast_tracker + sizeof(*mcast_tracker);
759
760 batadv_mcast_forw_tracker_for_each_dest(slot, num_dests_slot) {
761 /* find an empty slot */
762 if (!is_zero_ether_addr(slot))
763 continue;
764
765 if (!batadv_mcast_forw_shrink_fill(slot, num_dests_slot))
766 /* could not find a filler, so we successfully packed
767 * and can stop - and must not reduce num_dests_slot!
768 */
769 break;
770 }
771
772 /* num_dests_slot is now the amount of reduced, zeroed
773 * destinations at the end of the tracker TVLV
774 */
775 return num_dests_slot;
776 }
777
778 /**
779 * batadv_mcast_forw_shrink_align_offset() - get new alignment offset
780 * @num_dests_old: the old, to be updated amount of destination nodes
781 * @num_dests_reduce: the number of destinations that were removed
782 *
783 * Calculates the amount of potential extra alignment offset that is needed to
784 * adjust the TVLV padding after the change in destination nodes.
785 *
786 * Return:
787 * 0: If no change to padding is needed.
788 * 2: If padding needs to be removed.
789 * -2: If padding needs to be added.
790 */
791 static short
batadv_mcast_forw_shrink_align_offset(unsigned int num_dests_old,unsigned int num_dests_reduce)792 batadv_mcast_forw_shrink_align_offset(unsigned int num_dests_old,
793 unsigned int num_dests_reduce)
794 {
795 /* even amount of removed destinations -> no alignment change */
796 if (!(num_dests_reduce % 2))
797 return 0;
798
799 /* even to odd amount of destinations -> remove padding */
800 if (!(num_dests_old % 2))
801 return 2;
802
803 /* odd to even amount of destinations -> add padding */
804 return -2;
805 }
806
807 /**
808 * batadv_mcast_forw_shrink_update_headers() - update shrunk mc packet headers
809 * @skb: the batman-adv multicast packet to update headers of
810 * @num_dests_reduce: the number of destinations that were removed
811 *
812 * This updates any fields of a batman-adv multicast packet that are affected
813 * by the reduced number of destinations in the multicast tracket TVLV. In
814 * particular this updates:
815 *
816 * The num_dest field of the multicast tracker TVLV.
817 * The TVLV length field of the according generic TVLV header.
818 * The batman-adv multicast packet's total TVLV length field.
819 *
820 * Return: The offset in skb's tail direction at which the new batman-adv
821 * multicast packet header needs to start.
822 */
823 static unsigned int
batadv_mcast_forw_shrink_update_headers(struct sk_buff * skb,unsigned int num_dests_reduce)824 batadv_mcast_forw_shrink_update_headers(struct sk_buff *skb,
825 unsigned int num_dests_reduce)
826 {
827 struct batadv_tvlv_mcast_tracker *mcast_tracker;
828 struct batadv_mcast_packet *mcast_packet;
829 struct batadv_tvlv_hdr *tvlv_hdr;
830 unsigned char *skb_net_hdr;
831 unsigned int offset;
832 short align_offset;
833 u16 num_dests;
834
835 skb_net_hdr = skb_network_header(skb);
836 mcast_tracker = (struct batadv_tvlv_mcast_tracker *)skb_net_hdr;
837 num_dests = ntohs(mcast_tracker->num_dests);
838
839 align_offset = batadv_mcast_forw_shrink_align_offset(num_dests,
840 num_dests_reduce);
841 offset = ETH_ALEN * num_dests_reduce + align_offset;
842 num_dests -= num_dests_reduce;
843
844 /* update tracker header */
845 mcast_tracker->num_dests = htons(num_dests);
846
847 /* update tracker's tvlv header's length field */
848 tvlv_hdr = (struct batadv_tvlv_hdr *)(skb_network_header(skb) -
849 sizeof(*tvlv_hdr));
850 tvlv_hdr->len = htons(ntohs(tvlv_hdr->len) - offset);
851
852 /* update multicast packet header's tvlv length field */
853 mcast_packet = (struct batadv_mcast_packet *)skb->data;
854 mcast_packet->tvlv_len = htons(ntohs(mcast_packet->tvlv_len) - offset);
855
856 return offset;
857 }
858
859 /**
860 * batadv_mcast_forw_shrink_move_headers() - move multicast headers by offset
861 * @skb: the batman-adv multicast packet to move headers for
862 * @offset: a non-negative offset to move headers by, towards the skb tail
863 *
864 * Moves the batman-adv multicast packet header, its multicast tracker TVLV and
865 * any TVLVs in between by the given offset in direction towards the tail.
866 */
867 static void
batadv_mcast_forw_shrink_move_headers(struct sk_buff * skb,unsigned int offset)868 batadv_mcast_forw_shrink_move_headers(struct sk_buff *skb, unsigned int offset)
869 {
870 struct batadv_tvlv_mcast_tracker *mcast_tracker;
871 unsigned char *skb_net_hdr;
872 unsigned int len;
873 u16 num_dests;
874
875 skb_net_hdr = skb_network_header(skb);
876 mcast_tracker = (struct batadv_tvlv_mcast_tracker *)skb_net_hdr;
877 num_dests = ntohs(mcast_tracker->num_dests);
878 len = skb_network_offset(skb) + sizeof(*mcast_tracker);
879 len += num_dests * ETH_ALEN;
880
881 batadv_mcast_forw_scrape(skb, len, offset);
882 }
883
884 /**
885 * batadv_mcast_forw_shrink_tracker() - remove zero addresses in a tracker tvlv
886 * @skb: the batman-adv multicast packet to (potentially) shrink
887 *
888 * Removes all destinations with a zero MAC addresses (00:00:00:00:00:00) from
889 * the given batman-adv multicast packet's tracker TVLV and updates headers
890 * accordingly to maintain a valid batman-adv multicast packet.
891 */
batadv_mcast_forw_shrink_tracker(struct sk_buff * skb)892 static void batadv_mcast_forw_shrink_tracker(struct sk_buff *skb)
893 {
894 unsigned int offset;
895 u16 dests_reduced;
896
897 dests_reduced = batadv_mcast_forw_shrink_pack_dests(skb);
898 if (!dests_reduced)
899 return;
900
901 offset = batadv_mcast_forw_shrink_update_headers(skb, dests_reduced);
902 batadv_mcast_forw_shrink_move_headers(skb, offset);
903 }
904
905 /**
906 * batadv_mcast_forw_packet() - forward a batman-adv multicast packet
907 * @bat_priv: the bat priv with all the mesh interface information
908 * @skb: the received or locally generated batman-adv multicast packet
909 * @local_xmit: indicates that the packet was locally generated and not received
910 *
911 * Parses the tracker TVLV of a batman-adv multicast packet and forwards the
912 * packet as indicated in this TVLV.
913 *
914 * Caller needs to set the skb network header to the start of the multicast
915 * tracker TVLV (excluding the generic TVLV header) and the skb transport header
916 * to the next byte after this multicast tracker TVLV.
917 *
918 * Caller needs to free the skb.
919 *
920 * Return: NET_RX_SUCCESS or NET_RX_DROP on success or a negative error
921 * code on failure. NET_RX_SUCCESS if the received packet is supposed to be
922 * decapsulated and forwarded to the own mesh interface, NET_RX_DROP otherwise.
923 */
batadv_mcast_forw_packet(struct batadv_priv * bat_priv,struct sk_buff * skb,bool local_xmit)924 static int batadv_mcast_forw_packet(struct batadv_priv *bat_priv,
925 struct sk_buff *skb, bool local_xmit)
926 {
927 struct batadv_tvlv_mcast_tracker *mcast_tracker;
928 struct batadv_neigh_node *neigh_node;
929 struct sk_buff *nexthop_skb;
930 unsigned char *skb_net_hdr;
931 bool local_recv = false;
932 unsigned int tvlv_len;
933 unsigned long offset;
934 bool xmitted = false;
935 u8 *next_dest;
936 u16 num_dests;
937 u8 *dest;
938 int ret;
939
940 /* (at least) TVLV part needs to be linearized */
941 SKB_LINEAR_ASSERT(skb);
942
943 /* check if batadv_tvlv_mcast_tracker header is within skb length */
944 if (sizeof(*mcast_tracker) > skb_network_header_len(skb))
945 return -EINVAL;
946
947 skb_net_hdr = skb_network_header(skb);
948 mcast_tracker = (struct batadv_tvlv_mcast_tracker *)skb_net_hdr;
949 num_dests = ntohs(mcast_tracker->num_dests);
950
951 dest = (u8 *)mcast_tracker + sizeof(*mcast_tracker);
952
953 /* check if full tracker tvlv is within skb length */
954 tvlv_len = sizeof(*mcast_tracker) + ETH_ALEN * num_dests;
955 if (tvlv_len > skb_network_header_len(skb))
956 return -EINVAL;
957
958 /* invalidate checksum: */
959 skb->ip_summed = CHECKSUM_NONE;
960
961 batadv_mcast_forw_tracker_for_each_dest(dest, num_dests) {
962 if (is_zero_ether_addr(dest))
963 continue;
964
965 /* only unicast originator addresses supported */
966 if (is_multicast_ether_addr(dest)) {
967 eth_zero_addr(dest);
968 continue;
969 }
970
971 if (batadv_is_my_mac(bat_priv, dest)) {
972 eth_zero_addr(dest);
973 local_recv = true;
974 continue;
975 }
976
977 neigh_node = batadv_orig_to_router(bat_priv, dest, NULL);
978 if (!neigh_node) {
979 eth_zero_addr(dest);
980 continue;
981 }
982
983 nexthop_skb = skb_copy(skb, GFP_ATOMIC);
984 if (!nexthop_skb) {
985 batadv_neigh_node_put(neigh_node);
986 return -ENOMEM;
987 }
988
989 offset = dest - skb->data;
990 next_dest = nexthop_skb->data + offset;
991
992 batadv_mcast_forw_scrub_dests(bat_priv, neigh_node, dest,
993 next_dest, num_dests);
994 batadv_mcast_forw_shrink_tracker(nexthop_skb);
995
996 batadv_inc_counter(bat_priv, BATADV_CNT_MCAST_TX);
997 batadv_add_counter(bat_priv, BATADV_CNT_MCAST_TX_BYTES,
998 nexthop_skb->len + ETH_HLEN);
999 xmitted = true;
1000 ret = batadv_send_unicast_skb(nexthop_skb, neigh_node);
1001
1002 batadv_neigh_node_put(neigh_node);
1003
1004 if (ret < 0)
1005 return ret;
1006 }
1007
1008 if (xmitted) {
1009 if (local_xmit) {
1010 batadv_inc_counter(bat_priv, BATADV_CNT_MCAST_TX_LOCAL);
1011 batadv_add_counter(bat_priv,
1012 BATADV_CNT_MCAST_TX_LOCAL_BYTES,
1013 skb->len -
1014 skb_transport_offset(skb));
1015 } else {
1016 batadv_inc_counter(bat_priv, BATADV_CNT_MCAST_FWD);
1017 batadv_add_counter(bat_priv, BATADV_CNT_MCAST_FWD_BYTES,
1018 skb->len + ETH_HLEN);
1019 }
1020 }
1021
1022 if (local_recv)
1023 return NET_RX_SUCCESS;
1024 else
1025 return NET_RX_DROP;
1026 }
1027
1028 /**
1029 * batadv_mcast_forw_tracker_tvlv_handler() - handle an mcast tracker tvlv
1030 * @bat_priv: the bat priv with all the mesh interface information
1031 * @skb: the received batman-adv multicast packet
1032 *
1033 * Parses the tracker TVLV of an incoming batman-adv multicast packet and
1034 * forwards the packet as indicated in this TVLV.
1035 *
1036 * Caller needs to set the skb network header to the start of the multicast
1037 * tracker TVLV (excluding the generic TVLV header) and the skb transport header
1038 * to the next byte after this multicast tracker TVLV.
1039 *
1040 * Caller needs to free the skb.
1041 *
1042 * Return: NET_RX_SUCCESS or NET_RX_DROP on success or a negative error
1043 * code on failure. NET_RX_SUCCESS if the received packet is supposed to be
1044 * decapsulated and forwarded to the own mesh interface, NET_RX_DROP otherwise.
1045 */
batadv_mcast_forw_tracker_tvlv_handler(struct batadv_priv * bat_priv,struct sk_buff * skb)1046 int batadv_mcast_forw_tracker_tvlv_handler(struct batadv_priv *bat_priv,
1047 struct sk_buff *skb)
1048 {
1049 return batadv_mcast_forw_packet(bat_priv, skb, false);
1050 }
1051
1052 /**
1053 * batadv_mcast_forw_packet_hdrlen() - multicast packet header length
1054 * @num_dests: number of destination nodes
1055 *
1056 * Calculates the total batman-adv multicast packet header length for a given
1057 * number of destination nodes (excluding the outer ethernet frame).
1058 *
1059 * Return: The calculated total batman-adv multicast packet header length.
1060 */
batadv_mcast_forw_packet_hdrlen(unsigned int num_dests)1061 unsigned int batadv_mcast_forw_packet_hdrlen(unsigned int num_dests)
1062 {
1063 /**
1064 * If the number of destination entries is even then we need to add
1065 * two byte padding to the tracker TVLV.
1066 */
1067 int padding = (!(num_dests % 2)) ? 2 : 0;
1068
1069 return padding + num_dests * ETH_ALEN +
1070 sizeof(struct batadv_tvlv_mcast_tracker) +
1071 sizeof(struct batadv_tvlv_hdr) +
1072 sizeof(struct batadv_mcast_packet);
1073 }
1074
1075 /**
1076 * batadv_mcast_forw_expand_head() - expand headroom for an mcast packet
1077 * @bat_priv: the bat priv with all the mesh interface information
1078 * @skb: the multicast packet to send
1079 *
1080 * Tries to expand an skb's headroom so that its head to tail is 1298
1081 * bytes (minimum IPv6 MTU + vlan ethernet header size) large.
1082 *
1083 * Warning: This function may reallocate the skb data buffer via
1084 * skb_cow()/skb_linearize()/... Any pointer into the skb data (e.g.
1085 * obtained from skb->data or eth_hdr()) before this call must be
1086 * considered invalid afterwards and has to be reacquired.
1087 *
1088 * Return: -EINVAL if the given skb's length is too large or -ENOMEM on memory
1089 * allocation failure. Otherwise, on success, zero is returned.
1090 */
batadv_mcast_forw_expand_head(struct batadv_priv * bat_priv,struct sk_buff * skb)1091 static int batadv_mcast_forw_expand_head(struct batadv_priv *bat_priv,
1092 struct sk_buff *skb)
1093 {
1094 int hdr_size = VLAN_ETH_HLEN + IPV6_MIN_MTU - skb->len;
1095
1096 /* TODO: Could be tightened to actual number of destination nodes?
1097 * But it's tricky, number of destinations might have increased since
1098 * we last checked.
1099 */
1100 if (hdr_size < 0) {
1101 /* batadv_mcast_forw_mode_check_count() should ensure we do not
1102 * end up here
1103 */
1104 WARN_ON(1);
1105 return -EINVAL;
1106 }
1107
1108 if (skb_cow(skb, hdr_size) < 0)
1109 return -ENOMEM;
1110
1111 /* batadv_mcast_forw_scrape() + batadv_mcast_forw_packet() require linearized skb */
1112 if (skb_linearize(skb) < 0)
1113 return -ENOMEM;
1114
1115 return 0;
1116 }
1117
1118 /**
1119 * batadv_mcast_forw_push() - encapsulate skb in a batman-adv multicast packet
1120 * @bat_priv: the bat priv with all the mesh interface information
1121 * @skb: the multicast packet to encapsulate and send
1122 * @vid: the vlan identifier
1123 * @is_routable: indicates whether the destination is routable
1124 * @count: the number of originators the multicast packet needs to be sent to
1125 *
1126 * Encapsulates the given multicast packet in a batman-adv multicast packet.
1127 * A multicast tracker TVLV with destination originator addresses for any node
1128 * that signaled interest in it, that is either via the translation table or the
1129 * according want-all flags, is attached accordingly.
1130 *
1131 * Warning: This function may reallocate the skb data buffer via
1132 * batadv_mcast_forw_expand_head()/... Any pointer into the skb data (e.g.
1133 * obtained from skb->data or eth_hdr()) before this call must be
1134 * considered invalid afterwards and has to be reacquired.
1135 *
1136 * Return: true on success, false otherwise.
1137 */
batadv_mcast_forw_push(struct batadv_priv * bat_priv,struct sk_buff * skb,unsigned short vid,int is_routable,int count)1138 bool batadv_mcast_forw_push(struct batadv_priv *bat_priv, struct sk_buff *skb,
1139 unsigned short vid, int is_routable, int count)
1140 {
1141 unsigned short tvlv_len = 0;
1142 int ret;
1143
1144 if (batadv_mcast_forw_expand_head(bat_priv, skb) < 0)
1145 goto err;
1146
1147 skb_reset_transport_header(skb);
1148
1149 ret = batadv_mcast_forw_push_tvlvs(bat_priv, skb, vid, is_routable,
1150 count, &tvlv_len);
1151 if (ret < 0)
1152 goto err;
1153
1154 ret = batadv_mcast_forw_push_hdr(skb, tvlv_len);
1155 if (ret < 0)
1156 goto err;
1157
1158 return true;
1159
1160 err:
1161 if (tvlv_len)
1162 skb_pull(skb, tvlv_len);
1163
1164 return false;
1165 }
1166
1167 /**
1168 * batadv_mcast_forw_mcsend() - send a self prepared batman-adv multicast packet
1169 * @bat_priv: the bat priv with all the mesh interface information
1170 * @skb: the multicast packet to encapsulate and send
1171 *
1172 * Transmits a batman-adv multicast packet that was locally prepared and
1173 * consumes/frees it.
1174 *
1175 * Return: NET_XMIT_DROP on memory allocation failure. NET_XMIT_SUCCESS
1176 * otherwise.
1177 */
batadv_mcast_forw_mcsend(struct batadv_priv * bat_priv,struct sk_buff * skb)1178 int batadv_mcast_forw_mcsend(struct batadv_priv *bat_priv,
1179 struct sk_buff *skb)
1180 {
1181 int ret = batadv_mcast_forw_packet(bat_priv, skb, true);
1182
1183 if (ret < 0) {
1184 kfree_skb(skb);
1185 return NET_XMIT_DROP;
1186 }
1187
1188 consume_skb(skb);
1189 return NET_XMIT_SUCCESS;
1190 }
1191