Skip to content

Commit 9003913

Browse files
T-Xsimonwunderlich
authored andcommitted
batman-adv: mcast: implement multicast packet generation
Implement the preparation of a batman-adv multicast packet and use this under certain conditions. For one thing this implements the capability to push a complete batman-adv multicast packet header, including a tracker TVLV with all originator destinations that have signaled interest in it, onto a given ethernet frame with an IP multicast packet inside. For another checks are implemented to determine if encapsulating a multicast packet in this new batman-adv multicast packet type and using it is feasible. Those checks are: 1) Have all nodes signaled that they are capable of handling the new batman-adv multicast packet type? 2) Do all active hard interfaces of all nodes, including us, have an MTU of at least 1280 bytes? 3) Does a complete multicast packet header with all its destination addresses fit onto the given multicast packet / ethernet frame and does not exceed 1280 bytes? If all checks passed then the new batman-adv multicast packet type will be used for transmission and distribution. Otherwise we fall back to one or more batman-adv unicast packet transmissions, if possible. Or if not possible we will fall back to classic flooding through a batman-adv broadcast packet. Signed-off-by: Linus Lüssing <[email protected]> Signed-off-by: Simon Wunderlich <[email protected]>
1 parent 07afe1b commit 9003913

File tree

5 files changed

+840
-8
lines changed

5 files changed

+840
-8
lines changed

net/batman-adv/multicast.c

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,17 +1169,62 @@ static int batadv_mcast_forw_rtr_count(struct batadv_priv *bat_priv,
11691169
}
11701170
}
11711171

1172+
/**
1173+
* batadv_mcast_forw_mode_by_count() - get forwarding mode by count
1174+
* @bat_priv: the bat priv with all the soft interface information
1175+
* @skb: the multicast packet to check
1176+
* @vid: the vlan identifier
1177+
* @is_routable: stores whether the destination is routable
1178+
* @count: the number of originators the multicast packet need to be sent to
1179+
*
1180+
* For a multicast packet with multiple destination originators, checks which
1181+
* mode to use. For BATADV_FORW_MCAST it also encapsulates the packet with a
1182+
* complete batman-adv multicast header.
1183+
*
1184+
* Return:
1185+
* BATADV_FORW_MCAST: If all nodes have multicast packet routing
1186+
* capabilities and an MTU >= 1280 on all hard interfaces (including us)
1187+
* and the encapsulated multicast packet with all destination addresses
1188+
* would still fit into an 1280 bytes batman-adv multicast packet
1189+
* (excluding the outer ethernet frame) and we could successfully push
1190+
* the full batman-adv multicast packet header.
1191+
* BATADV_FORW_UCASTS: If the packet cannot be sent in a batman-adv
1192+
* multicast packet and the amount of batman-adv unicast packets needed
1193+
* is smaller or equal to the configured multicast fanout.
1194+
* BATADV_FORW_BCAST: Otherwise.
1195+
*/
1196+
static enum batadv_forw_mode
1197+
batadv_mcast_forw_mode_by_count(struct batadv_priv *bat_priv,
1198+
struct sk_buff *skb, unsigned short vid,
1199+
int is_routable, int count)
1200+
{
1201+
unsigned int mcast_hdrlen = batadv_mcast_forw_packet_hdrlen(count);
1202+
u8 own_tvlv_flags = bat_priv->mcast.mla_flags.tvlv_flags;
1203+
1204+
if (!atomic_read(&bat_priv->mcast.num_no_mc_ptype_capa) &&
1205+
own_tvlv_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA &&
1206+
skb->len + mcast_hdrlen <= IPV6_MIN_MTU &&
1207+
batadv_mcast_forw_push(bat_priv, skb, vid, is_routable, count))
1208+
return BATADV_FORW_MCAST;
1209+
1210+
if (count <= atomic_read(&bat_priv->multicast_fanout))
1211+
return BATADV_FORW_UCASTS;
1212+
1213+
return BATADV_FORW_BCAST;
1214+
}
1215+
11721216
/**
11731217
* batadv_mcast_forw_mode() - check on how to forward a multicast packet
11741218
* @bat_priv: the bat priv with all the soft interface information
11751219
* @skb: the multicast packet to check
1220+
* @vid: the vlan identifier
11761221
* @is_routable: stores whether the destination is routable
11771222
*
11781223
* Return: The forwarding mode as enum batadv_forw_mode.
11791224
*/
11801225
enum batadv_forw_mode
11811226
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
1182-
int *is_routable)
1227+
unsigned short vid, int *is_routable)
11831228
{
11841229
int ret, tt_count, ip_count, unsnoop_count, total_count;
11851230
bool is_unsnoopable = false;
@@ -1209,10 +1254,8 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
12091254
else if (unsnoop_count)
12101255
return BATADV_FORW_BCAST;
12111256

1212-
if (total_count <= atomic_read(&bat_priv->multicast_fanout))
1213-
return BATADV_FORW_UCASTS;
1214-
1215-
return BATADV_FORW_BCAST;
1257+
return batadv_mcast_forw_mode_by_count(bat_priv, skb, vid, *is_routable,
1258+
total_count);
12161259
}
12171260

