On Thursday 12 June 2014 02:00:27 Linus Lüssing wrote:
@@ -30,17 +53,21 @@
- Collect multicast addresses of the local multicast listeners
- on the given soft interface, dev, in the given mcast_list.
- If there is a bridge interface on top of dev, collect from that one
- instead.
*/
- Returns -ENOMEM on memory allocation error or the number of
- items added to the mcast_list otherwise.
static int batadv_mcast_mla_softif_get(struct net_device *dev, struct hlist_head *mcast_list) {
- struct net_device *bridge = batadv_mcast_get_bridge(dev); struct netdev_hw_addr *mc_list_entry; struct batadv_hw_addr *new; int ret = 0;
- netif_addr_lock_bh(dev);
- netif_addr_lock_bh(bridge ? bridge : dev); netdev_for_each_mc_addr(mc_list_entry, dev) { new = kmalloc(sizeof(*new), GFP_ATOMIC); if (!new) {
Maybe I am missing something but shouldn't we fetch the entries from the bridge interface instead of dev ?
/**
- batadv_mcast_mla_br_addr_cpy - copy a bridge multicast address
- @dst: destination to write to - a multicast MAC address
- @src: source to read from - a multicast IP address
- Converts a given multicast IPv4/IPv6 address from a bridge
- to its matching multicast MAC address and copies it into the given
- destination buffer.
- Caller needs to make sure the destination buffer can hold
- at least ETH_ALEN bytes.
- */
+static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src) +{
- if (src->proto == htons(ETH_P_IP)) {
/* RFC 1112 */
memcpy(dst, "\x01\x00\x5e", 3);
memcpy(dst + 3, ((char *)&src->u.ip4) + 1, ETH_ALEN - 3);
dst[3] &= 0x7F;
- }
+#if IS_ENABLED(CONFIG_IPV6)
- else if (src->proto == htons(ETH_P_IPV6)) {
/* RFC 2464 */
memcpy(dst, "\x33\x33", 2);
memcpy(dst + 2, &src->u.ip6.s6_addr32[3],
sizeof(src->u.ip6.s6_addr32[3]));
- }
+#endif
- else
memset(dst, 0, ETH_ALEN);
+}
Is there no cleaner way to do this ? "\x01\x00\x5e" and "\x33\x33" looks pretty hackish. Are there no defines for mcast prefixes somewhere ?
+/**
- batadv_mcast_mla_bridge_get - get bridged-in multicast listeners
- @dev: a bridge slave whose bridge to collect multicast addresses from
- @mcast_list: a list to put found addresses into
- Collects multicast addresses of the bridged-in multicast listeners
- from the bridge on top of the given soft interface, dev, in the
- given mcast_list.
- Returns -ENOMEM on memory allocation error or the number of
- items added to the mcast_list otherwise.
- */
+static int batadv_mcast_mla_bridge_get(struct net_device *dev,
struct hlist_head *mcast_list)
+{
That is probably where my confusion is coming from. Why do we query the bridge interface again ?
@@ -195,19 +306,18 @@ static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv) mcast_data.flags = BATADV_NO_FLAGS; memset(mcast_data.reserved, 0, sizeof(mcast_data.reserved));
- /* Avoid attaching MLAs, if there is a bridge on top of our soft
* interface, we don't support that yet (TODO)
*/
- if (batadv_mcast_has_bridge(bat_priv)) {
if (bat_priv->mcast.enabled) {
batadv_tvlv_container_unregister(bat_priv,
BATADV_TVLV_MCAST, 1);
bat_priv->mcast.enabled = false;
}
- if (!batadv_mcast_has_bridge(bat_priv))
goto skip;
return false;
- }
mcast_data.flags |= BATADV_MCAST_WANT_ALL_UNSNOOPABLES;
if (br_multicast_has_querier_adjacent(bat_priv->soft_iface, ETH_P_IP))
mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV4;
if (br_multicast_has_querier_adjacent(bat_priv->soft_iface, ETH_P_IPV6))
mcast_data.flags |= BATADV_MCAST_WANT_ALL_IPV6;
+skip: if (!bat_priv->mcast.enabled || mcast_data.flags != bat_priv->mcast.flags) { batadv_tvlv_container_register(bat_priv, BATADV_TVLV_MCAST, 1,
Please find a more intuitive goto label ('skip' is quite generic).
@@ -233,13 +344,17 @@ void batadv_mcast_mla_update(struct batadv_priv *bat_priv) int ret;
if (!batadv_mcast_mla_tvlv_update(bat_priv))
goto update;
goto skip;
ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list); if (ret < 0) goto out;
-update:
- ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list);
- if (ret < 0)
goto out;
+skip: batadv_mcast_mla_tt_retract(bat_priv, &mcast_list); batadv_mcast_mla_tt_add(bat_priv, &mcast_list);
Again, 'skip' isn't very self-explanatory.
Cheers, Marek