diff --git a/lib/mcast-group-index.h b/lib/mcast-group-index.h
index cb49ad7..ba995ba 100644
--- a/lib/mcast-group-index.h
+++ b/lib/mcast-group-index.h
@@ -28,6 +28,8 @@ enum ovn_mcast_tunnel_keys {
     OVN_MCAST_FLOOD_TUNNEL_KEY = OVN_MIN_MULTICAST,
     OVN_MCAST_UNKNOWN_TUNNEL_KEY,
     OVN_MCAST_MROUTER_FLOOD_TUNNEL_KEY,
+    OVN_MCAST_MROUTER_STATIC_TUNNEL_KEY,
+    OVN_MCAST_STATIC_TUNNEL_KEY,
     OVN_MIN_IP_MULTICAST,
     OVN_MAX_IP_MULTICAST = OVN_MAX_MULTICAST,
 };
diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
index 0f4f1c1..429ed7e 100644
--- a/northd/ovn-northd.8.xml
+++ b/northd/ovn-northd.8.xml
@@ -954,7 +954,11 @@ output;
       <li>
         A priority-100 flow that punts all IGMP packets to
         <code>ovn-controller</code> if IGMP snooping is enabled on the
-        logical switch.
+        logical switch. The flow also forwards the IGMP packets to the
+        <code>MC_MROUTER_STATIC</code> multicast group, which
+        <code>ovn-northd</code> populates with all the logical ports that
+        have <ref column="options" table="Logical_Switch_Port"/>
+        <code>:mcast_flood_reports='true'</code>.
       </li>
 
       <li>
@@ -976,10 +980,15 @@ output;
 
       <li>
         A priority-80 flow that forwards all unregistered IP multicast traffic
-        to the <code>MC_MROUTER_FLOOD</code> multicast group, if any.
-        Otherwise the flow drops all unregistered IP multicast packets.  This
-        flow is added only if <ref column="other_config"
-        table="Logical_Switch"/>:mcast_flood_unregistered='false'.
+        to the <code>MC_STATIC</code> multicast group, which
+        <code>ovn-northd</code> populates with all the logical ports that
+        have <ref column="options" table="Logical_Switch_Port"/>
+        <code>:mcast_flood='true'</code>. The flow also forwards
+        unregistered IP multicast traffic to the <code>MC_MROUTER_FLOOD</code>
+        multicast group, which <code>ovn-northd</code> populates with all the
+        logical ports connected to logical routers that have
+        <ref column="options" table="Logical_Router"/>
+        <code>:mcast_relay='true'</code>.
       </li>
 
       <li>
@@ -2027,6 +2036,17 @@ output;
 
       <li>
         <p>
+          Priority-450 flow that matches unregistered IP multicast traffic
+          and sets <code>outport</code> to the <code>MC_STATIC</code>
+          multicast group, which <code>ovn-northd</code> populates with the
+          logical ports that have
+          <ref column="options" table="Logical_Router_Port"/>
+          <code>:mcast_flood='true'</code>.
+        </p>
+      </li>
+
+      <li>
+        <p>
           For distributed logical routers where one of the logical router
           ports specifies a <code>redirect-chassis</code>, a priority-400
           logical flow for each ip source/destination couple that matches the
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index f393ceb..538daa1 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -448,7 +448,12 @@ struct mcast_switch_info {
                                  * should be flooded to the mrouter. Only
                                  * applicable if flood_unregistered == false.
                                  */
-
+    bool flood_reports;         /* True if the switch has at least one port
+                                 * configured to flood reports.
+                                 */
+    bool flood_static;          /* True if the switch has at least one port
+                                 * configured to flood traffic.
+                                 */
     int64_t table_size;         /* Max number of IP multicast groups. */
     int64_t idle_timeout;       /* Timeout after which an idle group is
                                  * flushed.
@@ -466,7 +471,10 @@ struct mcast_switch_info {
 };
 
 struct mcast_router_info {
-    bool relay; /* True if the router should relay IP multicast. */
+    bool relay;        /* True if the router should relay IP multicast. */
+    bool flood_static; /* True if the router has at least one port configured
+                        * to flood traffic.
+                        */
 };
 
 struct mcast_info {
@@ -481,6 +489,34 @@ struct mcast_info {
     };
 };
 
