[ovs-dev] [PATCH ovn v2] ovn-northd: Add static IP multicast flood configuration
Mark Michelson
mmichels at redhat.com
Wed Oct 9 15:01:51 UTC 2019
I've merged this to master.
On 9/24/19 4:02 AM, Dumitru Ceara wrote:
> Add the following new configuration options to the
> Logical_Switch_Port:options column in the OVN Northbound database:
>
> - mcast_flood: if set to 'true' all incoming IP multicast traffic
> (except IP multicast reports) entering the switch will also be
> flooded on the logical switch port.
> - mcast_flood_reports: if set to 'true' all incoming IP multicast
> entering the switch will also be flooded on the logical switch
> port. A clone of the packets is also processed by ovn-controller
> for snooping.
>
> Add the following new configuration option to the
> Logical_Router_Port:options column in the OVN Northbound database:
>
> - mcast_flood: if set to 'true' all incoming IP multicast traffic
> (including IP multicast reports) entering the router will be also
> flooded on the logical router port.
>
> Due to the fact that in the router pipeline multicast reports are
> not treated in a special way there's no need for an explicit
> 'mcast_flood_reports' option for router ports.
>
> Signed-off-by: Dumitru Ceara <dceara at redhat.com>
>
> ---
> v2: Rebase & fix tag in ovn-nb.xml
> ---
> lib/mcast-group-index.h | 2 +
> northd/ovn-northd.8.xml | 30 +++++--
> northd/ovn-northd.c | 212 ++++++++++++++++++++++++++++++++++++++++++------
> ovn-nb.xml | 33 ++++++++
> tests/ovn.at | 81 +++++++++++++++++-
> 5 files changed, 324 insertions(+), 34 deletions(-)
>
> 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( ->options, "mcast_flood", false);
> + mcast_info->flood_reports =
> + smap_get_bool( ->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
>
>
More information about the dev
mailing list