[ovs-dev] [PATCH ovn] ovn-northd: Fix IP local multicast flooding.
Mark Michelson
mmichels at redhat.com
Wed Feb 26 20:54:01 UTC 2020
Acked-by: Mark Michelson <mmichels at redhat.com>
On 2/14/20 5:42 AM, Dumitru Ceara wrote:
> Skip IGMP and MLD entries learned for local multicast groups when
> generating logical flows. We still allow ovn-controller to learn them as
> it might be useful information for administrators to see that hosts
> register for the groups even though they are not expected to send JOIN
> messages for this range.
>
> Fixes: ddc64665b678 ("OVN: Add ovn-northd IGMP support")
> Reported-by: Lucas Alvares Gomes <lmartins at redhat.com>
> Reported-at: https://bugzilla.redhat.com/1803008
> Signed-off-by: Dumitru Ceara <dceara at redhat.com>
> ---
> northd/ovn-northd.c | 15 +++++++
> tests/ovn.at | 119 +++++++++++++++++++++++++++++++++++++++++-----------
> 2 files changed, 109 insertions(+), 25 deletions(-)
>
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 46521b5..6d95ee2 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -6608,6 +6608,15 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
> &igmp_group->datapath->mcast_info.sw;
>
> if (IN6_IS_ADDR_V4MAPPED(&igmp_group->address)) {
> + /* RFC 4541, section 2.1.2, item 2: Skip groups in the 224.0.0.X
> + * range.
> + */
> + ovs_be32 group_address =
> + in6_addr_get_mapped_ipv4(&igmp_group->address);
> + if (ip_is_local_multicast(group_address)) {
> + continue;
> + }
> +
> if (mcast_sw_info->active_v4_flows >= mcast_sw_info->table_size) {
> continue;
> }
> @@ -6615,6 +6624,12 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
> ds_put_format(&match, "eth.mcast && ip4 && ip4.dst == %s ",
> igmp_group->mcgroup.name);
> } else {
> + /* RFC 4291, section 2.7.1: Skip groups that correspond to all
> + * hosts.
> + */
> + if (ipv6_is_all_hosts(&igmp_group->address)) {
> + continue;
> + }
> if (mcast_sw_info->active_v6_flows >= mcast_sw_info->table_size) {
> continue;
> }
> diff --git a/tests/ovn.at b/tests/ovn.at
> index ff9a732..d2f1101 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -15434,7 +15434,7 @@ ovn-nbctl set Logical_Switch sw1 \
> other_config:mcast_snoop="true"
>
> # No IGMP query should be generated by sw1 (mcast_querier="false").
> -truncate -s 0 expected
> +> expected
> OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> OVN_CHECK_PACKETS([hv1/vif2-tx.pcap], [expected])
> OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
> @@ -15454,14 +15454,14 @@ send_igmp_v3_report hv2-vif1 hv2 000000000002 $(ip_to_hex 10 0 0 2) f9f9 \
>
> # Check that the IGMP Group is learned on both hv.
> OVS_WAIT_UNTIL([
> - total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "2"
> ])
>
> # Send traffic and make sure it gets forwarded only on the two ports that
> # joined.
> -truncate -s 0 expected
> -truncate -s 0 expected_empty
> +> expected
> +> expected_empty
> send_ip_multicast_pkt hv1-vif2 hv1 \
> 000000000001 01005e000144 \
> $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
> @@ -15486,15 +15486,15 @@ send_igmp_v3_report hv1-vif1 hv1 \
>
> # Check IGMP_Group table on both HV.
> OVS_WAIT_UNTIL([
> - total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "1"
> ])
>
> # Send traffic and make sure it gets forwarded only on the port that joined.
> as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> as hv2 reset_pcap_file hv2-vif1 hv2/vif1
> -truncate -s 0 expected
> -truncate -s 0 expected_empty
> +> expected
> +> expected_empty
> send_ip_multicast_pkt hv1-vif2 hv1 \
> 000000000001 01005e000144 \
> $(ip_to_hex 10 0 0 42) $(ip_to_hex 239 0 1 68) 1e 20 ca70 11 \
> @@ -15514,10 +15514,43 @@ OVN_CHECK_PACKETS([hv2/vif3-tx.pcap], [expected_empty])
> # Flush IGMP groups.
> ovn-sbctl ip-multicast-flush sw1
> OVS_WAIT_UNTIL([
> - total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "0"
> ])
>
> +# Check that traffic for 224.0.0.X is flooded even if some hosts register for
> +# it.
> +# Inject IGMP Join for 224.0.0.42 on sw1-p11.
> +send_igmp_v3_report hv1-vif1 hv1 \
> + 000000000001 $(ip_to_hex 10 0 0 1) f9f8 \
> + $(ip_to_hex 224 0 0 42) 04 f9d3 \
> + /dev/null
> +
> +# Check that the IGMP Group is learned.
> +OVS_WAIT_UNTIL([
> + total_entries=`ovn-sbctl find IGMP_Group | grep "224.0.0.42" -c`
> + test "${total_entries}" = "1"
> +])
> +
> +# Send traffic and make sure it gets flooded to all ports.
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 reset_pcap_file hv1-vif2 hv1/vif2
> +as hv2 reset_pcap_file hv2-vif1 hv2/vif1
> +as hv2 reset_pcap_file hv2-vif2 hv2/vif2
> +> expected
> +send_ip_multicast_pkt hv1-vif2 hv1 \
> + 000000000001 01005e000144 \
> + $(ip_to_hex 10 0 0 42) $(ip_to_hex 224 0 0 42) 1e 01 f989 11 \
> + e518e518000a4b540000
> +store_ip_multicast_pkt \
> + 000000000001 01005e000144 \
> + $(ip_to_hex 10 0 0 42) $(ip_to_hex 224 0 0 42) 1e 01 f989 11 \
> + e518e518000a4b540000 expected
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
> +OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
> +
> # Enable IGMP snooping and querier on sw2 and set query interval to minimum.
> ovn-nbctl set Logical_Switch sw2 \
> other_config:mcast_snoop="true" \
> @@ -15527,7 +15560,7 @@ ovn-nbctl set Logical_Switch sw2 \
> other_config:mcast_ip4_src="20.0.0.254"
>
> # Wait for 1 query interval (1 sec) and check that two queries are generated.
> -truncate -s 0 expected
> +> expected
> store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
> store_igmp_v3_query 0000000002fe $(ip_to_hex 20 0 0 254) 84dd expected
>
> @@ -15545,7 +15578,7 @@ ovn-nbctl set Logical_Switch sw3 \
> other_config:mcast_snoop="true"
>
> # Send traffic from sw3 and make sure rtr doesn't relay it.
> -truncate -s 0 expected_empty
> +> expected_empty
>
> as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> as hv1 reset_pcap_file hv1-vif2 hv1/vif2
> @@ -15589,15 +15622,15 @@ send_igmp_v3_report hv2-vif3 hv2 \
>
> # Check that the IGMP Group is learned by all switches.
> OVS_WAIT_UNTIL([
> - total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "2"
> ])
>
> # Send traffic from sw3 and make sure it is relayed by rtr.
> # to ports that joined.
> -truncate -s 0 expected_routed_sw1
> -truncate -s 0 expected_routed_sw2
> -truncate -s 0 expected_empty
> +> expected_routed_sw1
> +> expected_routed_sw2
> +> expected_empty
>
> as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> as hv1 reset_pcap_file hv1-vif2 hv1/vif2
> @@ -15638,16 +15671,16 @@ send_igmp_v3_report hv1-vif4 hv1 \
>
> # Check that the IGMP Group is learned by all switches.
> OVS_WAIT_UNTIL([
> - total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "3"
> ])
>
> # Send traffic from sw3 and make sure it is relayed by rtr
> # to ports that joined.
> -truncate -s 0 expected_routed_sw1
> -truncate -s 0 expected_routed_sw2
> -truncate -s 0 expected_switched
> -truncate -s 0 expected_empty
> +> expected_routed_sw1
> +> expected_routed_sw2
> +> expected_switched
> +> expected_empty
>
> as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> as hv1 reset_pcap_file hv1-vif2 hv1/vif2
> @@ -15689,7 +15722,7 @@ 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`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "0"
> ])
>
> @@ -15702,10 +15735,10 @@ 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
> +> expected_empty
> +> expected_switched
> +> expected_routed
> +> expected_reports
>
> # Enable mcast_flood on sw1-p11
> ovn-nbctl set Logical_Switch_Port sw1-p11 options:mcast_flood='true'
> @@ -15727,7 +15760,7 @@ send_igmp_v3_report hv1-vif2 hv1 \
>
> # Check that the IGMP Group is learned.
> OVS_WAIT_UNTIL([
> - total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" | wc -l`
> + total_entries=`ovn-sbctl find IGMP_Group | grep "239.0.1.68" -c`
> test "${total_entries}" = "1"
> ])
>
> @@ -16077,6 +16110,42 @@ OVS_WAIT_UNTIL([
> test "${total_entries}" = "0"
> ])
>
> +# Check that traffic for "all-hosts" is flooded even if some hosts register
> +# for it.
> +# Inject MLD Join for ff02::1 on sw1-p11.
> +send_mld_v2_report hv1-vif1 hv1 \
> + 000000000001 10000000000000000000000000000001 \
> + ff020000000000000000000000000001 04 5e8a \
> + /dev/null
> +
> +# Check that the Multicast Group is learned.
> +OVS_WAIT_UNTIL([
> + total_entries=`ovn-sbctl find IGMP_Group | grep "ff02::1" -c`
> + test "${total_entries}" = "1"
> +])
> +
> +# Send traffic and make sure it gets flooded to all ports.
> +as hv1 reset_pcap_file hv1-vif1 hv1/vif1
> +as hv1 reset_pcap_file hv1-vif2 hv1/vif2
> +as hv2 reset_pcap_file hv2-vif1 hv2/vif1
> +as hv2 reset_pcap_file hv2-vif2 hv2/vif2
> +> expected
> +send_ip_multicast_pkt hv1-vif2 hv1 \
> + 000000000001 333300000001 \
> + 10000000000000000000000000000042 ff020000000000000000000000000001 \
> + 000e 01 11 \
> + 93407a69000eb90361736461640a
> +store_ip_multicast_pkt \
> + 000000000001 333300000001 \
> + 10000000000000000000000000000042 ff020000000000000000000000000001 \
> + 000e 01 11 \
> + 93407a69000eb90361736461640a \
> + expected
> +
> +OVN_CHECK_PACKETS([hv1/vif1-tx.pcap], [expected])
> +OVN_CHECK_PACKETS([hv2/vif1-tx.pcap], [expected])
> +OVN_CHECK_PACKETS([hv2/vif2-tx.pcap], [expected])
> +
> # Enable multicast snooping and querier on sw2 and set query interval to
> # minimum.
> ovn-nbctl set Logical_Switch sw2 \
>
More information about the dev
mailing list