12181261
/**
@@ -1772,6 +1815,31 @@ static void batadv_mcast_want_rtr6_update(struct batadv_priv *bat_priv,
17721815
}
17731816
}
17741817

1818+
/**
1819+
* batadv_mcast_have_mc_ptype_update() - update multicast packet type counter
1820+
* @bat_priv: the bat priv with all the soft interface information
1821+
* @orig: the orig_node which multicast state might have changed of
1822+
* @mcast_flags: flags indicating the new multicast state
1823+
*
1824+
* If the BATADV_MCAST_HAVE_MC_PTYPE_CAPA flag of this originator, orig, has
1825+
* toggled then this method updates the counter accordingly.
1826+
*/
1827+
static void batadv_mcast_have_mc_ptype_update(struct batadv_priv *bat_priv,
1828+
struct batadv_orig_node *orig,
1829+
u8 mcast_flags)
1830+
{
1831+
lockdep_assert_held(&orig->mcast_handler_lock);
1832+
1833+
/* switched from flag set to unset */
1834+
if (!(mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA) &&
1835+
orig->mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA)
1836+
atomic_inc(&bat_priv->mcast.num_no_mc_ptype_capa);
1837+
/* switched from flag unset to set */
1838+
else if (mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA &&
1839+
!(orig->mcast_flags & BATADV_MCAST_HAVE_MC_PTYPE_CAPA))
1840+
atomic_dec(&bat_priv->mcast.num_no_mc_ptype_capa);
1841+
}
1842+
17751843
/**
17761844
* batadv_mcast_tvlv_flags_get() - get multicast flags from an OGM TVLV
17771845
* @enabled: whether the originator has multicast TVLV support enabled
@@ -1840,6 +1908,7 @@ static void batadv_mcast_tvlv_ogm_handler(struct batadv_priv *bat_priv,
18401908
batadv_mcast_want_ipv6_update(bat_priv, orig, mcast_flags);
18411909
batadv_mcast_want_rtr4_update(bat_priv, orig, mcast_flags);
18421910
batadv_mcast_want_rtr6_update(bat_priv, orig, mcast_flags);
1911+
batadv_mcast_have_mc_ptype_update(bat_priv, orig, mcast_flags);
18431912

18441913
orig->mcast_flags = mcast_flags;
18451914
spin_unlock_bh(&orig->mcast_handler_lock);

net/batman-adv/multicast.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <linux/netlink.h>
1313
#include <linux/skbuff.h>
14+
#include <linux/types.h>
1415

1516
/**
1617
* enum batadv_forw_mode - the way a packet should be forwarded as
@@ -28,6 +29,12 @@ enum batadv_forw_mode {
2829
*/
2930
BATADV_FORW_UCASTS,
3031

32+
/**
33+
* @BATADV_FORW_MCAST: forward the packet to some nodes via a
34+
* batman-adv multicast packet
35+
*/
36+
BATADV_FORW_MCAST,
37+
3138
/** @BATADV_FORW_NONE: don't forward, drop it */
3239
BATADV_FORW_NONE,
3340
};
@@ -36,7 +43,7 @@ enum batadv_forw_mode {
3643

3744
enum batadv_forw_mode
3845
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
39-
int *is_routable);
46+
unsigned short vid, int *is_routable);
4047

4148
int batadv_mcast_forw_send(struct batadv_priv *bat_priv, struct sk_buff *skb,
4249
unsigned short vid, int is_routable);
@@ -57,11 +64,18 @@ void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node);
5764
int batadv_mcast_forw_tracker_tvlv_handler(struct batadv_priv *bat_priv,
5865
struct sk_buff *skb);
5966

67+
unsigned int batadv_mcast_forw_packet_hdrlen(unsigned int num_dests);
68+
69+
bool batadv_mcast_forw_push(struct batadv_priv *bat_priv, struct sk_buff *skb,
70+
unsigned short vid, int is_routable, int count);
71+
72+
int batadv_mcast_forw_mcsend(struct batadv_priv *bat_priv, struct sk_buff *skb);
73+
6074
#else
6175

6276
static inline enum batadv_forw_mode
6377
batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
64-
int *is_routable)
78+
unsigned short vid, int *is_routable)
6579
{
6680
return BATADV_FORW_BCAST;
6781
}
@@ -99,6 +113,13 @@ static inline void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node)
99113
{
100114
}
101115

116+
static inline int batadv_mcast_forw_mcsend(struct batadv_priv *bat_priv,
117+
struct sk_buff *skb)
118+
{
119+
kfree_skb(skb);
120+
return NET_XMIT_DROP;
121+
}
122+
102123
#endif /* CONFIG_BATMAN_ADV_MCAST */
103124

104125
#endif /* _NET_BATMAN_ADV_MULTICAST_H_ */

0 commit comments

Comments
 (0)