[ovs-dev] [PATCH ovn] RFC ovn-northd: bypass ct for allow ACLs

Numan Siddique numans at ovn.org
Tue Mar 2 18:38:02 UTC 2021


On Tue, Feb 2, 2021 at 10:09 AM Ihar Hrachyshka <ihrachys at redhat.com> wrote:
>
> NB: For now, the patch is for discussion only, pending performance
> measurements.
>
> For allow ACLs, bypass connection tracking by avoiding setting ct hints
> for matching traffic. Avoid sending all traffic to ct when a stateful
> ACL is present. Before the patch, this unnecessarily hit performance
> when mixed ACL action types were used for the same datapath.
>
> The patch takes inspiration from a now abandoned patch:
>
> "ovn-northd: Support mixing stateless/stateful ACLs with
> Stateless_Filter." by Dumitru Ceara.
>
> Signed-off-by: Ihar Hrachyshka <ihrachys at redhat.com>

Hi Ihar,

Sorry for the delay in the review of this patch.  Are you planning to submit it
as a formal patch ?

If the patch is still not ready as a formal one, can you please repost
this patch after rebasing ?


Thanks
Numan

> ---
>  NEWS                    |   1 +
>  northd/ovn-northd.8.xml |   9 +-
>  northd/ovn-northd.c     | 166 +++++++++++++++---------
>  tests/ovn-northd.at     | 271 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 384 insertions(+), 63 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index e89c5f408..67e87c476 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -10,6 +10,7 @@ Post-v20.12.0
>      "ovn-installed".  This external-id is set by ovn-controller only after all
>      openflow operations corresponding to the OVS interface being added have
>      been processed.
> +  - Bypass connection tracking for ACL "allow" action processing.
>
>  OVN v20.12.0 - 18 Dec 2020
>  --------------------------
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 70065a36d..ff91c0e00 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -319,7 +319,9 @@
>        before eventually advancing to ingress table <code>ACLs</code>. If
>        special ports such as route ports or localnet ports can't use ct(), a
>        priority-110 flow is added to skip over stateful ACLs. IPv6 Neighbor
> -      Discovery and MLD traffic also skips stateful ACLs.
> +      Discovery and MLD traffic also skips stateful ACLs. For stateless "allow"
> +      ACLs, a flow is added to bypass setting the hint for connection tracker
> +      processing.
>      </p>
>
>      <p>
> @@ -502,10 +504,7 @@
>      <ul>
>        <li>
>          <code>allow</code> ACLs translate into logical flows with
> -        the <code>next;</code> action.  If there are any stateful ACLs
> -        on this datapath, then <code>allow</code> ACLs translate to
> -        <code>ct_commit; next;</code> (which acts as a hint for the next tables
> -        to commit the connection to conntrack),
> +        the <code>next;</code> action.
>        </li>
>        <li>
>          <code>allow-related</code> ACLs translate into logical
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index b2eb93835..f7c17238f 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -4802,7 +4802,58 @@ skip_port_from_conntrack(struct ovn_datapath *od, struct ovn_port *op,
>  }
>
>  static void
> -build_pre_acls(struct ovn_datapath *od, struct hmap *lflows)
> +build_stateless_filter(struct ovn_datapath *od,
> +                       const struct nbrec_acl *acl,
> +                       struct hmap *lflows)
> +{
> +    /* Stateless filters must be applied in both directions so that reply
> +     * traffic bypasses conntrack too.
> +     */
> +    ovn_lflow_add_with_hint(lflows, od, S_SWITCH_IN_PRE_ACL,
> +                            acl->priority + OVN_ACL_PRI_OFFSET,
> +                            acl->match,
> +                            "next;",
> +                            &acl->header_);
> +    ovn_lflow_add_with_hint(lflows, od, S_SWITCH_OUT_PRE_ACL,
> +                            acl->priority + OVN_ACL_PRI_OFFSET,
> +                            acl->match,
> +                            "next;",
> +                            &acl->header_);
> +}
> +
> +static bool
> +acl_is_stateless(const struct nbrec_acl *acl)
> +{
> +    return !strcmp(acl->action, "allow");
> +}
> +
> +static void
> +build_stateless_filters(struct ovn_datapath *od, struct hmap *port_groups,
> +                        struct hmap *lflows)
> +{
> +    for (size_t i = 0; i < od->nbs->n_acls; i++) {
> +        const struct nbrec_acl *acl = od->nbs->acls[i];
> +        if (acl_is_stateless(acl)) {
> +            build_stateless_filter(od, acl, lflows);
> +        }
> +    }
> +
> +    struct ovn_port_group *pg;
> +    HMAP_FOR_EACH (pg, key_node, port_groups) {
> +        if (ovn_port_group_ls_find(pg, &od->nbs->header_.uuid)) {
> +            for (size_t i = 0; i < pg->nb_pg->n_acls; i++) {
> +                const struct nbrec_acl *acl = pg->nb_pg->acls[i];
> +                if (acl_is_stateless(acl)) {
> +                    build_stateless_filter(od, acl, lflows);
> +                }
> +            }
> +        }
> +    }
> +}
> +
> +static void
> +build_pre_acls(struct ovn_datapath *od, struct hmap *port_groups,
> +               struct hmap *lflows)
>  {
>      bool has_stateful = has_stateful_acl(od);
>
> @@ -4832,6 +4883,8 @@ build_pre_acls(struct ovn_datapath *od, struct hmap *lflows)
>                                       110, lflows);
>          }
>
> +        build_stateless_filters(od, port_groups, lflows);
> +
>          /* Ingress and Egress Pre-ACL Table (Priority 110).
>           *
>           * Not to do conntrack on ND and ICMP destination
> @@ -5252,70 +5305,67 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od,
>      bool ingress = !strcmp(acl->direction, "from-lport") ? true :false;
>      enum ovn_stage stage = ingress ? S_SWITCH_IN_ACL : S_SWITCH_OUT_ACL;
>
> -    if (!strcmp(acl->action, "allow")
> -        || !strcmp(acl->action, "allow-related")) {
> +    if (!strcmp(acl->action, "allow")) {
>          /* If there are any stateful flows, we must even commit "allow"
>           * actions.  This is because, while the initiater's
>           * direction may not have any stateful rules, the server's
>           * may and then its return traffic would not have an
>           * associated conntrack entry and would return "+invalid". */
> -        if (!has_stateful) {
> -            struct ds actions = DS_EMPTY_INITIALIZER;
> -            build_acl_log(&actions, acl, meter_groups);
> -            ds_put_cstr(&actions, "next;");
> -            ovn_lflow_add_with_hint(lflows, od, stage,
> -                                    acl->priority + OVN_ACL_PRI_OFFSET,
> -                                    acl->match, ds_cstr(&actions),
> -                                    &acl->header_);
> -            ds_destroy(&actions);
> -        } else {
> -            struct ds match = DS_EMPTY_INITIALIZER;
> -            struct ds actions = DS_EMPTY_INITIALIZER;
> +        struct ds actions = DS_EMPTY_INITIALIZER;
> +        build_acl_log(&actions, acl, meter_groups);
> +        ds_put_cstr(&actions, "next;");
> +        ovn_lflow_add_with_hint(lflows, od, stage,
> +                                acl->priority + OVN_ACL_PRI_OFFSET,
> +                                acl->match, ds_cstr(&actions),
> +                                &acl->header_);
> +        ds_destroy(&actions);
> +    } else if (!strcmp(acl->action, "allow-related")) {
> +        struct ds match = DS_EMPTY_INITIALIZER;
> +        struct ds actions = DS_EMPTY_INITIALIZER;
>
> -            /* Commit the connection tracking entry if it's a new
> -             * connection that matches this ACL.  After this commit,
> -             * the reply traffic is allowed by a flow we create at
> -             * priority 65535, defined earlier.
> -             *
> -             * It's also possible that a known connection was marked for
> -             * deletion after a policy was deleted, but the policy was
> -             * re-added while that connection is still known.  We catch
> -             * that case here and un-set ct_label.blocked (which will be done
> -             * by ct_commit in the "stateful" stage) to indicate that the
> -             * connection should be allowed to resume.
> -             */
> -            ds_put_format(&match, REGBIT_ACL_HINT_ALLOW_NEW " == 1 && (%s)",
> -                          acl->match);
> -            ds_put_cstr(&actions, REGBIT_CONNTRACK_COMMIT" = 1; ");
> -            build_acl_log(&actions, acl, meter_groups);
> -            ds_put_cstr(&actions, "next;");
> -            ovn_lflow_add_with_hint(lflows, od, stage,
> -                                    acl->priority + OVN_ACL_PRI_OFFSET,
> -                                    ds_cstr(&match),
> -                                    ds_cstr(&actions),
> -                                    &acl->header_);
> -
> -            /* Match on traffic in the request direction for an established
> -             * connection tracking entry that has not been marked for
> -             * deletion.  There is no need to commit here, so we can just
> -             * proceed to the next table. We use this to ensure that this
> -             * connection is still allowed by the currently defined
> -             * policy. Match untracked packets too. */
> -            ds_clear(&match);
> -            ds_clear(&actions);
> -            ds_put_format(&match, REGBIT_ACL_HINT_ALLOW " == 1 && (%s)",
> -                          acl->match);
> +        /* Commit the connection tracking entry if it's a new
> +         * connection that matches this ACL.  After this commit,
> +         * the reply traffic is allowed by a flow we create at
> +         * priority 65535, defined earlier.
> +         *
> +         * It's also possible that a known connection was marked for
> +         * deletion after a policy was deleted, but the policy was
> +         * re-added while that connection is still known.  We catch
> +         * that case here and un-set ct_label.blocked (which will be done
> +         * by ct_commit in the "stateful" stage) to indicate that the
> +         * connection should be allowed to resume.
> +         */
> +        ds_put_format(&match, REGBIT_ACL_HINT_ALLOW_NEW " == 1 && (%s)",
> +                      acl->match);
> +        ds_put_cstr(&actions, REGBIT_CONNTRACK_COMMIT" = 1; ");
> +        build_acl_log(&actions, acl, meter_groups);
> +        ds_put_cstr(&actions, "next;");
> +        ovn_lflow_add_with_hint(lflows, od, stage,
> +                                acl->priority + OVN_ACL_PRI_OFFSET,
> +                                ds_cstr(&match),
> +                                ds_cstr(&actions),
> +                                &acl->header_);
> +
> +        /* Match on traffic in the request direction for an established
> +         * connection tracking entry that has not been marked for
> +         * deletion.  There is no need to commit here, so we can just
> +         * proceed to the next table. We use this to ensure that this
> +         * connection is still allowed by the currently defined
> +         * policy. Match untracked packets too. */
> +        ds_clear(&match);
> +        ds_clear(&actions);
> +        ds_put_format(&match, REGBIT_ACL_HINT_ALLOW " == 1 && (%s)",
> +                      acl->match);
>
> -            build_acl_log(&actions, acl, meter_groups);
> -            ds_put_cstr(&actions, "next;");
> -            ovn_lflow_add_with_hint(lflows, od, stage,
> -                                    acl->priority + OVN_ACL_PRI_OFFSET,
> -                                    ds_cstr(&match), ds_cstr(&actions),
> -                                    &acl->header_);
> +        build_acl_log(&actions, acl, meter_groups);
> +        ds_put_cstr(&actions, "next;");
> +        ovn_lflow_add_with_hint(lflows, od, stage,
> +                                acl->priority + OVN_ACL_PRI_OFFSET,
> +                                ds_cstr(&match), ds_cstr(&actions),
> +                                &acl->header_);
>
> -            ds_destroy(&match);
> -            ds_destroy(&actions);
> -        }
> +        ds_destroy(&match);
> +        ds_destroy(&actions);
>      } else if (!strcmp(acl->action, "drop")
>                 || !strcmp(acl->action, "reject")) {
>          struct ds match = DS_EMPTY_INITIALIZER;
> @@ -6586,7 +6636,7 @@ build_lswitch_lflows_pre_acl_and_acl(struct ovn_datapath *od,
>                                       struct hmap *lbs)
>  {
>     if (od->nbs) {
> -        build_pre_acls(od, lflows);
> +        build_pre_acls(od, port_groups, lflows);
>          build_pre_lb(od, lflows, meter_groups, lbs);
>          build_pre_stateful(od, lflows);
>          build_acl_hints(od, lflows);
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 8597ca1b9..402c7e8b1 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -2337,6 +2337,277 @@ sed 's/reg8\[[0..15\]] == [[0-9]]*/reg8\[[0..15\]] == <cleared>/' | sort], [0],
>
>  AT_CLEANUP
>
> +AT_SETUP([ovn -- ACL allow omit conntrack - Logical_Switch])
> +ovn_start
> +
> +ovn-nbctl ls-add ls
> +ovn-nbctl lsp-add ls lsp1
> +ovn-nbctl lsp-set-addresses lsp1 00:00:00:00:00:01
> +ovn-nbctl lsp-add ls lsp2
> +ovn-nbctl lsp-set-addresses lsp2 00:00:00:00:00:02
> +
> +ovn-nbctl acl-add ls from-lport 3 "tcp" allow-related
> +ovn-nbctl acl-add ls from-lport 2 "udp" allow-related
> +ovn-nbctl acl-add ls from-lport 1 "ip" drop
> +ovn-nbctl --wait=sb sync
> +
> +flow_eth='eth.src == 00:00:00:00:00:01 && eth.dst == 00:00:00:00:00:02'
> +flow_ip='ip.ttl==64 && ip4.src == 42.42.42.1 && ip4.dst == 66.66.66.66'
> +flow_tcp='tcp && tcp.dst == 80'
> +flow_udp='udp && udp.dst == 80'
> +
> +# TCP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +ct_next(ct_state=new|trk) {
> +    ct_next(ct_state=new|trk) {
> +        output("lsp2");
> +    };
> +};
> +])
> +
> +# UDP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_next(ct_state=new|trk) {
> +        output("lsp2");
> +    };
> +};
> +])
> +
> +# Allow stateless for TCP.
> +ovn-nbctl acl-add ls from-lport 1 tcp allow
> +ovn-nbctl --wait=sb sync
> +
> +# TCP packets should not go to conntrack anymore.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +output("lsp2");
> +])
> +
> +# UDP packets still go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_next(ct_state=new|trk) {
> +        output("lsp2");
> +    };
> +};
> +])
> +
> +# Add a load balancer.
> +ovn-nbctl lb-add lb-tcp 66.66.66.66:80 42.42.42.2:8080 tcp
> +ovn-nbctl lb-add lb-udp 66.66.66.66:80 42.42.42.2:8080 udp
> +ovn-nbctl ls-lb-add ls lb-tcp
> +ovn-nbctl ls-lb-add ls lb-udp
> +
> +# Remove stateless for TCP.
> +ovn-nbctl acl-del ls
> +ovn-nbctl --wait=sb sync
> +
> +# TCP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +# UDP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +# Allow stateless for TCP.
> +ovn-nbctl acl-add ls from-lport 1 tcp allow
> +ovn-nbctl --wait=sb sync
> +
> +# TCP packets should go to conntrack for load balancing.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +# UDP packets still go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +AT_CLEANUP
> +
> +AT_SETUP([ovn -- ACL allow omit conntrack - Port_Group])
> +ovn_start
> +
> +ovn-nbctl ls-add ls
> +ovn-nbctl lsp-add ls lsp1
> +ovn-nbctl lsp-set-addresses lsp1 00:00:00:00:00:01
> +ovn-nbctl lsp-add ls lsp2
> +ovn-nbctl lsp-set-addresses lsp2 00:00:00:00:00:02
> +
> +ovn-nbctl pg-add pg lsp1 lsp2
> +ovn-nbctl acl-add pg from-lport 3 "tcp" allow-related
> +ovn-nbctl acl-add pg from-lport 2 "udp" allow-related
> +ovn-nbctl acl-add pg from-lport 1 "ip" drop
> +ovn-nbctl --wait=sb sync
> +
> +flow_eth='eth.src == 00:00:00:00:00:01 && eth.dst == 00:00:00:00:00:02'
> +flow_ip='ip.ttl==64 && ip4.src == 42.42.42.1 && ip4.dst == 66.66.66.66'
> +flow_tcp='tcp && tcp.dst == 80'
> +flow_udp='udp && udp.dst == 80'
> +
> +# TCP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +ct_next(ct_state=new|trk) {
> +    ct_next(ct_state=new|trk) {
> +        output("lsp2");
> +    };
> +};
> +])
> +
> +# UDP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_next(ct_state=new|trk) {
> +        output("lsp2");
> +    };
> +};
> +])
> +
> +# Allow stateless for TCP.
> +ovn-nbctl acl-add pg from-lport 1 tcp allow
> +ovn-nbctl --wait=sb sync
> +
> +# TCP packets should not go to conntrack anymore.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +output("lsp2");
> +])
> +
> +# UDP packets still go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_next(ct_state=new|trk) {
> +        output("lsp2");
> +    };
> +};
> +])
> +
> +# Add a load balancer.
> +ovn-nbctl lb-add lb-tcp 66.66.66.66:80 42.42.42.2:8080 tcp
> +ovn-nbctl lb-add lb-udp 66.66.66.66:80 42.42.42.2:8080 udp
> +ovn-nbctl ls-lb-add ls lb-tcp
> +ovn-nbctl ls-lb-add ls lb-udp
> +
> +# Remove stateless for TCP.
> +ovn-nbctl acl-del pg
> +ovn-nbctl --wait=sb sync
> +
> +# TCP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +# UDP packets should go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +# Allow stateless for TCP.
> +ovn-nbctl acl-add pg from-lport 1 tcp allow
> +ovn-nbctl --wait=sb sync
> +
> +# TCP packets should go to conntrack for load balancing.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +# UDP packets still go to conntrack.
> +flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}"
> +AT_CHECK([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl
> +# udp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80
> +ct_next(ct_state=new|trk) {
> +    ct_lb {
> +        reg0[[6]] = 0;
> +        ct_next(ct_state=new|trk) {
> +            output("lsp2");
> +        };
> +    };
> +};
> +])
> +
> +AT_CLEANUP
> +
>  AT_SETUP([ovn -- check BFD config propagation to SBDB])
>  AT_KEYWORDS([northd-bfd])
>  ovn_start
> --
> 2.29.2
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>


More information about the dev mailing list