Skip to content

Commit 6b25360

Browse files
T-Xsimonwunderlich
authored andcommitted
batman-adv: Avoid redundant multicast TT entries
If a node signals that it wants all traffic for a specific protocol family then there is no need to announce individual multicast addresses via TT. Signed-off-by: Linus Lüssing <[email protected]> Signed-off-by: Sven Eckelmann <[email protected]> Signed-off-by: Simon Wunderlich <[email protected]>
1 parent a163dc2 commit 6b25360

File tree

1 file changed

+52
-4
lines changed

1 file changed

+52
-4
lines changed

net/batman-adv/multicast.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,37 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
101101
return upper;
102102
}
103103

104+
/**
105+
* batadv_mcast_addr_is_ipv4() - check if multicast MAC is IPv4
106+
* @addr: the MAC address to check
107+
*
108+
* Return: True, if MAC address is one reserved for IPv4 multicast, false
109+
* otherwise.
110+
*/
111+
static bool batadv_mcast_addr_is_ipv4(const u8 *addr)
112+
{
113+
static const u8 prefix[] = {0x01, 0x00, 0x5E};
114+
115+
return memcmp(prefix, addr, sizeof(prefix)) == 0;
116+
}
117+
118+
/**
119+
* batadv_mcast_addr_is_ipv6() - check if multicast MAC is IPv6
120+
* @addr: the MAC address to check
121+
*
122+
* Return: True, if MAC address is one reserved for IPv6 multicast, false
123+
* otherwise.
124+
*/
125+
static bool batadv_mcast_addr_is_ipv6(const u8 *addr)
126+
{
127+
static const u8 prefix[] = {0x33, 0x33};
128+
129+
return memcmp(prefix, addr, sizeof(prefix)) == 0;
130+
}
131+
104132
/**
105133
* batadv_mcast_mla_softif_get() - get softif multicast listeners
134+
* @bat_priv: the bat priv with all the soft interface information
106135
* @dev: the device to collect multicast addresses from
107136
* @mcast_list: a list to put found addresses into
108137
*
@@ -119,16 +148,25 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
119148
* Return: -ENOMEM on memory allocation error or the number of
120149
* items added to the mcast_list otherwise.
121150
*/
122-
static int batadv_mcast_mla_softif_get(struct net_device *dev,
151+
static int batadv_mcast_mla_softif_get(struct batadv_priv *bat_priv,
152+
struct net_device *dev,
123153
struct hlist_head *mcast_list)
124154
{
155+
bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4;
156+
bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6;
125157
struct net_device *bridge = batadv_mcast_get_bridge(dev);
126158
struct netdev_hw_addr *mc_list_entry;
127159
struct batadv_hw_addr *new;
128160
int ret = 0;
129161

130162
netif_addr_lock_bh(bridge ? bridge : dev);
131163
netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) {
164+
if (all_ipv4 && batadv_mcast_addr_is_ipv4(mc_list_entry->addr))
165+
continue;
166+
167+
if (all_ipv6 && batadv_mcast_addr_is_ipv6(mc_list_entry->addr))
168+
continue;
169+
132170
new = kmalloc(sizeof(*new), GFP_ATOMIC);
133171
if (!new) {
134172
ret = -ENOMEM;
@@ -193,6 +231,7 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
193231

194232
/**
195233
* batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners
234+
* @bat_priv: the bat priv with all the soft interface information
196235
* @dev: a bridge slave whose bridge to collect multicast addresses from
197236
* @mcast_list: a list to put found addresses into
198237
*
@@ -204,10 +243,13 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
204243
* Return: -ENOMEM on memory allocation error or the number of
205244
* items added to the mcast_list otherwise.
206245
*/
207-
static int batadv_mcast_mla_bridge_get(struct net_device *dev,
246+
static int batadv_mcast_mla_bridge_get(struct batadv_priv *bat_priv,
247+
struct net_device *dev,
208248
struct hlist_head *mcast_list)
209249
{
210250
struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list);
251+
bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4;
252+
bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6;
211253
struct br_ip_list *br_ip_entry, *tmp;
212254
struct batadv_hw_addr *new;
213255
u8 mcast_addr[ETH_ALEN];
@@ -221,6 +263,12 @@ static int batadv_mcast_mla_bridge_get(struct net_device *dev,
221263
goto out;
222264

223265
list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) {
266+
if (all_ipv4 && br_ip_entry->addr.proto == htons(ETH_P_IP))
267+
continue;
268+
269+
if (all_ipv6 && br_ip_entry->addr.proto == htons(ETH_P_IPV6))
270+
continue;
271+
224272
batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr);
225273
if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list))
226274
continue;
@@ -568,11 +616,11 @@ static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)
568616
if (!batadv_mcast_mla_tvlv_update(bat_priv))
569617
goto update;
570618

571-
ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list);
619+
ret = batadv_mcast_mla_softif_get(bat_priv, soft_iface, &mcast_list);
572620
if (ret < 0)
573621
goto out;
574622

575-
ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
623+
ret = batadv_mcast_mla_bridge_get(bat_priv, soft_iface, &mcast_list);
576624
if (ret < 0)
577625
goto out;
578626

0 commit comments

Comments
 (0)