#!/usr/bin/env python

import unittest

from scapy.layers.l2 import Ether
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


class IgmpMode:
    HOST = 1
    ROUTER = 0


class TestIgmp(VppTestCase):
    """ IGMP Test Case """

    @classmethod
    def setUpClass(cls):
        super(TestIgmp, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(TestIgmp, cls).tearDownClass()

    def setUp(self):
        super(TestIgmp, self).setUp()

        self.create_pg_interfaces(range(4))
        self.sg_list = []
        self.config_list = []

        self.ip_addr = []
        self.ip_table = VppIpTable(self, 1)
        self.ip_table.add_vpp_config()

        for pg in self.pg_interfaces[2:]:
            pg.set_table_ip4(1)
        for pg in self.pg_interfaces:
            pg.admin_up()
            pg.config_ip4()
            pg.resolve_arp()

    def tearDown(self):
        for pg in self.pg_interfaces:
            self.vapi.igmp_clear_interface(pg.sw_if_index)
            pg.unconfig_ip4()
            pg.set_table_ip4(0)
            pg.admin_down()
        super(TestIgmp, self).tearDown()

    def send(self, ti, pkts):
        ti.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

    def test_igmp_flush(self):
        """ IGMP Link Up/down and Flush """

        #
        # FIX THIS. Link down.
        #

    def test_igmp_enable(self):
        """ IGMP enable/disable on an interface

        check for the addition/removal of the IGMP mroutes """

        self.vapi.igmp_enable_disable(self.pg0.sw_if_index, 1, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg1.sw_if_index, 1, IGMP_MODE.HOST)

        self.assertTrue(find_mroute(self, "224.0.0.1", "0.0.0.0", 32))
        self.assertTrue(find_mroute(self, "224.0.0.22", "0.0.0.0", 32))

        self.vapi.igmp_enable_disable(self.pg2.sw_if_index, 1, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg3.sw_if_index, 1, IGMP_MODE.HOST)

        self.assertTrue(find_mroute(self, "224.0.0.1", "0.0.0.0", 32,
                                    table_id=1))
        self.assertTrue(find_mroute(self, "224.0.0.22", "0.0.0.0", 32,
                                    table_id=1))
        self.vapi.igmp_enable_disable(self.pg0.sw_if_index, 0, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg1.sw_if_index, 0, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg2.sw_if_index, 0, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg3.sw_if_index, 0, IGMP_MODE.HOST)

        self.assertFalse(find_mroute(self, "224.0.0.1", "0.0.0.0", 32))
        self.assertFalse(find_mroute(self, "224.0.0.22", "0.0.0.0", 32))
        self.assertFalse(find_mroute(self, "224.0.0.1", "0.0.0.0", 32,
                                     table_id=1))
        self.assertFalse(find_mroute(self, "224.0.0.22", "0.0.0.0", 32,
                                     table_id=1))

    def verify_general_query(self, p):
        ip = p[IP]
        self.assertEqual(len(ip.options), 1)
        self.assertEqual(ip.options[0].option, 20)
        self.assertEqual(ip.dst, "224.0.0.1")
        self.assertEqual(ip.proto, 2)
        igmp = p[IGMPv3]
        self.assertEqual(igmp.type, 0x11)
        self.assertEqual(igmp.gaddr, "0.0.0.0")

    def verify_group_query(self, p, grp, srcs):
        ip = p[IP]
        self.assertEqual(ip.dst, grp)
        self.assertEqual(ip.proto, 2)
        self.assertEqual(len(ip.options), 1)
        self.assertEqual(ip.options[0].option, 20)
        self.assertEqual(ip.proto, 2)
        igmp = p[IGMPv3]
        self.assertEqual(igmp.type, 0x11)
        self.assertEqual(igmp.gaddr, grp)

    def verify_report(self, rx, records):
        ip = rx[IP]
        self.assertEqual(rx[IP].dst, "224.0.0.22")
        self.assertEqual(len(ip.options), 1)
        self.assertEqual(ip.options[0].option, 20)
        self.assertEqual(ip.proto, 2)
        self.assertEqual(IGMPv3.igmpv3types[rx[IGMPv3].type],
                         "Version 3 Membership Report")
        self.assertEqual(rx[IGMPv3mr].numgrp, len(records))

        received = rx[IGMPv3mr].records

        for ii in range(len(records)):
            gr = received[ii]
            r = records[ii]
            self.assertEqual(IGMPv3gr.igmpv3grtypes[gr.rtype], r.type)
            self.assertEqual(gr.numsrc, len(r.sg.saddrs))
            self.assertEqual(gr.maddr, r.sg.gaddr)
            self.assertEqual(len(gr.srcaddrs), len(r.sg.saddrs))

            self.assertEqual(sorted(gr.srcaddrs),
                             sorted(r.sg.saddrs))

    def add_group(self, itf, sg, n_pkts=2):
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        hs = VppHostState(self,
                          IGMP_FILTER.INCLUDE,
                          itf.sw_if_index,
                          sg)
        hs.add_vpp_config()

        capture = itf.get_capture(n_pkts, timeout=10)

        # reports are transmitted twice due to default rebostness value=2
        self.verify_report(capture[0],
                           [IgmpRecord(sg, "Allow New Sources")]),
        self.verify_report(capture[1],
                           [IgmpRecord(sg, "Allow New Sources")]),

        return hs

    def remove_group(self, hs):
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        hs.remove_vpp_config()

        capture = self.pg0.get_capture(1, timeout=10)

        self.verify_report(capture[0],
                           [IgmpRecord(hs.sg, "Block Old Sources")])

    def test_igmp_host(self):
        """ IGMP Host functions """

        #
        # Enable interface for host functions
        #
        self.vapi.igmp_enable_disable(self.pg0.sw_if_index,
                                      1,
                                      IGMP_MODE.HOST)

        #
        # Add one S,G of state and expect a state-change event report
        # indicating the addition of the S,G
        #
        h1 = self.add_group(self.pg0, IgmpSG("239.1.1.1", ["1.1.1.1"]))

        # search for the corresponding state created in VPP
        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
        self.assertEqual(len(dump), 1)
        self.assertTrue(find_igmp_state(dump, self.pg0,
                                        "239.1.1.1", "1.1.1.1"))

        #
        # Send a general query (to the all router's address)
        # expect VPP to respond with a membership report
        #
        p_g = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
               IP(src=self.pg0.remote_ip4, dst='224.0.0.1', tos=0xc0) /
               IGMPv3(type="Membership Query", mrcode=100) /
               IGMPv3mq(gaddr="0.0.0.0"))

        self.send(self.pg0, p_g)

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h1.sg, "Mode Is Include")])

        #
        # Group specific query
        #
        p_gs = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4, dst='239.1.1.1', tos=0xc0,
                   options=[IPOption(copy_flag=1, optclass="control",
                                     option="router_alert")]) /
                IGMPv3(type="Membership Query", mrcode=100) /
                IGMPv3mq(gaddr="239.1.1.1"))

        self.send(self.pg0, p_gs)

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h1.sg, "Mode Is Include")])

        #
        # A group and source specific query, with the source matching
        # the source VPP has
        #
        p_gs1 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                 IP(src=self.pg0.remote_ip4, dst='239.1.1.1', tos=0xc0,
                    options=[IPOption(copy_flag=1, optclass="control",
                                      option="router_alert")]) /
                 IGMPv3(type="Membership Query", mrcode=100) /
                 IGMPv3mq(gaddr="239.1.1.1", srcaddrs=["1.1.1.1"]))

        self.send(self.pg0, p_gs1)

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h1.sg, "Mode Is Include")])

        #
        # A group and source specific query, with the source NOT matching
        # the source VPP has. There should be no response.
        #
        p_gs2 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                 IP(src=self.pg0.remote_ip4, dst='239.1.1.1', tos=0xc0,
                    options=[IPOption(copy_flag=1, optclass="control",
                                      option="router_alert")]) /
                 IGMPv3(type="Membership Query", mrcode=100) /
                 IGMPv3mq(gaddr="239.1.1.1", srcaddrs=["1.1.1.2"]))

        self.send_and_assert_no_replies(self.pg0, p_gs2, timeout=10)

        #
        # A group and source specific query, with the multiple sources
        # one of which matches the source VPP has.
        # The report should contain only the source VPP has.
        #
        p_gs3 = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                 IP(src=self.pg0.remote_ip4, dst='239.1.1.1', tos=0xc0,
                    options=[IPOption(copy_flag=1, optclass="control",
                                      option="router_alert")]) /
                 IGMPv3(type="Membership Query", mrcode=100) /
                 IGMPv3mq(gaddr="239.1.1.1",
                          srcaddrs=["1.1.1.1", "1.1.1.2", "1.1.1.3"]))

        self.send(self.pg0, p_gs3)

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h1.sg, "Mode Is Include")])

        #
        # 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])
        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h1.sg, "Mode Is Include")])

        self.send(self.pg0, [p_gs1, p_gs2])
        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h1.sg, "Mode Is Include")])

        #
        # remove state, expect the report for the removal
        #
        self.remove_group(h1)

        dump = self.vapi.igmp_dump()
        self.assertFalse(dump)

        #
        # A group with multiple sources
        #
        h2 = self.add_group(self.pg0,
                            IgmpSG("239.1.1.1",
                                   ["1.1.1.1", "1.1.1.2", "1.1.1.3"]))

        # search for the corresponding state created in VPP
        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
        self.assertEqual(len(dump), 3)
        for s in h2.sg.saddrs:
            self.assertTrue(find_igmp_state(dump, self.pg0,
                                            "239.1.1.1", s))
        #
        # Send a general query (to the all router's address)
        # expect VPP to respond with a membership report will all sources
        #
        self.send(self.pg0, p_g)

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(h2.sg, "Mode Is Include")])

        #
        # Group and source specific query; some present some not
        #
        p_gs = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4, dst='239.1.1.1', tos=0xc0,
                   options=[IPOption(copy_flag=1, optclass="control",
                                     option="router_alert")]) /
                IGMPv3(type="Membership Query", mrcode=100) /
                IGMPv3mq(gaddr="239.1.1.1",
                         srcaddrs=["1.1.1.1", "1.1.1.2", "1.1.1.4"]))

        self.send(self.pg0, p_gs)

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(
                               IgmpSG('239.1.1.1', ["1.1.1.1", "1.1.1.2"]),
                               "Mode Is Include")])

        #
        # add loads more groups
        #
        h3 = self.add_group(self.pg0,
                            IgmpSG("239.1.1.2",
                                   ["2.1.1.1", "2.1.1.2", "2.1.1.3"]))
        h4 = self.add_group(self.pg0,
                            IgmpSG("239.1.1.3",
                                   ["3.1.1.1", "3.1.1.2", "3.1.1.3"]))
        h5 = self.add_group(self.pg0,
                            IgmpSG("239.1.1.4",
                                   ["4.1.1.1", "4.1.1.2", "4.1.1.3"]))
        h6 = self.add_group(self.pg0,
                            IgmpSG("239.1.1.5",
                                   ["5.1.1.1", "5.1.1.2", "5.1.1.3"]))
        h7 = self.add_group(self.pg0,
                            IgmpSG("239.1.1.6",
                                   ["6.1.1.1", "6.1.1.2",
                                    "6.1.1.3", "6.1.1.4",
                                    "6.1.1.5", "6.1.1.6",
                                    "6.1.1.7", "6.1.1.8",
                                    "6.1.1.9", "6.1.1.10",
                                    "6.1.1.11", "6.1.1.12",
                                    "6.1.1.13", "6.1.1.14",
                                    "6.1.1.15", "6.1.1.16"]))

        #
        # general query.
        # the order the groups come in is not important, so what is
        # checked for is what VPP is sending today.
        #
        self.send(self.pg0, p_g)

        capture = self.pg0.get_capture(1, timeout=10)

        self.verify_report(capture[0],
                           [IgmpRecord(h3.sg, "Mode Is Include"),
                            IgmpRecord(h2.sg, "Mode Is Include"),
                            IgmpRecord(h6.sg, "Mode Is Include"),
                            IgmpRecord(h4.sg, "Mode Is Include"),
                            IgmpRecord(h5.sg, "Mode Is Include"),
                            IgmpRecord(h7.sg, "Mode Is Include")])

        #
        # modify a group to add and remove some sources
        #
        h7.sg = IgmpSG("239.1.1.6",
                       ["6.1.1.1", "6.1.1.2",
                        "6.1.1.5", "6.1.1.6",
                        "6.1.1.7", "6.1.1.8",
                        "6.1.1.9", "6.1.1.10",
                        "6.1.1.11", "6.1.1.12",
                        "6.1.1.13", "6.1.1.14",
                        "6.1.1.15", "6.1.1.16",
                        "6.1.1.17", "6.1.1.18"])

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        h7.add_vpp_config()

        capture = self.pg0.get_capture(1, timeout=10)
        self.verify_report(capture[0],
                           [IgmpRecord(IgmpSG("239.1.1.6",
                                              ["6.1.1.17", "6.1.1.18"]),
                                       "Allow New Sources"),
                            IgmpRecord(IgmpSG("239.1.1.6",
                                              ["6.1.1.3", "6.1.1.4"]),
                                       "Block Old Sources")])

        #
        # add an additional groups with many sources so that each group
        # consumes the link MTU. We should therefore see multiple state
        # state reports when queried.
        #
        self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [560, 0, 0, 0])

        src_list = []
        for i in range(128):
            src_list.append("10.1.1.%d" % i)

        h8 = self.add_group(self.pg0,
                            IgmpSG("238.1.1.1", src_list))
        h9 = self.add_group(self.pg0,
                            IgmpSG("238.1.1.2", src_list))

        self.send(self.pg0, p_g)

        capture = self.pg0.get_capture(4, timeout=10)

        self.verify_report(capture[0],
                           [IgmpRecord(h3.sg, "Mode Is Include"),
                            IgmpRecord(h2.sg, "Mode Is Include"),
                            IgmpRecord(h6.sg, "Mode Is Include"),
                            IgmpRecord(h4.sg, "Mode Is Include"),
                            IgmpRecord(h5.sg, "Mode Is Include")])
        self.verify_report(capture[1],
                           [IgmpRecord(h8.sg, "Mode Is Include")])
        self.verify_report(capture[2],
                           [IgmpRecord(h7.sg, "Mode Is Include")])
        self.verify_report(capture[3],
                           [IgmpRecord(h9.sg, "Mode Is Include")])

        #
        # drop the MTU further (so a 128 sized group won't fit)
        #
        self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [512, 0, 0, 0])

        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()

        h10 = VppHostState(self,
                           IGMP_FILTER.INCLUDE,
                           self.pg0.sw_if_index,
                           IgmpSG("238.1.1.3", src_list))
        h10.add_vpp_config()

        capture = self.pg0.get_capture(2, timeout=10)

        #
        # remove state, expect the report for the removal
        # the dump should be empty
        #
        self.vapi.sw_interface_set_mtu(self.pg0.sw_if_index, [600, 0, 0, 0])
        self.remove_group(h8)
        self.remove_group(h9)
        self.remove_group(h2)
        self.remove_group(h3)
        self.remove_group(h4)
        self.remove_group(h5)
        self.remove_group(h6)
        self.remove_group(h7)
        self.remove_group(h10)

        self.logger.info(self.vapi.cli("sh igmp config"))
        self.assertFalse(self.vapi.igmp_dump())

        #
        # TODO
        #  ADD STATE ON MORE INTERFACES
        #

        self.vapi.igmp_enable_disable(self.pg0.sw_if_index,
                                      0,
                                      IGMP_MODE.HOST)

    def test_igmp_router(self):
        """ IGMP Router Functions """

        #
        # Drop reports when not enabled
        #
        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.1", srcaddrs=["10.1.1.1", "10.1.1.2"]))
        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,
                  options=[IPOption(copy_flag=1, optclass="control",
                                    option="router_alert")]) /
               IGMPv3(type="Version 3 Membership Report") /
               IGMPv3mr(numgrp=1) /
               IGMPv3gr(rtype="Block Old Sources",
                        maddr="239.1.1.1", srcaddrs=["10.1.1.1", "10.1.1.2"]))

        self.send(self.pg0, p_j)
        self.assertFalse(self.vapi.igmp_dump())

        #
        # drop the default timer values so these tests execute in a
        # reasonable time frame
        #
        self.vapi.cli("test igmp timers query 1 src 3 leave 1")

        #
        # enable router functions on the interface
        #
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        self.vapi.igmp_enable_disable(self.pg0.sw_if_index,
                                      1,
                                      IGMP_MODE.ROUTER)
        self.vapi.want_igmp_events(1)

        #
        # wait for router to send general query
        #
        for ii in range(3):
            capture = self.pg0.get_capture(1, timeout=2)
            self.verify_general_query(capture[0])
            self.pg_enable_capture(self.pg_interfaces)
            self.pg_start()

        #
        # re-send the report. VPP should now hold state for the new group
        # VPP sends a notification that a new group has been joined
        #
        self.send(self.pg0, p_j)

        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.1", 1))
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.2", 1))
        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
        self.assertEqual(len(dump), 2)
        self.assertTrue(find_igmp_state(dump, self.pg0,
                                        "239.1.1.1", "10.1.1.1"))
        self.assertTrue(find_igmp_state(dump, self.pg0,
                                        "239.1.1.1", "10.1.1.2"))

        #
        # wait for the per-source timer to expire
        # the state should be reaped
        # VPP sends a notification that the group has been left
        #
        self.assertTrue(wait_for_igmp_event(self, 4, self.pg0,
                                            "239.1.1.1", "10.1.1.1", 0))
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.2", 0))
        self.assertFalse(self.vapi.igmp_dump())

        #
        # resend the join. wait for two queries and then send a current-state
        # 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.
        #
        self.send(self.pg0, p_j)
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.1", 1))
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.2", 1))
        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
        self.assertEqual(len(dump), 2)

        capture = self.pg0.get_capture(2, timeout=3)
        self.verify_general_query(capture[0])
        self.verify_general_query(capture[1])

        p_cs = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
                IP(src=self.pg0.remote_ip4, dst="224.0.0.22", tos=0xc0,
                   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.1", srcaddrs=["10.1.1.1", "10.1.1.2"]))

        self.send(self.pg0, p_cs)

        self.sleep(2)
        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
        self.assertEqual(len(dump), 2)
        self.assertTrue(find_igmp_state(dump, self.pg0,
                                        "239.1.1.1", "10.1.1.1"))
        self.assertTrue(find_igmp_state(dump, self.pg0,
                                        "239.1.1.1", "10.1.1.2"))

        #
        # wait for the per-source timer to expire
        # the state should be reaped
        #
        self.assertTrue(wait_for_igmp_event(self, 4, self.pg0,
                                            "239.1.1.1", "10.1.1.1", 0))
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.2", 0))
        self.assertFalse(self.vapi.igmp_dump())

        #
        # resend the join, then a leave. Router sends a group+source
        # specific query containing both sources
        #
        self.send(self.pg0, p_j)

        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.1", 1))
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.2", 1))
        dump = self.vapi.igmp_dump(self.pg0.sw_if_index)
        self.assertEqual(len(dump), 2)

        self.send(self.pg0, p_l)
        capture = self.pg0.get_capture(1, timeout=3)
        self.verify_group_query(capture[0], "239.1.1.1",
                                ["10.1.1.1", "10.1.1.2"])

        #
        # the group specific query drops the timeout to leave (=1) seconds
        #
        self.assertTrue(wait_for_igmp_event(self, 2, self.pg0,
                                            "239.1.1.1", "10.1.1.1", 0))
        self.assertTrue(wait_for_igmp_event(self, 1, self.pg0,
                                            "239.1.1.1", "10.1.1.2", 0))
        self.assertFalse(self.vapi.igmp_dump())
        self.assertFalse(self.vapi.igmp_dump())

        #
        # 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,
                  options=[IPOption(copy_flag=1, optclass="control",
                                    option="router_alert")]) /
               IGMPv3(type="Version 3 Membership Report") /
               IGMPv3mr(numgrp=1) /
               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
        #
        self.vapi.igmp_enable_disable(self.pg0.sw_if_index,
                                      0,
                                      IGMP_MODE.ROUTER)

    def _create_igmpv3_pck(self, itf, rtype, maddr, srcaddrs):
        p = (Ether(dst=itf.local_mac, src=itf.remote_mac) /
             IP(src=itf.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=rtype,
                      maddr=maddr, srcaddrs=srcaddrs))
        return p

    def test_igmp_proxy_device(self):
        """ IGMP proxy device """
        self.pg2.admin_down()
        self.pg2.unconfig_ip4()
        self.pg2.set_table_ip4(0)
        self.pg2.config_ip4()
        self.pg2.admin_up()

        self.vapi.cli('test igmp timers query 10 src 3 leave 1')

        # enable IGMP
        self.vapi.igmp_enable_disable(self.pg0.sw_if_index, 1, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg1.sw_if_index, 1,
                                      IGMP_MODE.ROUTER)
        self.vapi.igmp_enable_disable(self.pg2.sw_if_index, 1,
                                      IGMP_MODE.ROUTER)

        # create IGMP proxy device
        self.vapi.igmp_proxy_device_add_del(0, self.pg0.sw_if_index, 1)
        self.vapi.igmp_proxy_device_add_del_interface(0,
                                                      self.pg1.sw_if_index, 1)
        self.vapi.igmp_proxy_device_add_del_interface(0,
                                                      self.pg2.sw_if_index, 1)

        # send join on pg1. join should be proxied by pg0
        p_j = self._create_igmpv3_pck(self.pg1, "Allow New Sources",
                                      "239.1.1.1", ["10.1.1.1", "10.1.1.2"])
        self.send(self.pg1, p_j)

        capture = self.pg0.get_capture(1, timeout=1)
        self.verify_report(capture[0], [IgmpRecord(IgmpSG("239.1.1.1",
                           ["10.1.1.1", "10.1.1.2"]), "Allow New Sources")])
        self.assertTrue(find_mroute(self, "239.1.1.1", "0.0.0.0", 32))

        # send join on pg2. join should be proxied by pg0.
        # the group should contain only 10.1.1.3 as
        # 10.1.1.1 was already reported
        p_j = self._create_igmpv3_pck(self.pg2, "Allow New Sources",
                                      "239.1.1.1", ["10.1.1.1", "10.1.1.3"])
        self.send(self.pg2, p_j)

        capture = self.pg0.get_capture(1, timeout=1)
        self.verify_report(capture[0], [IgmpRecord(IgmpSG("239.1.1.1",
                           ["10.1.1.3"]), "Allow New Sources")])
        self.assertTrue(find_mroute(self, "239.1.1.1", "0.0.0.0", 32))

        # send leave on pg2. leave for 10.1.1.3 should be proxyed
        # as pg2 was the only interface interested in 10.1.1.3
        p_l = self._create_igmpv3_pck(self.pg2, "Block Old Sources",
                                      "239.1.1.1", ["10.1.1.3"])
        self.send(self.pg2, p_l)

        capture = self.pg0.get_capture(1, timeout=2)
        self.verify_report(capture[0], [IgmpRecord(IgmpSG("239.1.1.1",
                           ["10.1.1.3"]), "Block Old Sources")])
        self.assertTrue(find_mroute(self, "239.1.1.1", "0.0.0.0", 32))

        # disable igmp on pg1 (also removes interface from proxy device)
        # proxy leave for 10.1.1.2. pg2 is still interested in 10.1.1.1
        self.pg_enable_capture(self.pg_interfaces)
        self.vapi.igmp_enable_disable(self.pg1.sw_if_index, 0,
                                      IGMP_MODE.ROUTER)

        capture = self.pg0.get_capture(1, timeout=1)
        self.verify_report(capture[0], [IgmpRecord(IgmpSG("239.1.1.1",
                           ["10.1.1.2"]), "Block Old Sources")])
        self.assertTrue(find_mroute(self, "239.1.1.1", "0.0.0.0", 32))

        # disable IGMP on pg0 and pg1.
        #   disabling IGMP on pg0 (proxy device upstream interface)
        #   removes this proxy device
        self.vapi.igmp_enable_disable(self.pg0.sw_if_index, 0, IGMP_MODE.HOST)
        self.vapi.igmp_enable_disable(self.pg2.sw_if_index, 0,
                                      IGMP_MODE.ROUTER)
        self.assertFalse(find_mroute(self, "239.1.1.1", "0.0.0.0", 32))


if __name__ == '__main__':
    unittest.main(testRunner=VppTestRunner)
