#!/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 """

    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)
