@@ -101,8 +101,37 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
101
101
return upper ;
102
102
}
103
103
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
+
104
132
/**
105
133
* batadv_mcast_mla_softif_get() - get softif multicast listeners
134
+ * @bat_priv: the bat priv with all the soft interface information
106
135
* @dev: the device to collect multicast addresses from
107
136
* @mcast_list: a list to put found addresses into
108
137
*
@@ -119,16 +148,25 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface)
119
148
* Return: -ENOMEM on memory allocation error or the number of
120
149
* items added to the mcast_list otherwise.
121
150
*/
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 ,
123
153
struct hlist_head * mcast_list )
124
154
{
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 ;
125
157
struct net_device * bridge = batadv_mcast_get_bridge (dev );
126
158
struct netdev_hw_addr * mc_list_entry ;
127
159
struct batadv_hw_addr * new ;
128
160
int ret = 0 ;
129
161
130
162
netif_addr_lock_bh (bridge ? bridge : dev );
131
163
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
+
132
170
new = kmalloc (sizeof (* new ), GFP_ATOMIC );
133
171
if (!new ) {
134
172
ret = - ENOMEM ;
@@ -193,6 +231,7 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
193
231
194
232
/**
195
233
* batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners
234
+ * @bat_priv: the bat priv with all the soft interface information
196
235
* @dev: a bridge slave whose bridge to collect multicast addresses from
197
236
* @mcast_list: a list to put found addresses into
198
237
*
@@ -204,10 +243,13 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src)
204
243
* Return: -ENOMEM on memory allocation error or the number of
205
244
* items added to the mcast_list otherwise.
206
245
*/
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 ,
208
248
struct hlist_head * mcast_list )
209
249
{
210
250
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 ;
211
253
struct br_ip_list * br_ip_entry , * tmp ;
212
254
struct batadv_hw_addr * new ;
213
255
u8 mcast_addr [ETH_ALEN ];
@@ -221,6 +263,12 @@ static int batadv_mcast_mla_bridge_get(struct net_device *dev,
221
263
goto out ;
222
264
223
265
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
+
224
272
batadv_mcast_mla_br_addr_cpy (mcast_addr , & br_ip_entry -> addr );
225
273
if (batadv_mcast_mla_is_duplicate (mcast_addr , mcast_list ))
226
274
continue ;
@@ -568,11 +616,11 @@ static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv)
568
616
if (!batadv_mcast_mla_tvlv_update (bat_priv ))
569
617
goto update ;
570
618
571
- ret = batadv_mcast_mla_softif_get (soft_iface , & mcast_list );
619
+ ret = batadv_mcast_mla_softif_get (bat_priv , soft_iface , & mcast_list );
572
620
if (ret < 0 )
573
621
goto out ;
574
622
575
- ret = batadv_mcast_mla_bridge_get (soft_iface , & mcast_list );
623
+ ret = batadv_mcast_mla_bridge_get (bat_priv , soft_iface , & mcast_list );
576
624
if (ret < 0 )
577
625
goto out ;
578
626
0 commit comments