+struct mcast_port_info {
+    bool flood;         /* True if the port should flood IP multicast traffic
+                         * regardless if it's registered or not. */
+    bool flood_reports; /* True if the port should flood IP multicast reports
+                         * (e.g., IGMP join/leave). */
+};
+
+static void
+init_mcast_port_info(struct mcast_port_info *mcast_info,
+                     const struct nbrec_logical_switch_port *nbsp,
+                     const struct nbrec_logical_router_port *nbrp)
+{
+    if (nbsp) {
+        mcast_info->flood =
+            smap_get_bool(&nbsp->options, "mcast_flood", false);
+        mcast_info->flood_reports =
+            smap_get_bool(&nbsp->options, "mcast_flood_reports",
+                          false);
+    } else if (nbrp) {
+        /* We don't process multicast reports in any special way on logical
+         * routers so just treat them as regular multicast traffic.
+         */
+        mcast_info->flood =
+            smap_get_bool(&nbrp->options, "mcast_flood", false);
+        mcast_info->flood_reports = mcast_info->flood;
+    }
+}
+
 static uint32_t
 ovn_mcast_group_allocate_key(struct mcast_info *mcast_info)
 {
@@ -1022,7 +1058,7 @@ build_datapaths(struct northd_context *ctx, struct hmap *datapaths,
         ovn_datapath_destroy(datapaths, od);
     }
 }
