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