[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20190813141804.20515-1-pruddy@vyatta.att-mail.com>
Date: Tue, 13 Aug 2019 15:18:04 +0100
From: Patrick Ruddy <pruddy@...tta.att-mail.com>
To: netdev@...r.kernel.org
Subject: [PATCH net-next] mcast: ensure L-L IPv6 packets are accepted by bridge
At present only all-nodes IPv6 multicast packets are accepted by
a bridge interface that is not in multicast router mode. Since
other protocols can be running in the absense of multicast
forwarding e.g. OSPFv3 IPv6 ND. Change the test to allow
all of the FFx2::/16 range to be accepted when not in multicast
router mode. This aligns the code with IPv4 link-local reception
and RFC4291
Signed-off-by: Patrick Ruddy <pruddy@...tta.att-mail.com>
---
include/net/addrconf.h | 15 +++++++++++++++
net/bridge/br_multicast.c | 2 +-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index becdad576859..05b42867e969 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -434,6 +434,21 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
htonl(0xFF000000) | addr->s6_addr32[3]);
}
+/*
+ * link local multicast address range ffx2::/16 rfc4291
+ */
+static inline bool ipv6_addr_is_ll_mcast(const struct in6_addr *addr)
+{
+#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
+ __be64 *p = (__be64 *)addr;
+ return ((p[0] & cpu_to_be64(0xff0f000000000000UL))
+ ^ cpu_to_be64(0xff02000000000000UL)) == 0UL;
+#else
+ return ((addr->s6_addr32[0] & htonl(0xff0f0000)) ^
+ htonl(0xff020000)) == 0;
+#endif
+}
+
static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 9b379e110129..ed3957381fa2 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1664,7 +1664,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
err = ipv6_mc_check_mld(skb);
if (err == -ENOMSG) {
- if (!ipv6_addr_is_ll_all_nodes(&ipv6_hdr(skb)->daddr))
+ if (!ipv6_addr_is_ll_mcast(&ipv6_hdr(skb)->daddr))
BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
if (ipv6_addr_is_all_snoopers(&ipv6_hdr(skb)->daddr)) {
--
2.20.1
Powered by blists - more mailing lists