Commit bfbed92ea8 for frr
commit bfbed92ea8b7a23edb8dbd6e88d875ffd4d5b789
Author: Jafar Al-Gharaibeh <jafar@atcorp.com>
Date: Mon Oct 5 13:18:01 2026 -0500
tests: build IGMPv3 reports for current scapy
Scapy 2.7 turned IGMPv3() into a query type byte, so the stacked report
never installed a group and retries sent the same query again. Send one
membership report, with ttl 1, and exit if the send fails.
Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
diff --git a/tests/topotests/pim_igmp_specific_query_frag/igmp_send.py b/tests/topotests/pim_igmp_specific_query_frag/igmp_send.py
index 10fcf6eb63..8c271ac58d 100644
--- a/tests/topotests/pim_igmp_specific_query_frag/igmp_send.py
+++ b/tests/topotests/pim_igmp_specific_query_frag/igmp_send.py
@@ -13,28 +13,45 @@ import sys
import argparse
import json
-from scapy.main import load_contrib
from scapy.layers.l2 import Ether
from scapy.layers.inet import IP, IPOption_Router_Alert
from scapy.sendrecv import sendp
# pylint: disable=C0413
-load_contrib("igmpv3")
-from scapy.contrib.igmpv3 import IGMPv3, IGMPv3mr, IGMPv3gr
+# Names from the other scapy live only on one import path. Bind them up
+# front so the fallback report is not a use before assignment.
+IGMPv3 = IGMPv3mr = IGMPv3gr = None
+IGMPv3_MR = IGMPv3_MR_Group = None
+try:
+ # Current scapy. IGMPv3_MR is the whole report. Stacking a separate
+ # IGMPv3() in front of it puts a query type byte on the wire, and pimd
+ # never installs the group.
+ from scapy.layers.igmp import IGMPv3_MR, IGMPv3_MR_Group
+except ImportError:
+ from scapy.contrib.igmpv3 import IGMPv3, IGMPv3mr, IGMPv3gr
+
+
+def igmp_report(rtype, group, sources):
+ "One IGMPv3 membership report for a single group record."
+
+ if IGMPv3_MR is not None:
+ return IGMPv3_MR(
+ records=[IGMPv3_MR_Group(rtype=rtype, maddr=group, srcaddrs=sources)]
+ )
+
+ return IGMPv3() / IGMPv3mr(
+ records=[IGMPv3gr(rtype=rtype, maddr=group, srcaddrs=sources)]
+ )
def get_packet(rtype, group, src_ip, sources):
"Builds a single Ethernet/IP/IGMPv3 Membership Report packet"
- record = IGMPv3gr(rtype=rtype, maddr=group, srcaddrs=sources)
-
- pkt = (
+ return (
Ether(dst="01:00:5e:00:00:16")
- / IP(src=src_ip, dst="224.0.0.22", options=[IPOption_Router_Alert()])
- / IGMPv3()
- / IGMPv3mr(records=[record])
+ / IP(src=src_ip, dst="224.0.0.22", ttl=1, options=[IPOption_Router_Alert()])
+ / igmp_report(rtype, group, sources)
)
- return pkt
def main():
@@ -84,8 +101,9 @@ def main():
sendp(packets, iface=args.iface, verbose=False)
except Exception as e:
print(f"Send error: {e}")
+ sys.exit(1)
- print(f"Success")
+ print("Success")
if __name__ == "__main__":