On Thu, Mar 2, 2023 at 12:31 PM Ales Musil <[email protected]> wrote:

> Currently, there is one ct.est flow per LB VIP,
> that was required to keep track if we need to
> pass the "skip_snat" or "force_snat" flags.
> However since c1d6b8ac ("northd: Store skip_snat and force_snat in
> ct_label/mark")
> the flags are carried in the ct entry and
> we can use match on them the same way we do
> for related traffic.
>
> Simplify the logic for established
> traffic through load balancers, by removing
> the requirement for one ct.est flow per VIP
> and replacing them with three generic ct.est flows:
> match=(ct.est && !ct.rel && !ct.new && ct_mark.natted), action=(next;)
> match=(ct.est && !ct.rel && !ct.new && ct_mark.natted &&
> ct_mark.force_snat == 1), action=(flags.force_snat_for_lb = 1; next;)
> match=(ct.est && !ct.rel && !ct.new && ct_mark.natted && ct_mark.skip_snat
> == 1), action=(flags.skip_snat_for_lb = 1; next;)
>
> This allows us avoiding of matching on L4
> in defrag stage by not storing the L3 and L4
> destination in registers. Match directly on
> L3 and L4 destination for ct.new in DNAT stage.
>
> Populate the registers in LB affinity check stage
> as they are needed for LB affinity learn.
>
> Reported-at: https://bugzilla.redhat.com/2172048
> Reported-at: https://bugzilla.redhat.com/2170885
> Signed-off-by: Ales Musil <[email protected]>
> ---
>  northd/northd.c     | 157 +++++++++++------------
>  tests/ovn-northd.at | 295 +++++++++++++++++++++++---------------------
>  tests/ovn.at        |  10 +-
>  3 files changed, 226 insertions(+), 236 deletions(-)
>
> diff --git a/northd/northd.c b/northd/northd.c
> index 770a5b50e..273c1f99b 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -7109,7 +7109,9 @@ build_lb_rules_pre_stateful(struct hmap *lflows,
> struct ovn_northd_lb *lb,
>   * - load balancing affinity check:
>   *   table=lr_in_lb_aff_check, priority=100
>   *      match=(new_lb_match)
> - *      action=(REGBIT_KNOWN_LB_SESSION = chk_lb_aff(); next;)
> + *      action=(REG_NEXT_HOP_IPV4 = ip4.dst;
> + *              REG_ORIG_TP_DPORT_ROUTER = tcp.dst;
> + *              REGBIT_KNOWN_LB_SESSION = chk_lb_aff(); next;)
>   *
>   * - load balancing:
>   *   table=lr_in_dnat, priority=150
> @@ -7150,16 +7152,11 @@ build_lb_affinity_lr_flows(struct hmap *lflows,
> struct ovn_northd_lb *lb,
>          return;
>      }
>
> -    static char *aff_check = REGBIT_KNOWN_LB_SESSION" = chk_lb_aff();
> next;";
> -
> -    ovn_lflow_add_with_dp_group(
> -        lflows, dp_bitmap, S_ROUTER_IN_LB_AFF_CHECK, 100,
> -        new_lb_match, aff_check, &lb->nlb->header_);
> -
>      struct ds aff_action = DS_EMPTY_INITIALIZER;
>      struct ds aff_action_learn = DS_EMPTY_INITIALIZER;
>      struct ds aff_match = DS_EMPTY_INITIALIZER;
>      struct ds aff_match_learn = DS_EMPTY_INITIALIZER;
> +    struct ds aff_check_action = DS_EMPTY_INITIALIZER;
>
>      bool ipv6 = !IN6_IS_ADDR_V4MAPPED(&lb_vip->vip);
>      const char *ip_match = ipv6 ? "ip6" : "ip4";
> @@ -7175,6 +7172,20 @@ build_lb_affinity_lr_flows(struct hmap *lflows,
> struct ovn_northd_lb *lb,
>          ct_flag = "; force_snat";
>      }
>
> +    /* Create affinity check flow. */
> +    ds_put_format(&aff_check_action, "%s = %s; ", reg_vip,
> lb_vip->vip_str);
> +
> +    if (lb_vip->port_str) {
> +        ds_put_format(&aff_check_action, REG_ORIG_TP_DPORT_ROUTER" =
> %s.dst; ",
> +                      lb->proto);
> +    }
> +    ds_put_cstr(&aff_check_action, REGBIT_KNOWN_LB_SESSION
> +                " = chk_lb_aff(); next;");
> +
> +    ovn_lflow_add_with_dp_group(
> +        lflows, dp_bitmap, S_ROUTER_IN_LB_AFF_CHECK, 100,
> +        new_lb_match, ds_cstr(&aff_check_action), &lb->nlb->header_);
> +
>      /* Prepare common part of affinity LB and affinity learn action. */
>      ds_put_format(&aff_action, "%s = %s; ", reg_vip, lb_vip->vip_str);
>      ds_put_cstr(&aff_action_learn, "commit_lb_aff(vip = \"");
> @@ -7272,6 +7283,7 @@ build_lb_affinity_lr_flows(struct hmap *lflows,
> struct ovn_northd_lb *lb,
>      ds_destroy(&aff_action_learn);
>      ds_destroy(&aff_match);
>      ds_destroy(&aff_match_learn);
> +    ds_destroy(&aff_check_action);
>  }
>
>  /* Builds the logical switch flows related to load balancer affinity.
> @@ -10469,10 +10481,8 @@ enum lrouter_nat_lb_flow_type {
>
>  struct lrouter_nat_lb_flows_ctx {
>      const char *new_action[LROUTER_NAT_LB_FLOW_MAX];
> -    const char *est_action[LROUTER_NAT_LB_FLOW_MAX];
>
>      struct ds *new_match;
> -    struct ds *est_match;
>      struct ds *undnat_match;
>
>      struct ovn_lb_vip *lb_vip;
> @@ -10490,10 +10500,21 @@ build_distr_lrouter_nat_flows_for_lb(struct
> lrouter_nat_lb_flows_ctx *ctx,
>                                       enum lrouter_nat_lb_flow_type type,
>                                       struct ovn_datapath *od)
>  {
> -    char *gw_action = od->is_gw_router ? "ct_dnat;" : "ct_dnat_in_czone;";
> +    char *undnat_action;
> +    switch (type) {
> +    case LROUTER_NAT_LB_FLOW_FORCE_SNAT:
> +        undnat_action = "flags.force_snat_for_lb = 1; next;";
> +        break;
> +    case LROUTER_NAT_LB_FLOW_SKIP_SNAT:
> +        undnat_action = "flags.skip_snat_for_lb = 1; next;";
> +        break;
> +    case LROUTER_NAT_LB_FLOW_NORMAL:
> +    case LROUTER_NAT_LB_FLOW_MAX:
> +        undnat_action = od->is_gw_router ? "ct_dnat;" :
> "ct_dnat_in_czone;";
> +        break;
> +    }
>      /* Store the match lengths, so we can reuse the ds buffer. */
>      size_t new_match_len = ctx->new_match->length;
> -    size_t est_match_len = ctx->est_match->length;
>      size_t undnat_match_len = ctx->undnat_match->length;
>
>
> @@ -10506,33 +10527,24 @@ build_distr_lrouter_nat_flows_for_lb(struct
> lrouter_nat_lb_flows_ctx *ctx,
>      if (ctx->lb_vip->n_backends || !ctx->lb_vip->empty_backend_rej) {
>          ds_put_format(ctx->new_match, " && is_chassis_resident(%s)",
>                        od->l3dgw_ports[0]->cr_port->json_key);
> -        ds_put_format(ctx->est_match, " && is_chassis_resident(%s)",
> -                      od->l3dgw_ports[0]->cr_port->json_key);
>      }
>
>      ovn_lflow_add_with_hint__(ctx->lflows, od, S_ROUTER_IN_DNAT,
> ctx->prio,
>                                ds_cstr(ctx->new_match),
> ctx->new_action[type],
>                                NULL, meter, &ctx->lb->nlb->header_);
> -    ovn_lflow_add_with_hint(ctx->lflows, od, S_ROUTER_IN_DNAT, ctx->prio,
> -                            ds_cstr(ctx->est_match),
> ctx->est_action[type],
> -                            &ctx->lb->nlb->header_);
>
>      ds_truncate(ctx->new_match, new_match_len);
> -    ds_truncate(ctx->est_match, est_match_len);
>
>      if (!ctx->lb_vip->n_backends) {
>          return;
>      }
>
> -    const char *action = (type == LROUTER_NAT_LB_FLOW_NORMAL)
> -                         ? gw_action : ctx->est_action[type];
> -
>      ds_put_format(ctx->undnat_match,
>                    ") && outport == %s && is_chassis_resident(%s)",
>                    od->l3dgw_ports[0]->json_key,
>                    od->l3dgw_ports[0]->cr_port->json_key);
>      ovn_lflow_add_with_hint(ctx->lflows, od, S_ROUTER_OUT_UNDNAT, 120,
> -                            ds_cstr(ctx->undnat_match), action,
> +                            ds_cstr(ctx->undnat_match), undnat_action,
>                              &ctx->lb->nlb->header_);
>      ds_truncate(ctx->undnat_match, undnat_match_len);
>  }
> @@ -10575,11 +10587,6 @@ build_gw_lrouter_nat_flows_for_lb(struct
> lrouter_nat_lb_flows_ctx *ctx,
>              ctx->new_action[type], &ctx->lb->nlb->header_);
>      }
>      bitmap_free(dp_non_meter);
> -
> -    ovn_lflow_add_with_dp_group(
> -        ctx->lflows, dp_bitmap, S_ROUTER_IN_DNAT, ctx->prio,
> -        ds_cstr(ctx->est_match), ctx->est_action[type],
> -        &ctx->lb->nlb->header_);
>  }
>
>  static void
> @@ -10591,19 +10598,13 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip
> *lb_vip,
>                                 const struct shash *meter_groups,
>                                 const struct chassis_features *features)
>  {
> -    const char *ct_natted = features->ct_no_masked_label
> -                            ? "ct_mark.natted"
> -                            : "ct_label.natted";
> -
>      bool ipv4 = lb_vip->address_family == AF_INET;
>      const char *ip_match = ipv4 ? "ip4" : "ip6";
> -    const char *ip_reg = ipv4 ? REG_NEXT_HOP_IPV4 : REG_NEXT_HOP_IPV6;
>
>      int prio = 110;
>
>      struct ds skip_snat_act = DS_EMPTY_INITIALIZER;
>      struct ds force_snat_act = DS_EMPTY_INITIALIZER;
> -    struct ds est_match = DS_EMPTY_INITIALIZER;
>      struct ds undnat_match = DS_EMPTY_INITIALIZER;
>      struct ds unsnat_match = DS_EMPTY_INITIALIZER;
>
> @@ -10620,19 +10621,14 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip
> *lb_vip,
>       * of "ct_lb_mark($targets);". The other flow is for ct.est with
>       * an action of "next;".
>       */
> -    ds_put_format(match, "ct.new && !ct.rel && %s && %s == %s",
> -                  ip_match, ip_reg, lb_vip->vip_str);
> +    ds_put_format(match, "ct.new && !ct.rel && %s && %s.dst == %s",
> +                  ip_match, ip_match, lb_vip->vip_str);
>      if (lb_vip->vip_port) {
>          prio = 120;
> -        ds_put_format(match, " && %s && "REG_ORIG_TP_DPORT_ROUTER" == %d",
> -                      lb->proto, lb_vip->vip_port);
> +        ds_put_format(match, " && %s && %s.dst == %d",
> +                      lb->proto, lb->proto, lb_vip->vip_port);
>      }
>
> -    ds_put_cstr(&est_match, "ct.est");
> -    /* Clone the match after initial "ct.new" (6 bytes). */
> -    ds_put_cstr(&est_match, ds_cstr(match) + 6);
> -    ds_put_format(&est_match, " && %s == 1", ct_natted);
> -
>      /* Add logical flows to UNDNAT the load balanced reverse traffic in
>       * the router egress pipleine stage - S_ROUTER_OUT_UNDNAT if the
> logical
>       * router has a gateway router port associated.
> @@ -10669,20 +10665,12 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip
> *lb_vip,
>          .lflows = lflows,
>          .meter_groups = meter_groups,
>          .new_match = match,
> -        .est_match = &est_match,
>          .undnat_match = &undnat_match
>      };
>
>      ctx.new_action[LROUTER_NAT_LB_FLOW_NORMAL] = ds_cstr(action);
> -    ctx.est_action[LROUTER_NAT_LB_FLOW_NORMAL] = "next;";
> -
>      ctx.new_action[LROUTER_NAT_LB_FLOW_SKIP_SNAT] =
> ds_cstr(&skip_snat_act);
> -    ctx.est_action[LROUTER_NAT_LB_FLOW_SKIP_SNAT] =
> -                                        "flags.skip_snat_for_lb = 1;
> next;";
> -
>      ctx.new_action[LROUTER_NAT_LB_FLOW_FORCE_SNAT] =
> ds_cstr(&force_snat_act);
> -    ctx.est_action[LROUTER_NAT_LB_FLOW_FORCE_SNAT] =
> -                                        "flags.force_snat_for_lb = 1;
> next;";
>
>      enum {
>          LROUTER_NAT_LB_AFF            = LROUTER_NAT_LB_FLOW_MAX,
> @@ -10765,7 +10753,6 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip
> *lb_vip,
>
>      ds_destroy(&unsnat_match);
>      ds_destroy(&undnat_match);
> -    ds_destroy(&est_match);
>      ds_destroy(&skip_snat_act);
>      ds_destroy(&force_snat_act);
>
> @@ -10839,39 +10826,19 @@ build_lrouter_defrag_flows_for_lb(struct
> ovn_northd_lb *lb,
>          return;
>      }
>
> -    struct ds defrag_actions = DS_EMPTY_INITIALIZER;
>      for (size_t i = 0; i < lb->n_vips; i++) {
>          struct ovn_lb_vip *lb_vip = &lb->vips[i];
> +        bool ipv6 = lb_vip->address_family == AF_INET6;
>          int prio = 100;
>
> -        ds_clear(&defrag_actions);
>          ds_clear(match);
> -
> -        if (lb_vip->address_family == AF_INET) {
> -            ds_put_format(match, "ip && ip4.dst == %s", lb_vip->vip_str);
> -            ds_put_format(&defrag_actions, REG_NEXT_HOP_IPV4" = %s; ",
> -                          lb_vip->vip_str);
> -        } else {
> -            ds_put_format(match, "ip && ip6.dst == %s", lb_vip->vip_str);
> -            ds_put_format(&defrag_actions, REG_NEXT_HOP_IPV6" = %s; ",
> -                          lb_vip->vip_str);
> -        }
> -
> -        if (lb_vip->port_str) {
> -            ds_put_format(match, " && %s", lb->proto);
> -            prio = 110;
> -
> -            ds_put_format(&defrag_actions, REG_ORIG_TP_DPORT_ROUTER
> -                          " = %s.dst; ", lb->proto);
> -        }
> -
> -        ds_put_format(&defrag_actions, "ct_dnat;");
> +        ds_put_format(match, "ip && ip%c.dst == %s", ipv6 ? '6' : '4',
> +                      lb_vip->vip_str);
>
>          ovn_lflow_add_with_dp_group(
>              lflows, lb->nb_lr_map, S_ROUTER_IN_DEFRAG, prio,
> -            ds_cstr(match), ds_cstr(&defrag_actions), &lb->nlb->header_);
> +            ds_cstr(match), "ct_dnat;", &lb->nlb->header_);
>      }
> -    ds_destroy(&defrag_actions);
>  }
>
>  static void
> @@ -14236,10 +14203,10 @@ build_lrouter_nat_defrag_and_lb(struct
> ovn_datapath *od, struct hmap *lflows,
>      ovn_lflow_add(lflows, od, S_ROUTER_OUT_EGR_LOOP, 0, "1", "next;");
>      ovn_lflow_add(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 0, "1", "next;");
>
> -    /* Ingress DNAT and DEFRAG Table (Priority 50/70).
> -     *
> -     * The defrag stage needs to have flows for ICMP in order to get
> -     * the correct ct_state that can be used by DNAT stage.
> +    const char *ct_flag_reg = features->ct_no_masked_label
> +                              ? "ct_mark"
> +                              : "ct_label";
> +    /* Ingress DNAT (Priority 50/70).
>       *
>       * Allow traffic that is related to an existing conntrack entry.
>       * At the same time apply NAT for this traffic.
> @@ -14250,16 +14217,10 @@ build_lrouter_nat_defrag_and_lb(struct
> ovn_datapath *od, struct hmap *lflows,
>       * that's generated from a non-listening UDP port.  */
>      if (od->has_lb_vip && features->ct_lb_related) {
>          ds_clear(match);
> -        const char *ct_flag_reg = features->ct_no_masked_label
> -                                  ? "ct_mark"
> -                                  : "ct_label";
>
>          ds_put_cstr(match, "ct.rel && !ct.est && !ct.new");
>          size_t match_len = match->length;
>
> -        ovn_lflow_add(lflows, od, S_ROUTER_IN_DEFRAG, 50, "icmp || icmp6",
> -                      "ct_dnat;");
> -
>          ds_put_format(match, " && %s.skip_snat == 1", ct_flag_reg);
>          ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
>                        "flags.skip_snat_for_lb = 1; ct_commit_nat;");
> @@ -14270,10 +14231,34 @@ build_lrouter_nat_defrag_and_lb(struct
> ovn_datapath *od, struct hmap *lflows,
>                        "flags.force_snat_for_lb = 1; ct_commit_nat;");
>
>          ds_truncate(match, match_len);
> -        ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 50,
> -                      "ct.rel && !ct.est && !ct.new", "ct_commit_nat;");
> +        ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 50, ds_cstr(match),
> +                      "ct_commit_nat;");
> +    }
>
> +    /* Ingress DNAT (Priority 50/70).
> +     *
> +     * Pass the traffic that is already established to the next table with
> +     * proper flags set.
> +     */
> +    if (od->has_lb_vip) {
>          ds_clear(match);
> +
> +        ds_put_format(match, "ct.est && !ct.rel && !ct.new && %s.natted",
> +                      ct_flag_reg);
> +        size_t match_len = match->length;
> +
> +        ds_put_format(match, " && %s.skip_snat == 1", ct_flag_reg);
> +        ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
> +                      "flags.skip_snat_for_lb = 1; next;");
> +
> +        ds_truncate(match, match_len);
> +        ds_put_format(match, " && %s.force_snat == 1", ct_flag_reg);
> +        ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 70, ds_cstr(match),
> +                      "flags.force_snat_for_lb = 1; next;");
> +
> +        ds_truncate(match, match_len);
> +        ovn_lflow_add(lflows, od, S_ROUTER_IN_DNAT, 50, ds_cstr(match),
> +                      "next;");
>      }
>
>      /* If the router has load balancer or DNAT rules, re-circulate every
> packet
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 3fa02d2b3..1d5d70d88 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -3757,18 +3757,18 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.100 && tcp), action=(reg0 = 10.0.0.100; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.100), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80),
> action=(ct_lb_mark(backends=10.0.0.40:8080);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.40:8080);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -3788,18 +3788,18 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.100 && tcp), action=(reg0 = 10.0.0.100; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.100), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -3838,18 +3838,18 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.100 && tcp), action=(reg0 = 10.0.0.100; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.100), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -3902,18 +3902,18 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.100 && tcp), action=(reg0 = 10.0.0.100; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.100), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.100 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -3953,14 +3953,13 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.100 && tcp), action=(reg0 = 10.0.0.100; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.20 && tcp), action=(reg0 = 10.0.0.20; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.100), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.20), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | grep skip_snat_for_lb | sort],
> [0], [dnl
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.skip_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80),
> action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> skip_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.20 && tcp && tcp.dst == 80),
> action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> skip_snat);)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
>
> @@ -5211,25 +5210,23 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> udp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.100), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.210), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=7 (lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20 && inport == "lr0-public" &&
> is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1 &&
> is_chassis_resident("cr-lr0-public")), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.200 && is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 &&
> ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 &&
> is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=
> 10.0.0.50:82,10.0.0.60:82);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=
> 10.0.0.50:6062,10.0.0.60:6062);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.200 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.100 && tcp && tcp.dst == 8082 &&
> is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=
> 10.0.0.50:82,10.0.0.60:82);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60 &&
> is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=
> 10.0.0.50:6062,10.0.0.60:6062);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5284,25 +5281,23 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> udp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.100), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.210), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=7 (lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.200),
> action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 &&
> ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082),
> action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60),
> action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.200),
> action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.100 && tcp && tcp.dst == 8082),
> action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60),
> action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5349,25 +5344,23 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> udp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.100), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.210), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=7 (lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.100 && tcp && tcp.dst == 8082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5416,28 +5409,25 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.10 && tcp), action=(reg0 = 172.168.0.10; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> udp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.100), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.210), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=7 (lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.10 && tcp && tcp.dst == 9082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.100 && tcp && tcp.dst == 8082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5496,31 +5486,27 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(reg0 = 172.168.0.200; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 10.0.0.10 && tcp), action=(reg0 = 10.0.0.10; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.10 && tcp), action=(reg0 = 172.168.0.10; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.100 && tcp), action=(reg0 = 172.168.0.100; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> udp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip6.dst ==
> def0::2 && tcp), action=(xxreg0 = def0::2; reg9[[16..31]] = tcp.dst;
> ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 10.0.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.10), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.100), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.200), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.210), action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip6.dst ==
> def0::2), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=7 (lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000),
> action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=[[aef0::2]]:80,[[aef0::3]]:80; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.200), action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=10.0.0.80,10.0.0.81; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.10 && tcp && tcp.dst == 9082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.100 && tcp && tcp.dst == 8082),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,
> 10.0.0.60:82; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip6 && ip6.dst == def0::2 && tcp && tcp.dst == 8000),
> action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=[[aef0::2]]:80,[[aef0::3]]:80; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5572,18 +5558,17 @@ AT_CHECK([grep "lr_in_unsnat" lr0flows | sort],
> [0], [dnl
>
>  AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl
>    table=5 (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && tcp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> tcp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=110  , match=(ip && ip4.dst ==
> 172.168.0.210 && udp), action=(reg0 = 172.168.0.210; reg9[[16..31]] =
> udp.dst; ct_dnat;)
> -  table=5 (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=5 (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.210), action=(ct_dnat;)
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && tcp && tcp.dst == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.0.210 && udp && udp.dst == 60),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,
> 10.0.0.60:6062; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5634,9 +5619,11 @@ ovn-sbctl set service_monitor $sm_vip2
> status=offline
>
>  AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.10.10 && ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.10.10), action=(reg0 = 0; reject { outport <->
> inport; next(pipeline=egress,table=3);};)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.10.10), action=(reg0 = 0; reject { outport <->
> inport; next(pipeline=egress,table=3);};)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5646,9 +5633,11 @@ check ovn-nbctl --wait=sb set load_balancer lb5
> options:skip_snat=true
>
>  AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.10.10 && ct_mark.natted == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.10.10), action=(flags.skip_snat_for_lb = 1; reg0
> = 0; reject { outport <-> inport; next(pipeline=egress,table=3);};)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.10.10), action=(flags.skip_snat_for_lb = 1;
> reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=3);};)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -5660,9 +5649,11 @@ check ovn-nbctl --wait=sb set logical_router lr0
> options:lb_force_snat_ip="route
>
>  AT_CHECK([ovn-sbctl dump-flows lr0 | grep "lr_in_dnat" | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.168.10.10 && ct_mark.natted == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.168.10.10), action=(flags.force_snat_for_lb = 1; reg0
> = 0; reject { outport <-> inport; next(pipeline=egress,table=3);};)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.168.10.10), action=(flags.force_snat_for_lb = 1;
> reg0 = 0; reject { outport <-> inport; next(pipeline=egress,table=3);};)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -7886,8 +7877,10 @@ check ovn-nbctl
>            \
>  AS_BOX([No chassis registered - use ct_lb_mark and ct_mark.natted])
>  check ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb], [0], [dnl
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 66.66.66.66 && ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=6 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 &&
> ip4.dst == 66.66.66.66), action=(reg1 = 66.66.66.66; ct_lb_mark;)
>    table=6 (ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1),
> action=(ct_lb_mark;)
>    table=12(ls_in_lb           ), priority=110  , match=(ct.new && ip4.dst
> == 66.66.66.66), action=(reg0[[1]] = 0; ct_lb_mark(backends=42.42.42.2);)
> @@ -7898,8 +7891,10 @@ AS_BOX([Chassis registered that doesn't support
> ct_lb_mark - use ct_lb and ct_la
>  check ovn-sbctl chassis-add hv geneve 127.0.0.1
>  check ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb], [0], [dnl
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 66.66.66.66 && ct_label.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 66.66.66.66), action=(ct_lb(backends=42.42.42.2);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 66.66.66.66), action=(ct_lb(backends=42.42.42.2);)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_label.natted && ct_label.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_label.natted && ct_label.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_label.natted), action=(next;)
>    table=6 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 &&
> ip4.dst == 66.66.66.66), action=(reg1 = 66.66.66.66; ct_lb;)
>    table=6 (ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1),
> action=(ct_lb;)
>    table=12(ls_in_lb           ), priority=110  , match=(ct.new && ip4.dst
> == 66.66.66.66), action=(reg0[[1]] = 0; ct_lb(backends=42.42.42.2);)
> @@ -7910,8 +7905,10 @@ AS_BOX([Chassis upgrades and supports ct_lb_mark -
> use ct_lb_mark and ct_mark.na
>  check ovn-sbctl set chassis hv other_config:ct-no-masked-label=true
>  check ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb], [0], [dnl
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 66.66.66.66 && ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);)
> +  table=7 (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=6 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 &&
> ip4.dst == 66.66.66.66), action=(reg1 = 66.66.66.66; ct_lb_mark;)
>    table=6 (ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1),
> action=(ct_lb_mark;)
>    table=12(ls_in_lb           ), priority=110  , match=(ct.new && ip4.dst
> == 66.66.66.66), action=(reg0[[1]] = 0; ct_lb_mark(backends=42.42.42.2);)
> @@ -8244,15 +8241,17 @@ AT_CAPTURE_FILE([R1flows])
>
>  AT_CHECK([grep "lr_in_lb_aff_check" R1flows | sort], [0], [dnl
>    table=6 (lr_in_lb_aff_check ), priority=0    , match=(1), action=(next;)
> -  table=6 (lr_in_lb_aff_check ), priority=100  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80),
> action=(reg9[[6]] = chk_lb_aff(); next;)
> +  table=6 (lr_in_lb_aff_check ), priority=100  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(reg0 =
> 172.16.0.10; reg9[[16..31]] = tcp.dst; reg9[[6]] = chk_lb_aff(); next;)
>  ])
>  AT_CHECK([grep "lr_in_dnat " R1flows | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80),
> action=(ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);)
>    table=7 (lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 =
> 172.16.0.10; ct_lb_mark(backends=10.0.0.2:80);)
>    table=7 (lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 =
> 172.16.0.10; ct_lb_mark(backends=20.0.0.2:80);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -8270,11 +8269,13 @@ AT_CAPTURE_FILE([R1flows_skip_snat])
>
>  AT_CHECK([grep "lr_in_dnat " R1flows_skip_snat | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.skip_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,
> 20.0.0.2:80; skip_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80),
> action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,
> 20.0.0.2:80; skip_snat);)
>    table=7 (lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 =
> 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> skip_snat);)
>    table=7 (lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 =
> 172.16.0.10; flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80;
> skip_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -8289,11 +8290,13 @@ AT_CAPTURE_FILE([R1flows_force_snat])
>
>  AT_CHECK([grep "lr_in_dnat " R1flows_force_snat | sort], [0], [dnl
>    table=7 (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80 &&
> ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;)
> -  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 172.16.0.10 && tcp && reg9[[16..31]] == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,
> 20.0.0.2:80; force_snat);)
> +  table=7 (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80,
> 20.0.0.2:80; force_snat);)
>    table=7 (lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4 && reg4 == 10.0.0.2 && reg8[[0..15]] == 80), action=(reg0 =
> 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> force_snat);)
>    table=7 (lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4 && reg4 == 20.0.0.2 && reg8[[0..15]] == 80), action=(reg0 =
> 172.16.0.10; flags.force_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80;
> force_snat);)
> +  table=7 (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=7 (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=7 (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=7 (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -8569,12 +8572,13 @@ ovn-sbctl dump-flows | DUMP_FLOWS_SORTED > lflows0
>
>  AT_CHECK([grep -e "lr_in_defrag" -e "lr_in_dnat" lflows0], [0], [dnl
>    table=? (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=? (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 192.168.0.1), action=(reg0 = 192.168.0.1; ct_dnat;)
> -  table=? (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=? (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 192.168.0.1), action=(ct_dnat;)
>    table=? (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=? (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 192.168.0.1 && ct_mark.natted == 1), action=(next;)
> -  table=? (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 192.168.0.1), action=(ct_lb_mark(backends=192.168.1.10);)
> +  table=? (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 192.168.0.1),
> action=(ct_lb_mark(backends=192.168.1.10);)
> +  table=? (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=? (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=? (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=? (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=? (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=? (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> @@ -8599,10 +8603,12 @@ ovn-sbctl dump-flows | DUMP_FLOWS_SORTED > lflows1
>
>  AT_CHECK([grep -e "lr_in_defrag" -e "lr_in_dnat" lflows1], [0], [dnl
>    table=? (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=? (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 192.168.0.1), action=(reg0 = 192.168.0.1; ct_dnat;)
> +  table=? (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 192.168.0.1), action=(ct_dnat;)
>    table=? (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=? (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 192.168.0.1 && ct_label.natted == 1), action=(next;)
> -  table=? (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 192.168.0.1), action=(ct_lb(backends=192.168.1.10);)
> +  table=? (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 192.168.0.1), action=(ct_lb(backends=192.168.1.10);)
> +  table=? (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_label.natted), action=(next;)
> +  table=? (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_label.natted && ct_label.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=? (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_label.natted && ct_label.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>  ])
>
>  AT_CHECK([grep -e "ls_in_acl" -e "ls_out_acl" lflows1 | grep
> "priority=65532"], [0], [dnl
> @@ -8625,12 +8631,13 @@ ovn-sbctl dump-flows | DUMP_FLOWS_SORTED > lflows2
>
>  AT_CHECK([grep -e "lr_in_defrag" -e "lr_in_dnat" lflows2], [0], [dnl
>    table=? (lr_in_defrag       ), priority=0    , match=(1), action=(next;)
> -  table=? (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 192.168.0.1), action=(reg0 = 192.168.0.1; ct_dnat;)
> -  table=? (lr_in_defrag       ), priority=50   , match=(icmp || icmp6),
> action=(ct_dnat;)
> +  table=? (lr_in_defrag       ), priority=100  , match=(ip && ip4.dst ==
> 192.168.0.1), action=(ct_dnat;)
>    table=? (lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=? (lr_in_dnat         ), priority=110  , match=(ct.est && !ct.rel
> && ip4 && reg0 == 192.168.0.1 && ct_mark.natted == 1), action=(next;)
> -  table=? (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && reg0 == 192.168.0.1), action=(ct_lb_mark(backends=192.168.1.10);)
> +  table=? (lr_in_dnat         ), priority=110  , match=(ct.new && !ct.rel
> && ip4 && ip4.dst == 192.168.0.1),
> action=(ct_lb_mark(backends=192.168.1.10);)
> +  table=? (lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted), action=(next;)
>    table=? (lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new), action=(ct_commit_nat;)
> +  table=? (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> +  table=? (lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && ct_mark.natted && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; next;)
>    table=? (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.force_snat == 1), action=(flags.force_snat_for_lb =
> 1; ct_commit_nat;)
>    table=? (lr_in_dnat         ), priority=70   , match=(ct.rel && !ct.est
> && !ct.new && ct_mark.skip_snat == 1), action=(flags.skip_snat_for_lb = 1;
> ct_commit_nat;)
>  ])
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 778d2dbe0..0d2edce05 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -24372,7 +24372,7 @@ AT_CAPTURE_FILE([sbflows2])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows > sbflows2
>     ovn-sbctl dump-flows lr0 | grep ct_lb_mark | grep priority=120 | sed
> 's/table=..//'], 0,
> -  [  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel &&
> ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=
> 10.0.0.3:80,20.0.0.3:80; hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
> +  [  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel &&
> ip4 && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=
> 10.0.0.3:80,20.0.0.3:80; hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
>  ])
>
>  # get the svc monitor mac.
> @@ -24414,8 +24414,7 @@ AT_CHECK(
>  AT_CAPTURE_FILE([sbflows4])
>  ovn-sbctl dump-flows lr0 > sbflows4
>  AT_CHECK([grep lr_in_dnat sbflows4 | grep priority=120 | sed
> 's/table=..//' | sort], [0], [dnl
> -  (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel && ip4
> && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1
> && is_chassis_resident("cr-lr0-public")), action=(next;)
> -  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && ip4
> && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
> +  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && ip4
> && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
>  ])
>
>  # Delete sw0-p1
> @@ -24571,7 +24570,7 @@ AT_CAPTURE_FILE([sbflows2])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows > sbflows2
>     ovn-sbctl dump-flows lr0 | grep ct_lb_mark | grep priority=120 | sed
> 's/table=..//'], 0,
> -  [  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel &&
> ip6 && xxreg0 == 2001::a && tcp && reg9[[16..31]] == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=[[2001::3]]:80,[[2002::3]]:80;
> hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
> +  [  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel &&
> ip6 && ip6.dst == 2001::a && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=[[2001::3]]:80,[[2002::3]]:80;
> hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
>  ])
>
>  # get the svc monitor mac.
> @@ -24613,8 +24612,7 @@ AT_CHECK(
>  AT_CAPTURE_FILE([sbflows4])
>  ovn-sbctl dump-flows lr0 > sbflows4
>  AT_CHECK([grep lr_in_dnat sbflows4 | grep priority=120 | sed
> 's/table=..//' | sort], [0], [dnl
> -  (lr_in_dnat         ), priority=120  , match=(ct.est && !ct.rel && ip6
> && xxreg0 == 2001::a && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1
> && is_chassis_resident("cr-lr0-public")), action=(next;)
> -  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && ip6
> && xxreg0 == 2001::a && tcp && reg9[[16..31]] == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
> +  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && ip6
> && ip6.dst == 2001::a && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
>  ])
>
>  # Delete sw0-p1
> --
> 2.39.2
>
>
Hi,

this patch doesn't address documentation as it is just PoC
that it could work.

Thanks,
Ales

-- 

Ales Musil

Senior Software Engineer - OVN Core

Red Hat EMEA <https://www.redhat.com>

[email protected]    IM: amusil
<https://red.ht/sig>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to