-
Notifications
You must be signed in to change notification settings - Fork 324
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <linus.luessing@c0d3.blue>
- Loading branch information
Showing
1 changed file
with
209 additions
and
0 deletions.
There are no files selected for viewing
209 changes: 209 additions & 0 deletions
209
patches/packages/routing/0003-batman-adv-multicast-TT-fixes-and-cleanups.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
From: Linus Lüssing <linus.luessing@c0d3.blue> | ||
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 <linus.luessing@c0d3.blue> | ||
|
||
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?= <linus.luessing@c0d3.blue> | ||
+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 <linus.luessing@c0d3.blue> | ||
+Signed-off-by: Sven Eckelmann <sven@narfation.org> | ||
+--- | ||
+ 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?= <linus.luessing@c0d3.blue> | ||
+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 <linus.luessing@c0d3.blue> | ||
+Signed-off-by: Sven Eckelmann <sven@narfation.org> | ||
+--- | ||
+ 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 | ||
+ |