Page MenuHomeFreeBSD

D59160.1794273883.diff
No OneTemporary

Authored By
Unknown
Size
5 KB
Referenced Files
None
Subscribers
None

D59160.1794273883.diff

diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c
--- a/sbin/ifconfig/af_inet6.c
+++ b/sbin/ifconfig/af_inet6.c
@@ -725,6 +725,8 @@
DEF_CMD("-no_prefer_iface",-ND6_IFF_NO_PREFER_IFACE,setnd6flags),
DEF_CMD("no_dad", ND6_IFF_NO_DAD, setnd6flags),
DEF_CMD("-no_dad", -ND6_IFF_NO_DAD, setnd6flags),
+ DEF_CMD("no_mld", ND6_IFF_NO_MLD, setnd6flags),
+ DEF_CMD("-no_mld", -ND6_IFF_NO_MLD, setnd6flags),
DEF_CMD_ARG("pltime", setip6pltime),
DEF_CMD_ARG("vltime", setip6vltime),
DEF_CMD("eui64", 0, setip6eui64),
diff --git a/sbin/ifconfig/af_nd6.c b/sbin/ifconfig/af_nd6.c
--- a/sbin/ifconfig/af_nd6.c
+++ b/sbin/ifconfig/af_nd6.c
@@ -62,7 +62,8 @@
[6] = "NO_RADR",
[7] = "NO_PREFER_IFACE",
[8] = "NO_DAD",
- [11] = "STABLEADDR",
+ [11] = "STABLEADDR",
+ [12] = "NO_MLD",
[15] = "DEFAULTIF",
};
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -1007,6 +1007,21 @@
.It Cm -no_dad
Clear a flag
.Cm no_dad .
+.It Cm no_mld
+Disable transmission of MLD membership reports on the interface.
+The interface continues to join multicast groups, including the
+mandatory solicited-node groups, and Neighbor Discovery is unaffected;
+only report transmission is suppressed.
+No Done message is sent when a group is left.
+This is deliberately non-conformant with RFC 3810 and is intended for
+interfaces facing a layer 2 fabric whose policy forbids MLD, such as an
+Internet Exchange peering port.
+It is unsafe on a fabric whose switches prune multicast by MLD snooping
+(RFC 4541): suppressing reports will eventually stop inbound
+solicited-node delivery and break Neighbor Discovery.
+.It Cm -no_mld
+Transmit MLD membership reports normally.
+This is the default.
.It Cm stableaddr
Set a flag to create SLAAC addresses using a stable algorithm
according to RFC 7217.
diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c
--- a/sys/netinet6/mld6.c
+++ b/sys/netinet6/mld6.c
@@ -93,6 +93,7 @@
#include <netinet6/ip6_mroute.h>
#include <netinet6/mld6.h>
#include <netinet6/mld6_var.h>
+#include <netinet6/nd6.h>
#include <security/mac/mac_framework.h>
@@ -3062,6 +3063,21 @@
goto out;
}
+ /*
+ * Interfaces marked ND6_IFF_NO_MLD do not transmit reports. The
+ * state machine has already committed the transition, so callers
+ * observe a successful transmission. This matches the semantics of
+ * an egress packet filter, which drops the packet after ip6_output()
+ * has accepted it. Intentional suppression is not counted as an
+ * output error.
+ */
+ if (ifp->if_inet6->nd_flags & ND6_IFF_NO_MLD) {
+ CTR3(KTR_MLD, "%s: suppressed %p on ifindex %u (no_mld set).",
+ __func__, m, ifindex);
+ m_freem(m);
+ goto out;
+ }
+
im6o.im6o_multicast_hlim = 1;
im6o.im6o_multicast_loop = V_ip6_mrouting_enabled;
im6o.im6o_multicast_ifp = ifp;
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -74,6 +74,13 @@
#define ND6_IFF_NO_PREFER_IFACE 0x80 /* XXX: not related to ND. */
#define ND6_IFF_NO_DAD 0x100
#define ND6_IFF_STABLEADDR 0x800
+/*
+ * Suppress MLD report transmission on the interface. Deliberately
+ * non-conformant with RFC 3810 5; intended for L2 fabrics whose policy
+ * forbids MLD (e.g. IXP peering ports). Unsafe where switches prune
+ * multicast by MLD snooping (RFC 4541).
+ */
+#define ND6_IFF_NO_MLD 0x1000
struct in6_nbrinfo {
char ifname[IFNAMSIZ]; /* if name, e.g. "en0" */
diff --git a/tests/sys/netinet6/mld.sh b/tests/sys/netinet6/mld.sh
--- a/tests/sys/netinet6/mld.sh
+++ b/tests/sys/netinet6/mld.sh
@@ -118,11 +118,67 @@
vnet_cleanup
}
+
+atf_test_case "no_mld" "cleanup"
+no_mld_head() {
+ atf_set descr 'ND6_IFF_NO_MLD suppresses MLD reports but not ND'
+ atf_set require.user root
+}
+no_mld_body() {
+ j="mld:no_mld"
+ pcap="$(pwd)/no_mld.pcap"
+
+ vnet_init
+
+ epair=$(vnet_mkepair)
+
+ vnet_mkjail ${j}a ${epair}a
+ vnet_mkjail ${j}b ${epair}b
+
+ jexec ${j}a ifconfig ${epair}a inet6 no_mld up
+ atf_check -o match:"NO_MLD" jexec ${j}a ifconfig ${epair}a
+
+ # Capture only what the suppressed side transmits (-Q out), using a
+ # plain ip6 filter; BPF cannot match ICMPv6 types through MLD's
+ # Hop-by-Hop header, so classification is done on tcpdump's decoded
+ # output below.
+ jexec ${j}a tcpdump -Q out -qnni ${epair}a -w ${pcap} ip6 &
+ tcpid=$!
+ sleep 1
+
+ jexec ${j}a ifconfig ${epair}a inet6 2001:db8::1/64
+ jexec ${j}b ifconfig ${epair}b inet6 2001:db8::2/64 up
+ sleep 5
+ kill ${tcpid}
+ wait ${tcpid} 2>/dev/null
+
+ # The capture must be valid before its absence of MLD means anything:
+ # the DAD NS proves the suppressed side transmitted ICMPv6.
+ atf_check -o match:"neighbor" -e ignore -x "tcpdump -nr ${pcap}"
+
+ # ...and no MLD left the suppressed interface.
+ atf_check -o match:"^0$" -e ignore -x \
+ "tcpdump -nr ${pcap} | grep -c 'listener' || true"
+
+ # ND resolves and reachability holds with suppression active.
+ atf_check -s exit:0 -o ignore \
+ jexec ${j}a ping -6 -c 3 2001:db8::2
+
+ # Clearing the flag restores reporting.
+ jexec ${j}a ifconfig ${epair}a inet6 -no_mld
+ atf_check -o not-match:"NO_MLD" jexec ${j}a ifconfig ${epair}a
+}
+no_mld_cleanup() {
+ vnet_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "mldraw01"
atf_add_test_case "pr233683"
+ atf_add_test_case "no_mld"
+
}
# end

File Metadata

Mime Type
text/plain
Expires
Tue, Nov 10, 1:24 AM (50 m, 7 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41603731
Default Alt Text
D59160.1794273883.diff (5 KB)

Event Timeline