bbaaef
From 635df521886b802dd7d4dce0da45fda8759e9d1f Mon Sep 17 00:00:00 2001
bbaaef
From: Dumitru Ceara <dceara@redhat.com>
bbaaef
Date: Thu, 27 Feb 2020 10:15:59 +0100
bbaaef
Subject: [PATCH] ovn-northd: Fix IP local multicast flooding.
bbaaef
bbaaef
Skip IGMP entries learned for local multicast groups when generating
bbaaef
logical flows. We still allow ovn-controller to learn them as
bbaaef
it might be useful information for administrators to see that hosts
bbaaef
register for the groups even though they are not expected to send JOIN
bbaaef
messages for this range.
bbaaef
bbaaef
Note: The upstream OVN master patch doesn't apply cleanly because OVN
bbaaef
2.12 doesn't support MLD. The conflict is however easy to solve and
bbaaef
involves removing the IPv6 specific code.
bbaaef
bbaaef
Fixes: ddc64665b678 ("OVN: Add ovn-northd IGMP support")
bbaaef
Reported-by: Lucas Alvares Gomes <lmartins@redhat.com>
bbaaef
Reported-at: https://bugzilla.redhat.com/1803008
bbaaef
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
bbaaef
Acked-by: Mark Michelson <mmichels@redhat.com>
bbaaef
(cherry picked from OVN commit 755ffada2a66416173d5f1e09672909d40f87fd1)
bbaaef
bbaaef
Conflicts:
bbaaef
	ovn/northd/ovn-northd.c
bbaaef
	tests/ovn.at
bbaaef
Signed-off-by: Ben Pfaff <blp@ovn.org>
bbaaef
bbaaef
(cherry picked from upstream commit 616e3c592af8dcf77a40af67042c4c417f4d550a)
bbaaef
bbaaef
Conflicts:
bbaaef
	ovn/northd/ovn-northd.c
bbaaef
bbaaef
Change-Id: Iedfaa16b10521cbaa3a0e0b373476aa7ac5903fd
bbaaef
---
bbaaef
 ovn/northd/ovn-northd.c |  9 +++++++++
bbaaef
 tests/ovn.at            | 48 +++++++++++++++++++++++++++++++++++++++---------
bbaaef
 2 files changed, 48 insertions(+), 9 deletions(-)
bbaaef
bbaaef
diff --git a/ovn/northd/ovn-northd.c b/ovn/northd/ovn-northd.c
bbaaef
index 7cb3773..1d21f8c 100644
bbaaef
--- a/ovn/northd/ovn-northd.c
bbaaef
+++ b/ovn/northd/ovn-northd.c
bbaaef
@@ -6309,6 +6309,15 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
bbaaef
         struct mcast_switch_info *mcast_sw_info =
bbaaef
             &igmp_group->datapath->mcast_info.sw;
bbaaef
 
bbaaef
+        /* RFC 4541, section 2.1.2, item 2: Skip groups in the 224.0.0.X
bbaaef
+         * range.
bbaaef
+         */
bbaaef
+        ovs_be32 group_address =
bbaaef
+            in6_addr_get_mapped_ipv4(&igmp_group->address);
bbaaef
+        if (ip_is_local_multicast(group_address)) {
bbaaef
+            continue;
bbaaef
+        }
bbaaef
+
bbaaef
         if (mcast_sw_info->active_flows >= mcast_sw_info->table_size) {
bbaaef
             continue;
bbaaef
         }
bbaaef
diff --git a/tests/ovn.at b/tests/ovn.at
bbaaef
index d74a8b0..d6e9b65 100644
bbaaef
--- a/tests/ovn.at
bbaaef
+++ b/tests/ovn.at
bbaaef
@@ -15293,7 +15293,7 @@ ovn-nbctl set Logical_Switch sw1       \
bbaaef
     other_config:mcast_snoop="true"
bbaaef
 
bbaaef
 # No IGMP query should be generated by sw1 (mcast_querier="false").
bbaaef
-truncate -s 0 expected
bbaaef
+> expected
bbaaef
 OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
bbaaef
 OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
bbaaef
 OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
bbaaef
@@ -15313,14 +15313,14 @@ send_igmp_v3_report hv2-vif1 hv2 000000000002 $(ip_to_hex 10 0 0 2) f9f9 \
bbaaef
 
bbaaef
 # Check that the IGMP Group is learned on both hv.
