I noticed some tests failing but I think the ddlog tests look flakey as
I saw other failures without these patches.

I did my best to review the ddlog part but I am not familiar with ddlog

On 12/04/2021 15:41, [email protected] wrote:
> From: Numan Siddique <[email protected]>
> 
> For a load balancer traffic destined to VIP, we do the below actions
> related to conntrack in the ingress logical switch pipeline.
>   1.  Send the packet to conntrack - ct()
>   2a. if ct.new then ct_lb(backends)
>   2b. if ct.est then ct(nat)
> 
> The step 2b is unnecessary and can be removed to avoid another
> recirculation.
> 
> This patch improves this by doing the below.
> 
> For a load balancer traffic destined to VIP, we will now do
>   1.   ct(nat)
>   2a.  if ct.new - ct_lb(backends)
>   2b.  if ct.est, no further action related to conntrack.
> 
> For non load balancer connection traffic, we will now do
>   1.  ct(nat)
>   2a. if ct.new then ct(commit)
>   2b  if ct.est, no further action related to conntrack.
> 
> The same improvement is done for the egress logical switch
> pipeline.  The stages - ls_in_lb and ls_out_lb are removed
> since these stages are no longer needed.
> 
> Signed-off-by: Numan Siddique <[email protected]>
> ---
>  northd/ovn-northd.8.xml | 150 ++++++++++++-----------
>  northd/ovn-northd.c     | 154 +++++++++--------------
>  northd/ovn_northd.dl    | 184 ++++++++++------------------
>  tests/ovn-northd.at     | 265 ++++++++++++++++++++++++++++++----------
>  tests/ovn.at            | 177 ++++++++++++++-------------
>  5 files changed, 495 insertions(+), 435 deletions(-)
> 
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index a62f5c057a..6b295c8e63 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -443,10 +443,11 @@
>        addresses (and ports) are configured in <code>OVN_Northbound</code>
>        database for alogical switch datapath, a priority-100 flow is added

You did not introduce it^ but perhaps you could fix.

s/alogical/a logical

>        with the match <code>ip</code> to match on IP packets and sets the 
> action
> -      <code>reg0[0] = 1; next;</code> to act as a hint for table
> +      <code>reg0[2] = 1; next;</code> to act as a hint for table
>        <code>Pre-stateful</code> to send IP packets to the connection tracker
> -      for packet de-fragmentation before eventually advancing to ingress
> -      table <code>LB</code>.
> +      for packet de-fragmentation (and to possibly do dnat for already

Maybe capitalize to "DNAT" to keep consistent with the rest of the man page
> +      established load balanced traffic) before eventually advancing to 
> ingress
> +      table <code>Stateful</code>.
>        If controller_event has been enabled and load balancing rules with
>        empty backends have been added in <code>OVN_Northbound</code>, a 130 
> flow
>        is added to trigger ovn-controller events whenever the chassis 
> receives a
> @@ -504,11 +505,38 @@
>      <p>
>        This table prepares flows for all possible stateful processing
>        in next tables.  It contains a priority-0 flow that simply moves
> -      traffic to the next table.  A priority-100 flow sends the packets to
> -      connection tracker based on a hint provided by the previous tables
> -      (with a match for <code>reg0[0] == 1</code>) by using the
> -      <code>ct_next;</code> action.
> +      traffic to the next table.
>      </p>
> +    <ul>
> +      <li>
> +        Priority-120 flows that send the packets to connection tracker using
> +        <code>ct_lb;</code> as the action so that the already established
> +        traffic destined to the load balancer VIP gets dnatted based on a 
> hint

DNATted
> +        provided by the previous tables (with a match
> +        for <code>reg0[2] == 1</code> and on supported load balancer 
> protocols
> +        and address families).  For IPv4 traffic the flows also load the
> +        original destination IP and transport port in registers
> +        <code>reg1</code> and <code>reg2</code>.  For IPv6 traffic the flows
> +        also load the original destination IP and transport port in
> +        registers <code>xxreg1</code> and <code>reg2</code>.
> +      </li>
> +
> +      <li>
> +         A priority-110 flow sends the packets to connection tracker based
> +         on a hint provided by the previous tables
> +         (with a match for <code>reg0[2] == 1</code>) by using the
> +         <code>ct_lb;</code> action.  This flow is added to handle
> +         the traffic for load balancer VIPs whose protocol is not defined
> +         (mainly for ICMP traffic).
> +      </li>
> +
> +      <li>
> +         A priority-100 flow sends the packets to connection tracker based
> +         on a hint provided by the previous tables
> +         (with a match for <code>reg0[0] == 1</code>) by using the
> +         <code>ct_next;</code> action.
> +      </li>
> +    </ul>
>  
>      <h3>Ingress Table 8: <code>from-lport</code> ACL hints</h3>
>  
> @@ -743,33 +771,7 @@
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 12: LB</h3>
> -
> -    <p>
> -      It contains a priority-0 flow that simply moves traffic to the next
> -      table.
> -    </p>
> -
> -    <p>
> -      A priority-65535 flow with the match
> -      <code>inport == <var>I</var></code> for all logical switch
> -      datapaths to move traffic to the next table. Where <var>I</var>
> -      is the peer of a logical router port. This flow is added to
> -      skip the connection tracking of packets which enter from
> -      logical router datapath to logical switch datapath.
> -    </p>
> -
> -    <p>
> -      For established connections a priority 65534 flow matches on
> -      <code>ct.est &amp;&amp; !ct.rel &amp;&amp; !ct.new &amp;&amp;
> -      !ct.inv</code> and sets an action <code>reg0[2] = 1; next;</code> to 
> act
> -      as a hint for table <code>Stateful</code> to send packets through
> -      connection tracker to NAT the packets.  (The packet will automatically
> -      get DNATed to the same IP address as the first packet in that
> -      connection.)
> -    </p>
> -
> -    <h3>Ingress Table 13: Stateful</h3>
> +    <h3>Ingress Table 12: Stateful</h3>
>  
>      <ul>
>        <li>
> @@ -826,23 +828,12 @@
>          <code>ct_commit; next;</code> action based on a hint provided by
>          the previous tables (with a match for <code>reg0[1] == 1</code>).
>        </li>
> -      <li>
> -        Priority-100 flows that send the packets to connection tracker using
> -        <code>ct_lb;</code> as the action based on a hint provided by the
> -        previous tables (with a match for <code>reg0[2] == 1</code> and
> -        on supported load balancer protocols and address families).
> -        For IPv4 traffic the flows also load the original destination
> -        IP and transport port in registers <code>reg1</code> and
> -        <code>reg2</code>.  For IPv6 traffic the flows also load the original
> -        destination IP and transport port in registers <code>xxreg1</code> 
> and
> -        <code>reg2</code>.
> -      </li>
>        <li>
>          A priority-0 flow that simply moves traffic to the next table.
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 14: Pre-Hairpin</h3>
> +    <h3>Ingress Table 13: Pre-Hairpin</h3>
>      <ul>
>        <li>
>          If the logical switch has load balancer(s) configured, then a
> @@ -860,7 +851,7 @@
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 15: Nat-Hairpin</h3>
> +    <h3>Ingress Table 14: Nat-Hairpin</h3>
>      <ul>
>        <li>
>           If the logical switch has load balancer(s) configured, then a
> @@ -895,7 +886,7 @@
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 16: Hairpin</h3>
> +    <h3>Ingress Table 15: Hairpin</h3>
>      <ul>
>        <li>
>          A priority-1 flow that hairpins traffic matched by non-default
> @@ -908,7 +899,7 @@
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 17: ARP/ND responder</h3>
> +    <h3>Ingress Table 16: ARP/ND responder</h3>
>  
>      <p>
>        This table implements ARP/ND responder in a logical switch for known
> @@ -1198,7 +1189,7 @@ output;
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 18: DHCP option processing</h3>
> +    <h3>Ingress Table 17: DHCP option processing</h3>
>  
>      <p>
>        This table adds the DHCPv4 options to a DHCPv4 packet from the
> @@ -1259,7 +1250,7 @@ next;
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 19: DHCP responses</h3>
> +    <h3>Ingress Table 18: DHCP responses</h3>
>  
>      <p>
>        This table implements DHCP responder for the DHCP replies generated by
> @@ -1340,7 +1331,7 @@ output;
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 20 DNS Lookup</h3>
> +    <h3>Ingress Table 19 DNS Lookup</h3>
>  
>      <p>
>        This table looks up and resolves the DNS names to the corresponding
> @@ -1369,7 +1360,7 @@ reg0[4] = dns_lookup(); next;
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 21 DNS Responses</h3>
> +    <h3>Ingress Table 20 DNS Responses</h3>
>  
>      <p>
>        This table implements DNS responder for the DNS replies generated by
> @@ -1404,7 +1395,7 @@ output;
>        </li>
>      </ul>
>  
> -    <h3>Ingress table 22 External ports</h3>
> +    <h3>Ingress table 21 External ports</h3>
>  
>      <p>
>        Traffic from the <code>external</code> logical ports enter the ingress
> @@ -1447,7 +1438,7 @@ output;
>        </li>
>      </ul>
>  
> -    <h3>Ingress Table 23 Destination Lookup</h3>
> +    <h3>Ingress Table 22 Destination Lookup</h3>
>  
>      <p>
>        This table implements switching behavior.  It contains these logical
> @@ -1673,9 +1664,11 @@ output;
>        Moreover it contains a priority-110 flow to move IPv6 Neighbor 
> Discovery
>        traffic to the next table. If any load balancing rules exist for the
>        datapath, a priority-100 flow is added with a match of <code>ip</code>
> -      and action of <code>reg0[0] = 1; next;</code> to act as a hint for
> +      and action of <code>reg0[2] = 1; next;</code> to act as a hint for
>        table <code>Pre-stateful</code> to send IP packets to the connection
> -      tracker for packet de-fragmentation.
> +      tracker for packet de-fragmentation and possibly dnat the destination

Maybe DNAT
> +      VIP to one of the selected backend for already commited load balanced
> +      traffic.
>      </p>
>  
>      <p>
> @@ -1717,20 +1710,39 @@ output;
>      <h3>Egress Table 2: Pre-stateful</h3>
>  
>      <p>
> -      This is similar to ingress table <code>Pre-stateful</code>.
> +      This is similar to ingress table <code>Pre-stateful</code>.  This table
> +      adds the below 3 logical flows.
>      </p>
>  
> -    <h3>Egress Table 3: LB</h3>
> -    <p>
> -      This is similar to ingress table <code>LB</code>.
> -    </p>
> +    <ul>
> +      <li>
> +        A Priority-120 flow that send the packets to connection tracker using
> +        <code>ct_lb;</code> as the action so that the already established
> +        traffic gets undnatted from the backend IP to the load balancer VIP

