Typos. A bunch of typos I've been collecting.
[vpp.git] / test / test_igmp.py
index da2fa9a..e94d29b 100644 (file)
@@ -2,13 +2,13 @@
 
 import unittest
 
-from framework import VppTestCase, VppTestRunner, running_extended_tests
-from vpp_igmp import *
-
 from scapy.layers.l2 import Ether
-from scapy.layers.inet import IP
-from scapy.contrib.igmpv3 import *
-from scapy.contrib.igmp import *
+from scapy.layers.inet import IP, IPOption
+from scapy.contrib.igmpv3 import IGMPv3, IGMPv3gr, IGMPv3mq, IGMPv3mr
+
+from framework import VppTestCase, VppTestRunner, running_extended_tests
+from vpp_igmp import find_igmp_state, IGMP_FILTER, IgmpRecord, IGMP_MODE, \
+    IgmpSG, VppHostState, wait_for_igmp_event
 from vpp_ip_route import find_mroute, VppIpTable
 
 
@@ -265,7 +265,7 @@ class TestIgmp(VppTestCase):
                            [IgmpRecord(h1.sg, "Mode Is Include")])
 
         #
-        # Two source and group specific queires in qucik sucession, the
+        # Two source and group specific queries in quick succession, the
         # first does not have VPPs source the second does. then vice-versa
         #
         self.send(self.pg0, [p_gs2, p_gs1])
@@ -554,7 +554,7 @@ class TestIgmp(VppTestCase):
 
         #
         # resend the join. wait for two queries and then send a current-state
-        # record to include all sources. this should reset the exiry time
+        # record to include all sources. this should reset the expiry time
         # on the sources and thus they will still be present in 2 seconds time.
         # If the source timer was not refreshed, then the state would have
         # expired in 3 seconds.
@@ -601,7 +601,7 @@ class TestIgmp(VppTestCase):
         self.assertFalse(self.vapi.igmp_dump())
 
         #
-        # resend the join, then a leave. Router sends a gruop+source
+        # resend the join, then a leave. Router sends a group+source
         # specific query containing both sources
         #
         self.send(self.pg0, p_j)
@@ -629,7 +629,7 @@ class TestIgmp(VppTestCase):
         self.assertFalse(self.vapi.igmp_dump())
 
         #
-        # A (*,G) host report
+        # a TO_EX({}) / IN_EX({}) is treated like a (*,G) join
         #
         p_j = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4, dst="224.0.0.22", tos=0xc0, ttl=1,
@@ -637,13 +637,78 @@ class TestIgmp(VppTestCase):
                                     option="router_alert")]) /
                IGMPv3(type="Version 3 Membership Report") /
                IGMPv3mr(numgrp=1) /
-               IGMPv3gr(rtype="Allow New Sources", maddr="239.1.1.2"))
+               IGMPv3gr(rtype="Change To Exclude Mode", maddr="239.1.1.2"))
 
         self.send(self.pg0, p_j)
 
         self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                             "239.1.1.2", "0.0.0.0", 1))
 
+        p_j = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
+               IP(src=self.pg0.remote_ip4, dst="224.0.0.22", tos=0xc0, ttl=1,
+                  options=[IPOption(copy_flag=1, optclass="control",
+                                    option="router_alert")]) /
+               IGMPv3(type="Version 3 Membership Report") /
+               IGMPv3mr(numgrp=1) /
+               IGMPv3gr(rtype="Mode Is Exclude", maddr="239.1.1.3"))
+
+        self.send(self.pg0, p_j)
+
+        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
+                                            "239.1.1.3", "0.0.0.0", 1))
+
+        #
+        # A 'allow sources' for {} should be ignored as it should
+        # never be sent.
+        #
+        p_j = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
+               IP(src=self.pg0.remote_ip4, dst="224.0.0.22", tos=0xc0, ttl=1,
+                  options=[IPOption(copy_flag=1, optclass="control",
+                                    option="router_alert")]) /
+               IGMPv3(type="Version 3 Membership Report") /
+               IGMPv3mr(numgrp=1) /
+               IGMPv3gr(rtype="Allow New Sources", maddr="239.1.1.4"))
+
+        self.send(self.pg0, p_j)
+
+        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
+        self.assertTrue(find_igmp_state(dump, self.pg0,
+                                        "239.1.1.2", "0.0.0.0"))
+        self.assertTrue(find_igmp_state(dump, self.pg0,
+                                        "239.1.1.3", "0.0.0.0"))
+        self.assertFalse(find_igmp_state(dump, self.pg0,
+                                         "239.1.1.4", "0.0.0.0"))
+
+        #
+        # a TO_IN({}) and IS_IN({}) are treated like a (*,G) leave
+        #
+        self.vapi.cli("set logging class igmp level debug")
+        p_l = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
+               IP(src=self.pg0.remote_ip4, dst="224.0.0.22", tos=0xc0, ttl=1,
+                  options=[IPOption(copy_flag=1, optclass="control",
+                                    option="router_alert")]) /
+               IGMPv3(type="Version 3 Membership Report") /
+               IGMPv3mr(numgrp=1) /
+               IGMPv3gr(rtype="Change To Include Mode", maddr="239.1.1.2"))
+
+        self.send(self.pg0, p_l)
+        self.assertTrue(wait_for_igmp_event(self, 2, self.pg0,
+                                            "239.1.1.2", "0.0.0.0", 0))
+
+        p_l = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
+               IP(src=self.pg0.remote_ip4, dst="224.0.0.22", tos=0xc0, ttl=1,
+                  options=[IPOption(copy_flag=1, optclass="control",
+                                    option="router_alert")]) /
+               IGMPv3(type="Version 3 Membership Report") /
+               IGMPv3mr(numgrp=1) /
+               IGMPv3gr(rtype="Mode Is Include", maddr="239.1.1.3"))
+
+        self.send(self.pg0, p_l)
+
+        self.assertTrue(wait_for_igmp_event(self, 2, self.pg0,
+                                            "239.1.1.3", "0.0.0.0", 0))
+        self.assertFalse(self.vapi.igmp_dump(self.pg0.sw_if_index))
+
         #
         # disable router config
         #