On Tue, May 20, 2025 at 1:03 PM Ales Musil <amu...@redhat.com> wrote:

> There is a difference between userspace and kernel DP for fragmented
> packets. The kernel DP will try to reassemble the fragments during CT
> lookup, however userspace won't reassemble them. In case of LB with
> protocol match we cannot match on L4 header for later fragments
> because the information is not available. Match on CT L4 fields
> instead, this shouldn't cause any HWOL issues because the match
> is adjusted only for ct.new packets that cannot be offloaded anyway.
>
> Move the original test for fragmented traffic through LB into
> system-ovn.at so it's no longer skipped with userspace DP.
>
> Reported-at: https://issues.redhat.com/browse/FDP-684
> Signed-off-by: Ales Musil <amu...@redhat.com>
> Acked-by: Dumitru Ceara <dce...@redhat.com>
> ---
> v3: Rebase on top of current main.
>     Add Dumitru's ack.
> ---
>  lib/logical-fields.c     |  15 ++++
>  northd/northd.c          |   6 +-
>  tests/ovn-northd.at      | 150 +++++++++++++++++++--------------------
>  tests/ovn.at             |  27 ++++---
>  tests/system-ovn-kmod.at | 141 ------------------------------------
>  tests/system-ovn.at      | 145 +++++++++++++++++++++++++++++++++++++
>  6 files changed, 255 insertions(+), 229 deletions(-)
>
> diff --git a/lib/logical-fields.c b/lib/logical-fields.c
> index db2d08ada..fabe17338 100644
> --- a/lib/logical-fields.c
> +++ b/lib/logical-fields.c
> @@ -355,6 +355,21 @@ ovn_init_symtab(struct shash *symtab)
>
>      expr_symtab_add_ovn_field(symtab, "icmp4.frag_mtu",
> OVN_ICMP4_FRAG_MTU);
>      expr_symtab_add_ovn_field(symtab, "icmp6.frag_mtu",
> OVN_ICMP6_FRAG_MTU);
> +
> +    expr_symtab_add_field(symtab, "ct_proto", MFF_CT_NW_PROTO,
> +                          "ct.trk", false);
> +
> +    expr_symtab_add_predicate(symtab, "ct_udp", "ct_proto == 17");
> +    expr_symtab_add_field(symtab, "ct_udp.dst", MFF_CT_TP_DST,
> +                          "ct_udp", false);
> +
> +    expr_symtab_add_predicate(symtab, "ct_tcp", "ct_proto == 6");
> +    expr_symtab_add_field(symtab, "ct_tcp.dst", MFF_CT_TP_DST,
> +                          "ct_tcp", false);
> +
> +    expr_symtab_add_predicate(symtab, "ct_sctp", "ct_proto == 132");
> +    expr_symtab_add_field(symtab, "ct_sctp.dst", MFF_CT_TP_DST,
> +                          "ct_sctp", false);
>  }
>
>  const char *
> diff --git a/northd/northd.c b/northd/northd.c
> index a3d278746..613317a4a 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -8329,7 +8329,7 @@ build_lb_affinity_ls_flows(struct lflow_table
> *lflows,
>                    ip_match, ip_match, lb_vip->vip_str);
>
>      if (lb_vip->port_str) {
> -        ds_put_format(&new_lb_match, " && %s && %s.dst == %s",
> +        ds_put_format(&new_lb_match, " && ct_%s && ct_%s.dst == %s",
>                        lb->proto, lb->proto, lb_vip->port_str);
>      }
>
> @@ -8493,7 +8493,7 @@ build_lb_rules(struct lflow_table *lflows, struct
> ovn_lb_datapaths *lb_dps,
>                        lb_vip->vip_str);
>          int priority = 110;
>          if (lb_vip->port_str) {
> -            ds_put_format(match, " && %s.dst == %s", lb->proto,
> +            ds_put_format(match, " && ct_%s.dst == %s", lb->proto,
>                            lb_vip->port_str);
>              priority = 120;
>          }
> @@ -12472,7 +12472,7 @@ build_lrouter_nat_flows_for_lb(
>                    ip_match, ip_match, lb_vip->vip_str);
>      if (lb_vip->port_str) {
>          prio = 120;
> -        ds_put_format(match, " && %s && %s.dst == %s",
> +        ds_put_format(match, " && ct_%s && ct_%s.dst == %s",
>                        lb->proto, lb->proto, lb_vip->port_str);
>      }
>
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index f66ba4c85..136e72e8a 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -1475,7 +1475,7 @@ check ovn-nbctl --wait=sb ls-lb-add sw0 lb1
>  AT_CAPTURE_FILE([sbflows])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows | grep 'priority=120.*backends'
> | ovn_strip_lflows], 0, [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>
>  # disabled LSPs should not be a backend of Load Balancer
> @@ -1484,7 +1484,7 @@ check ovn-nbctl lsp-set-enabled sw0-p1 disabled
>  AT_CAPTURE_FILE([sbflows])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows | grep 'priority=120.*backends'
> | ovn_strip_lflows], 0, [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=20.0.0.3:80);)
>  ])
>  wait_row_count Service_Monitor 1
>
> @@ -1493,7 +1493,7 @@ check ovn-nbctl lsp-set-enabled sw0-p1 enabled
>  AT_CAPTURE_FILE([sbflows])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows | grep 'priority=120.*backends'
> | ovn_strip_lflows], 0, [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>  wait_row_count Service_Monitor 2
>
> @@ -1504,7 +1504,7 @@ wait_row_count Service_Monitor 0
>  AT_CAPTURE_FILE([sbflows2])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows2 | grep
> 'priority=120.*backends' | ovn_strip_lflows], [0],
> -[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>
>  AS_BOX([Create the Load_Balancer_Health_Check again.])
> @@ -1516,7 +1516,7 @@ check ovn-nbctl --wait=sb sync
>
>  ovn-sbctl dump-flows sw0 | grep backends | grep priority=120 > lflows.txt
>  AT_CHECK([cat lflows.txt | ovn_strip_lflows], [0], [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>
>  AS_BOX([Get the uuid of both the service_monitor])
> @@ -1526,7 +1526,7 @@ sm_sw1_p1=$(fetch_column Service_Monitor _uuid
> logical_port=sw1-p1)
>  AT_CAPTURE_FILE([sbflows3])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows 3 | grep
> 'priority=120.*backends' | ovn_strip_lflows], [0],
> -[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>
>  AS_BOX([Set the service monitor for sw1-p1 to offline])
> @@ -1537,7 +1537,7 @@ check ovn-nbctl --wait=sb sync
>  AT_CAPTURE_FILE([sbflows4])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows4 | grep
> 'priority=120.*backends' | ovn_strip_lflows], [0],
> -[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);)
> +[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);)
>  ])
>
>  AS_BOX([Set the service monitor for sw0-p1 to offline])
> @@ -1552,8 +1552,8 @@ OVS_WAIT_FOR_OUTPUT(
>
>  AT_CAPTURE_FILE([sbflows6])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw0 | tee sbflows6 | grep "ip4.dst == 10.0.0.10
> && tcp.dst == 80" | grep priority=120 | grep ls_in_lb | ovn_strip_lflows],
> [0], [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(drop;)
> +  [ovn-sbctl dump-flows sw0 | tee sbflows6 | grep "ip4.dst == 10.0.0.10
> && ct_tcp.dst == 80" | grep priority=120 | grep ls_in_lb |
> ovn_strip_lflows], [0], [dnl
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(drop;)
>  ])
>
>  AS_BOX([Set the service monitor for sw0-p1 and sw1-p1 to online])
> @@ -1566,7 +1566,7 @@ check ovn-nbctl --wait=sb sync
>  AT_CAPTURE_FILE([sbflows7])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows7 | grep backends | grep
> priority=120 | ovn_strip_lflows], 0,
> -[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>
>  AS_BOX([Set the service monitor for sw1-p1 to error])
> @@ -1574,10 +1574,10 @@ check ovn-sbctl set service_monitor $sm_sw1_p1
> status=error
>  wait_row_count Service_Monitor 1 logical_port=sw1-p1 status=error
>  check ovn-nbctl --wait=sb sync
>
> -ovn-sbctl dump-flows sw0 | grep "ip4.dst == 10.0.0.10 && tcp.dst == 80" \
> +ovn-sbctl dump-flows sw0 | grep "ip4.dst == 10.0.0.10 && ct_tcp.dst ==
> 80" \
>  | grep priority=120 > lflows.txt
>  AT_CHECK([cat lflows.txt | grep ls_in_lb | ovn_strip_lflows], [0], [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);)
>  ])
>
>  AS_BOX([Add one more vip to lb1])
> @@ -1603,8 +1603,8 @@ AT_CAPTURE_FILE([sbflows9])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows9 | grep backends | grep
> priority=120 | ovn_strip_lflows],
>    0,
> -[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg4 = 10.0.0.40;
> reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000);)
> +[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.40 && ct_tcp.dst == 1000), action=(reg4 = 10.0.0.40;
> reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000);)
>  ])
>
>  AS_BOX([Set the service monitor for sw1-p1 to online])
> @@ -1617,8 +1617,8 @@ AT_CAPTURE_FILE([sbflows10])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw0 | tee sbflows10 | grep backends | grep
> priority=120 | ovn_strip_lflows],
>    0,
> -[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg4 = 10.0.0.40;
> reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000,20.0.0.3:80);)
> +[  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.40 && ct_tcp.dst == 1000), action=(reg4 = 10.0.0.40;
> reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000,20.0.0.3:80);)
>  ])
>
>  AS_BOX([Associate lb1 to sw1])
> @@ -1627,8 +1627,8 @@ AT_CAPTURE_FILE([sbflows11])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows sw1 | tee sbflows11 | grep backends | grep
> priority=120 | ovn_strip_lflows],
>    0, [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg4 = 10.0.0.40;
> reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000,20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.40 && ct_tcp.dst == 1000), action=(reg4 = 10.0.0.40;
> reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000,20.0.0.3:80);)
>  ])
>
>  AS_BOX([Now create lb2 same as lb1 but udp protocol.])
> @@ -1684,8 +1684,8 @@ check ovn-sbctl set service_monitor $sm_sw1_p1
> status=offline
>
>  AT_CAPTURE_FILE([sbflows12])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw0 | tee sbflows12 | grep "ip4.dst == 10.0.0.10
> && tcp.dst == 80" | grep priority=120 | grep ls_in_lb | ovn_strip_lflows],
> [0], [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0 = 0; reject { outport
> <-> inport; next(pipeline=egress,table=??);};)
> +  [ovn-sbctl dump-flows sw0 | tee sbflows12 | grep "ip4.dst == 10.0.0.10
> && ct_tcp.dst == 80" | grep priority=120 | grep ls_in_lb |
> ovn_strip_lflows], [0], [dnl
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg0 = 0; reject {
> outport <-> inport; next(pipeline=egress,table=??);};)
>  ])
>
>  AT_CLEANUP
> @@ -4399,8 +4399,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.100 && ct_tcp && ct_tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.40:8080);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -4430,8 +4430,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.100 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -4481,8 +4481,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.100 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -4549,8 +4549,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.100 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> force_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -4604,7 +4604,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>  ])
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | grep skip_snat_for_lb |
> ovn_strip_lflows], [0], [dnl
> -  table=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.20 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && 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.rpl && ct_mark.skip_snat == 1),
> action=(flags.skip_snat_for_lb = 1; ct_commit_nat;)
>  ])
> @@ -4785,8 +4785,8 @@ check_stateful_flows() {
>    table=??(ls_in_lb           ), priority=0    , match=(1), action=(next;)
>    table=??(ls_in_lb           ), priority=110  , match=(ct.trk && !ct.rpl
> && reg0[[19]] == 1 && ip4), action=(reg4 = ct_nw_dst(); reg2[[0..15]] =
> ct_tp_dst(); next;)
>    table=??(ls_in_lb           ), priority=110  , match=(ct.trk && !ct.rpl
> && reg0[[19]] == 1 && ip6), action=(xxreg1 = ct_ip6_dst(); reg2[[0..15]] =
> ct_tp_dst(); next;)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.4:8080);)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.20 && tcp.dst == 80), action=(reg4 = 10.0.0.20;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.40:8080);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.20 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.20;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.40:8080);)
>  ])
>
>      AT_CHECK([grep "ls_in_stateful" sw0flows | ovn_strip_lflows], [0],
> [dnl
> @@ -6040,9 +6040,9 @@ AT_CHECK([grep "lr_in_dnat" lr0flows |
> ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(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=??(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=??(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=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -6110,9 +6110,9 @@ AT_CHECK([grep "lr_in_dnat" lr0flows |
> ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(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(10.0.0.3);)
>    table=??(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=??(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=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -6184,9 +6184,9 @@ AT_CHECK([grep "lr_in_dnat" lr0flows |
> ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
>    table=??(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=??(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=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(ct_lb_mark(backends=10.0.0.4:8080);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_tcp.dst ==
> 8082), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_udp.dst == 60),
> action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -6247,9 +6247,9 @@ AT_CHECK([grep "lr_in_dnat" lr0flows |
> ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
>    table=??(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=??(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=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -6314,10 +6314,10 @@ AT_CHECK([grep "lr_in_dnat" lr0flows |
> ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
>    table=??(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=??(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=??(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=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.10 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -6393,11 +6393,11 @@ AT_CHECK([grep "lr_in_dnat" lr0flows |
> ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=100  , match=(ip && ip4.dst ==
> 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);)
>    table=??(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=??(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=??(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=??(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=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080;
> force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.10 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip6 && ip6.dst == def0::2 && ct_tcp && ct_tcp.dst == 8000),
> action=(flags.force_snat_for_lb = 1;
> ct_lb_mark(backends=[[aef0::2]]:80,[[aef0::3]]:80; force_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -6462,8 +6462,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.210 && ct_udp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -9656,13 +9656,13 @@ AT_CAPTURE_FILE([S1flows])
>
>  AT_CHECK([grep "ls_in_lb " S0flows | ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_lb           ), priority=0    , match=(1), action=(next;)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.10 && tcp.dst == 80), action=(reg4 = 172.16.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80);)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.11 && tcp.dst == 8080), action=(reg4 = 172.16.0.11;
> reg2[[0..15]] = 8080; ct_lb_mark(backends=10.0.0.2:8080);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.10 && ct_tcp.dst == 80), action=(reg4 = 172.16.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.11 && ct_tcp.dst == 8080), action=(reg4 = 172.16.0.11;
> reg2[[0..15]] = 8080; ct_lb_mark(backends=10.0.0.2:8080);)
>  ])
>  AT_CHECK([grep "ls_in_lb " S1flows | ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_lb           ), priority=0    , match=(1), action=(next;)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.10 && tcp.dst == 80), action=(reg4 = 172.16.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80);)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.11 && tcp.dst == 8080), action=(reg4 = 172.16.0.11;
> reg2[[0..15]] = 8080; ct_lb_mark(backends=10.0.0.2:8080);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.10 && ct_tcp.dst == 80), action=(reg4 = 172.16.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.11 && ct_tcp.dst == 8080), action=(reg4 = 172.16.0.11;
> reg2[[0..15]] = 8080; ct_lb_mark(backends=10.0.0.2:8080);)
>  ])
>
>  ovn-sbctl get datapath S0 _uuid > dp_uuids
> @@ -9788,13 +9788,13 @@ AT_CAPTURE_FILE([S0flows])
>
>  AT_CHECK([grep "ls_in_lb_aff_check" S0flows | ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_lb_aff_check ), priority=0    , match=(1), action=(next;)
> -  table=??(ls_in_lb_aff_check ), priority=100  , match=(ct.new && ip4 &&
> ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80), action=(reg9[[6]] =
> chk_lb_aff(); next;)
> +  table=??(ls_in_lb_aff_check ), priority=100  , match=(ct.new && ip4 &&
> ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80), action=(reg9[[6]] =
> chk_lb_aff(); next;)
>  ])
>  AT_CHECK([grep "ls_in_lb " S0flows | ovn_strip_lflows], [0], [dnl
>    table=??(ls_in_lb           ), priority=0    , match=(1), action=(next;)
>    table=??(ls_in_lb           ), priority=110  , match=(ct.trk && !ct.rpl
> && reg0[[19]] == 1 && ip4), action=(reg4 = ct_nw_dst(); reg2[[0..15]] =
> ct_tp_dst(); next;)
>    table=??(ls_in_lb           ), priority=110  , match=(ct.trk && !ct.rpl
> && reg0[[19]] == 1 && ip6), action=(xxreg1 = ct_ip6_dst(); reg2[[0..15]] =
> ct_tp_dst(); next;)
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.10 && tcp.dst == 80), action=(reg4 = 172.16.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 172.16.0.10 && ct_tcp.dst == 80), action=(reg4 = 172.16.0.10;
> reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80);)
>    table=??(ls_in_lb           ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(reg4 = 172.16.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=
> 10.0.0.2:80);)
>    table=??(ls_in_lb           ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg2[[0..15]] ==
> 80), action=(reg4 = 172.16.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=
> 20.0.0.2:80);)
>  ])
> @@ -9810,11 +9810,11 @@ AT_CAPTURE_FILE([R1flows])
>
>  AT_CHECK([grep "lr_in_lb_aff_check" R1flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_lb_aff_check ), priority=0    , match=(1), action=(next;)
> -  table=??(lr_in_lb_aff_check ), priority=100  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80),
> action=(reg9[[6]] = chk_lb_aff(); next;)
> +  table=??(lr_in_lb_aff_check ), priority=100  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(reg9[[6]] = chk_lb_aff(); next;)
>  ])
>  AT_CHECK([grep "lr_in_dnat " R1flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && tcp && tcp.dst == 80),
> action=(reg4 = 172.16.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=
> 10.0.0.2:80,20.0.0.2:80);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(reg4 = 172.16.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=
> 10.0.0.2:80,20.0.0.2:80);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(ct_lb_mark(backends=10.0.0.2:80);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg2[[0..15]] ==
> 80), action=(ct_lb_mark(backends=20.0.0.2:80);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
> @@ -9838,7 +9838,7 @@ AT_CAPTURE_FILE([R1flows_skip_snat])
>
>  AT_CHECK([grep "lr_in_dnat " R1flows_skip_snat | ovn_strip_lflows], [0],
> [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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; reg4 = 172.16.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.skip_snat_for_lb = 1; reg4 = 172.16.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
> @@ -9859,7 +9859,7 @@ AT_CAPTURE_FILE([R1flows_force_snat])
>
>  AT_CHECK([grep "lr_in_dnat " R1flows_force_snat | ovn_strip_lflows], [0],
> [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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; reg4 = 172.16.0.10; reg2[[0..15]] =
> 80; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; reg4 = 172.16.0.10; reg2[[0..15]] =
> 80; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> force_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80;
> force_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
> @@ -9879,7 +9879,7 @@ AT_CAPTURE_FILE([R1flows_force_skip_snat])
>
>  AT_CHECK([grep "lr_in_dnat " R1flows_force_skip_snat | ovn_strip_lflows],
> [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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; reg4 = 172.16.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.skip_snat_for_lb = 1; reg4 = 172.16.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
> @@ -9903,8 +9903,8 @@ AT_CAPTURE_FILE([R1flows_2lbs])
>
>  AT_CHECK([grep "lr_in_dnat " R1flows_2lbs | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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; reg4 = 172.16.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);)
> -  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.20 && tcp && tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; reg4 = 172.16.0.20; reg2[[0..15]] =
> 80; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.10 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.skip_snat_for_lb = 1; reg4 = 172.16.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; skip_snat);)
> +  table=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.16.0.20 && ct_tcp && ct_tcp.dst == 80),
> action=(flags.force_snat_for_lb = 1; reg4 = 172.16.0.20; reg2[[0..15]] =
> 80; ct_lb_mark(backends=10.0.0.2:80,20.0.0.2:80; force_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.10 && reg4 == 20.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=20.0.0.2:80;
> skip_snat);)
>    table=??(lr_in_dnat         ), priority=150  , match=(reg9[[6]] == 1 &&
> ct.new && ip4.dst == 172.16.0.20 && reg4 == 10.0.0.2 && reg2[[0..15]] ==
> 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.2:80;
> force_snat);)
> @@ -12362,7 +12362,7 @@ check ovn-nbctl --wait=sb ls-lb-add sw0 lb1
>  check_engine_stats lflow norecompute compute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>
> -lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80"')
> +lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80"')
>  sw0_uuid=$(fetch_column Datapath_Binding _uuid external_ids:name=sw0)
>
>  lb_lflow_dp=$(ovn-sbctl --bare --columns logical_datapath list
> logical_flow $lb_lflow_uuid)
> @@ -12400,7 +12400,7 @@ check ovn-nbctl --wait=sb set load_balancer lb1
> options:foo=bar
>  check_engine_stats lflow recompute nocompute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>
> -lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80"')
> +lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80"')
>
>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
>  check ovn-nbctl --wait=sb clear load_balancer lb2 vips
> @@ -12481,7 +12481,7 @@ check ovn-nbctl --wait=sb clear load_balancer lb1
> vips
>
>  AT_CHECK([ovn-sbctl --bare --columns logical_datapath list logical_flow
> $lb_lflow_uuid], [1], [ignore], [ignore])
>
> -lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80"')
> +lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80"')
>  AT_CHECK([test "$lb_lflow_uuid" = ""])
>
>
> @@ -12498,7 +12498,7 @@ check ovn-nbctl --wait=sb ls-lb-add sw1 lb3
>  check_engine_stats lflow norecompute compute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>
> -lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80"')
> +lb_lflow_uuid=$(fetch_column Logical_flow _uuid match='"ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80"')
>
>  lb_lflow_dp=$(ovn-sbctl --bare --columns logical_datapath list
> logical_flow $lb_lflow_uuid)
>  AT_CHECK([test "$lb_lflow_dp" = ""])
> @@ -15975,7 +15975,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=10   , match=(ip && ct.new &&
> inport == "lr0-public" && is_chassis_resident("cr-lr0-public")),
> action=(ct_commit_to_zone(dnat);)
> -  table=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -16019,7 +16019,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=10   , match=(ip && ct.new &&
> inport == "lr0-public" && is_chassis_resident("cr-lr0-public")),
> action=(ct_commit_to_zone(dnat);)
> -  table=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_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=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -16065,7 +16065,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
>    table=??(lr_in_dnat         ), priority=10   , match=(ip && ct.new),
> action=(ct_commit_to_zone(dnat);)
> -  table=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_tcp.dst ==
> 8082), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> @@ -16106,7 +16106,7 @@ AT_CHECK([grep "lr_in_defrag" lr0flows |
> ovn_strip_lflows], [0], [dnl
>
>  AT_CHECK([grep "lr_in_dnat" lr0flows | ovn_strip_lflows], [0], [dnl
>    table=??(lr_in_dnat         ), priority=0    , match=(1), action=(next;)
> -  table=??(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=??(lr_in_dnat         ), priority=120  , match=(ct.new &&
> !ct.rel && ip4 && ip4.dst == 172.168.0.100 && ct_tcp && ct_tcp.dst ==
> 8082), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted), action=(next;)
>    table=??(lr_in_dnat         ), priority=50   , match=(ct.rel && !ct.est
> && !ct.new && !ct.rpl), action=(ct_commit_nat;)
>    table=??(lr_in_dnat         ), priority=70   , match=(ct.est && !ct.rel
> && !ct.new && !ct.rpl && ct_mark.natted && ct_mark.force_snat == 1),
> action=(flags.force_snat_for_lb = 1; next;)
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 596a7be2b..03273a3a8 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -154,7 +154,14 @@ ct_mark.natted = ct_mark[1]
>  ct_mark.obs_collector_id = ct_mark[16..23]
>  ct_mark.obs_stage = ct_mark[4..5]
>  ct_mark.skip_snat = ct_mark[2]
> +ct_proto = NXM_NX_CT_NW_PROTO
> +ct_sctp = ct_proto == 132
> +ct_sctp.dst = NXM_NX_CT_TP_DST
>  ct_state = NXM_NX_CT_STATE
> +ct_tcp = ct_proto == 6
> +ct_tcp.dst = NXM_NX_CT_TP_DST
> +ct_udp = ct_proto == 17
> +ct_udp.dst = NXM_NX_CT_TP_DST
>  ]])
>  AT_CLEANUP
>
> @@ -26712,14 +26719,14 @@ OVS_WAIT_FOR_OUTPUT(
>     ovn-sbctl dump-flows sw0 | grep ct_lb_mark | grep priority=120 | sed
> 's/table=..//'], 0,
>    [dnl
>    (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4.dst
> == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10; reg2[[0..15]] =
> 80; ct_lb_mark;)
> -  (ls_in_lb           ), priority=120  , match=(ct.new && ip4.dst ==
> 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10; reg2[[0..15]] = 80;
> ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80;
> hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
> +  (ls_in_lb           ), priority=120  , match=(ct.new && ip4.dst ==
> 10.0.0.10 && ct_tcp.dst == 80), action=(reg4 = 10.0.0.10; reg2[[0..15]] =
> 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80;
> hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
>  ])
>
>  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 && 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");)
> +  [  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel &&
> ip4 && ip4.dst == 10.0.0.10 && ct_tcp && ct_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.
> @@ -26753,16 +26760,16 @@ grep "405400000003${svc_mon_src_mac}" | wc -l`]
>  AT_CAPTURE_FILE([sbflows3])
>  ovn-sbctl dump-flows sw0 > sbflows3
>  AT_CHECK(
> -  [grep "ip4.dst == 10.0.0.10 && tcp.dst == 80" sbflows3 | grep
> priority=120 |\
> +  [grep "ip4.dst == 10.0.0.10" sbflows3 | grep priority=120 |\
>     ovn_strip_lflows], [0], [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(drop;)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip4.dst == 10.0.0.10 && ct_tcp.dst == 80), action=(drop;)
>    table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 &&
> ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg4 = 10.0.0.10;
> reg2[[0..15]] = 80; ct_lb_mark;)
>  ])
>
>  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.new && !ct.rel && ip4
> && ip4.dst == 10.0.0.10 && tcp && tcp.dst == 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 && ct_tcp && ct_tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
>  ])
>
>  # Delete sw0-p1
> @@ -26918,14 +26925,14 @@ OVS_WAIT_FOR_OUTPUT(
>     ovn-sbctl dump-flows sw0 | grep ct_lb_mark | grep priority=120 | sed
> 's/table=..//'], 0,
>    [dnl
>    (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip6.dst
> == 2002::a && tcp.dst == 80), action=(xxreg1 = 2002::a; reg2[[0..15]] = 80;
> ct_lb_mark;)
> -  (ls_in_lb           ), priority=120  , match=(ct.new && ip6.dst ==
> 2002::a && tcp.dst == 80), action=(xxreg1 = 2002::a; reg2[[0..15]] = 80;
> ct_lb_mark(backends=[[2001::3]]:80,[[2002::3]]:80;
> hash_fields="ipv6_dst,ipv6_src,tcp_dst,tcp_src");)
> +  (ls_in_lb           ), priority=120  , match=(ct.new && ip6.dst ==
> 2002::a && ct_tcp.dst == 80), action=(xxreg1 = 2002::a; reg2[[0..15]] = 80;
> ct_lb_mark(backends=[[2001::3]]:80,[[2002::3]]:80;
> hash_fields="ipv6_dst,ipv6_src,tcp_dst,tcp_src");)
>  ])
>
>  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 && ip6.dst == 2002::a && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=[[2001::3]]:80,[[2002::3]]:80;
> hash_fields="ipv6_dst,ipv6_src,tcp_dst,tcp_src");)
> +  [  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel &&
> ip6 && ip6.dst == 2002::a && ct_tcp && ct_tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")),
> action=(ct_lb_mark(backends=[[2001::3]]:80,[[2002::3]]:80;
> hash_fields="ipv6_dst,ipv6_src,tcp_dst,tcp_src");)
>  ])
>
>  # get the svc monitor mac.
> @@ -26958,16 +26965,16 @@ grep "405400000003${svc_mon_src_mac}" | wc -l`]
>  AT_CAPTURE_FILE([sbflows3])
>  ovn-sbctl dump-flows sw0 > sbflows3
>  AT_CHECK(
> -  [grep "ip6.dst == 2002::a && tcp.dst == 80" sbflows3 | grep
> priority=120 |\
> +  [grep "ip6.dst == 2002::a" sbflows3 | grep priority=120 |\
>     ovn_strip_lflows], [0], [dnl
> -  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip6.dst == 2002::a && tcp.dst == 80), action=(drop;)
> +  table=??(ls_in_lb           ), priority=120  , match=(ct.new &&
> ip6.dst == 2002::a && ct_tcp.dst == 80), action=(drop;)
>    table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 &&
> ip6.dst == 2002::a && tcp.dst == 80), action=(xxreg1 = 2002::a;
> reg2[[0..15]] = 80; ct_lb_mark;)
>  ])
>
>  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.new && !ct.rel && ip6
> && ip6.dst == 2002::a && tcp && tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
> +  (lr_in_dnat         ), priority=120  , match=(ct.new && !ct.rel && ip6
> && ip6.dst == 2002::a && ct_tcp && ct_tcp.dst == 80 &&
> is_chassis_resident("cr-lr0-public")), action=(drop;)
>  ])
>
>  # Delete sw0-p1
> diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at
> index f0d4de1f8..438908335 100644
> --- a/tests/system-ovn-kmod.at
> +++ b/tests/system-ovn-kmod.at
> @@ -598,147 +598,6 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port
> patch-.*/d
>  AT_CLEANUP
>  ])
>
> -OVN_FOR_EACH_NORTHD([
> -AT_SETUP([LB correctly handles fragmented traffic])
> -AT_KEYWORDS([ovnlb])
> -
> -CHECK_CONNTRACK()
> -CHECK_CONNTRACK_NAT()
> -
> -ovn_start
> -OVS_TRAFFIC_VSWITCHD_START()
> -ADD_BR([br-int])
> -ADD_BR([br-ext])
> -
> -# Logical network:
> -# 2 logical switches "public" (192.168.1.0/24) and "internal" (
> 172.16.1.0/24)
> -# connected to a router lr.
> -# internal has a server.
> -# client is connected through localnet.
> -
> -check ovs-ofctl add-flow br-ext action=normal
> -# Set external-ids in br-int needed for ovn-controller
> -check ovs-vsctl \
> -        -- set Open_vSwitch . external-ids:system-id=hv1 \
> -        -- set Open_vSwitch .
> external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> -        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
> -        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
> -        -- set bridge br-int fail-mode=secure
> other-config:disable-in-band=true \
> -        -- set Open_vSwitch .
> external-ids:ovn-bridge-mappings=phynet:br-ext
> -
> -
> -# Start ovn-controller
> -start_daemon ovn-controller
> -
> -check ovn-nbctl lr-add lr
> -check ovn-nbctl ls-add internal
> -check ovn-nbctl ls-add public
> -
> -check ovn-nbctl lrp-add lr lr-pub 00:00:01:01:02:03 192.168.1.1/24
> -check <http://192.168.1.1/24-check> ovn-nbctl lsp-add  public pub-lr --
> set Logical_Switch_Port pub-lr \
> -    type=router options:router-port=lr-pub addresses=\"00:00:01:01:02:03\"
> -
> -check ovn-nbctl lrp-add lr lr-internal 00:00:01:01:02:04 172.16.1.1/24
> -check <http://172.16.1.1/24-check> ovn-nbctl lsp-add internal
> internal-lr -- set Logical_Switch_Port internal-lr \
> -    type=router options:router-port=lr-internal
> addresses=\"00:00:01:01:02:04\"
> -
> -check ovn-nbctl lsp-add public ln_port \
> -                -- lsp-set-addresses ln_port unknown \
> -                -- lsp-set-type ln_port localnet \
> -                -- lsp-set-options ln_port network_name=phynet
> -
> -ADD_NAMESPACES(client)
> -ADD_VETH(client, client, br-ext, "192.168.1.2/24", "f0:00:00:01:02:03", \
> -         "192.168.1.1")
> -NS_EXEC([client], [ip l set dev client mtu 900])
> -
> -ADD_NAMESPACES(server)
> -ADD_VETH(server, server, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \
> -         "172.16.1.1")
> -check ovn-nbctl lsp-add internal server \
> --- lsp-set-addresses server "f0:00:0f:01:02:03 172.16.1.2"
> -
> -check ovn-nbctl set logical_router lr options:chassis=hv1
> -
> -AT_DATA([client.py], [dnl
> -import socket
> -
> -sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> -sock.sendto(b"x" * 1000, ("172.16.1.20", 4242))
> -])
> -
> -test_fragmented_traffic() {
> -    check ovn-nbctl --wait=hv sync
> -
> -    check ovs-appctl dpctl/flush-conntrack
> -
> -    NETNS_DAEMONIZE([server], [nc -l -u 172.16.1.2 4242 > /dev/null],
> [server.pid])
> -
> -    # Collect ICMP packets on client side
> -    NETNS_START_TCPDUMP([client], [-U -i client -vnne udp],
> [tcpdump-client])
> -
> -    # Collect UDP packets on server side
> -    NETNS_START_TCPDUMP([server], [-U -i server -vnne 'udp and ip[[6:2]]
> > 0 and not ip[[6]] = 64'], [tcpdump-server])
> -
> -    NS_CHECK_EXEC([client], [$PYTHON3 ./client.py])
> -    OVS_WAIT_UNTIL([test "$(cat tcpdump-server.tcpdump | wc -l)" = "4"])
> -
> -    kill $(cat tcpdump-client.pid) $(cat tcpdump-server.pid) $(cat
> server.pid)
> -}
> -
> -AS_BOX([LB on router without port and protocol])
> -check ovn-nbctl lb-add lb1 172.16.1.20 172.16.1.2
> -check ovn-nbctl lr-lb-add lr lb1
> -
> -test_fragmented_traffic
> -
> -check ovn-nbctl lr-lb-del lr
> -check ovn-nbctl lb-del lb1
> -
> -AS_BOX([LB on router with port and protocol])
> -check ovn-nbctl lb-add lb1 172.16.1.20:4242 172.16.1.2:4242 udp
> -check ovn-nbctl lr-lb-add lr lb1
> -
> -test_fragmented_traffic
> -
> -check ovn-nbctl lr-lb-del lr
> -check ovn-nbctl lb-del lb1
> -
> -AS_BOX([LB on switch without port and protocol])
> -check ovn-nbctl lb-add lb1 172.16.1.20 172.16.1.2
> -check ovn-nbctl ls-lb-add public lb1
> -
> -test_fragmented_traffic
> -
> -check ovn-nbctl ls-lb-del public
> -check ovn-nbctl lb-del lb1
> -
> -AS_BOX([LB on switch witho port and protocol])
> -check ovn-nbctl lb-add lb1 172.16.1.20:4242 172.16.1.2:4242 udp
> -check ovn-nbctl ls-lb-add public lb1
> -
> -test_fragmented_traffic
> -
> -check ovn-nbctl ls-lb-del public
> -check ovn-nbctl lb-del lb1
> -
> -OVN_CLEANUP_CONTROLLER([hv1])
> -
> -as ovn-sb
> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> -
> -as ovn-nb
> -OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> -
> -as northd
> -OVS_APP_EXIT_AND_WAIT([ovn-northd])
> -
> -as
> -OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
> -/connection dropped.*/d"])
> -AT_CLEANUP
> -])
> -
>  OVN_FOR_EACH_NORTHD([
>  AT_SETUP([SNAT in separate zone from DNAT])
>
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index ac9dedbf3..9de017ed0 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -17808,3 +17808,148 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query
> port patch-.*/d
>
>  AT_CLEANUP
>  ])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([LB correctly handles fragmented traffic])
> +AT_KEYWORDS([ovnlb])
> +
> +CHECK_CONNTRACK()
> +CHECK_CONNTRACK_NAT()
> +
> +ovn_start
> +OVS_TRAFFIC_VSWITCHD_START()
> +ADD_BR([br-int])
> +ADD_BR([br-ext])
> +
> +# Logical network:
> +# 2 logical switches "public" (192.168.1.0/24) and "internal" (
> 172.16.1.0/24)
> +# connected to a router lr.
> +# internal has a server.
> +# client is connected through localnet.
> +
> +check ovs-ofctl add-flow br-ext action=normal
> +# Set external-ids in br-int needed for ovn-controller
> +check ovs-vsctl \
> +        -- set Open_vSwitch . external-ids:system-id=hv1 \
> +        -- set Open_vSwitch .
> external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \
> +        -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \
> +        -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \
> +        -- set bridge br-int fail-mode=secure
> other-config:disable-in-band=true \
> +        -- set Open_vSwitch .
> external-ids:ovn-bridge-mappings=phynet:br-ext
> +
> +
> +# Start ovn-controller
> +start_daemon ovn-controller
> +
> +# Set the minimal fragment size for userspace DP.
> +# Note that this call will fail for system DP as this setting is not
> supported there.
> +ovs-appctl dpctl/ipf-set-min-frag v4 500
> +
> +check ovn-nbctl lr-add lr
> +check ovn-nbctl ls-add internal
> +check ovn-nbctl ls-add public
> +
> +check ovn-nbctl lrp-add lr lr-pub 00:00:01:01:02:03 192.168.1.1/24
> +check ovn-nbctl lsp-add  public pub-lr -- set Logical_Switch_Port pub-lr \
> +    type=router options:router-port=lr-pub addresses=\"00:00:01:01:02:03\"
> +
> +check ovn-nbctl lrp-add lr lr-internal 00:00:01:01:02:04 172.16.1.1/24
> +check ovn-nbctl lsp-add internal internal-lr -- set Logical_Switch_Port
> internal-lr \
> +    type=router options:router-port=lr-internal
> addresses=\"00:00:01:01:02:04\"
> +
> +check ovn-nbctl lsp-add public ln_port \
> +                -- lsp-set-addresses ln_port unknown \
> +                -- lsp-set-type ln_port localnet \
> +                -- lsp-set-options ln_port network_name=phynet
> +
> +ADD_NAMESPACES(client)
> +ADD_VETH(client, client, br-ext, "192.168.1.2/24", "f0:00:00:01:02:03", \
> +         "192.168.1.1")
> +NS_EXEC([client], [ip l set dev client mtu 900])
> +
> +ADD_NAMESPACES(server)
> +ADD_VETH(server, server, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \
> +         "172.16.1.1")
> +check ovn-nbctl lsp-add internal server \
> +-- lsp-set-addresses server "f0:00:0f:01:02:03 172.16.1.2"
> +
> +check ovn-nbctl set logical_router lr options:chassis=hv1
> +
> +AT_DATA([client.py], [dnl
> +import socket
> +
> +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
> +sock.sendto(b"x" * 1000, ("172.16.1.20", 4242))
> +])
> +
> +test_fragmented_traffic() {
> +    check ovn-nbctl --wait=hv sync
> +
> +    check ovs-appctl dpctl/flush-conntrack
> +
> +    NETNS_DAEMONIZE([server], [nc -l -u 172.16.1.2 4242 > /dev/null],
> [server.pid])
> +
> +    # Collect ICMP packets on client side
> +    NETNS_START_TCPDUMP([client], [-U -i client -vnne udp],
> [tcpdump-client])
> +
> +    # Collect UDP packets on server side
> +    NETNS_START_TCPDUMP([server], [-U -i server -vnne 'udp and ip[[6:2]]
> > 0 and not ip[[6]] = 64'], [tcpdump-server])
> +
> +    NS_CHECK_EXEC([client], [$PYTHON3 ./client.py])
> +    OVS_WAIT_UNTIL([test "$(cat tcpdump-server.tcpdump | wc -l)" = "4"])
> +
> +    kill $(cat tcpdump-client.pid) $(cat tcpdump-server.pid) $(cat
> server.pid)
> +}
> +
> +AS_BOX([LB on router without port and protocol])
> +check ovn-nbctl lb-add lb1 172.16.1.20 172.16.1.2
> +check ovn-nbctl lr-lb-add lr lb1
> +
> +test_fragmented_traffic
> +
> +check ovn-nbctl lr-lb-del lr
> +check ovn-nbctl lb-del lb1
> +
> +AS_BOX([LB on router with port and protocol])
> +check ovn-nbctl lb-add lb1 172.16.1.20:4242 172.16.1.2:4242 udp
> +check ovn-nbctl lr-lb-add lr lb1
> +
> +test_fragmented_traffic
> +
> +check ovn-nbctl lr-lb-del lr
> +check ovn-nbctl lb-del lb1
> +
> +AS_BOX([LB on switch without port and protocol])
> +check ovn-nbctl lb-add lb1 172.16.1.20 172.16.1.2
> +check ovn-nbctl ls-lb-add public lb1
> +
> +test_fragmented_traffic
> +
> +check ovn-nbctl ls-lb-del public
> +check ovn-nbctl lb-del lb1
> +
> +AS_BOX([LB on switch witho port and protocol])
> +check ovn-nbctl lb-add lb1 172.16.1.20:4242 172.16.1.2:4242 udp
> +check ovn-nbctl ls-lb-add public lb1
> +
> +test_fragmented_traffic
> +
> +check ovn-nbctl ls-lb-del public
> +check ovn-nbctl lb-del lb1
> +
> +OVN_CLEANUP_CONTROLLER([hv1])
> +
> +as ovn-sb
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +as ovn-nb
> +OVS_APP_EXIT_AND_WAIT([ovsdb-server])
> +
> +as northd
> +OVS_APP_EXIT_AND_WAIT([ovn-northd])
> +
> +as
> +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d
> +/connection dropped.*/d"])
> +AT_CLEANUP
> +])
> --
> 2.49.0
>
>
Thank you Dumitru,

I went ahead and merged this into main.

Regards,
Ales
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to