bbaaef
 OVS_WAIT_UNTIL([
bbaaef
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
bbaaef
+    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
bbaaef
     test "${total_entries}" = "2"
bbaaef
 ])
bbaaef
 
bbaaef
 # Send traffic and make sure it gets forwarded only on the two ports that
bbaaef
 # joined.
bbaaef
-truncate -s 0 expected
bbaaef
-truncate -s 0 expected_empty
bbaaef
+> expected
bbaaef
+> expected_empty
bbaaef
 send_ip_multicast_pkt hv1-vif2 hv1 \
bbaaef
     000000000001 01005e000144 \
bbaaef
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
bbaaef
@@ -15345,15 +15345,15 @@ send_igmp_v3_report hv1-vif1 hv1 \
bbaaef
 
bbaaef
 # Check IGMP_Group table on both HV.
bbaaef
 OVS_WAIT_UNTIL([
bbaaef
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
bbaaef
+    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
bbaaef
     test "${total_entries}" = "1"
bbaaef
 ])
bbaaef
 
bbaaef
 # Send traffic and make sure it gets forwarded only on the port that joined.
bbaaef
 as hv1 reset_pcap_file hv1-vif1 hv1/vif1
bbaaef
 as hv2 reset_pcap_file hv2-vif1 hv2/vif1
bbaaef
-truncate -s 0 expected
bbaaef
-truncate -s 0 expected_empty
bbaaef
+> expected
bbaaef
+> expected_empty
bbaaef
 send_ip_multicast_pkt hv1-vif2 hv1 \
bbaaef
     000000000001 01005e000144 \
bbaaef
     $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
bbaaef
@@ -15373,10 +15373,40 @@ OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
bbaaef
 # Flush IGMP groups.
bbaaef
 ovn-sbctl ip-multicast-flush sw1
bbaaef
 OVS_WAIT_UNTIL([
bbaaef
-    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
bbaaef
+    total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
bbaaef
     test "${total_entries}" = "0"
bbaaef
 ])
bbaaef
 
bbaaef
+# Check that traffic for 224.0.0.X is flooded even if some hosts register for
bbaaef
+# it.
bbaaef
+# Inject IGMP Join for 224.0.0.42 on sw1-p11.
bbaaef
+send_igmp_v3_report hv1-vif1 hv1 \
bbaaef
+    000000000001 $(ip_to_hex 10 0 0 1) f9f8 \
bbaaef
+    $(ip_to_hex 224 0 0 42) 04 f9d3 \
bbaaef
+    /dev/null
bbaaef
+
bbaaef
+# Check that the IGMP Group is learned.
bbaaef
+OVS_WAIT_UNTIL([
bbaaef
+    total_entries=`ovn-sbctl find IGMP_Group | grep "224.0.0.42" -c`
bbaaef
+    test "${total_entries}" = "1"
bbaaef
+])
bbaaef
+
bbaaef
+# Send traffic and make sure it gets flooded to all ports.
bbaaef
+as hv1 reset_pcap_file hv1-vif1 hv1/vif1
bbaaef
+as hv1 reset_pcap_file hv1-vif2 hv1/vif2
bbaaef
+as hv2 reset_pcap_file hv2-vif1 hv2/vif1
bbaaef
+as hv2 reset_pcap_file hv2-vif2 hv2/vif2
bbaaef
+> expected
bbaaef
+send_ip_multicast_pkt hv1-vif2 hv1 \
bbaaef
+    000000000001 01005e000144 \
bbaaef
+    $(ip_to_hex 10 0 0 42) $(ip_to_hex 224 0 0 42) 1e f989 11 \
bbaaef
+    e518e518000a4b540000 \
bbaaef
+    expected
bbaaef
+
bbaaef
+OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
bbaaef
+OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
bbaaef
+OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
bbaaef
+
bbaaef
 # Enable IGMP snooping and querier on sw2 and set query interval to minimum.
bbaaef
 ovn-nbctl set Logical_Switch sw2 \
bbaaef
     other_config:mcast_snoop="true" \
bbaaef
@@ -15386,7 +15416,7 @@ ovn-nbctl set Logical_Switch sw2 \
bbaaef
     other_config:mcast_ip4_src="20.0.0.254"
bbaaef
 
bbaaef
 # Wait for 1 query interval (1 sec) and check that two queries are generated.
bbaaef
-truncate -s 0 expected
bbaaef
+> expected
bbaaef
 store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
bbaaef
 store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
bbaaef
 
bbaaef
-- 
bbaaef
1.8.3.1
bbaaef