-
+
 struct ovn_port {
     struct hmap_node key_node;  /* Index on 'key'. */
     char *key;                  /* nbs->name, nbr->name, sb->logical_port. */
@@ -1044,6 +1080,9 @@ struct ovn_port {
 
     struct lport_addresses lrp_networks;
 
+    /* Logical port multicast data. */
+    struct mcast_port_info mcast_info;
+
     bool derived; /* Indicates whether this is an additional port
                    * derived from nbsp or nbrp. */
 
@@ -1060,6 +1099,23 @@ struct ovn_port {
     struct ovs_list list;       /* In list of similar records. */
 };
 
+static void
+ovn_port_set_sb(struct ovn_port *op,
+                const struct sbrec_port_binding *sb)
+{
+    op->sb = sb;
+}
+
+static void
+ovn_port_set_nb(struct ovn_port *op,
+                const struct nbrec_logical_switch_port *nbsp,
+                const struct nbrec_logical_router_port *nbrp)
+{
+    op->nbsp = nbsp;
+    op->nbrp = nbrp;
+    init_mcast_port_info(&op->mcast_info, op->nbsp, op->nbrp);
+}
+
 static struct ovn_port *
 ovn_port_create(struct hmap *ports, const char *key,
                 const struct nbrec_logical_switch_port *nbsp,
@@ -1073,9 +1129,8 @@ ovn_port_create(struct hmap *ports, const char *key,
     op->json_key = ds_steal_cstr(&json_key);
 
     op->key = xstrdup(key);
-    op->sb = sb;
-    op->nbsp = nbsp;
-    op->nbrp = nbrp;
+    ovn_port_set_sb(op, sb);
+    ovn_port_set_nb(op, nbsp, nbrp);
     op->derived = false;
     hmap_insert(ports, &op->key_node, hash_string(op->key, 0));
     return op;
@@ -1878,7 +1933,7 @@ join_logical_ports(struct northd_context *ctx,
                                      nbsp->name);
                         continue;
                     }
-                    op->nbsp = nbsp;
+                    ovn_port_set_nb(op, nbsp, NULL);
                     ovs_list_remove(&op->list);
 
                     uint32_t queue_id = smap_get_int(&op->sb->options,
@@ -1969,7 +2024,7 @@ join_logical_ports(struct northd_context *ctx,
                                      nbrp->name);
                         continue;
                     }
-                    op->nbrp = nbrp;
+                    ovn_port_set_nb(op, NULL, nbrp);
                     ovs_list_remove(&op->list);
                     ovs_list_push_back(both, &op->list);
 
@@ -2014,7 +2069,7 @@ join_logical_ports(struct northd_context *ctx,
                     struct ovn_port *crp = ovn_port_find(ports, redirect_name);
                     if (crp) {
                         crp->derived = true;
-                        crp->nbrp = nbrp;
+                        ovn_port_set_nb(crp, NULL, nbrp);
                         ovs_list_remove(&crp->list);
                         ovs_list_push_back(both, &crp->list);
                     } else {
@@ -2890,7 +2945,7 @@ build_ports(struct northd_context *ctx,
             continue;
         }
 
-        op->sb = sbrec_port_binding_insert(ctx->ovnsb_txn);
+        ovn_port_set_sb(op, sbrec_port_binding_insert(ctx->ovnsb_txn));
         ovn_port_update_sbrec(ctx, sbrec_chassis_by_name, op,
                               &chassis_qdisc_queues,
                               &active_ha_chassis_grps);
@@ -2932,6 +2987,14 @@ static const struct multicast_group mc_flood =
 static const struct multicast_group mc_mrouter_flood =
     { MC_MROUTER_FLOOD, OVN_MCAST_MROUTER_FLOOD_TUNNEL_KEY };
 
+#define MC_MROUTER_STATIC "_MC_mrouter_static"
+static const struct multicast_group mc_mrouter_static =
+    { MC_MROUTER_STATIC, OVN_MCAST_MROUTER_STATIC_TUNNEL_KEY };
+
+#define MC_STATIC "_MC_static"
+static const struct multicast_group mc_static =
+    { MC_STATIC, OVN_MCAST_STATIC_TUNNEL_KEY };
+
 #define MC_UNKNOWN "_MC_unknown"
 static const struct multicast_group mc_unknown =
     { MC_UNKNOWN, OVN_MCAST_UNKNOWN_TUNNEL_KEY };
@@ -3145,7 +3208,23 @@ ovn_igmp_group_get_ports(const struct sbrec_igmp_group *sb_igmp_group,
 
      *n_ports = 0;
      for (size_t i = 0; i < sb_igmp_group->n_ports; i++) {
-        ports[(*n_ports)] =
+        struct ovn_port *port =
+            ovn_port_find(ovn_ports, sb_igmp_group->ports[i]->logical_port);
+
+        /* If this is already a flood port skip it for the group. */
+        if (port->mcast_info.flood) {
+            continue;
+        }
+
+        /* If this is already a port of a router on which relay is enabled,
+         * skip it for the group. Traffic is flooded there anyway.
+         */
+        if (port->peer && port->peer->od &&
+                port->peer->od->mcast_info.rtr.relay) {
+            continue;
+        }
+
+        ports[(*n_ports)] = port;
             ovn_port_find(ovn_ports, sb_igmp_group->ports[i]->logical_port);
         if (ports[(*n_ports)]) {
             (*n_ports)++;
@@ -5440,9 +5519,18 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
         struct mcast_switch_info *mcast_sw_info = &od->mcast_info.sw;
 
         if (mcast_sw_info->enabled) {
+            ds_clear(&actions);
+            if (mcast_sw_info->flood_reports) {
+                ds_put_cstr(&actions,
+                            "clone { "
+                                "outport = \""MC_MROUTER_STATIC"\"; "
+                                "output; "
+                            "};");
+            }
+            ds_put_cstr(&actions, "igmp;");
             /* Punt IGMP traffic to controller. */
             ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 100,
-                          "ip4 && ip.proto == 2", "igmp;");
+                          "ip4 && ip.proto == 2", ds_cstr(&actions));
 
             /* Flood all IP multicast traffic destined to 224.0.0.X to all
              * ports - RFC 4541, section 2.1.2, item 2.
@@ -5451,17 +5539,30 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
                           "ip4 && ip4.dst == 224.0.0.0/24",
                           "outport = \""MC_FLOOD"\"; output;");
 
-            /* Drop unregistered IP multicast if not allowed. */
+            /* Forward uregistered IP multicast to routers with relay enabled
+             * and to any ports configured to flood IP multicast traffic.
+             * If configured to flood unregistered traffic this will be
+             * handled by the L2 multicast flow.
+             */
             if (!mcast_sw_info->flood_unregistered) {
-                /* Forward unregistered IP multicast to mrouter (if any). */
+                ds_clear(&actions);
+
                 if (mcast_sw_info->flood_relay) {
-                    ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 80,
-                                  "ip4 && ip4.mcast",
-                                  "outport = \""MC_MROUTER_FLOOD"\"; output;");
+                    ds_put_cstr(&actions,
+                                "clone { "
+                                    "outport = \""MC_MROUTER_FLOOD"\"; "
+                                    "output; "
+                                "}; ");
+                }
+
+                if (mcast_sw_info->flood_static) {
+                    ds_put_cstr(&actions, "outport =\""MC_STATIC"\"; output;");
                 } else {
-                    ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 80,
-                                  "ip4 && ip4.mcast", "drop;");
+                    ds_put_cstr(&actions, "drop;");
                 }
+
+                ovn_lflow_add(lflows, od, S_SWITCH_IN_L2_LKUP, 80,
+                              "ip4 && ip4.mcast", ds_cstr(&actions));
             }
         }
 
@@ -5491,11 +5592,20 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
 
         ds_put_format(&match, "eth.mcast && ip4 && ip4.dst == %s ",
                       igmp_group->mcgroup.name);
+
         /* Also flood traffic to all multicast routers with relay enabled. */
         if (mcast_sw_info->flood_relay) {
             ds_put_cstr(&actions,
                         "clone { "
-                            "outport = \""MC_MROUTER_FLOOD "\"; output; "
+                            "outport = \""MC_MROUTER_FLOOD "\"; "
+                            "output; "
+                        "};");
+        }
+        if (mcast_sw_info->flood_static) {
+            ds_put_cstr(&actions,
+                        "clone { "
+                            "outport =\""MC_STATIC"\"; "
+                            "output; "
                         "};");
         }
         ds_put_format(&actions, "outport = \"%s\"; output; ",
@@ -7711,6 +7821,7 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
         if (!od->nbr || !od->mcast_info.rtr.relay) {
             continue;
         }
+
         struct ovn_igmp_group *igmp_group;
 
         LIST_FOR_EACH (igmp_group, list_node, &od->mcast_info.groups) {
@@ -7718,11 +7829,35 @@ build_lrouter_flows(struct hmap *datapaths, struct hmap *ports,
             ds_clear(&actions);
             ds_put_format(&match, "ip4 && ip4.dst == %s ",
                           igmp_group->mcgroup.name);
+            if (od->mcast_info.rtr.flood_static) {
+                ds_put_cstr(&actions,
+                            "clone { "
+                                "outport = \""MC_STATIC"\"; "
+                                "ip.ttl--; "
+                                "next; "
+                            "};");
+            }
             ds_put_format(&actions, "outport = \"%s\"; ip.ttl--; next;",
                           igmp_group->mcgroup.name);
             ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING, 500,
                           ds_cstr(&match), ds_cstr(&actions));
         }
+
+        /* If needed, flood unregistered multicast on statically configured
+         * ports.
+         */
+        if (od->mcast_info.rtr.flood_static) {
+            ds_clear(&match);
+            ds_clear(&actions);
+            ds_put_format(&match, "ip4.mcast");
+            ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING, 450,
+                          "ip4.mcast",
+                          "clone { "
+                                "outport = \""MC_STATIC"\"; "
+                                "ip.ttl--; "
+                                "next; "
+                          "};");
+        }
     }
 
     /* Logical router ingress table 8: Policy.
@@ -8893,11 +9028,15 @@ build_mcast_groups(struct northd_context *ctx,
     hmap_init(igmp_groups);
 
     HMAP_FOR_EACH (op, key_node, ports) {
-        if (!op->nbsp) {
-            continue;
-        }
-
-        if (lsp_is_enabled(op->nbsp)) {
+        if (op->nbrp && lrport_is_enabled(op->nbrp)) {
+            /* If this port is configured to always flood multicast traffic
+             * add it to the MC_STATIC group.
+             */
+            if (op->mcast_info.flood) {
+                ovn_multicast_add(mcast_groups, &mc_static, op);
+                op->od->mcast_info.rtr.flood_static = true;
+            }
+        } else if (op->nbsp && lsp_is_enabled(op->nbsp)) {
             ovn_multicast_add(mcast_groups, &mc_flood, op);
 
             /* If this port is connected to a multicast router then add it
@@ -8907,6 +9046,22 @@ build_mcast_groups(struct northd_context *ctx,
                     op->peer->od && op->peer->od->mcast_info.rtr.relay) {
                 ovn_multicast_add(mcast_groups, &mc_mrouter_flood, op);
             }
+
+            /* If this port is configured to always flood multicast reports
+             * add it to the MC_MROUTER_STATIC group.
+             */
+            if (op->mcast_info.flood_reports) {
+                ovn_multicast_add(mcast_groups, &mc_mrouter_static, op);
+                op->od->mcast_info.sw.flood_reports = true;
+            }
+
+            /* If this port is configured to always flood multicast traffic
+             * add it to the MC_STATIC group.
+             */
+            if (op->mcast_info.flood) {
+                ovn_multicast_add(mcast_groups, &mc_static, op);
+                op->od->mcast_info.sw.flood_static = true;
+            }
         }
     }
 
@@ -8967,8 +9122,13 @@ build_mcast_groups(struct northd_context *ctx,
         for (size_t i = 0; i < od->n_router_ports; i++) {
             struct ovn_port *router_port = od->router_ports[i]->peer;
 
+            /* If the router the port connects to doesn't have multicast
+             * relay enabled or if it was already configured to flood
+             * multicast traffic then skip it.
+             */
             if (!router_port || !router_port->od ||
-                    !router_port->od->mcast_info.rtr.relay) {
+                    !router_port->od->mcast_info.rtr.relay ||
+                    router_port->mcast_info.flood) {
                 continue;
             }
 
diff --git a/ovn-nb.xml b/ovn-nb.xml
index b41b579..1504f8f 100644
--- a/ovn-nb.xml
+++ b/ovn-nb.xml
@@ -671,6 +671,26 @@
         </column>
       </group>
 
+      <group title="IP Multicast Snooping Options">
+        <p>
+          These options apply when the port is part of a logical switch
+          which has <ref table="Logical_Switch" column="other_config"/>
+          :mcast_snoop set to <code>true</code>.
+        </p>
+
+        <column name="options" key="mcast_flood"
+                type='{"type": "boolean"}'>
+          If set to <code>true</code>, multicast packets (except reports) are
+          unconditionally forwarded to the specific port.
+        </column>
+
+        <column name="options" key="mcast_flood_reports"
+                type='{"type": "boolean"}'>
+          If set to <code>true</code>, multicast reports are unconditionally
+          forwarded to the specific port.
+        </column>
+      </group>
+
     </group>
 
     <group title="Containers">
@@ -2005,6 +2025,19 @@
 
       </column>
 
+      <column name="options" key="mcast_flood"
+              type='{"type": "boolean"}'>
+        <p>
+          If set to <code>true</code>, multicast traffic (including reports)
+          are unconditionally forwarded to the specific port.
+        </p>
+
+        <p>
+          This option applies when the port is part of a logical router which
+          has <ref table="Logical_Router" column="options"/>:mcast_relay set
+          to <code>true</code>.
+        </p>
+      </column>
     </group>
 
     <group title="Attachment">
diff --git a/tests/ovn.at b/tests/ovn.at
index 04898dd..f03e701 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -15122,7 +15122,6 @@ OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
 
 # Flush IGMP groups.
 ovn-sbctl ip-multicast-flush sw1
-ovn-nbctl --wait=hv -t 3 sync
 OVS_WAIT_UNTIL([
     total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
     test "${total_entries}" = "0"
@@ -15174,12 +15173,12 @@ send_ip_multicast_pkt hv2-vif4 hv2 \
 # Sleep a bit to make sure no traffic is received and then check.
 sleep 1
 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
-OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_empty])
+OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
+OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
 
 # Enable IGMP relay on rtr
@@ -15250,6 +15249,82 @@ OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
 OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
 
+# Flush IGMP groups.
+ovn-sbctl ip-multicast-flush sw1
+ovn-sbctl ip-multicast-flush sw2
+ovn-sbctl ip-multicast-flush sw3
+OVS_WAIT_UNTIL([
+    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
+    test "${total_entries}" = "0"
+])
+
+as hv1 reset_pcap_file hv1-vif1 hv1/vif1
+as hv1 reset_pcap_file hv1-vif2 hv1/vif2
+as hv1 reset_pcap_file hv1-vif3 hv1/vif3
+as hv1 reset_pcap_file hv1-vif4 hv1/vif4
+as hv2 reset_pcap_file hv2-vif1 hv2/vif1
+as hv2 reset_pcap_file hv2-vif2 hv2/vif2
+as hv2 reset_pcap_file hv2-vif3 hv2/vif3
+as hv2 reset_pcap_file hv2-vif4 hv2/vif4
+
+truncate -s 0 expected_empty
+truncate -s 0 expected_switched
+truncate -s 0 expected_routed
+truncate -s 0 expected_reports
+
+# Enable mcast_flood on sw1-p11
+ovn-nbctl set Logical_Switch_Port sw1-p11 options:mcast_flood='true'
+
+# Enable mcast_flood_reports on sw1-p21
+ovn-nbctl set Logical_Switch_Port sw1-p21 options:mcast_flood_reports='true'
+# Enable mcast_flood on rtr-sw2
+ovn-nbctl set Logical_Router_Port rtr-sw2 options:mcast_flood='true'
+# Enable mcast_flood on sw2-p1
+ovn-nbctl set Logical_Switch_Port sw2-p1 options:mcast_flood='true'
+
+ovn-nbctl --wait=hv sync
+
+# Inject IGMP Join for 239.0.1.68 on sw1-p12.
+send_igmp_v3_report hv1-vif2 hv1 \
+    000000000001 $(ip_to_hex 10 0 0 1) f9f8 \
+    $(ip_to_hex 239 0 1 68) 04 e9b9 \
+    expected_reports
+
+# Check that the IGMP Group is learned.
+OVS_WAIT_UNTIL([
+    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
+    test "${total_entries}" = "1"
+])
+
+# Send traffic from sw1-p21
+send_ip_multicast_pkt hv2-vif1 hv2 \
+    000000000001 01005e000144 \
+    $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
+    e518e518000a3b3a0000
+store_ip_multicast_pkt \
+    000000000001 01005e000144 \
+    $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
+    e518e518000a3b3a0000 expected_switched
+store_ip_multicast_pkt \
+    000000000200 01005e000144 \
+    $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 1f cb70 11 \
+    e518e518000a3b3a0000 expected_routed
+
+# Sleep a bit to make sure no duplicate traffic is received
+sleep 1
+
+# Check that traffic is switched to sw1-p11 and sw1-p12
+# Check that IGMP join is flooded on sw1-p21
+# Check that traffic is routed by rtr to rtr-sw2 and then switched to sw2-p1
+OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected_switched])
+OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected_switched])
+OVN_CHECK_PACKETS([hv1/vif3-tx.pcap], [expected_routed])
+OVN_CHECK_PACKETS([hv1/vif4-tx.pcap], [expected_empty])
+OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected_reports])
+OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected_empty])
+OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
+OVN_CHECK_PACKETS([hv2/vif4-tx.pcap], [expected_empty])
+
 OVN_CLEANUP([hv1], [hv2])
 AT_CLEANUP
 
