Skip to content

Commit 07afe1b

Browse files
T-Xsimonwunderlich
authored andcommitted
batman-adv: mcast: implement multicast packet reception and forwarding
Implement functionality to receive and forward a new TVLV capable multicast packet type. The new batman-adv multicast packet type allows to contain several originator destination addresses within a TVLV. Routers on the way will potentially split the batman-adv multicast packet and adjust its tracker TVLV contents. Routing decisions are still based on the selected BATMAN IV or BATMAN V routing algorithm. So this new batman-adv multicast packet type retains the same loop-free properties. Also a new OGM multicast TVLV flag is introduced to signal to other nodes that we are capable of handling a batman-adv multicast packet and multicast tracker TVLV. And that all of our hard interfaces have an MTU of at least 1280 bytes (IPv6 minimum MTU), as a simple solution for now to avoid MTU issues while forwarding. Signed-off-by: Linus Lüssing <[email protected]> Signed-off-by: Simon Wunderlich <[email protected]>
1 parent e4679a1 commit 07afe1b

File tree

13 files changed

+518
-18
lines changed

13 files changed

+518
-18
lines changed

include/uapi/linux/batadv_packet.h

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,17 @@ enum batadv_icmp_packettype {
116116
* only need routable IPv4 multicast packets we signed up for explicitly
117117
* @BATADV_MCAST_WANT_NO_RTR6: we have no IPv6 multicast router and therefore
118118
* only need routable IPv6 multicast packets we signed up for explicitly
119+
* @BATADV_MCAST_HAVE_MC_PTYPE_CAPA: we can parse, receive and forward
120+
* batman-adv multicast packets with a multicast tracker TVLV. And all our
121+
* hard interfaces have an MTU of at least 1280 bytes.
119122
*/
120123
enum batadv_mcast_flags {
121124
BATADV_MCAST_WANT_ALL_UNSNOOPABLES = 1UL << 0,
122125
BATADV_MCAST_WANT_ALL_IPV4 = 1UL << 1,
123126
BATADV_MCAST_WANT_ALL_IPV6 = 1UL << 2,
124127
BATADV_MCAST_WANT_NO_RTR4 = 1UL << 3,
125128
BATADV_MCAST_WANT_NO_RTR6 = 1UL << 4,
129+
BATADV_MCAST_HAVE_MC_PTYPE_CAPA = 1UL << 5,
126130
};
127131

128132
/* tt data subtypes */
@@ -174,14 +178,16 @@ enum batadv_bla_claimframe {
174178
* @BATADV_TVLV_TT: translation table tvlv
175179
* @BATADV_TVLV_ROAM: roaming advertisement tvlv
176180
* @BATADV_TVLV_MCAST: multicast capability tvlv
181+
* @BATADV_TVLV_MCAST_TRACKER: multicast tracker tvlv
177182
*/
178183
enum batadv_tvlv_type {
179-
BATADV_TVLV_GW = 0x01,
180-
BATADV_TVLV_DAT = 0x02,
181-
BATADV_TVLV_NC = 0x03,
182-
BATADV_TVLV_TT = 0x04,
183-
BATADV_TVLV_ROAM = 0x05,
184-
BATADV_TVLV_MCAST = 0x06,
184+
BATADV_TVLV_GW = 0x01,
185+
BATADV_TVLV_DAT = 0x02,
186+
BATADV_TVLV_NC = 0x03,
187+
BATADV_TVLV_TT = 0x04,
188+
BATADV_TVLV_ROAM = 0x05,
189+
BATADV_TVLV_MCAST = 0x06,
190+
BATADV_TVLV_MCAST_TRACKER = 0x07,
185191
};
186192

187193
#pragma pack(2)
@@ -487,6 +493,25 @@ struct batadv_bcast_packet {
487493
*/
488494
};
489495

496+
/**
497+
* struct batadv_mcast_packet - multicast packet for network payload
498+
* @packet_type: batman-adv packet type, part of the general header
499+
* @version: batman-adv protocol version, part of the general header
500+
* @ttl: time to live for this packet, part of the general header
501+
* @reserved: reserved byte for alignment
502+
* @tvlv_len: length of the appended tvlv buffer (in bytes)
503+
*/
504+
struct batadv_mcast_packet {
505+
__u8 packet_type;
506+
__u8 version;
507+
__u8 ttl;
508+
__u8 reserved;
509+
__be16 tvlv_len;
510+
/* "4 bytes boundary + 2 bytes" long to make the payload after the
511+
* following ethernet header again 4 bytes boundary aligned
512+
*/
513+
};
514+
490515
/**
491516
* struct batadv_coded_packet - network coded packet
492517
* @packet_type: batman-adv packet type, part of the general header
@@ -628,6 +653,14 @@ struct batadv_tvlv_mcast_data {
628653
__u8 reserved[3];
629654
};
630655

656+
/**
657+
* struct batadv_tvlv_mcast_tracker - payload of a multicast tracker tvlv
658+
* @num_dests: number of subsequent destination originator MAC addresses
659+
*/
660+
struct batadv_tvlv_mcast_tracker {
661+
__be16 num_dests;
662+
};
663+
631664
#pragma pack()
632665

633666
#endif /* _UAPI_LINUX_BATADV_PACKET_H_ */

net/batman-adv/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ batman-adv-y += hash.o
2020
batman-adv-$(CONFIG_BATMAN_ADV_DEBUG) += log.o
2121
batman-adv-y += main.o
2222
batman-adv-$(CONFIG_BATMAN_ADV_MCAST) += multicast.o
23+
batman-adv-$(CONFIG_BATMAN_ADV_MCAST) += multicast_forw.o
2324
batman-adv-y += netlink.o
2425
batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o
2526
batman-adv-y += originator.o

net/batman-adv/fragmentation.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
#include "hard-interface.h"
2727
#include "originator.h"
28-
#include "routing.h"
2928
#include "send.h"
3029

3130
/**
@@ -351,18 +350,14 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
351350
struct batadv_orig_node *orig_node_src)
352351
{
353352
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
354-
struct batadv_orig_node *orig_node_dst;
355353
struct batadv_neigh_node *neigh_node = NULL;
356354
struct batadv_frag_packet *packet;
357355
u16 total_size;
358356
bool ret = false;
359357

360358
packet = (struct batadv_frag_packet *)skb->data;
361-
orig_node_dst = batadv_orig_hash_find(bat_priv, packet->dest);
362-
if (!orig_node_dst)
363-
goto out;
364359

365-
neigh_node = batadv_find_router(bat_priv, orig_node_dst, recv_if);
360+
neigh_node = batadv_orig_to_router(bat_priv, packet->dest, recv_if);
366361
if (!neigh_node)
367362
goto out;
368363

@@ -381,7 +376,6 @@ bool batadv_frag_skb_fwd(struct sk_buff *skb,
381376
}
382377

383378
out:
384-
batadv_orig_node_put(orig_node_dst);
385379
batadv_neigh_node_put(neigh_node);
386380
return ret;
387381
}

net/batman-adv/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,8 @@ static void batadv_recv_handler_init(void)
532532

533533
/* broadcast packet */
534534
batadv_rx_handler[BATADV_BCAST] = batadv_recv_bcast_packet;
535+
/* multicast packet */
536+
batadv_rx_handler[BATADV_MCAST] = batadv_recv_mcast_packet;
535537

536538
/* unicast packets ... */
537539
/* unicast with 4 addresses packet */

net/batman-adv/multicast.c

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,37 @@ static u8 batadv_mcast_mla_rtr_flags_get(struct batadv_priv *bat_priv,
235235
return flags;
236236
}
237237

238+
/**
239+
* batadv_mcast_mla_forw_flags_get() - get multicast forwarding flags
240+
* @bat_priv: the bat priv with all the soft interface information
241+
*
242+
* Checks if all active hard interfaces have an MTU larger or equal to 1280
243+
* bytes (IPv6 minimum MTU).
244+
*
245+
* Return: BATADV_MCAST_HAVE_MC_PTYPE_CAPA if yes, BATADV_NO_FLAGS otherwise.
246+
*/
247+
static u8 batadv_mcast_mla_forw_flags_get(struct batadv_priv *bat_priv)
248+
{
249+
const struct batadv_hard_iface *hard_iface;
250+
251+
rcu_read_lock();
252+
list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
253+
if (hard_iface->if_status != BATADV_IF_ACTIVE)
254+
continue;
255+
256+
if (hard_iface->soft_iface != bat_priv->soft_iface)
257+
continue;
258+
259+
if (hard_iface->net_dev->mtu < IPV6_MIN_MTU) {
260+
rcu_read_unlock();
261+
return BATADV_NO_FLAGS;
262+
}
263+
}
264+
rcu_read_unlock();
265+
266+
return BATADV_MCAST_HAVE_MC_PTYPE_CAPA;
267+
}
268+
238269
/**
239270
* batadv_mcast_mla_flags_get() - get the new multicast flags
240271
* @bat_priv: the bat priv with all the soft interface information
@@ -256,6 +287,7 @@ batadv_mcast_mla_flags_get(struct batadv_priv *bat_priv)
256287
mla_flags.enabled = 1;
257288
mla_flags.tvlv_flags |= batadv_mcast_mla_rtr_flags_get(bat_priv,
258289
bridge);
290+
mla_flags.tvlv_flags |= batadv_mcast_mla_forw_flags_get(bat_priv);
259291

260292
if (!bridge)
261293
return mla_flags;
@@ -806,23 +838,25 @@ static void batadv_mcast_flags_log(struct batadv_priv *bat_priv, u8 flags)
806838
{
807839
bool old_enabled = bat_priv->mcast.mla_flags.enabled;
808840
u8 old_flags = bat_priv->mcast.mla_flags.tvlv_flags;
809-
char str_old_flags[] = "[.... . ]";
841+
char str_old_flags[] = "[.... . .]";
810842

811-
sprintf(str_old_flags, "[%c%c%c%s%s]",
843+
sprintf(str_old_flags, "[%c%c%c%s%s%c]",
812844
(old_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
813845
(old_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
814846
(old_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',
815847
!(old_flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
816-
!(old_flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
848+
!(old_flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",
849+
!(old_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');
817850

818851
batadv_dbg(BATADV_DBG_MCAST, bat_priv,
819-
"Changing multicast flags from '%s' to '[%c%c%c%s%s]'\n",
852+
"Changing multicast flags from '%s' to '[%c%c%c%s%s%c]'\n",
820853
old_enabled ? str_old_flags : "<undefined>",
821854
(flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.',
822855
(flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.',
823856
(flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.',
824857
!(flags & BATADV_MCAST_WANT_NO_RTR4) ? "R4" : ". ",
825-
!(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ");
858+
!(flags & BATADV_MCAST_WANT_NO_RTR6) ? "R6" : ". ",
859+
!(flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) ? 'P' : '.');
826860
}
827861

828862
/**
@@ -1820,6 +1854,10 @@ void batadv_mcast_init(struct batadv_priv *bat_priv)
18201854
batadv_tvlv_handler_register(bat_priv, batadv_mcast_tvlv_ogm_handler,
18211855
NULL, NULL, BATADV_TVLV_MCAST, 2,
18221856
BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
1857+
batadv_tvlv_handler_register(bat_priv, NULL, NULL,
1858+
batadv_mcast_forw_tracker_tvlv_handler,
1859+
BATADV_TVLV_MCAST_TRACKER, 1,
1860+
BATADV_TVLV_HANDLER_OGM_CIFNOTFND);
18231861

18241862
INIT_DELAYED_WORK(&bat_priv->mcast.work, batadv_mcast_mla_update);
18251863
batadv_mcast_start_timer(bat_priv);

net/batman-adv/multicast.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ void batadv_mcast_free(struct batadv_priv *bat_priv);
5252

5353
void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
5454

55+
/* multicast_forw.c */
56+
57+
int batadv_mcast_forw_tracker_tvlv_handler(struct batadv_priv *bat_priv,
58+
struct sk_buff *skb);
59+
5560
#else
5661

5762
static inline enum batadv_forw_mode

0 commit comments

Comments
 (0)