[CORD-381] Implement L3McastToL2 tests

- Be careful with 224.1.1.1

Change-Id: I3f233315520be19ce062363898a4bb829531e3b1
diff --git a/ofdpa/flows.py b/ofdpa/flows.py
index dc5d2e9..675b284 100755
--- a/ofdpa/flows.py
+++ b/ofdpa/flows.py
@@ -943,6 +943,9 @@
     different ports. 4094-port is used as egress vlan_id.
     """
     def runTest( self ):
+        """
+        port1 (vlan 300)-> All Ports (vlan 300)
+        """
         Groups = Queue.LifoQueue( )
         try:
         # We can forward on the in_port but egress_vlan has to be different from ingress_vlan
@@ -1001,6 +1004,354 @@
 
                 verify_no_other_packets( self )
 
+            parsed_pkt = simple_udp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=vlan_id,
+                    eth_dst=dst_mac_str, eth_src=port1_mac_str, ip_ttl=64, ip_src=src_ip_str,
+                    ip_dst=dst_ip_str )
+            pkt = str( parsed_pkt )
+            self.dataplane.send( port1, pkt )
+            for port in config[ "port_map" ].keys( ):
+                if port == port2 or port == port1:
+                    verify_no_packet( self, pkt, port )
+                    continue
+                verify_packet( self, pkt, port )
+            verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2UntagToUntag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is untagged.
+    4094 is used as internal vlan_id. The packet goes out
+    untagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = False,
+                is_egress_tagged    = False,
+                is_vlan_translated  = False,
+                is_max_vlan         = True
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen  = 96,
+                    eth_dst = port_to_dst_mac_str[in_port],
+                    eth_src = port_to_src_mac_str[in_port],
+                    ip_ttl  = 64,
+                    ip_src  = port_to_src_ip_str[in_port],
+                    ip_dst  = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen  = 96,
+                        eth_dst = port_to_dst_mac_str[in_port],
+                        eth_src = port_to_src_mac_str[in_port],
+                        ip_ttl  = 64,
+                        ip_src  = port_to_src_ip_str[in_port],
+                        ip_dst  = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2UntagToTag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is untagged.
+    300 is used as vlan_id. The packet goes out
+    tagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = False,
+                is_egress_tagged    = True,
+                is_vlan_translated  = False,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen  = 96,
+                    eth_dst = port_to_dst_mac_str[in_port],
+                    eth_src = port_to_src_mac_str[in_port],
+                    ip_ttl  = 64,
+                    ip_src  = port_to_src_ip_str[in_port],
+                    ip_dst  = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen          = 100,
+                        dl_vlan_enable  = True,
+                        vlan_vid        = port_to_out_vlan[in_port],
+                        eth_dst         = port_to_dst_mac_str[in_port],
+                        eth_src         = port_to_src_mac_str[in_port],
+                        ip_ttl          = 64,
+                        ip_src          = port_to_src_ip_str[in_port],
+                        ip_dst          = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+
+class L3McastToL2TagToUntag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is tagged.
+    300 is used as vlan_id. The packet goes out
+    untagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = False,
+                is_vlan_translated  = False,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen          = 96,
+                        eth_dst         = port_to_dst_mac_str[in_port],
+                        eth_src         = port_to_src_mac_str[in_port],
+                        ip_ttl          = 64,
+                        ip_src          = port_to_src_ip_str[in_port],
+                        ip_dst          = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2TagToTag( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is tagged.
+    300 is used as vlan_id. The packet goes out tagged.
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = True,
+                is_vlan_translated  = False,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen         = 100,
+                        dl_vlan_enable = True,
+                        vlan_vid       = port_to_in_vlan[in_port],
+                        eth_dst        = port_to_dst_mac_str[in_port],
+                        eth_src        = port_to_src_mac_str[in_port],
+                        ip_ttl         = 64,
+                        ip_src         = port_to_src_ip_str[in_port],
+                        ip_dst         = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
+        finally:
+            delete_all_flows( self.controller )
+            delete_groups( self.controller, Groups )
+            delete_all_groups( self.controller )
+
+class L3McastToL2TagToTagTranslated( base_tests.SimpleDataPlane ):
+    """
+    Mcast routing, in this test case the traffic is tagged.
+    port+1 is used as ingress vlan_id. The packet goes out
+    tagged. 4094-port is used as egress vlan_id
+    """
+    def runTest( self ):
+        Groups = Queue.LifoQueue( )
+        try:
+            if len( config[ "port_map" ] ) < 2:
+                logging.info( "Port count less than 2, can't run this case" )
+                assert (False)
+                return
+            ports      = config[ "port_map" ].keys( )
+            dst_ip_str = "224.0.0.1"
+            (
+                port_to_in_vlan,
+                port_to_out_vlan,
+                port_to_src_mac_str,
+                port_to_dst_mac_str,
+                port_to_src_ip_str,
+                Groups) = fill_mcast_pipeline_L3toL2(
+                self.controller,
+                logging,
+                ports,
+                is_ingress_tagged   = True,
+                is_egress_tagged    = True,
+                is_vlan_translated  = True,
+                is_max_vlan         = False
+                )
+
+            for in_port in ports:
+
+                parsed_pkt = simple_udp_packet(
+                    pktlen         = 100,
+                    dl_vlan_enable = True,
+                    vlan_vid       = port_to_in_vlan[in_port],
+                    eth_dst        = port_to_dst_mac_str[in_port],
+                    eth_src        = port_to_src_mac_str[in_port],
+                    ip_ttl         = 64,
+                    ip_src         = port_to_src_ip_str[in_port],
+                    ip_dst         = dst_ip_str
+                    )
+                pkt = str( parsed_pkt )
+                self.dataplane.send( in_port, pkt )
+
+                for out_port in ports:
+
+                    parsed_pkt = simple_udp_packet(
+                        pktlen         = 100,
+                        dl_vlan_enable = True,
+                        vlan_vid       = port_to_out_vlan[in_port],
+                        eth_dst        = port_to_dst_mac_str[in_port],
+                        eth_src        = port_to_src_mac_str[in_port],
+                        ip_ttl         = 64,
+                        ip_src         = port_to_src_ip_str[in_port],
+                        ip_dst         = dst_ip_str
+                        )
+                    pkt = str( parsed_pkt )
+                    if out_port == in_port:
+                        verify_no_packet( self, pkt, in_port )
+                        continue
+                    verify_packet( self, pkt, out_port )
+                    verify_no_other_packets( self )
         finally:
             delete_all_flows( self.controller )
             delete_groups( self.controller, Groups )