I see "unDNATted" as the spelling elsewhere. Maybe you could change to
keep consistent.

> +        based on a hint provided by the previous tables with a match
> +        for <code>reg0[2] == 1</code>.  If the packet was not dnatted 
> earlier,

Maybe DNATted
> +        then <code>ct_lb</code> functions like <code>ct_next</code>.
> +      </li>
> +
> +      <li>
> +        A priority-100 flow sends the packets to connection tracker based
> +        on a hint provided by the previous tables
> +        (with a match for <code>reg0[0] == 1</code>) by using the
> +        <code>ct_next;</code> action.
> +      </li>
> +
> +      <li>
> +        A priority-0 flow that matches all packets to advance to the next
> +        table.
> +      </li>
> +    </ul>
>  
> -    <h3>Egress Table 4: <code>from-lport</code> ACL hints</h3>
> +    <h3>Egress Table 3: <code>from-lport</code> ACL hints</h3>
>      <p>
>        This is similar to ingress table <code>ACL hints</code>.
>      </p>
>  
> -    <h3>Egress Table 5: <code>to-lport</code> ACLs</h3>
> +    <h3>Egress Table 4: <code>to-lport</code> ACLs</h3>
>  
>      <p>
>        This is similar to ingress table <code>ACLs</code> except for
> @@ -1767,28 +1779,28 @@ output;
>        </li>
>      </ul>
>  
> -    <h3>Egress Table 6: <code>to-lport</code> QoS Marking</h3>
> +    <h3>Egress Table 5: <code>to-lport</code> QoS Marking</h3>
>  
>      <p>
>        This is similar to ingress table <code>QoS marking</code> except
>        they apply to <code>to-lport</code> QoS rules.
>      </p>
>  
> -    <h3>Egress Table 7: <code>to-lport</code> QoS Meter</h3>
> +    <h3>Egress Table 6: <code>to-lport</code> QoS Meter</h3>
>  
>      <p>
>        This is similar to ingress table <code>QoS meter</code> except
>        they apply to <code>to-lport</code> QoS rules.
>      </p>
>  
> -    <h3>Egress Table 8: Stateful</h3>
> +    <h3>Egress Table 7: Stateful</h3>
>  
>      <p>
>        This is similar to ingress table <code>Stateful</code> except that
>        there are no rules added for load balancing new connections.
>      </p>
>  
> -    <h3>Egress Table 9: Egress Port Security - IP</h3>
> +    <h3>Egress Table 8: Egress Port Security - IP</h3>
>  
>      <p>
>        This is similar to the port security logic in table
> @@ -1798,7 +1810,7 @@ output;
>        <code>ip4.src</code> and <code>ip6.src</code>
>      </p>
>  
> -    <h3>Egress Table 10: Egress Port Security - L2</h3>
> +    <h3>Egress Table 9: Egress Port Security - L2</h3>
>  
>      <p>
>        This is similar to the ingress port security logic in ingress table
> diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
> index 9839b8c4f5..637d3a10a9 100644
> --- a/northd/ovn-northd.c
> +++ b/northd/ovn-northd.c
> @@ -147,32 +147,30 @@ enum ovn_stage {
>      PIPELINE_STAGE(SWITCH, IN,  ACL,            9, "ls_in_acl")           \
>      PIPELINE_STAGE(SWITCH, IN,  QOS_MARK,      10, "ls_in_qos_mark")      \
>      PIPELINE_STAGE(SWITCH, IN,  QOS_METER,     11, "ls_in_qos_meter")     \
> -    PIPELINE_STAGE(SWITCH, IN,  LB,            12, "ls_in_lb")            \
> -    PIPELINE_STAGE(SWITCH, IN,  STATEFUL,      13, "ls_in_stateful")      \
> -    PIPELINE_STAGE(SWITCH, IN,  PRE_HAIRPIN,   14, "ls_in_pre_hairpin")   \
> -    PIPELINE_STAGE(SWITCH, IN,  NAT_HAIRPIN,   15, "ls_in_nat_hairpin")   \
> -    PIPELINE_STAGE(SWITCH, IN,  HAIRPIN,       16, "ls_in_hairpin")       \
> -    PIPELINE_STAGE(SWITCH, IN,  ARP_ND_RSP,    17, "ls_in_arp_rsp")       \
> -    PIPELINE_STAGE(SWITCH, IN,  DHCP_OPTIONS,  18, "ls_in_dhcp_options")  \
> -    PIPELINE_STAGE(SWITCH, IN,  DHCP_RESPONSE, 19, "ls_in_dhcp_response") \
> -    PIPELINE_STAGE(SWITCH, IN,  DNS_LOOKUP,    20, "ls_in_dns_lookup")    \
> -    PIPELINE_STAGE(SWITCH, IN,  DNS_RESPONSE,  21, "ls_in_dns_response")  \
> -    PIPELINE_STAGE(SWITCH, IN,  EXTERNAL_PORT, 22, "ls_in_external_port") \
> -    PIPELINE_STAGE(SWITCH, IN,  L2_LKUP,       23, "ls_in_l2_lkup")       \
> -    PIPELINE_STAGE(SWITCH, IN,  L2_UNKNOWN,    24, "ls_in_l2_unknown")    \
> +    PIPELINE_STAGE(SWITCH, IN,  STATEFUL,      12, "ls_in_stateful")      \
> +    PIPELINE_STAGE(SWITCH, IN,  PRE_HAIRPIN,   13, "ls_in_pre_hairpin")   \
> +    PIPELINE_STAGE(SWITCH, IN,  NAT_HAIRPIN,   14, "ls_in_nat_hairpin")   \
> +    PIPELINE_STAGE(SWITCH, IN,  HAIRPIN,       15, "ls_in_hairpin")       \
> +    PIPELINE_STAGE(SWITCH, IN,  ARP_ND_RSP,    16, "ls_in_arp_rsp")       \
> +    PIPELINE_STAGE(SWITCH, IN,  DHCP_OPTIONS,  17, "ls_in_dhcp_options")  \
> +    PIPELINE_STAGE(SWITCH, IN,  DHCP_RESPONSE, 18, "ls_in_dhcp_response") \
> +    PIPELINE_STAGE(SWITCH, IN,  DNS_LOOKUP,    19, "ls_in_dns_lookup")    \
> +    PIPELINE_STAGE(SWITCH, IN,  DNS_RESPONSE,  20, "ls_in_dns_response")  \
> +    PIPELINE_STAGE(SWITCH, IN,  EXTERNAL_PORT, 21, "ls_in_external_port") \
> +    PIPELINE_STAGE(SWITCH, IN,  L2_LKUP,       22, "ls_in_l2_lkup")       \
> +    PIPELINE_STAGE(SWITCH, IN,  L2_UNKNOWN,    23, "ls_in_l2_unknown")    \
>                                                                            \
>      /* Logical switch egress stages. */                                   \
>      PIPELINE_STAGE(SWITCH, OUT, PRE_LB,       0, "ls_out_pre_lb")         \
>      PIPELINE_STAGE(SWITCH, OUT, PRE_ACL,      1, "ls_out_pre_acl")        \
>      PIPELINE_STAGE(SWITCH, OUT, PRE_STATEFUL, 2, "ls_out_pre_stateful")   \
> -    PIPELINE_STAGE(SWITCH, OUT, LB,           3, "ls_out_lb")             \
> -    PIPELINE_STAGE(SWITCH, OUT, ACL_HINT,     4, "ls_out_acl_hint")       \
> -    PIPELINE_STAGE(SWITCH, OUT, ACL,          5, "ls_out_acl")            \
> -    PIPELINE_STAGE(SWITCH, OUT, QOS_MARK,     6, "ls_out_qos_mark")       \
> -    PIPELINE_STAGE(SWITCH, OUT, QOS_METER,    7, "ls_out_qos_meter")      \
> -    PIPELINE_STAGE(SWITCH, OUT, STATEFUL,     8, "ls_out_stateful")       \
> -    PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_IP,  9, "ls_out_port_sec_ip")    \
> -    PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_L2, 10, "ls_out_port_sec_l2")    \
> +    PIPELINE_STAGE(SWITCH, OUT, ACL_HINT,     3, "ls_out_acl_hint")       \
> +    PIPELINE_STAGE(SWITCH, OUT, ACL,          4, "ls_out_acl")            \
> +    PIPELINE_STAGE(SWITCH, OUT, QOS_MARK,     5, "ls_out_qos_mark")       \
> +    PIPELINE_STAGE(SWITCH, OUT, QOS_METER,    6, "ls_out_qos_meter")      \
> +    PIPELINE_STAGE(SWITCH, OUT, STATEFUL,     7, "ls_out_stateful")       \
> +    PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_IP,  8, "ls_out_port_sec_ip")    \
> +    PIPELINE_STAGE(SWITCH, OUT, PORT_SEC_L2,  9, "ls_out_port_sec_l2")    \
>                                                                        \
>      /* Logical router ingress stages. */                              \
>      PIPELINE_STAGE(ROUTER, IN,  ADMISSION,       0, "lr_in_admission")    \
> @@ -5159,9 +5157,9 @@ build_pre_lb(struct ovn_datapath *od, struct hmap 
> *lflows,
>       */>      if (vip_configured) {
>          ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_LB,
> -                      100, "ip", REGBIT_CONNTRACK_DEFRAG" = 1; next;");
> +                      100, "ip", REGBIT_CONNTRACK_NAT" = 1; next;");
>          ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_LB,
> -                      100, "ip", REGBIT_CONNTRACK_DEFRAG" = 1; next;");
> +                      100, "ip", REGBIT_CONNTRACK_NAT" = 1; next;");
>      }

