From 7e404ac51784ad9f389b8c4baaaa89d62243f3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Wed, 7 Mar 2018 10:10:32 +0100 Subject: [PATCH] batman-adv: multicast TT fixes and cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first one adds a fix that might potentially result in multicast packet loss once we would enable multicast_mode again. The second one avoids some small but unnecessary overhead. More importantly though, it is supposed to ease further multicast improvements later (e.g. no need for a multicast sending node to determine overlap between WANT_ALL_IPV4/6 flags and TT entries while on fast-path). Signed-off-by: Linus Lüssing --- ...-adv-multicast-TT-fixes-and-cleanups.patch | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 patches/packages/routing/0003-batman-adv-multicast-TT-fixes-and-cleanups.patch diff --git a/patches/packages/routing/0003-batman-adv-multicast-TT-fixes-and-cleanups.patch b/patches/packages/routing/0003-batman-adv-multicast-TT-fixes-and-cleanups.patch new file mode 100644 index 00000000..93d9c56c --- /dev/null +++ b/patches/packages/routing/0003-batman-adv-multicast-TT-fixes-and-cleanups.patch @@ -0,0 +1,209 @@ +From: Linus Lüssing +Date: Wed, 7 Mar 2018 10:05:41 +0100 +Subject: batman-adv: multicast TT fixes and cleanups + +The first one adds a fix that might potentially result in multicast packet +loss once we would enable multicast_mode again. + +The second one avoids some small but unnecessary overhead. More +importantly though, it is supposed to ease further multicast improvements +later (e.g. no need for a multicast sending node to determine overlap +between WANT_ALL_IPV4/6 flags and TT entries while on fast-path). + +Signed-off-by: Linus Lüssing + +diff --git a/batman-adv/patches/0002-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch b/batman-adv/patches/0002-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..138ff7568548d87b9e31efd6c122527102ab2b48 +--- /dev/null ++++ b/batman-adv/patches/0002-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch +@@ -0,0 +1,44 @@ ++From 25b61cec1f45008040d8eb5a5e6c8a4ea027b138 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Linus=20L=C3=BCssing?= ++Date: Sun, 4 Mar 2018 13:08:17 +0100 ++Subject: [PATCH] batman-adv: Fix multicast packet loss with a single ++ WANT_ALL_IPV4/6 flag ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++As the kernel doc describes too the code is supposed to skip adding ++multicast TT entries if both the WANT_ALL_IPV4 and WANT_ALL_IPV6 flags ++are present. ++ ++Unfortunately, the current code even skips adding multicast TT entries ++if only either the WANT_ALL_IPV4 or WANT_ALL_IPV6 is present. ++ ++This could lead to IPv6 multicast packet loss if only an IGMP but not an ++MLD querier is present for instance or vice versa. ++ ++Fixes: 391b59cdb111 ("batman-adv: Add multicast optimization support for bridged setups") ++Signed-off-by: Linus Lüssing ++Signed-off-by: Sven Eckelmann ++--- ++ net/batman-adv/multicast.c | 4 ++-- ++ 1 file changed, 2 insertions(+), 2 deletions(-) ++ ++diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c ++index 6eaffe50..15a7b314 100644 ++--- a/net/batman-adv/multicast.c +++++ b/net/batman-adv/multicast.c ++@@ -543,8 +543,8 @@ static bool batadv_mcast_mla_tvlv_update(struct batadv_priv *bat_priv) ++ bat_priv->mcast.enabled = true; ++ } ++ ++- return !(mcast_data.flags & ++- (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6)); +++ return !(mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV4 && +++ mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV6); ++ } ++ ++ /** ++-- ++2.11.0 ++ +diff --git a/batman-adv/patches/0003-batman-adv-Avoid-redundant-multicast-TT-entries.patch b/batman-adv/patches/0003-batman-adv-Avoid-redundant-multicast-TT-entries.patch +new file mode 100644 +index 0000000000000000000000000000000000000000..b960052ac63c304454f1988cec76d10ac398d2ca +--- /dev/null ++++ b/batman-adv/patches/0003-batman-adv-Avoid-redundant-multicast-TT-entries.patch +@@ -0,0 +1,139 @@ ++From e6a1e766956e66cbc5b2068896a8e55d4e49d894 Mon Sep 17 00:00:00 2001 ++From: =?UTF-8?q?Linus=20L=C3=BCssing?= ++Date: Sun, 4 Mar 2018 21:02:18 +0100 ++Subject: [PATCH] batman-adv: Avoid redundant multicast TT entries ++MIME-Version: 1.0 ++Content-Type: text/plain; charset=UTF-8 ++Content-Transfer-Encoding: 8bit ++ ++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 ++Signed-off-by: Sven Eckelmann ++--- ++ net/batman-adv/multicast.c | 56 ++++++++++++++++++++++++++++++++++++++++++---- ++ 1 file changed, 52 insertions(+), 4 deletions(-) ++ ++diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c ++index 15a7b314..17ad1933 100644 ++--- a/net/batman-adv/multicast.c +++++ b/net/batman-adv/multicast.c ++@@ -102,7 +102,36 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface) ++ } ++ ++ /** +++ * batadv_mcast_addr_is_ipv4() - check if multicast MAC is IPv4 +++ * @addr: the MAC address to check +++ * +++ * Return: True, if MAC address is one reserved for IPv4 multicast, false +++ * otherwise. +++ */ +++static bool batadv_mcast_addr_is_ipv4(const u8 *addr) +++{ +++ static const u8 prefix[] = {0x01, 0x00, 0x5E}; +++ +++ return memcmp(prefix, addr, sizeof(prefix)) == 0; +++} +++ +++/** +++ * batadv_mcast_addr_is_ipv6() - check if multicast MAC is IPv6 +++ * @addr: the MAC address to check +++ * +++ * Return: True, if MAC address is one reserved for IPv6 multicast, false +++ * otherwise. +++ */ +++static bool batadv_mcast_addr_is_ipv6(const u8 *addr) +++{ +++ static const u8 prefix[] = {0x33, 0x33}; +++ +++ return memcmp(prefix, addr, sizeof(prefix)) == 0; +++} +++ +++/** ++ * batadv_mcast_mla_softif_get() - get softif multicast listeners +++ * @bat_priv: the bat priv with all the soft interface information ++ * @dev: the device to collect multicast addresses from ++ * @mcast_list: a list to put found addresses into ++ * ++@@ -119,9 +148,12 @@ static struct net_device *batadv_mcast_get_bridge(struct net_device *soft_iface) ++ * Return: -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, +++static int batadv_mcast_mla_softif_get(struct batadv_priv *bat_priv, +++ struct net_device *dev, ++ struct hlist_head *mcast_list) ++ { +++ bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4; +++ bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6; ++ struct net_device *bridge = batadv_mcast_get_bridge(dev); ++ struct netdev_hw_addr *mc_list_entry; ++ struct batadv_hw_addr *new; ++@@ -129,6 +161,12 @@ static int batadv_mcast_mla_softif_get(struct net_device *dev, ++ ++ netif_addr_lock_bh(bridge ? bridge : dev); ++ netdev_for_each_mc_addr(mc_list_entry, bridge ? bridge : dev) { +++ if (all_ipv4 && batadv_mcast_addr_is_ipv4(mc_list_entry->addr)) +++ continue; +++ +++ if (all_ipv6 && batadv_mcast_addr_is_ipv6(mc_list_entry->addr)) +++ continue; +++ ++ new = kmalloc(sizeof(*new), GFP_ATOMIC); ++ if (!new) { ++ ret = -ENOMEM; ++@@ -193,6 +231,7 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src) ++ ++ /** ++ * batadv_mcast_mla_bridge_get() - get bridged-in multicast listeners +++ * @bat_priv: the bat priv with all the soft interface information ++ * @dev: a bridge slave whose bridge to collect multicast addresses from ++ * @mcast_list: a list to put found addresses into ++ * ++@@ -204,10 +243,13 @@ static void batadv_mcast_mla_br_addr_cpy(char *dst, const struct br_ip *src) ++ * Return: -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, +++static int batadv_mcast_mla_bridge_get(struct batadv_priv *bat_priv, +++ struct net_device *dev, ++ struct hlist_head *mcast_list) ++ { ++ struct list_head bridge_mcast_list = LIST_HEAD_INIT(bridge_mcast_list); +++ bool all_ipv4 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV4; +++ bool all_ipv6 = bat_priv->mcast.flags & BATADV_MCAST_WANT_ALL_IPV6; ++ struct br_ip_list *br_ip_entry, *tmp; ++ struct batadv_hw_addr *new; ++ u8 mcast_addr[ETH_ALEN]; ++@@ -221,6 +263,12 @@ static int batadv_mcast_mla_bridge_get(struct net_device *dev, ++ goto out; ++ ++ list_for_each_entry(br_ip_entry, &bridge_mcast_list, list) { +++ if (all_ipv4 && br_ip_entry->addr.proto == htons(ETH_P_IP)) +++ continue; +++ +++ if (all_ipv6 && br_ip_entry->addr.proto == htons(ETH_P_IPV6)) +++ continue; +++ ++ batadv_mcast_mla_br_addr_cpy(mcast_addr, &br_ip_entry->addr); ++ if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) ++ continue; ++@@ -568,11 +616,11 @@ static void __batadv_mcast_mla_update(struct batadv_priv *bat_priv) ++ if (!batadv_mcast_mla_tvlv_update(bat_priv)) ++ goto update; ++ ++- ret = batadv_mcast_mla_softif_get(soft_iface, &mcast_list); +++ ret = batadv_mcast_mla_softif_get(bat_priv, soft_iface, &mcast_list); ++ if (ret < 0) ++ goto out; ++ ++- ret = batadv_mcast_mla_bridge_get(soft_iface, &mcast_list); +++ ret = batadv_mcast_mla_bridge_get(bat_priv, soft_iface, &mcast_list); ++ if (ret < 0) ++ goto out; ++ ++-- ++2.11.0 ++