From 0b56054f223ff3419c39f7c9d65ceec9b5ae6fea Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Tue, 15 Jul 2025 16:16:21 +0800 Subject: [PATCH 1/3] pim6d: drop mismatch report packets Drop report packets in case group/dstip mismatch appears for MLDv1. Signed-off-by: anlan_cs --- pimd/pim6_mld.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c index 98be267250..1b850dc293 100644 --- a/pimd/pim6_mld.c +++ b/pimd/pim6_mld.c @@ -57,6 +57,8 @@ static void gm_sg_timer_start(struct gm_if *gm_ifp, struct gm_sg *sg, #define log_pkt_src(msg) \ "[MLD %s:%s %pI6] " msg, gm_ifp->ifp->vrf->name, gm_ifp->ifp->name, \ &pkt_src->sin6_addr +#define log_pkt_dst(msg) \ + "[MLD %s:%s %pI6] " msg, gm_ifp->ifp->vrf->name, gm_ifp->ifp->name, pkt_dst #define log_sg(sg, msg) \ "[MLD %s:%s %pSG] " msg, sg->iface->ifp->vrf->name, \ sg->iface->ifp->name, &sg->sgaddr @@ -1036,9 +1038,8 @@ static void gm_handle_v2_report(struct gm_if *gm_ifp, gm_packet_free(pkt); } -static void gm_handle_v1_report(struct gm_if *gm_ifp, - const struct sockaddr_in6 *pkt_src, char *data, - size_t len) +static void gm_handle_v1_report(struct gm_if *gm_ifp, const struct sockaddr_in6 *pkt_src, + pim_addr *pkt_dst, char *data, size_t len) { struct mld_v1_pkt *hdr; struct gm_packet_state *pkt; @@ -1057,6 +1058,14 @@ static void gm_handle_v1_report(struct gm_if *gm_ifp, gm_ifp->stats.rx_old_report++; hdr = (struct mld_v1_pkt *)data; + if (pim_addr_cmp(hdr->grp, *pkt_dst)) { + if (PIM_DEBUG_GM_PACKETS) + zlog_debug(log_pkt_dst( + "malformed MLDv1 report (destination address should be %pI6)"), + &hdr->grp); + gm_ifp->stats.rx_drop_malformed++; + return; + } if (gm_sg_filter_match(gm_ifp, PIMADDR_ANY, hdr->grp)) return; @@ -1705,7 +1714,7 @@ static void gm_rx_process(struct gm_if *gm_ifp, gm_handle_query(gm_ifp, pkt_src, pkt_dst, data, pktlen); break; case ICMP6_MLD_V1_REPORT: - gm_handle_v1_report(gm_ifp, pkt_src, data, pktlen); + gm_handle_v1_report(gm_ifp, pkt_src, pkt_dst, data, pktlen); break; case ICMP6_MLD_V1_DONE: gm_handle_v1_leave(gm_ifp, pkt_src, data, pktlen); From 3f42d71d8b4918222633aa20cb14679ecff99c08 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sun, 12 Oct 2025 15:32:04 +0800 Subject: [PATCH 2/3] tests: correct MLDv1 report check Before this PR, the MLDv1 reports without router-alert option wrongly used ff02::16 as destination address, ff02::16 is an bound (join-group) address on interface, so router-alert check is skipped by kernel. With this PR, the MLDv1 reports without router-alert option and with an unbound destination address are always dropped because kernel will discard them with unbound destination address. Add two changes: 1. Use group address as destination address for MLDv1 report 2. Remove the wrong check on MLDv1 report without router-alert Signed-off-by: anlan_cs --- .../multicast_features/test_multicast_features.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/topotests/multicast_features/test_multicast_features.py b/tests/topotests/multicast_features/test_multicast_features.py index 30a340e0c8..f0f47a9d1c 100644 --- a/tests/topotests/multicast_features/test_multicast_features.py +++ b/tests/topotests/multicast_features/test_multicast_features.py @@ -658,7 +658,7 @@ def test_igmp_router_alert(): def host_send_mldv1_packet(host, source, group, router_alert=True): "Sends packet using specified script from host." command = f"python3 {CWD}/../lib/packet/mld/mld_v1.py" - command += f" --src_ip={source} --gaddr={group}" + command += f" --src_ip={source} --dst_ip={group} --gaddr={group}" command += f" --iface={host}-eth0" if router_alert: command += f" --enable_router_alert" @@ -714,13 +714,10 @@ def test_mld_router_alert(): # # Test that without require-router-alert we learn MLD groups # - group = "ff05::100" - host_send_mldv1_packet("h1", source, group, router_alert=False) - test_func = partial(expect_mld_group, "r1", "r1-eth2", group) - logger.info(f"Waiting for r1 to learn {group} in interface r1-eth2") - rv, _ = topotest.run_and_expect(test_func, True, count=10, wait=2) - assert rv, "failed to learn group using MLDv1 without router alert" - + # MLDv1 reports without router-alert are always dropped, they are not + # controlled by require-router-alert command. So skip the check of + # MLDv1 reports without router-alert. + # group = "ff05::101" host_send_mldv2_packet("h1", source, group, router_alert=False) test_func = partial(expect_mld_group, "r1", "r1-eth2", group) From 509be1c1839104eb4cfe34060027f6c235f4b6de Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sun, 12 Oct 2025 15:53:48 +0800 Subject: [PATCH 3/3] doc: update require-router-alert command Add note that MLDv1 reports are not controlled by "require-router-alert" command. Signed-off-by: anlan_cs --- doc/user/pimv6.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst index 8daa101fe4..94170c0bb2 100644 --- a/doc/user/pimv6.rst +++ b/doc/user/pimv6.rst @@ -260,7 +260,8 @@ is in a vrf, enter the interface command with the vrf keyword at the end. .. clicmd:: ipv6 mld require-router-alert - Only accept MLD reports with the router-alert IPv6 hop option. + Only accept MLD reports with the router-alert IPv6 hop option. MLDv1 reports + without this option are always dropped and not controlled by this command. .. clicmd:: ipv6 mld join X:X::X:X [Y:Y::Y:Y]