The comment above this that describes this code^ needs to be changed.
>  }
>  
> @@ -5173,10 +5171,46 @@ build_pre_stateful(struct ovn_datapath *od, struct 
> hmap *lflows)
>      ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 0, "1", "next;");
>      ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 0, "1", "next;");
>  
> +    const char *lb_protocols[] = {"tcp", "udp", "sctp"};
> +    struct ds actions = DS_EMPTY_INITIALIZER;
> +    struct ds match = DS_EMPTY_INITIALIZER;
> +
> +    for (size_t i = 0; i < ARRAY_SIZE(lb_protocols); i++) {
> +        ds_clear(&match);
> +        ds_clear(&actions);
> +        ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip4 && %s",
> +                      lb_protocols[i]);
> +        ds_put_format(&actions, REG_ORIG_DIP_IPV4 " = ip4.dst; "
> +                                REG_ORIG_TP_DPORT " = %s.dst; ct_lb;",
> +                      lb_protocols[i]);
> +        ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120,
> +                      ds_cstr(&match), ds_cstr(&actions));
> +
> +        ds_clear(&match);
> +        ds_clear(&actions);
> +        ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip6 && %s",
> +                      lb_protocols[i]);
> +        ds_put_format(&actions, REG_ORIG_DIP_IPV6 " = ip6.dst; "
> +                                REG_ORIG_TP_DPORT " = %s.dst; ct_lb;",
> +                      lb_protocols[i]);
> +        ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120,
> +                      ds_cstr(&match), ds_cstr(&actions));
> +    }
> +
> +    ds_destroy(&actions);
> +    ds_destroy(&match);
> +
> +    ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 110,
> +                  REGBIT_CONNTRACK_NAT" == 1", "ct_lb;");
> +
> +    ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 110,
> +                  REGBIT_CONNTRACK_NAT" == 1", "ct_lb;");
> +
>      /* If REGBIT_CONNTRACK_DEFRAG is set as 1, then the packets should be
>       * sent to conntrack for tracking and defragmentation. */
>      ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 100,
>                    REGBIT_CONNTRACK_DEFRAG" == 1", "ct_next;");
> +>      ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 100,
>                    REGBIT_CONNTRACK_DEFRAG" == 1", "ct_next;");
>  }
> @@ -5856,37 +5890,6 @@ build_qos(struct ovn_datapath *od, struct hmap 
> *lflows) {
>      }
>  }
>  
> -static void
> -build_lb(struct ovn_datapath *od, struct hmap *lflows)
> -{
> -    /* Ingress and Egress LB Table (Priority 0): Packets are allowed by
> -     * default.  */
> -    ovn_lflow_add(lflows, od, S_SWITCH_IN_LB, 0, "1", "next;");
> -    ovn_lflow_add(lflows, od, S_SWITCH_OUT_LB, 0, "1", "next;");
> -
> -    if (od->nbs->n_load_balancer) {
> -        for (size_t i = 0; i < od->n_router_ports; i++) {
> -            skip_port_from_conntrack(od, od->router_ports[i],
> -                                     S_SWITCH_IN_LB, S_SWITCH_OUT_LB,
> -                                     UINT16_MAX, lflows);
> -        }
> -    }
> -
> -    if (od->has_lb_vip) {
> -        /* Ingress and Egress LB Table (Priority 65534).
> -         *
> -         * Send established traffic through conntrack for just NAT. */
> -        ovn_lflow_add(lflows, od, S_SWITCH_IN_LB, UINT16_MAX - 1,
> -                      "ct.est && !ct.rel && !ct.new && !ct.inv && "
> -                      "ct_label.natted == 1",
> -                      REGBIT_CONNTRACK_NAT" = 1; next;");
> -        ovn_lflow_add(lflows, od, S_SWITCH_OUT_LB, UINT16_MAX - 1,
> -                      "ct.est && !ct.rel && !ct.new && !ct.inv && "
> -                      "ct_label.natted == 1",
> -                      REGBIT_CONNTRACK_NAT" = 1; next;");
> -    }
> -}
> -
>  static void
>  build_lb_rules(struct ovn_datapath *od, struct hmap *lflows,
>                 struct ovn_northd_lb *lb)
> @@ -5971,48 +5974,6 @@ build_stateful(struct ovn_datapath *od, struct hmap 
> *lflows, struct hmap *lbs)
>                    REGBIT_CONNTRACK_COMMIT" == 1",
>                    "ct_commit { ct_label.blocked = 0; }; next;");
>  
> -    /* If REGBIT_CONNTRACK_NAT is set as 1, then packets should just be sent
> -     * through nat (without committing).
> -     *
> -     * REGBIT_CONNTRACK_COMMIT is set for new connections and
> -     * REGBIT_CONNTRACK_NAT is set for established connections. So they
> -     * don't overlap.
> -     *
> -     * In the ingress pipeline, also store the original destination IP and
> -     * transport port to be used when detecting hairpin packets.
> -     */
> -    const char *lb_protocols[] = {"tcp", "udp", "sctp"};
> -    struct ds actions = DS_EMPTY_INITIALIZER;
> -    struct ds match = DS_EMPTY_INITIALIZER;
> -
> -    for (size_t i = 0; i < ARRAY_SIZE(lb_protocols); i++) {
> -        ds_clear(&match);
> -        ds_clear(&actions);
> -        ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip4 && %s",
> -                      lb_protocols[i]);
> -        ds_put_format(&actions, REG_ORIG_DIP_IPV4 " = ip4.dst; "
> -                                REG_ORIG_TP_DPORT " = %s.dst; ct_lb;",
> -                      lb_protocols[i]);
> -        ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
> -                      ds_cstr(&match), ds_cstr(&actions));
> -
> -        ds_clear(&match);
> -        ds_clear(&actions);
> -        ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip6 && %s",
> -                      lb_protocols[i]);
> -        ds_put_format(&actions, REG_ORIG_DIP_IPV6 " = ip6.dst; "
> -                                REG_ORIG_TP_DPORT " = %s.dst; ct_lb;",
> -                      lb_protocols[i]);
> -        ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
> -                      ds_cstr(&match), ds_cstr(&actions));
> -    }
> -
> -    ds_destroy(&actions);
> -    ds_destroy(&match);
> -
> -    ovn_lflow_add(lflows, od, S_SWITCH_OUT_STATEFUL, 100,
> -                  REGBIT_CONNTRACK_NAT" == 1", "ct_lb;");
> -
>      /* Load balancing rules for new connections get committed to conntrack
>       * table.  So even if REGBIT_CONNTRACK_COMMIT is set in a previous table
>       * a higher priority rule for load balancing below also commits the
> @@ -6803,7 +6764,6 @@ build_lswitch_lflows_pre_acl_and_acl(struct 
> ovn_datapath *od,

I think the comment above this function is wrong now as it references
table numbers.

>          build_acl_hints(od, lflows);
>          build_acls(od, lflows, port_groups, meter_groups);
>          build_qos(od, lflows);
> -        build_lb(od, lflows);
>          build_stateful(od, lflows, lbs);
>          build_lb_hairpin(od, lflows);
>      }
> diff --git a/northd/ovn_northd.dl b/northd/ovn_northd.dl
> index 0063021e13..2c0796938c 100644
> --- a/northd/ovn_northd.dl
> +++ b/northd/ovn_northd.dl
> @@ -1398,32 +1398,30 @@ function s_SWITCH_IN_ACL_HINT():        Stage { 
> Stage{Ingress,  8, "ls_in_acl_hi
>  function s_SWITCH_IN_ACL():             Stage { Stage{Ingress,  9, 
> "ls_in_acl"} }
>  function s_SWITCH_IN_QOS_MARK():        Stage { Stage{Ingress, 10, 
> "ls_in_qos_mark"} }
>  function s_SWITCH_IN_QOS_METER():       Stage { Stage{Ingress, 11, 
> "ls_in_qos_meter"} }
> -function s_SWITCH_IN_LB():              Stage { Stage{Ingress, 12, 
> "ls_in_lb"} }
> -function s_SWITCH_IN_STATEFUL():        Stage { Stage{Ingress, 13, 
> "ls_in_stateful"} }
> -function s_SWITCH_IN_PRE_HAIRPIN():     Stage { Stage{Ingress, 14, 
> "ls_in_pre_hairpin"} }
> -function s_SWITCH_IN_NAT_HAIRPIN():     Stage { Stage{Ingress, 15, 
> "ls_in_nat_hairpin"} }
> -function s_SWITCH_IN_HAIRPIN():         Stage { Stage{Ingress, 16, 
> "ls_in_hairpin"} }
> -function s_SWITCH_IN_ARP_ND_RSP():      Stage { Stage{Ingress, 17, 
> "ls_in_arp_rsp"} }
> -function s_SWITCH_IN_DHCP_OPTIONS():    Stage { Stage{Ingress, 18, 
> "ls_in_dhcp_options"} }
> -function s_SWITCH_IN_DHCP_RESPONSE():   Stage { Stage{Ingress, 19, 
> "ls_in_dhcp_response"} }
> -function s_SWITCH_IN_DNS_LOOKUP():      Stage { Stage{Ingress, 20, 
> "ls_in_dns_lookup"} }
> -function s_SWITCH_IN_DNS_RESPONSE():    Stage { Stage{Ingress, 21, 
> "ls_in_dns_response"} }
> -function s_SWITCH_IN_EXTERNAL_PORT():   Stage { Stage{Ingress, 22, 
> "ls_in_external_port"} }
> -function s_SWITCH_IN_L2_LKUP():         Stage { Stage{Ingress, 23, 
> "ls_in_l2_lkup"} }
> -function s_SWITCH_IN_L2_UNKNOWN():      Stage { Stage{Ingress, 24, 
> "ls_in_l2_unknown"} }
> +function s_SWITCH_IN_STATEFUL():        Stage { Stage{Ingress, 12, 
> "ls_in_stateful"} }
> +function s_SWITCH_IN_PRE_HAIRPIN():     Stage { Stage{Ingress, 13, 
> "ls_in_pre_hairpin"} }
> +function s_SWITCH_IN_NAT_HAIRPIN():     Stage { Stage{Ingress, 14, 
> "ls_in_nat_hairpin"} }
> +function s_SWITCH_IN_HAIRPIN():         Stage { Stage{Ingress, 15, 
> "ls_in_hairpin"} }
> +function s_SWITCH_IN_ARP_ND_RSP():      Stage { Stage{Ingress, 16, 
> "ls_in_arp_rsp"} }
> +function s_SWITCH_IN_DHCP_OPTIONS():    Stage { Stage{Ingress, 17, 
> "ls_in_dhcp_options"} }
> +function s_SWITCH_IN_DHCP_RESPONSE():   Stage { Stage{Ingress, 18, 
> "ls_in_dhcp_response"} }
> +function s_SWITCH_IN_DNS_LOOKUP():      Stage { Stage{Ingress, 19, 
> "ls_in_dns_lookup"} }
> +function s_SWITCH_IN_DNS_RESPONSE():    Stage { Stage{Ingress, 20, 
> "ls_in_dns_response"} }
> +function s_SWITCH_IN_EXTERNAL_PORT():   Stage { Stage{Ingress, 21, 
> "ls_in_external_port"} }
> +function s_SWITCH_IN_L2_LKUP():         Stage { Stage{Ingress, 22, 
> "ls_in_l2_lkup"} }
> +function s_SWITCH_IN_L2_UNKNOWN():      Stage { Stage{Ingress, 23, 
> "ls_in_l2_unknown"} }
>  
>  /* Logical switch egress stages. */
>  function s_SWITCH_OUT_PRE_LB():         Stage { Stage{ Egress,  0, 
> "ls_out_pre_lb"} }
>  function s_SWITCH_OUT_PRE_ACL():        Stage { Stage{ Egress,  1, 
> "ls_out_pre_acl"} }
>  function s_SWITCH_OUT_PRE_STATEFUL():   Stage { Stage{ Egress,  2, 
> "ls_out_pre_stateful"} }
> -function s_SWITCH_OUT_LB():             Stage { Stage{ Egress,  3, 
> "ls_out_lb"} }
> -function s_SWITCH_OUT_ACL_HINT():       Stage { Stage{ Egress,  4, 
> "ls_out_acl_hint"} }
> -function s_SWITCH_OUT_ACL():            Stage { Stage{ Egress,  5, 
> "ls_out_acl"} }
> -function s_SWITCH_OUT_QOS_MARK():       Stage { Stage{ Egress,  6, 
> "ls_out_qos_mark"} }
> -function s_SWITCH_OUT_QOS_METER():      Stage { Stage{ Egress,  7, 
> "ls_out_qos_meter"} }
> -function s_SWITCH_OUT_STATEFUL():       Stage { Stage{ Egress,  8, 
> "ls_out_stateful"} }
> -function s_SWITCH_OUT_PORT_SEC_IP():    Stage { Stage{ Egress,  9, 
> "ls_out_port_sec_ip"} }
> -function s_SWITCH_OUT_PORT_SEC_L2():    Stage { Stage{ Egress, 10, 
> "ls_out_port_sec_l2"} }
> +function s_SWITCH_OUT_ACL_HINT():       Stage { Stage{ Egress,  3, 
> "ls_out_acl_hint"} }
> +function s_SWITCH_OUT_ACL():            Stage { Stage{ Egress,  4, 
> "ls_out_acl"} }
> +function s_SWITCH_OUT_QOS_MARK():       Stage { Stage{ Egress,  5, 
> "ls_out_qos_mark"} }
> +function s_SWITCH_OUT_QOS_METER():      Stage { Stage{ Egress,  6, 
> "ls_out_qos_meter"} }
> +function s_SWITCH_OUT_STATEFUL():       Stage { Stage{ Egress,  7, 
> "ls_out_stateful"} }
> +function s_SWITCH_OUT_PORT_SEC_IP():    Stage { Stage{ Egress,  8, 
> "ls_out_port_sec_ip"} }
> +function s_SWITCH_OUT_PORT_SEC_L2():    Stage { Stage{ Egress,  9, 
> "ls_out_port_sec_l2"} }
>  
>  /* Logical router ingress stages. */
>  function s_ROUTER_IN_ADMISSION():       Stage { Stage{Ingress,  0, 
> "lr_in_admission"} }
> @@ -2049,7 +2047,7 @@ Flow(.logical_datapath = sw.ls._uuid,
>      Some {(var __match, var __action)} = build_empty_lb_event_flow(
>          vip, lb, has_elb_meter).
>  
> -/* 'REGBIT_CONNTRACK_DEFRAG' is set to let the pre-stateful table send
> +/* 'rEGBIT_CONNTRACK_NAT' is set to let the pre-stateful table send>   * 
> packet to conntrack for defragmentation.
>   *
>   * Send all the packets to conntrack in the ingress pipeline if the
> @@ -2083,17 +2081,21 @@ for (sw in &Switch(.has_lb_vip = true)) {
>           .stage            = s_SWITCH_IN_PRE_LB(),
>           .priority         = 100,
>           .__match          = "ip",
> -         .actions          = "${rEGBIT_CONNTRACK_DEFRAG()} = 1; next;",
> +         .actions          = "${rEGBIT_CONNTRACK_NAT()} = 1; next;",
>           .external_ids     = map_empty());
>      Flow(.logical_datapath = sw.ls._uuid,
>           .stage            = s_SWITCH_OUT_PRE_LB(),
>           .priority         = 100,
>           .__match          = "ip",
> -         .actions          = "${rEGBIT_CONNTRACK_DEFRAG()} = 1; next;",
> +         .actions          = "${rEGBIT_CONNTRACK_NAT()} = 1; next;",
>           .external_ids     = map_empty())
>  }
>  
>  /* Pre-stateful */
> +relation LbProtocol[string]
> +LbProtocol["tcp"].
> +LbProtocol["udp"].
> +LbProtocol["sctp"].
>  for (&Switch(.ls = ls)) {
>      /* Ingress and Egress pre-stateful Table (Priority 0): Packets are
>       * allowed by default. */
> @@ -2110,6 +2112,47 @@ for (&Switch(.ls = ls)) {
>           .actions          = "next;",
>           .external_ids     = map_empty());
>  
> +    /* If REGBIT_CONNTRACK_NAT is set as 1, then packets should just be sent

should be rEGBIT? and below?
> +     * through nat (without committing).
> +     *
> +     * REGBIT_CONNTRACK_COMMIT is set for new connections and
> +     * REGBIT_CONNTRACK_NAT is set for established connections. So they
> +     * don't overlap.
> +     *
> +     * In the ingress pipeline, also store the original destination IP and
> +     * transport port to be used when detecting hairpin packets.
> +     */
> +    for (LbProtocol[protocol]) {
> +        Flow(.logical_datapath = ls._uuid,
> +             .stage            = s_SWITCH_IN_PRE_STATEFUL(),
> +             .priority         = 120,
> +             .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1 && ip4 && 
> ${protocol}",
> +             .actions          = "${rEG_ORIG_DIP_IPV4()} = ip4.dst; "
> +                                 "${rEG_ORIG_TP_DPORT()} = ${protocol}.dst; 
> ct_lb;",
> +             .external_ids     = map_empty());
> +        Flow(.logical_datapath = ls._uuid,
> +             .stage            = s_SWITCH_IN_PRE_STATEFUL(),
> +             .priority         = 120,
> +             .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1 && ip6 && 
> ${protocol}",
> +             .actions          = "${rEG_ORIG_DIP_IPV6()} = ip6.dst; "
> +                                 "${rEG_ORIG_TP_DPORT()} = ${protocol}.dst; 
> ct_lb;",
> +             .external_ids     = map_empty())
> +    };
> +
> +    Flow(.logical_datapath = ls._uuid,
> +         .stage            = s_SWITCH_IN_PRE_STATEFUL(),
> +         .priority         = 110,
> +         .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1",
> +         .actions          = "ct_lb;",
> +         .external_ids     = map_empty());
> +
> +    Flow(.logical_datapath = ls._uuid,
> +         .stage            = s_SWITCH_OUT_PRE_STATEFUL(),
> +         .priority         = 110,
> +         .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1",
> +         .actions          = "ct_lb;",
> +         .external_ids     = map_empty());
> +
>      /* If REGBIT_CONNTRACK_DEFRAG is set as 1, then the packets should be
>       * sent to conntrack for tracking and defragmentation. */
>      Flow(.logical_datapath = ls._uuid,
> @@ -2723,66 +2766,7 @@ for (SwitchQoS(.sw = &sw, .qos = &qos)) {
>      }
>  }
>  
> -/* LB rules */
> -for (&Switch(.ls = ls, .has_lb_vip = has_lb_vip)) {
> -    /* Ingress and Egress LB Table (Priority 0): Packets are allowed by
> -     * default.  */
> -    Flow(.logical_datapath = ls._uuid,
> -         .stage            = s_SWITCH_IN_LB(),
> -         .priority         = 0,
> -         .__match          = "1",
> -         .actions          = "next;",
> -         .external_ids     = map_empty());
> -    Flow(.logical_datapath = ls._uuid,
> -         .stage            = s_SWITCH_OUT_LB(),
> -         .priority         = 0,
> -         .__match          = "1",
> -         .actions          = "next;",
> -         .external_ids     = map_empty());
> -
> -    if (not ls.load_balancer.is_empty()) {
> -        for (&SwitchPort(.lsp = lsp@nb::Logical_Switch_Port{.__type = 
> "router"},
> -                         .json_name = lsp_name,
> -                         .sw = &Switch{.ls = ls})) {
> -            Flow(.logical_datapath = ls._uuid,
> -                 .stage            = s_SWITCH_IN_LB(),
> -                 .priority         = 65535,
> -                 .__match          = "ip && inport == ${lsp_name}",
> -                 .actions          = "next;",
> -                 .external_ids     = stage_hint(lsp._uuid));
> -            Flow(.logical_datapath = ls._uuid,
> -                 .stage            = s_SWITCH_OUT_LB(),
> -                 .priority         = 65535,
> -                 .__match          = "ip && outport == ${lsp_name}",
> -                 .actions          = "next;",
> -                 .external_ids     = stage_hint(lsp._uuid))
> -        }
> -    };
> -
> -    if (has_lb_vip) {
> -        /* Ingress and Egress LB Table (Priority 65534).
> -         *
> -         * Send established traffic through conntrack for just NAT. */
> -        Flow(.logical_datapath = ls._uuid,
> -             .stage            = s_SWITCH_IN_LB(),
> -             .priority         = 65534,
> -             .__match          = "ct.est && !ct.rel && !ct.new && !ct.inv && 
> ct_label.natted == 1",
> -             .actions          = "${rEGBIT_CONNTRACK_NAT()} = 1; next;",
> -             .external_ids     = map_empty());
> -        Flow(.logical_datapath = ls._uuid,
> -             .stage            = s_SWITCH_OUT_LB(),
> -             .priority         = 65534,
> -             .__match          = "ct.est && !ct.rel && !ct.new && !ct.inv && 
> ct_label.natted == 1",
> -             .actions          = "${rEGBIT_CONNTRACK_NAT()} = 1; next;",
> -             .external_ids     = map_empty())
> -    }
> -}
> -
>  /* stateful rules */
> -relation LbProtocol[string]
> -LbProtocol["tcp"].
> -LbProtocol["udp"].
> -LbProtocol["sctp"].
>  for (&Switch(.ls = ls)) {
>      /* Ingress and Egress stateful Table (Priority 0): Packets are
>       * allowed by default. */
> @@ -2814,40 +2798,6 @@ for (&Switch(.ls = ls)) {
>           .priority         = 100,
>           .__match          = "${rEGBIT_CONNTRACK_COMMIT()} == 1",
>           .actions          = "ct_commit { ct_label.blocked = 0; }; next;",
> -         .external_ids     = map_empty());
> -
> -    /* If REGBIT_CONNTRACK_NAT is set as 1, then packets should just be sent
> -     * through nat (without committing).
> -     *
> -     * REGBIT_CONNTRACK_COMMIT is set for new connections and
> -     * REGBIT_CONNTRACK_NAT is set for established connections. So they
> -     * don't overlap.
> -     *
> -     * In the ingress pipeline, also store the original destination IP and
> -     * transport port to be used when detecting hairpin packets.
> -     */
> -    for (LbProtocol[protocol]) {
> -        Flow(.logical_datapath = ls._uuid,
> -             .stage            = s_SWITCH_IN_STATEFUL(),
> -             .priority         = 100,
> -             .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1 && ip4 && 
> ${protocol}",
> -             .actions          = "${rEG_ORIG_DIP_IPV4()} = ip4.dst; "
> -                                 "${rEG_ORIG_TP_DPORT()} = ${protocol}.dst; 
> ct_lb;",
> -             .external_ids     = map_empty());
> -        Flow(.logical_datapath = ls._uuid,
> -             .stage            = s_SWITCH_IN_STATEFUL(),
> -             .priority         = 100,
> -             .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1 && ip6 && 
> ${protocol}",
> -             .actions          = "${rEG_ORIG_DIP_IPV6()} = ip6.dst; "
> -                                 "${rEG_ORIG_TP_DPORT()} = ${protocol}.dst; 
> ct_lb;",
> -             .external_ids     = map_empty())
> -    };
> -
> -    Flow(.logical_datapath = ls._uuid,
> -         .stage            = s_SWITCH_OUT_STATEFUL(),
> -         .priority         = 100,
> -         .__match          = "${rEGBIT_CONNTRACK_NAT()} == 1",
> -         .actions          = "ct_lb;",
>           .external_ids     = map_empty())
>  }
>  
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 96476497df..32b092bcd9 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -1201,7 +1201,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.*ct_lb' | sed 
> 's/table=..//'], 0, [dnl
> +  [ovn-sbctl dump-flows sw0 | tee sbflows | grep 'priority=120.*backends' | 
> sed 's/table=..//'], 0, [dnl
I presume the change s/ct_lb/backends is because you now have multiple
"ct_lb" actions in the "ls_in_stateful" table?
>    (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>  
> @@ -1211,7 +1211,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.*ct_lb' | 
> sed 's/table=..//'], [0],
> +  [ovn-sbctl dump-flows sw0 | tee sbflows2 | grep 'priority=120.*backends' | 
> sed 's/table=..//'], [0],
>  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>  
> @@ -1222,7 +1222,7 @@ health_check @hc
>  wait_row_count Service_Monitor 2
>  check ovn-nbctl --wait=sb sync
>  
> -ovn-sbctl dump-flows sw0 | grep ct_lb | grep priority=120 > lflows.txt
> +ovn-sbctl dump-flows sw0 | grep backends | grep priority=120 > lflows.txt
>  AT_CHECK([cat lflows.txt | sed 's/table=..//'], [0], [dnl
>    (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
> @@ -1233,7 +1233,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.*ct_lb' | 
> sed 's/table=..//'], [0],
> +  [ovn-sbctl dump-flows sw0 | tee sbflows 3 | grep 'priority=120.*backends' 
> | sed 's/table=..//'], [0],
>  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>  
> @@ -1244,7 +1244,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.*ct_lb' | 
> sed 's/table=..//'], [0],
> +  [ovn-sbctl dump-flows sw0 | tee sbflows4 | grep 'priority=120.*backends' | 
> sed 's/table=..//'], [0],
>  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80);)
>  ])
>  
> @@ -1256,7 +1256,7 @@ check ovn-nbctl --wait=sb sync
>  
>  AT_CAPTURE_FILE([sbflows5])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw0 | tee sbflows5 | grep 'priority=120.*ct_lb'], 1)
> +  [ovn-sbctl dump-flows sw0 | tee sbflows5 | grep 'priority=120.*backends'], 
> 1)
>  
>  AT_CAPTURE_FILE([sbflows6])
>  OVS_WAIT_FOR_OUTPUT(
> @@ -1273,7 +1273,7 @@ check ovn-nbctl --wait=sb sync
>  
>  AT_CAPTURE_FILE([sbflows7])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw0 | tee sbflows7 | grep ct_lb | grep priority=120 
> | sed 's/table=..//'], 0,
> +  [ovn-sbctl dump-flows sw0 | tee sbflows7 | grep backends | grep 
> priority=120 | sed 's/table=..//'], 0,
>  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>  ])
>  
> @@ -1309,7 +1309,7 @@ wait_row_count Service_Monitor 1 port=1000
>  
>  AT_CAPTURE_FILE([sbflows9])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw0 | tee sbflows9 | grep ct_lb | grep priority=120 
> | sed 's/table=..//' | sort],
> +  [ovn-sbctl dump-flows sw0 | tee sbflows9 | grep backends | grep 
> priority=120 | sed 's/table=..//' | sort],
>    0,
>  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80);)
>    (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.40 && tcp.dst == 1000), action=(reg1 = 10.0.0.40; reg2[[0..15]] = 
> 1000; ct_lb(backends=10.0.0.3:1000);)
> @@ -1323,7 +1323,7 @@ check ovn-nbctl --wait=sb sync
>  
>  AT_CAPTURE_FILE([sbflows10])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw0 | tee sbflows10 | grep ct_lb | grep priority=120 
> | sed 's/table=..//' | sort],
> +  [ovn-sbctl dump-flows sw0 | tee sbflows10 | grep backends | grep 
> priority=120 | sed 's/table=..//' | sort],
>    0,
>  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>    (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.40 && tcp.dst == 1000), action=(reg1 = 10.0.0.40; reg2[[0..15]] = 
> 1000; ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);)
> @@ -1333,7 +1333,7 @@ AS_BOX([Associate lb1 to sw1])
>  check ovn-nbctl --wait=sb ls-lb-add sw1 lb1
>  AT_CAPTURE_FILE([sbflows11])
>  OVS_WAIT_FOR_OUTPUT(
> -  [ovn-sbctl dump-flows sw1 | tee sbflows11 | grep ct_lb | grep priority=120 
> | sed 's/table=..//' | sort],
> +  [ovn-sbctl dump-flows sw1 | tee sbflows11 | grep backends | grep 
> priority=120 | sed 's/table=..//' | sort],
>    0, [dnl
>    (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80);)
>    (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.40 && tcp.dst == 1000), action=(reg1 = 10.0.0.40; reg2[[0..15]] = 
> 1000; ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);)
> @@ -1393,7 +1393,7 @@ 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 | sed 's/table=..//'], [0], [dnl
> -  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg0 = 0; reject { outport <-> inport; 
> next(pipeline=egress,table=6);};)
> +  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg0 = 0; reject { outport <-> inport; 
> next(pipeline=egress,table=5);};)
>  ])
>  
>  AT_CLEANUP
> @@ -1813,13 +1813,13 @@ AT_CHECK([ovn-sbctl lflow-list | grep 
> "ls_out_pre_lb.*priority=100" | grep reg0
>  ovn-nbctl ls-lb-add sw0 lb1
>  ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep "ls_out_pre_lb.*priority=100" | grep 
> reg0 | sort], [0], [dnl
> -  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[0]] = 1; next;)
> +  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
>  ])
>  
>  ovn-nbctl ls-lb-add sw0 lb2
>  ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep "ls_out_pre_lb.*priority=100" | grep 
> reg0 | sort], [0], [dnl
> -  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[0]] = 1; next;)
> +  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
>  ])
>  
>  lb1_uuid=$(ovn-nbctl --bare --columns _uuid find load_balancer name=lb1)
> @@ -1828,7 +1828,7 @@ lb2_uuid=$(ovn-nbctl --bare --columns _uuid find 
> load_balancer name=lb2)
>  ovn-nbctl clear load_balancer $lb1_uuid vips
>  ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep "ls_out_pre_lb.*priority=100" | grep 
> reg0 | sort], [0], [dnl
> -  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[0]] = 1; next;)
> +  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
>  ])
>  
>  ovn-nbctl clear load_balancer $lb2_uuid vips
> @@ -1841,14 +1841,14 @@ ovn-nbctl set load_balancer $lb2_uuid 
> vips:"10.0.0.11"="10.0.0.4"
>  
>  ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep "ls_out_pre_lb.*priority=100" | grep 
> reg0 | sort], [0], [dnl
> -  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[0]] = 1; next;)
> +  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
>  ])
>  
>  # Now reverse the order of clearing the vip.
>  ovn-nbctl clear load_balancer $lb2_uuid vips
>  ovn-nbctl --wait=sb sync
>  AT_CHECK([ovn-sbctl lflow-list | grep "ls_out_pre_lb.*priority=100" | grep 
> reg0 | sort], [0], [dnl
> -  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[0]] = 1; next;)
> +  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
>  ])
>  
>  ovn-nbctl clear load_balancer $lb1_uuid vips
> @@ -1900,10 +1900,10 @@ AT_CAPTURE_FILE([sw1flows])
>  
>  AT_CHECK(
>    [grep -E 'ls_(in|out)_acl' sw0flows sw1flows | grep pg0 | sort], [0], [dnl
> -sw0flows:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw0flows:  table=9 (ls_in_acl          ), priority=2002 , match=(inport == 
> @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst 
> <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=egress,table=6); };)
> -sw1flows:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows:  table=9 (ls_in_acl          ), priority=2002 , match=(inport == 
> @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst 
> <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=egress,table=6); };)
> +sw0flows:  table=4 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw0flows:  table=9 (ls_in_acl          ), priority=2002 , match=(inport == 
> @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst 
> <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=egress,table=5); };)
> +sw1flows:  table=4 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows:  table=9 (ls_in_acl          ), priority=2002 , match=(inport == 
> @pg0 && ip4 && tcp && tcp.dst == 80), action=(reg0 = 0; reject { /* eth.dst 
> <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=egress,table=5); };)
>  ])
>  
>  AS_BOX([2])
> @@ -1916,10 +1916,10 @@ ovn-sbctl dump-flows sw1 > sw1flows2
>  AT_CAPTURE_FILE([sw1flows2])
>  
>  AT_CHECK([grep "ls_out_acl" sw0flows2 sw1flows2 | grep pg0 | sort], [0], [dnl
> -sw0flows2:  table=5 (ls_out_acl         ), priority=2002 , match=(outport == 
> @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw0flows2:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows2:  table=5 (ls_out_acl         ), priority=2002 , match=(outport == 
> @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows2:  table=5 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> +sw0flows2:  table=4 (ls_out_acl         ), priority=2002 , match=(outport == 
> @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw0flows2:  table=4 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows2:  table=4 (ls_out_acl         ), priority=2002 , match=(outport == 
> @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows2:  table=4 (ls_out_acl         ), priority=2003 , match=(outport == 
> @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; 
> ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
>  ])
>  
>  AS_BOX([3])
> @@ -1932,18 +1932,18 @@ ovn-sbctl dump-flows sw1 > sw1flows3
>  AT_CAPTURE_FILE([sw1flows3])
>  
>  AT_CHECK([grep "ls_out_acl" sw0flows3 sw1flows3 | grep pg0 | sort], [0], [dnl
> -sw0flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[7]] 
> == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
> -sw0flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[8]] 
> == 1 && (outport == @pg0 && ip)), action=(next;)
> -sw0flows3:  table=5 (ls_out_acl         ), priority=2002 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw0flows3:  table=5 (ls_out_acl         ), priority=2002 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw0flows3:  table=5 (ls_out_acl         ), priority=2003 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw0flows3:  table=5 (ls_out_acl         ), priority=2003 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[7]] 
> == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
> -sw1flows3:  table=5 (ls_out_acl         ), priority=2001 , match=(reg0[[8]] 
> == 1 && (outport == @pg0 && ip)), action=(next;)
> -sw1flows3:  table=5 (ls_out_acl         ), priority=2002 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows3:  table=5 (ls_out_acl         ), priority=2002 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows3:  table=5 (ls_out_acl         ), priority=2003 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> -sw1flows3:  table=5 (ls_out_acl         ), priority=2003 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=23); };)
> +sw0flows3:  table=4 (ls_out_acl         ), priority=2001 , match=(reg0[[7]] 
> == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
> +sw0flows3:  table=4 (ls_out_acl         ), priority=2001 , match=(reg0[[8]] 
> == 1 && (outport == @pg0 && ip)), action=(next;)
> +sw0flows3:  table=4 (ls_out_acl         ), priority=2002 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw0flows3:  table=4 (ls_out_acl         ), priority=2002 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw0flows3:  table=4 (ls_out_acl         ), priority=2003 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw0flows3:  table=4 (ls_out_acl         ), priority=2003 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows3:  table=4 (ls_out_acl         ), priority=2001 , match=(reg0[[7]] 
> == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;)
> +sw1flows3:  table=4 (ls_out_acl         ), priority=2001 , match=(reg0[[8]] 
> == 1 && (outport == @pg0 && ip)), action=(next;)
> +sw1flows3:  table=4 (ls_out_acl         ), priority=2002 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows3:  table=4 (ls_out_acl         ), priority=2002 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows3:  table=4 (ls_out_acl         ), priority=2003 , 
> match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit 
> { ct_label.blocked = 1; };  reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst 
> <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
> +sw1flows3:  table=4 (ls_out_acl         ), priority=2003 , match=((reg0[[9]] 
> == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* 
> eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; 
> next(pipeline=ingress,table=22); };)
>  ])
>  AT_CLEANUP
>  ])
> @@ -2083,17 +2083,17 @@ check ovn-nbctl --wait=sb \
>      -- acl-add ls from-lport 2 "udp" allow-related \
>      -- acl-add ls to-lport 2 "udp" allow-related
>  AT_CHECK([ovn-sbctl lflow-list ls | grep -e ls_in_acl_hint -e 
> ls_out_acl_hint -e ls_in_acl -e ls_out_acl | grep 'ct\.' | sort], [0], [dnl
> -  table=4 (ls_out_acl_hint    ), priority=1    , match=(ct.est && 
> ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=2    , match=(ct.est && 
> ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=3    , match=(!ct.est), 
> action=(reg0[[9]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; 
> next;)
> -  table=4 (ls_out_acl_hint    ), priority=5    , match=(!ct.trk), 
> action=(reg0[[8]] = 1; reg0[[9]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; 
> next;)
> -  table=4 (ls_out_acl_hint    ), priority=7    , match=(ct.new && !ct.est), 
> action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
> -  table=5 (ls_out_acl         ), priority=1    , match=(ip && (!ct.est || 
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> -  table=5 (ls_out_acl         ), priority=65535, match=(!ct.est && ct.rel && 
> !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
> -  table=5 (ls_out_acl         ), priority=65535, match=(ct.est && !ct.rel && 
> !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;)
> -  table=5 (ls_out_acl         ), priority=65535, match=(ct.inv || (ct.est && 
> ct.rpl && ct_label.blocked == 1)), action=(drop;)
> +  table=3 (ls_out_acl_hint    ), priority=1    , match=(ct.est && 
> ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=2    , match=(ct.est && 
> ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=3    , match=(!ct.est), 
> action=(reg0[[9]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; 
> next;)
> +  table=3 (ls_out_acl_hint    ), priority=5    , match=(!ct.trk), 
> action=(reg0[[8]] = 1; reg0[[9]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; 
> next;)
> +  table=3 (ls_out_acl_hint    ), priority=7    , match=(ct.new && !ct.est), 
> action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
> +  table=4 (ls_out_acl         ), priority=1    , match=(ip && (!ct.est || 
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> +  table=4 (ls_out_acl         ), priority=65535, match=(!ct.est && ct.rel && 
> !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
> +  table=4 (ls_out_acl         ), priority=65535, match=(ct.est && !ct.rel && 
> !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;)
> +  table=4 (ls_out_acl         ), priority=65535, match=(ct.inv || (ct.est && 
> ct.rpl && ct_label.blocked == 1)), action=(drop;)
>    table=8 (ls_in_acl_hint     ), priority=1    , match=(ct.est && 
> ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
>    table=8 (ls_in_acl_hint     ), priority=2    , match=(ct.est && 
> ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
>    table=8 (ls_in_acl_hint     ), priority=3    , match=(!ct.est), 
> action=(reg0[[9]] = 1; next;)
> @@ -2115,17 +2115,17 @@ check ovn-nbctl --wait=sb \
>      -- ls-lb-add ls lb
>  
>  AT_CHECK([ovn-sbctl lflow-list ls | grep -e ls_in_acl_hint -e 
> ls_out_acl_hint -e ls_in_acl -e ls_out_acl | grep 'ct\.' | sort], [0], [dnl
> -  table=4 (ls_out_acl_hint    ), priority=1    , match=(ct.est && 
> ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=2    , match=(ct.est && 
> ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=3    , match=(!ct.est), 
> action=(reg0[[9]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; 
> next;)
> -  table=4 (ls_out_acl_hint    ), priority=5    , match=(!ct.trk), 
> action=(reg0[[8]] = 1; reg0[[9]] = 1; next;)
> -  table=4 (ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; 
> next;)
> -  table=4 (ls_out_acl_hint    ), priority=7    , match=(ct.new && !ct.est), 
> action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
> -  table=5 (ls_out_acl         ), priority=1    , match=(ip && (!ct.est || 
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> -  table=5 (ls_out_acl         ), priority=65535, match=(!ct.est && ct.rel && 
> !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
> -  table=5 (ls_out_acl         ), priority=65535, match=(ct.est && !ct.rel && 
> !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;)
> -  table=5 (ls_out_acl         ), priority=65535, match=(ct.inv || (ct.est && 
> ct.rpl && ct_label.blocked == 1)), action=(drop;)
> +  table=3 (ls_out_acl_hint    ), priority=1    , match=(ct.est && 
> ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=2    , match=(ct.est && 
> ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=3    , match=(!ct.est), 
> action=(reg0[[9]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=4    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; 
> next;)
> +  table=3 (ls_out_acl_hint    ), priority=5    , match=(!ct.trk), 
> action=(reg0[[8]] = 1; reg0[[9]] = 1; next;)
> +  table=3 (ls_out_acl_hint    ), priority=6    , match=(!ct.new && ct.est && 
> !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; 
> next;)
> +  table=3 (ls_out_acl_hint    ), priority=7    , match=(ct.new && !ct.est), 
> action=(reg0[[7]] = 1; reg0[[9]] = 1; next;)
> +  table=4 (ls_out_acl         ), priority=1    , match=(ip && (!ct.est || 
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> +  table=4 (ls_out_acl         ), priority=65535, match=(!ct.est && ct.rel && 
> !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
> +  table=4 (ls_out_acl         ), priority=65535, match=(ct.est && !ct.rel && 
> !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;)
> +  table=4 (ls_out_acl         ), priority=65535, match=(ct.inv || (ct.est && 
> ct.rpl && ct_label.blocked == 1)), action=(drop;)
>    table=8 (ls_in_acl_hint     ), priority=1    , match=(ct.est && 
> ct_label.blocked == 0), action=(reg0[[10]] = 1; next;)
>    table=8 (ls_in_acl_hint     ), priority=2    , match=(ct.est && 
> ct_label.blocked == 1), action=(reg0[[9]] = 1; next;)
>    table=8 (ls_in_acl_hint     ), priority=3    , match=(!ct.est), 
> action=(reg0[[9]] = 1; next;)
> @@ -2354,20 +2354,20 @@ check ovn-nbctl \
>  check ovn-nbctl --wait=sb sync
>  
>  AT_CHECK([ovn-sbctl lflow-list sw0 | grep ls_in_pre_hairpin | sort], [0], 
> [dnl
> -  table=14(ls_in_pre_hairpin  ), priority=0    , match=(1), action=(next;)
> -  table=14(ls_in_pre_hairpin  ), priority=100  , match=(ip && ct.trk), 
> action=(reg0[[6]] = chk_lb_hairpin(); reg0[[12]] = chk_lb_hairpin_reply(); 
> next;)
> +  table=13(ls_in_pre_hairpin  ), priority=0    , match=(1), action=(next;)
> +  table=13(ls_in_pre_hairpin  ), priority=100  , match=(ip && ct.trk), 
> action=(reg0[[6]] = chk_lb_hairpin(); reg0[[12]] = chk_lb_hairpin_reply(); 
> next;)
>  ])
>  
>  AT_CHECK([ovn-sbctl lflow-list sw0 | grep ls_in_nat_hairpin | sort], [0], 
> [dnl
> -  table=15(ls_in_nat_hairpin  ), priority=0    , match=(1), action=(next;)
> -  table=15(ls_in_nat_hairpin  ), priority=100  , match=(ip && ct.est && 
> ct.trk && reg0[[6]] == 1), action=(ct_snat;)
> -  table=15(ls_in_nat_hairpin  ), priority=100  , match=(ip && ct.new && 
> ct.trk && reg0[[6]] == 1), action=(ct_snat_to_vip; next;)
> -  table=15(ls_in_nat_hairpin  ), priority=90   , match=(ip && reg0[[12]] == 
> 1), action=(ct_snat;)
> +  table=14(ls_in_nat_hairpin  ), priority=0    , match=(1), action=(next;)
> +  table=14(ls_in_nat_hairpin  ), priority=100  , match=(ip && ct.est && 
> ct.trk && reg0[[6]] == 1), action=(ct_snat;)
> +  table=14(ls_in_nat_hairpin  ), priority=100  , match=(ip && ct.new && 
> ct.trk && reg0[[6]] == 1), action=(ct_snat_to_vip; next;)
> +  table=14(ls_in_nat_hairpin  ), priority=90   , match=(ip && reg0[[12]] == 
> 1), action=(ct_snat;)
>  ])
>  
>  AT_CHECK([ovn-sbctl lflow-list sw0 | grep ls_in_hairpin | sort], [0], [dnl
> -  table=16(ls_in_hairpin      ), priority=0    , match=(1), action=(next;)
> -  table=16(ls_in_hairpin      ), priority=1    , match=((reg0[[6]] == 1 || 
> reg0[[12]] == 1)), action=(eth.dst <-> eth.src; outport = inport; 
> flags.loopback = 1; output;)
> +  table=15(ls_in_hairpin      ), priority=0    , match=(1), action=(next;)
> +  table=15(ls_in_hairpin      ), priority=1    , match=((reg0[[6]] == 1 || 
> reg0[[12]] == 1)), action=(eth.dst <-> eth.src; outport = inport; 
> flags.loopback = 1; output;)
>  ])
>  
>  AT_CLEANUP
> @@ -2950,4 +2950,135 @@ wait_row_count FDB 0
>  ovn-sbctl list FDB
>  
>  AT_CLEANUP
> -])
> \ No newline at end of file
> +])
> +
> +OVN_FOR_EACH_NORTHD([
> +AT_SETUP([ovn -- LS load balancer logical flows])
> +ovn_start
> +
> +check ovn-nbctl \
> +    -- ls-add sw0 \
> +    -- lb-add lb0 10.0.0.10:80 10.0.0.4:8080 \
> +    -- ls-lb-add sw0 lb0
> +
> +check ovn-nbctl lr-add lr0
> +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
> +check ovn-nbctl lsp-add sw0 sw0-lr0
> +check ovn-nbctl lsp-set-type sw0-lr0 router
> +check ovn-nbctl lsp-set-addresses sw0-lr0 00:00:00:00:ff:01
> +check ovn-nbctl lsp-set-options sw0-lr0 router-port=lr0-sw0
> +
> +check ovn-nbctl --wait=sb sync
> +
> +check_stateful_flows() {
> +    ovn-sbctl dump-flows sw0 > sw0flows
> +    AT_CAPTURE_FILE([sw0flows])
> +
> +    AT_CHECK([grep "ls_in_pre_lb" sw0flows | sort], [0], [dnl
> +  table=6 (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
> +  table=6 (ls_in_pre_lb       ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
> +  table=6 (ls_in_pre_lb       ), priority=110  , match=(eth.dst == 
> $svc_monitor_mac), action=(next;)
> +  table=6 (ls_in_pre_lb       ), priority=110  , match=(ip && inport == 
> "sw0-lr0"), action=(next;)
> +  table=6 (ls_in_pre_lb       ), priority=110  , match=(nd || nd_rs || nd_ra 
> || mldv1 || mldv2), action=(next;)
> +])
> +
> +    AT_CHECK([grep "ls_in_pre_stateful" sw0flows | sort], [0], [dnl
> +  table=7 (ls_in_pre_stateful ), priority=0    , match=(1), action=(next;)
> +  table=7 (ls_in_pre_stateful ), priority=100  , match=(reg0[[0]] == 1), 
> action=(ct_next;)
> +  table=7 (ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), 
> action=(ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb;)
> +])
> +
> +    AT_CHECK([grep "ls_in_lb" sw0flows | sort], [0], [])
> +
> +    AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl
> +  table=12(ls_in_stateful     ), priority=0    , match=(1), action=(next;)
> +  table=12(ls_in_stateful     ), priority=100  , match=(reg0[[1]] == 1), 
> action=(ct_commit { ct_label.blocked = 0; }; next;)
> +  table=12(ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.4:8080);)
> +])
> +
> +    AT_CHECK([grep "ls_out_pre_lb" sw0flows | sort], [0], [dnl
> +  table=0 (ls_out_pre_lb      ), priority=0    , match=(1), action=(next;)
> +  table=0 (ls_out_pre_lb      ), priority=100  , match=(ip), 
> action=(reg0[[2]] = 1; next;)
> +  table=0 (ls_out_pre_lb      ), priority=110  , match=(eth.src == 
> $svc_monitor_mac), action=(next;)
> +  table=0 (ls_out_pre_lb      ), priority=110  , match=(ip && outport == 
> "sw0-lr0"), action=(next;)
> +  table=0 (ls_out_pre_lb      ), priority=110  , match=(nd || nd_rs || nd_ra 
> || mldv1 || mldv2), action=(next;)
> +])
> +
> +    AT_CHECK([grep "ls_out_pre_stateful" sw0flows | sort], [0], [dnl
> +  table=2 (ls_out_pre_stateful), priority=0    , match=(1), action=(next;)
> +  table=2 (ls_out_pre_stateful), priority=100  , match=(reg0[[0]] == 1), 
> action=(ct_next;)
> +  table=2 (ls_out_pre_stateful), priority=110  , match=(reg0[[2]] == 1), 
> action=(ct_lb;)
> +])
> +
> +    AT_CHECK([grep "ls_out_lb" sw0flows | sort], [0], [])

This might be a bit cryptic in the future ("what is the ls_out_lb
table?!?") as it will not exist. Do we really need this check here? If
so, maybe add  a comment to explain why it is here.
> +
> +    AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl
> +  table=7 (ls_out_stateful    ), priority=0    , match=(1), action=(next;)
> +  table=7 (ls_out_stateful    ), priority=100  , match=(reg0[[1]] == 1), 
> action=(ct_commit { ct_label.blocked = 0; }; next;)
> +])
> +}
> +
> +check_stateful_flows
> +
> +# Add few ACLs
> +check ovn-nbctl --wait=sb acl-add sw0 from-lport 1002 "ip4 && tcp && tcp.dst 
> == 80" allow-related
> +check ovn-nbctl --wait=sb acl-add sw0 to-lport 1002 "ip4 && tcp && tcp.src 
> == 80" drop
> +
> +check_stateful_flows
> +
> +# Remove load balancer from sw0
> +check ovn-nbctl --wait=sb ls-lb-del sw0 lb0
> +
> +ovn-sbctl dump-flows sw0 > sw0flows
> +AT_CAPTURE_FILE([sw0flows])
> +
> +AT_CHECK([grep "ls_in_pre_lb" sw0flows | sort], [0], [dnl
> +  table=6 (ls_in_pre_lb       ), priority=0    , match=(1), action=(next;)
> +  table=6 (ls_in_pre_lb       ), priority=110  , match=(eth.dst == 
> $svc_monitor_mac), action=(next;)
> +  table=6 (ls_in_pre_lb       ), priority=110  , match=(ip && inport == 
> "sw0-lr0"), action=(next;)
> +  table=6 (ls_in_pre_lb       ), priority=110  , match=(nd || nd_rs || nd_ra 
> || mldv1 || mldv2), action=(next;)
> +])
> +
> +AT_CHECK([grep "ls_in_pre_stateful" sw0flows | sort], [0], [dnl
> +  table=7 (ls_in_pre_stateful ), priority=0    , match=(1), action=(next;)
> +  table=7 (ls_in_pre_stateful ), priority=100  , match=(reg0[[0]] == 1), 
> action=(ct_next;)
> +  table=7 (ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), 
> action=(ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb;)
> +  table=7 (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
> ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb;)
> +])
> +
> +AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl
> +  table=12(ls_in_stateful     ), priority=0    , match=(1), action=(next;)
> +  table=12(ls_in_stateful     ), priority=100  , match=(reg0[[1]] == 1), 
> action=(ct_commit { ct_label.blocked = 0; }; next;)
> +])
> +
> +AT_CHECK([grep "ls_out_pre_lb" sw0flows | sort], [0], [dnl
> +  table=0 (ls_out_pre_lb      ), priority=0    , match=(1), action=(next;)
> +  table=0 (ls_out_pre_lb      ), priority=110  , match=(eth.src == 
> $svc_monitor_mac), action=(next;)
> +  table=0 (ls_out_pre_lb      ), priority=110  , match=(ip && outport == 
> "sw0-lr0"), action=(next;)
It seems like this^ flow is not described in the man page for
ovn-northd. You did not introduce this but maybe you could update it by
coping the description from the Ingress table.
> +  table=0 (ls_out_pre_lb      ), priority=110  , match=(nd || nd_rs || nd_ra 
> || mldv1 || mldv2), action=(next;)
> +])
> +
> +AT_CHECK([grep "ls_out_pre_stateful" sw0flows | sort], [0], [dnl
> +  table=2 (ls_out_pre_stateful), priority=0    , match=(1), action=(next;)
> +  table=2 (ls_out_pre_stateful), priority=100  , match=(reg0[[0]] == 1), 
> action=(ct_next;)
> +  table=2 (ls_out_pre_stateful), priority=110  , match=(reg0[[2]] == 1), 
> action=(ct_lb;)
> +])
> +
> +AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl
> +  table=7 (ls_out_stateful    ), priority=0    , match=(1), action=(next;)
> +  table=7 (ls_out_stateful    ), priority=100  , match=(reg0[[1]] == 1), 
> action=(ct_commit { ct_label.blocked = 0; }; next;)
> +])
> +
> +AT_CLEANUP
> +])
> diff --git a/tests/ovn.at b/tests/ovn.at
> index 73cc8bf025..d7da84459c 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -14088,16 +14088,16 @@ check ovn-nbctl acl-add ls1 to-lport 3 
> 'ip4.src==10.0.0.1' allow
>  check ovn-nbctl --wait=hv sync
>  
>  # Check OVS flows, the less restrictive flows should have been installed.
> -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
> +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
>      grep "priority=1003" | \
>      sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
> - table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
> + table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
>  ])
>  
>  # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
> @@ -14132,16 +14132,16 @@ check ovn-nbctl acl-del ls1 to-lport 3 
> 'ip4.src==10.0.0.1 || ip4.src==10.0.0.1'
>  check ovn-nbctl --wait=hv sync
>  
>  # Check OVS flows, the second less restrictive allow ACL should have been 
> installed.
> -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
> +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
>      grep "priority=1003" | \
>      sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
> - table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
> + table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
>  ])
>  
>  # Remove the less restrictive allow ACL.
> @@ -14149,16 +14149,16 @@ check ovn-nbctl acl-del ls1 to-lport 3 
> 'ip4.src==10.0.0.1'
>  check ovn-nbctl --wait=hv sync
>  
>  # Check OVS flows, the 10.0.0.1 conjunction should have been reinstalled.
> -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
> +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
>      grep "priority=1003" | \
>      sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
> - table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
> + table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
>  ])
>  
>  # Traffic 10.0.0.1, 10.0.0.2 -> 10.0.0.3, 10.0.0.4 should be allowed.
> @@ -14188,16 +14188,16 @@ check ovn-nbctl acl-add ls1 to-lport 3 
> 'ip4.src==10.0.0.1' allow
>  check ovn-nbctl --wait=hv sync
>  
>  # Check OVS flows, the less restrictive flows should have been installed.
> -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
> +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
>     grep "priority=1003" | \
>     sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
> - table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
> + table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
>  ])
>  
>  # Add another ACL that overlaps with the existing less restrictive ones.
> @@ -14208,19 +14208,19 @@ check ovn-nbctl --wait=hv sync
>  # with an additional conjunction action.
>  #
>  # New non-conjunctive flows should be added to match on 'udp'.
> -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
> +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
>     grep "priority=1003" | \
>     sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
> - table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,conj_id=4,ip,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,46)
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction(),conjunction()
> - table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
> - table=45, priority=1003,udp,metadata=0x1 actions=resubmit(,46)
> - table=45, priority=1003,udp6,metadata=0x1 actions=resubmit(,46)
> + table=44, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,conj_id=4,ip,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
> actions=conjunction(),conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
> actions=conjunction(),conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
> actions=resubmit(,45)
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
> actions=conjunction(),conjunction()
> + table=44, priority=1003,ip,metadata=0x1,nw_src=10.0.0.42 
> actions=conjunction()
> + table=44, priority=1003,udp,metadata=0x1 actions=resubmit(,45)
> + table=44, priority=1003,udp6,metadata=0x1 actions=resubmit(,45)
>  ])
>  
>  OVN_CLEANUP([hv1])
> @@ -15549,7 +15549,7 @@ wait_for_ports_up ls1-lp_ext1
>  # There should be a flow in hv2 to drop traffic from ls1-lp_ext1 destined
>  # to router mac.
>  AT_CHECK([as hv2 ovs-ofctl dump-flows br-int \
> -table=30,dl_src=f0:00:00:00:00:03,dl_dst=a0:10:00:00:00:01 | \
> +table=29,dl_src=f0:00:00:00:00:03,dl_dst=a0:10:00:00:00:01 | \
>  grep -c "actions=drop"], [0], [1
>  ])
>  
> @@ -19994,7 +19994,14 @@ AT_CAPTURE_FILE([sbflows])
>  OVS_WAIT_FOR_OUTPUT(
>    [ovn-sbctl dump-flows > sbflows
>     ovn-sbctl dump-flows sw0 | grep ct_lb | grep priority=120 | sed 
> 's/table=..//'], 0,
> -  [  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(backends=10.0.0.3:80,20.0.0.3:80; 
> hash_fields="ip_dst,ip_src,tcp_dst,tcp_src");)
> +  [dnl
> +  (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4 && 
> sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb;)
> +  (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4 && 
> tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb;)
> +  (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip4 && 
> udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb;)
> +  (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip6 && 
> sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb;)
> +  (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip6 && 
> tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb;)
> +  (ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && ip6 && 
> udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb;)
> +  (ls_in_stateful     ), priority=120  , match=(ct.new && ip4.dst == 
> 10.0.0.10 && tcp.dst == 80), action=(reg1 = 10.0.0.10; reg2[[0..15]] = 80; 
> ct_lb(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])
> @@ -22731,7 +22738,7 @@ check ovn-nbctl --wait=hv sync
>  # wait_conj_id_count COUNT ["ID COUNT [MATCH]"]...
>  #
>  # Waits until COUNT flows matching against conj_id appear in the
> -# table 45 on hv1's br-int bridge.  Makes the flows available in
> +# table 44 on hv1's br-int bridge.  Makes the flows available in
>  # "hv1flows", which will be logged on error.
>  #
>  # In addition, for each quoted "ID COUNT" or "ID COUNT MATCH",
> @@ -22748,7 +22755,7 @@ wait_conj_id_count() {
>    echo "waiting for $1 conj_id flows..."
>    OVS_WAIT_FOR_OUTPUT_UNQUOTED(
>      [ovs-ofctl dump-flows br-int > hv1flows
> -     grep table=45 hv1flows | grep -c conj_id],
> +     grep table=44 hv1flows | grep -c conj_id],
>      [$retval], [$1
>  ])
>  
> @@ -22757,7 +22764,7 @@ wait_conj_id_count() {
>      set -- $arg; id=$1 count=$2 match=$3
>      echo "checking that there are $count ${match:+$match }flows with 
> conj_id=$id..."
>      AT_CHECK_UNQUOTED(
> -      [grep table=45 hv1flows | grep "$match" | grep -c conj_id=$id],
> +      [grep table=44 hv1flows | grep "$match" | grep -c conj_id=$id],
>        [0], [$count
>  ])
>    done
> @@ -22782,8 +22789,8 @@ wait_conj_id_count 1 "3 1 udp"
>  AS_BOX([Add back the tcp ACL.])
>  check ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && ip4 
> && tcp.dst >= 80 && tcp.dst <= 82" allow
>  wait_conj_id_count 2 "3 1 udp" "4 1 tcp"
> -AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep udp 
> | grep -c "conj_id=3")])
> -AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=45 | grep tcp 
> | grep -c "conj_id=4")])
> +AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=44 | grep udp 
> | grep -c "conj_id=3")])
> +AT_CHECK([test 1 = $(as hv1 ovs-ofctl dump-flows br-int table=44 | grep tcp 
> | grep -c "conj_id=4")])
>  
>  AS_BOX([Add another tcp ACL.])
>  check ovn-nbctl --wait=hv acl-add pg0 to-lport 1002 "outport == @pg0 && 
> inport == @pg0 && ip4 && tcp.dst >= 84 && tcp.dst <= 86" allow
> @@ -24750,43 +24757,43 @@ AT_CHECK([kill -0 $(cat hv1/ovn-controller.pid)])
>  check ovn-nbctl --wait=hv sync
>  
>  # Check OVS flows are installed properly.
> -AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=45 | ofctl_strip_all | \
> +AT_CHECK([as hv1 ovs-ofctl dump-flows br-int table=44 | ofctl_strip_all | \
>      grep "priority=2002" | grep conjunction | \
>      sed 's/conjunction([[^)]]*)/conjunction()/g' | sort], [0], [dnl
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x10/0xfff0
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x100/0xff00
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x1000/0xf000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2/0xfffe
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x20/0xffe0
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x200/0xfe00
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2000/0xe000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4/0xfffc
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x40/0xffc0
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x400/0xfc00
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4000/0xc000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8/0xfff8
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x80/0xff80
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x800/0xf800
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8000/0x8000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=1 
> actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x100/0x100,reg15=0x3,metadata=0x1,nw_src=192.168.47.3 
> actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x10/0xfff0
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x100/0xff00
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x1000/0xf000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2/0xfffe
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x20/0xffe0
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x200/0xfe00
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2000/0xe000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4/0xfffc
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x40/0xffc0
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x400/0xfc00
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4000/0xc000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8/0xfff8
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x80/0xff80
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x800/0xf800
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8000/0x8000
>  actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=1 
> actions=conjunction()
> - table=45, 
> priority=2002,udp,reg0=0x80/0x80,reg15=0x3,metadata=0x1,nw_src=192.168.47.3 
> actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x10/0xfff0
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x100/0xff00
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x1000/0xf000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2/0xfffe
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x20/0xffe0
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x200/0xfe00
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2000/0xe000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4/0xfffc
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x40/0xffc0
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x400/0xfc00
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4000/0xc000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8/0xfff8
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x80/0xff80
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x800/0xf800
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8000/0x8000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,metadata=0x1,nw_src=192.168.47.3,tp_dst=1 
> actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x100/0x100,reg15=0x3,metadata=0x1,nw_src=192.168.47.3 
> actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x10/0xfff0
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x100/0xff00
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x1000/0xf000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2/0xfffe
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x20/0xffe0
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x200/0xfe00
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x2000/0xe000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4/0xfffc
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x40/0xffc0
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x400/0xfc00
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x4000/0xc000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8/0xfff8
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x80/0xff80
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x800/0xf800
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=0x8000/0x8000
>  actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,metadata=0x1,nw_src=192.168.47.3,tp_dst=1 
> actions=conjunction()
> + table=44, 
> priority=2002,udp,reg0=0x80/0x80,reg15=0x3,metadata=0x1,nw_src=192.168.47.3 
> actions=conjunction()
>  ])
>  
>  OVN_CLEANUP([hv1])
> 


_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to