The existing OpenFlow table layout left zero free
slots between regions: the ingress pipeline occupied
tables 8-41, the output implementation tables started
immediately at 42, the egress pipeline at 48, and the
post-egress auxiliary tables at 64.  Adding even a
single new ingress stage would cause a collision with
the output tables, requiring a cascade of renumbering.

Introduce comfortable gaps between the four table
regions so that future stages can be added without
disturbing the rest of the layout:

  Tables 8-41:    ingress pipeline (34 stages, unchanged)
  Tables 42-51:   gap (10 free slots)
  Tables 52-57:   output implementation (6 tables)
  Tables 58-61:   gap (4 free slots)
  Tables 62-77:   egress pipeline (16 stages)
  Tables 78-87:   gap (10 free slots)
  Tables 88-112:  post-egress auxiliary tables (25 tables)
  Tables 113-254: unused (142 free slots)

Add BUILD_ASSERT_DECL guards to catch any future
overlap at compile time.

Assisted-by: Claude Opus 4.6, Claude Code
Signed-off-by: Ales Musil <[email protected]>
---
 controller/lflow.h     |  75 ++++++++++++++-----------
 controller/physical.c  | 107 +++++++++++++++++------------------
 ovn-architecture.7.xml | 124 ++++++++++++++++++++---------------------
 tests/ovn-macros.at    |  63 ++++++++++-----------
 tests/ovn.at           |   2 -
 5 files changed, 189 insertions(+), 182 deletions(-)

diff --git a/controller/lflow.h b/controller/lflow.h
index 4bae1dfab..786cf974e 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -63,47 +63,54 @@ struct uuid;
  *
  * These are heavily documented in ovn-architecture(7), please update it if
  * you make any changes. */
-#define OFTABLE_PHY_TO_LOG                0
+#define OFTABLE_PHY_TO_LOG                  0
 
 /* Start of LOG_PIPELINE_LEN tables. */
-#define OFTABLE_LOG_INGRESS_PIPELINE      8
-#define OFTABLE_OUTPUT_LARGE_PKT_DETECT  42
-#define OFTABLE_OUTPUT_LARGE_PKT_PROCESS 43
-#define OFTABLE_REMOTE_OUTPUT            44
-#define OFTABLE_REMOTE_VTEP_OUTPUT       45
-#define OFTABLE_LOCAL_OUTPUT             46
-#define OFTABLE_CHECK_LOOPBACK           47
+#define OFTABLE_LOG_INGRESS_PIPELINE        8
+#define OFTABLE_OUTPUT_LARGE_PKT_DETECT    52
+#define OFTABLE_OUTPUT_LARGE_PKT_PROCESS   53
+#define OFTABLE_REMOTE_OUTPUT              54
+#define OFTABLE_REMOTE_VTEP_OUTPUT         55
+#define OFTABLE_LOCAL_OUTPUT               56
+#define OFTABLE_CHECK_LOOPBACK             57
 
 /* Start of the OUTPUT section of the pipeline. */
 #define OFTABLE_OUTPUT_INIT OFTABLE_OUTPUT_LARGE_PKT_DETECT
 
 /* Start of LOG_PIPELINE_LEN tables. */
-#define OFTABLE_LOG_EGRESS_PIPELINE      48
-#define OFTABLE_SAVE_INPORT              64
-#define OFTABLE_LOG_TO_PHY               65
-#define OFTABLE_MAC_BINDING              66
-#define OFTABLE_MAC_LOOKUP               67
-#define OFTABLE_CHK_LB_HAIRPIN           68
-#define OFTABLE_CHK_LB_HAIRPIN_REPLY     69
-#define OFTABLE_CT_SNAT_HAIRPIN          70
-#define OFTABLE_GET_FDB                  71
-#define OFTABLE_LOOKUP_FDB               72
-#define OFTABLE_CHK_IN_PORT_SEC          73
-#define OFTABLE_CHK_IN_PORT_SEC_ND       74
-#define OFTABLE_CHK_OUT_PORT_SEC         75
-#define OFTABLE_ECMP_NH_MAC              76
-#define OFTABLE_ECMP_NH                  77
-#define OFTABLE_CHK_LB_AFFINITY          78
-#define OFTABLE_MAC_CACHE_USE            79
-#define OFTABLE_CT_ZONE_LOOKUP           80
-#define OFTABLE_CT_ORIG_NW_DST_LOAD      81
-#define OFTABLE_CT_ORIG_IP6_DST_LOAD     82
-#define OFTABLE_CT_ORIG_TP_DST_LOAD      83
-#define OFTABLE_FLOOD_REMOTE_CHASSIS     84
-#define OFTABLE_CT_STATE_SAVE            85
-#define OFTABLE_CT_ORIG_PROTO_LOAD       86
-#define OFTABLE_GET_REMOTE_FDB           87
-#define OFTABLE_LEARN_REMOTE_FDB         88
+#define OFTABLE_LOG_EGRESS_PIPELINE        62
+#define OFTABLE_SAVE_INPORT                88
+#define OFTABLE_LOG_TO_PHY                 89
+#define OFTABLE_MAC_BINDING                90
+#define OFTABLE_MAC_LOOKUP                 91
+#define OFTABLE_CHK_LB_HAIRPIN             92
+#define OFTABLE_CHK_LB_HAIRPIN_REPLY       93
+#define OFTABLE_CT_SNAT_HAIRPIN            94
+#define OFTABLE_GET_FDB                    95
+#define OFTABLE_LOOKUP_FDB                 96
+#define OFTABLE_CHK_IN_PORT_SEC            97
+#define OFTABLE_CHK_IN_PORT_SEC_ND         98
+#define OFTABLE_CHK_OUT_PORT_SEC           99
+#define OFTABLE_ECMP_NH_MAC               100
+#define OFTABLE_ECMP_NH                   101
+#define OFTABLE_CHK_LB_AFFINITY           102
+#define OFTABLE_MAC_CACHE_USE             103
+#define OFTABLE_CT_ZONE_LOOKUP            104
+#define OFTABLE_CT_ORIG_NW_DST_LOAD       105
+#define OFTABLE_CT_ORIG_IP6_DST_LOAD      106
+#define OFTABLE_CT_ORIG_TP_DST_LOAD       107
+#define OFTABLE_FLOOD_REMOTE_CHASSIS      108
+#define OFTABLE_CT_STATE_SAVE             109
+#define OFTABLE_CT_ORIG_PROTO_LOAD        110
+#define OFTABLE_GET_REMOTE_FDB            111
+#define OFTABLE_LEARN_REMOTE_FDB          112
+
+/* Verify that table regions do not overlap. */
+BUILD_ASSERT_DECL(OFTABLE_LOG_INGRESS_PIPELINE + LOG_PIPELINE_INGRESS_LEN
+                  <= OFTABLE_OUTPUT_LARGE_PKT_DETECT);
+BUILD_ASSERT_DECL(OFTABLE_CHECK_LOOPBACK < OFTABLE_LOG_EGRESS_PIPELINE);
+BUILD_ASSERT_DECL(OFTABLE_LOG_EGRESS_PIPELINE + LOG_PIPELINE_EGRESS_LEN
+                  <= OFTABLE_SAVE_INPORT);
 
 
 struct lflow_ctx_in {
diff --git a/controller/physical.c b/controller/physical.c
index 42b42e948..7584d6065 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -805,7 +805,7 @@ put_redirect_overlay_to_source(const struct 
sbrec_port_binding *binding,
      * from ct_label to send the packet back to p1's host.
      */
 
-    /* Table 45 (LOCAL_OUTPUT), priority 110
+    /* Table 56 (LOCAL_OUTPUT), priority 110
      * =====================================
      *
      * Each flow matches a logical inport to a nf port and checks if
@@ -837,7 +837,7 @@ put_redirect_overlay_to_source(const struct 
sbrec_port_binding *binding,
                     binding->header_.uuid.parts[0], match,
                     ofpacts_p, &binding->header_.uuid);
 
-    /* Table 45 (LOCAL_OUTPUT), priority 110
+    /* Table 56 (LOCAL_OUTPUT), priority 110
      * In case NF is sending back a response on the port it received the
      * packet on, instead of forwarding out of the other port (e.g. NF sending
      * RST to the SYN received), the ct lookup in linked port's zone would
@@ -870,7 +870,7 @@ put_redirect_overlay_to_source(const struct 
sbrec_port_binding *binding,
                         ofpacts_p, &binding->header_.uuid);
     }
 
-    /* Table 45 (LOCAL_OUTPUT), priority 109
+    /* Table 56 (LOCAL_OUTPUT), priority 109
      * =====================================
      *
      * A flow is installed For each {remote tunnel_id, nf port} combination. It
@@ -1314,7 +1314,7 @@ put_replace_router_port_mac_flows(const struct 
physical_ctx *ctx,
         }
         free(cr_peer_name);
 
-        /* Table 65, priority 150.
+        /* Table 89, priority 150.
          * =======================
          *
          * Implements output to localnet port.
@@ -1442,12 +1442,12 @@ put_local_common_flows(uint32_t dp_key,
 
     uint32_t port_key = pb->tunnel_key;
 
-    /* Table 45, priority 100.
+    /* Table 56, priority 100.
      * =======================
      *
      * Implements output to local hypervisor.  Each flow matches a
      * logical output port on the local hypervisor, and resubmits to
-     * table 46.
+     * table 57.
      */
 
     ofpbuf_clear(ofpacts_p);
@@ -1457,13 +1457,13 @@ put_local_common_flows(uint32_t dp_key,
 
     put_zones_ofpacts(zone_ids, ofpacts_p);
 
-    /* Resubmit to table 46. */
+    /* Resubmit to table 57. */
     put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p);
     ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100,
                     pb->header_.uuid.parts[0], &match, ofpacts_p,
                     &pb->header_.uuid);
 
-    /* Table 46, Priority 100.
+    /* Table 57, Priority 100.
      * =======================
      *
      * Drop packets whose logical inport and outport are the same
@@ -1480,7 +1480,7 @@ put_local_common_flows(uint32_t dp_key,
                     pb->header_.uuid.parts[0], &match, ofpacts_p,
                     &pb->header_.uuid);
 
-    /* Table 46, Priority 1.
+    /* Table 57, Priority 1.
      * =======================
      * For datapath with network function ports, add a flow to clear only the
      * required logical registers.
@@ -1498,7 +1498,7 @@ put_local_common_flows(uint32_t dp_key,
                         ofpacts_p, &pb->datapath->header_.uuid);
     }
 
-    /* Table 64, Priority 100.
+    /* Table 88, Priority 100.
      * =======================
      *
      * If the packet is supposed to hair-pin because the
@@ -1507,7 +1507,7 @@ put_local_common_flows(uint32_t dp_key,
      *   - or if "nested_container" flag is set and the destination is the
      *     parent port,
      * temporarily set the in_port to OFPP_NONE, resubmit to
-     * table 65 for logical-to-physical translation, then restore
+     * table 89 for logical-to-physical translation, then restore
      * the port number.
      *
      * If 'parent_pb' is not NULL, then the 'pb' represents a nested
@@ -2197,8 +2197,8 @@ consider_port_binding(const struct physical_ctx *ctx,
     }
 
     if (type == LP_VIF) {
-        /* Table 80, priority 100.
-         * =======================
+        /* Table 104, priority 100.
+         * ========================
          *
          * Process ICMP{4,6} error packets too big locally generated from the
          * kernel in order to lookup proper ct_zone. */
@@ -2260,12 +2260,12 @@ consider_port_binding(const struct physical_ctx *ctx,
             ha_chassis_group_is_active(binding->ha_chassis_group,
                                        ctx->active_tunnels, ctx->chassis))) {
 
-        /* Table 45, priority 100.
+        /* Table 56, priority 100.
          * =======================
          *
          * Implements output to local hypervisor.  Each flow matches a
          * logical output port on the local hypervisor, and resubmits to
-         * table 46.  For ports of type "chassisredirect", the logical
+         * table 57.  For ports of type "chassisredirect", the logical
          * output port is changed from the "chassisredirect" port to the
          * underlying distributed port. */
 
@@ -2306,7 +2306,7 @@ consider_port_binding(const struct physical_ctx *ctx,
              * go out from the same tunnel inport. */
             put_load(ofp_to_u16(OFPP_NONE), MFF_IN_PORT, 0, 16, ofpacts_p);
 
-            /* Resubmit to table 46. */
+            /* Resubmit to table 57. */
             put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p);
         }
 
@@ -2509,7 +2509,7 @@ consider_port_binding(const struct physical_ctx *ctx,
                                           ofport, flow_table);
         }
 
-        /* Table 65, Priority 100.
+        /* Table 89, Priority 100.
          * =======================
          *
          * Deliver the packet to the local vif. */
@@ -2539,7 +2539,7 @@ consider_port_binding(const struct physical_ctx *ctx,
                                               ofport, flow_table);
         }
 
-        /* Table 46, priority 160.
+        /* Table 57, priority 160.
          * =======================
          *
          * Do not forward local traffic from a localport to a localnet port.
@@ -2610,13 +2610,13 @@ consider_port_binding(const struct physical_ctx *ctx,
             }
         }
 
-        /* Table 43, priority 150.
+        /* Table 54, priority 150.
          * =======================
          *
          * Handles packets received from ports of type "localport".  These
          * ports are present on every hypervisor.  Traffic that originates at
          * one should never go over a tunnel to a remote hypervisor,
-         * so resubmit them to table 45 for local delivery. */
+         * so resubmit them to table 56 for local delivery. */
         if (type == LP_LOCALPORT) {
             ofpbuf_clear(ofpacts_p);
             put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p);
@@ -2644,7 +2644,7 @@ consider_port_binding(const struct physical_ctx *ctx,
         }
     } else if (access_type == PORT_LOCALNET && !ctx->always_tunnel) {
         /* Remote port connected by localnet port */
-        /* Table 45, priority 100.
+        /* Table 56, priority 100.
          * =======================
          *
          * Implements switching to localnet port. Each flow matches a
@@ -2664,7 +2664,7 @@ consider_port_binding(const struct physical_ctx *ctx,
 
         put_load(localnet_port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p);
 
-        /* Resubmit to table 45. */
+        /* Resubmit to table 56. */
         put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p);
         ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100,
                         binding->header_.uuid.parts[0],
@@ -2681,7 +2681,7 @@ consider_port_binding(const struct physical_ctx *ctx,
     const char *redirect_type = smap_get(&binding->options,
                                          "redirect-type");
 
-    /* Table 43, priority 100.
+    /* Table 54, priority 100.
      * =======================
      *
      * Handles traffic that needs to be sent to a remote hypervisor.  Each
@@ -3999,8 +3999,8 @@ physical_run(struct physical_ctx *p_ctx,
     put_chassis_mac_conj_id_flow(p_ctx->chassis_table, p_ctx->chassis,
                                  &ofpacts, flow_table);
 
-    /* Set up flows in table 0 for physical-to-logical translation and in table
-     * 64 for logical-to-physical translation. */
+    /* Set up flows in table 0 for physical-to-logical translation and in
+     * table 88 for logical-to-physical translation. */
     const struct sbrec_port_binding *binding;
     SBREC_PORT_BINDING_TABLE_FOR_EACH (binding, p_ctx->port_binding_table) {
         consider_port_binding(p_ctx, binding, get_lport_type(binding),
@@ -4015,7 +4015,7 @@ physical_run(struct physical_ctx *p_ctx,
     ofctrl_add_flow(flow_table, OFTABLE_CT_ZONE_LOOKUP, 0, 0,
                     &ct_look_def_match, &ofpacts, hc_uuid);
 
-    /* Handle output to multicast groups, in tables 40 and 41. */
+    /* Handle output to multicast groups, in tables 54 and 56. */
     const struct sbrec_multicast_group *mc;
     SBREC_MULTICAST_GROUP_TABLE_FOR_EACH (mc, p_ctx->mc_group_table) {
         consider_mc_group(p_ctx, mc, flow_table);
@@ -4031,7 +4031,7 @@ physical_run(struct physical_ctx *p_ctx,
      * have metadata about the ingress and egress logical ports.
      * VXLAN encapsulations have metadata about the egress logical port only.
      * We set MFF_LOG_DATAPATH, MFF_LOG_INPORT, and MFF_LOG_OUTPORT from the
-     * tunnel key data where possible, then resubmit to table 45 to handle
+     * tunnel key data where possible, then resubmit to table 56 to handle
      * packets to the local hypervisor. */
     struct chassis_tunnel *tun;
     HMAP_FOR_EACH (tun, hmap_node, p_ctx->chassis_tunnels) {
@@ -4133,7 +4133,7 @@ physical_run(struct physical_ctx *p_ctx,
      */
     add_default_drop_flow(p_ctx, OFTABLE_PHY_TO_LOG, flow_table);
 
-    /* Table 41-42, priority 0.
+    /* Table 52-53, priority 0.
      * ========================
      *
      * Default resubmit actions for OFTABLE_OUTPUT_LARGE_PKT_* tables.
@@ -4159,12 +4159,12 @@ physical_run(struct physical_ctx *p_ctx,
     ofctrl_add_flow(flow_table, OFTABLE_OUTPUT_LARGE_PKT_PROCESS, 0, 0, &match,
                     &ofpacts, hc_uuid);
 
-    /* Table 43, priority 150.
+    /* Table 54, priority 150.
      * =======================
      *
      * Handles packets received from a VXLAN tunnel which get resubmitted to
      * OFTABLE_LOG_INGRESS_PIPELINE due to lack of needed metadata in VXLAN,
-     * explicitly skip sending back out any tunnels and resubmit to table 43
+     * explicitly skip sending back out any tunnels and resubmit to table 56
      * for local delivery, except packets which have MLF_ALLOW_LOOPBACK bit
      * set.
      */
@@ -4172,13 +4172,13 @@ physical_run(struct physical_ctx *p_ctx,
     match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0, MLF_RCV_FROM_RAMP,
                          MLF_RCV_FROM_RAMP | MLF_ALLOW_LOOPBACK);
 
-    /* Resubmit to table 45. */
+    /* Resubmit to table 56. */
     ofpbuf_clear(&ofpacts);
     put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts);
     ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0,
                     &match, &ofpacts, hc_uuid);
 
-    /* Table 43, priority 150.
+    /* Table 54, priority 150.
      * =======================
      *
      * Packets that should not be sent to other hypervisors.
@@ -4186,13 +4186,13 @@ physical_run(struct physical_ctx *p_ctx,
     match_init_catchall(&match);
     match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0,
                          MLF_LOCAL_ONLY, MLF_LOCAL_ONLY);
-    /* Resubmit to table 45. */
+    /* Resubmit to table 56. */
     ofpbuf_clear(&ofpacts);
     put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts);
     ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0,
                     &match, &ofpacts, hc_uuid);
 
-    /* Table 43, Priority 0.
+    /* Table 54, Priority 0.
      * =======================
      *
      * Resubmit packets that are not directed at OVN tunnels or part of a
@@ -4203,7 +4203,7 @@ physical_run(struct physical_ctx *p_ctx,
     ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, 0, &match,
                     &ofpacts, hc_uuid);
 
-    /* Table 44, Priority 0.
+    /* Table 55, Priority 0.
      * =======================
      *
      * Resubmit packets that are not directed to remote VTEP to the local
@@ -4214,19 +4214,20 @@ physical_run(struct physical_ctx *p_ctx,
     ofctrl_add_flow(flow_table, OFTABLE_REMOTE_VTEP_OUTPUT, 0, 0, &match,
                     &ofpacts, hc_uuid);
 
-    /* Table 45, priority 0.
+    /* Table 56, priority 0.
      * ======================
      *
      * Drop packets that do not match previous flows.
      */
     add_default_drop_flow(p_ctx, OFTABLE_LOCAL_OUTPUT, flow_table);
 
-    /* Table 46, Priority 0.
+    /* Table 57, Priority 0.
      * =======================
      *
      * Resubmit packets that don't output to the ingress port (already checked
-     * in table 44) to the logical egress pipeline, clearing the logical
-     * registers (for consistent behavior with packets that get tunneled). */
+     * at higher priority in this table) to the logical egress pipeline,
+     * clearing the logical registers (for consistent behavior with packets
+     * that get tunneled). */
     match_init_catchall(&match);
     ofpbuf_clear(&ofpacts);
     for (int i = 0; i < MFF_N_LOG_REGS; i++) {
@@ -4236,25 +4237,25 @@ physical_run(struct physical_ctx *p_ctx,
     ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 0, 0, &match,
                     &ofpacts, hc_uuid);
 
-    /* Table 64, Priority 0.
+    /* Table 88, Priority 0.
      * =======================
      *
      * Resubmit packets that do not have the MLF_ALLOW_LOOPBACK flag set
-     * to table 65 for logical-to-physical translation. */
+     * to table 89 for logical-to-physical translation. */
     match_init_catchall(&match);
     ofpbuf_clear(&ofpacts);
     put_resubmit(OFTABLE_LOG_TO_PHY, &ofpacts);
     ofctrl_add_flow(flow_table, OFTABLE_SAVE_INPORT, 0, 0, &match,
                     &ofpacts, hc_uuid);
 
-    /* Table 65, priority 0.
+    /* Table 89, priority 0.
      * ======================
      *
      * Drop packets that do not match previous flows.
      */
     add_default_drop_flow(p_ctx, OFTABLE_LOG_TO_PHY, flow_table);
 
-    /* Table 81, 82 and 83
+    /* Table 105, 106 and 107
      * Match on ct.trk and ct.est | ct.new and store the ct_nw_dst, ct_ip6_dst,
      * ct_tp_dst and ct_proto in the registers. */
     uint32_t ct_state_est = OVS_CS_F_TRACKED | OVS_CS_F_ESTABLISHED;
@@ -4265,9 +4266,9 @@ physical_run(struct physical_ctx *p_ctx,
 
     /* Add the flows:
      * match = (ct.trk && ct.est), action = (<reg_result> = ct_tp_dst)
-     * table = 83
+     * table = 107
      * match = (ct.trk && ct.new), action = (<reg_result> = ct_tp_dst)
-     * table = 83
+     * table = 107
      */
     match_set_ct_state_masked(&match, ct_state_est, ct_state_est);
     put_move(MFF_CT_TP_DST, 0,  MFF_LOG_RESULT_REG, 0, 16, &ofpacts);
@@ -4281,9 +4282,9 @@ physical_run(struct physical_ctx *p_ctx,
 
     /* Add the flows:
      * match = (ct.trk && ct.est), action = (<reg_result> = ct_proto)
-     * table = 86
+     * table = 110
      * match = (ct.trk && ct.new), action = (<reg_result> = ct_proto)
-     * table = 86
+     * table = 110
      */
      ofpbuf_clear(&ofpacts);
      put_move(MFF_CT_NW_PROTO, 0,  MFF_LOG_RESULT_REG, 0, 8, &ofpacts);
@@ -4295,9 +4296,9 @@ physical_run(struct physical_ctx *p_ctx,
                      &match_new, &ofpacts, hc_uuid);
     /* Add the flows:
      * match = (ct.trk && ct.est && ip4), action = (<reg_result> = ct_nw_dst)
-     * table = 81
+     * table = 105
      * match = (ct.trk && ct.new && ip4), action = (<reg_result> = ct_nw_dst)
-     * table = 81
+     * table = 105
      */
     ofpbuf_clear(&ofpacts);
     match_set_dl_type(&match, htons(ETH_TYPE_IP));
@@ -4312,9 +4313,9 @@ physical_run(struct physical_ctx *p_ctx,
 
     /* Add the flows:
      * match = (ct.trk && ct.est && ip6), action = (<reg_result> = ct_ip6_dst)
-     * table = 82
+     * table = 106
      * match = (ct.trk && ct.new && ip6), action = (<reg_result> = ct_ip6_dst)
-     * table = 82
+     * table = 106
      */
     ofpbuf_clear(&ofpacts);
     match_set_dl_type(&match, htons(ETH_TYPE_IPV6));
@@ -4333,7 +4334,7 @@ physical_run(struct physical_ctx *p_ctx,
 
     /* Add the flow:
      * match = (1), action = (reg4[0..7] = ct_state[0..7])
-     * table = 85, priority = UINT16_MAX - 1
+     * table = 109, priority = UINT16_MAX - 1
      */
     match_init_catchall(&match);
     ofpbuf_clear(&ofpacts);
@@ -4343,7 +4344,7 @@ physical_run(struct physical_ctx *p_ctx,
 
     /* Add the flow:
      * match = (!ct.trk), action = (reg4[0..7] = 0)
-     * table = 85, priority = UINT16_MAX
+     * table = 109, priority = UINT16_MAX
      */
     match_init_catchall(&match);
     ofpbuf_clear(&ofpacts);
diff --git a/ovn-architecture.7.xml b/ovn-architecture.7.xml
index 522a56a8a..c49c83dd6 100644
--- a/ovn-architecture.7.xml
+++ b/ovn-architecture.7.xml
@@ -1237,8 +1237,8 @@
         output port field, and since they do not carry a logical output port
         field in the tunnel key, when a packet is received from ramp switch
         VXLAN tunnel by an OVN hypervisor, the packet is resubmitted to table 8
-        to determine the output port(s); when the packet reaches table 42,
-        these packets are resubmitted to table 43 for local delivery by
+        to determine the output port(s); when the packet reaches table 54,
+        these packets are resubmitted to table 56 for local delivery by
         checking a MLF_RCV_FROM_RAMP flag, which is set when the packet
         arrives from a ramp tunnel.
       </p>
@@ -1336,20 +1336,20 @@
         output port is known. These pieces of information are obtained
         from the tunnel encapsulation metadata (see <code>Tunnel
         Encapsulations</code> for encoding details). Then the actions resubmit
-        to table 45 to enter the logical egress pipeline.
+        to table 62 to enter the logical egress pipeline.
       </p>
     </li>
 
     <li>
       <p>
-        OpenFlow tables 8 through 39 execute the logical ingress pipeline from
+        OpenFlow tables 8 through 41 execute the logical ingress pipeline from
         the <code>Logical_Flow</code> table in the OVN Southbound database.
         These tables are expressed entirely in terms of logical concepts like
         logical ports and logical datapaths.  A big part of
         <code>ovn-controller</code>'s job is to translate them into equivalent
         OpenFlow (in particular it translates the table numbers:
-        <code>Logical_Flow</code> tables 0 through 29 become OpenFlow tables 8
-        through 39).
+        <code>Logical_Flow</code> tables 0 through 33 become OpenFlow tables 8
+        through 41).
       </p>
 
       <p>
@@ -1391,9 +1391,9 @@
       <dl>
         <dt><code>output:</code></dt>
         <dd>
-          Implemented by resubmitting the packet to table 40.  If the pipeline
+          Implemented by resubmitting the packet to table 52.  If the pipeline
           executes more than one <code>output</code> action, then each one is
-          separately resubmitted to table 40.  This can be used to send
+          separately resubmitted to table 52.  This can be used to send
           multiple copies of the packet to multiple ports.  (If the packet was
           not modified between the <code>output</code> actions, and some of the
           copies are destined to the same hypervisor, then using a logical
@@ -1405,10 +1405,10 @@
         <dd>
           <p>
             Implemented by storing arguments into OpenFlow fields, then
-            resubmitting to table 66, which <code>ovn-controller</code>
+            resubmitting to table 90, which <code>ovn-controller</code>
             populates with flows generated from the <code>MAC_Binding</code>
             table in the OVN Southbound database.  If there is a match in table
-            66, then its actions store the bound MAC in the Ethernet
+            90, then its actions store the bound MAC in the Ethernet
             destination address field.
           </p>
 
@@ -1440,10 +1440,10 @@
         <dd>
           <p>
             Implemented by storing arguments into OpenFlow fields, then
-            resubmitting to table 67, which <code>ovn-controller</code>
+            resubmitting to table 91, which <code>ovn-controller</code>
             populates with flows generated from the <code>MAC_Binding</code>
             table in the OVN Southbound database.  If there is a match in table
-            67, then its actions set the logical flow flag 
<code>MLF_LOOKUP_MAC</code>.
+            91, then its actions set the logical flow flag 
<code>MLF_LOOKUP_MAC</code>.
           </p>
 
           <p>
@@ -1457,13 +1457,13 @@
 
     <li>
       <p>
-        OpenFlow tables 40 through 44 implement the <code>output</code> action
-        in the logical ingress pipeline.  Specifically, table 40 serves as an
-        entry point to egress pipeline. Table 40 detects IP packets that are
-        too big for a corresponding interface. Table 41 produces ICMPv4
+        OpenFlow tables 52 through 57 implement the <code>output</code> action
+        in the logical ingress pipeline.  Specifically, table 52 serves as an
+        entry point to egress pipeline. Table 52 detects IP packets that are
+        too big for a corresponding interface. Table 53 produces ICMPv4
         Fragmentation Needed (or ICMPv6 Too Big) errors and deliver them back
-        to the offending port. table 42 handles packets to remote hypervisors,
-        table 43 handles packets to the local hypervisor, and table 44 checks
+        to the offending port. Table 54 handles packets to remote hypervisors,
+        table 56 handles packets to the local hypervisor, and table 57 checks
         whether packets whose logical ingress and egress port are the same
         should be discarded.
       </p>
@@ -1471,28 +1471,28 @@
       <p>
         Logical patch ports are a special case.  Logical patch ports do not
         have a physical location and effectively reside on every hypervisor.
-        Thus, flow table 43, for output to ports on the local hypervisor,
+        Thus, flow table 56, for output to ports on the local hypervisor,
         naturally implements output to unicast logical patch ports too.
         However, applying the same logic to a logical patch port that is part
         of a logical multicast group yields packet duplication, because each
         hypervisor that contains a logical port in the multicast group will
         also output the packet to the logical patch port.  Thus, multicast
-        groups implement output to logical patch ports in table 42.
+        groups implement output to logical patch ports in table 54.
       </p>
 
       <p>
-        Each flow in table 42 matches on a logical output port for unicast or
+        Each flow in table 54 matches on a logical output port for unicast or
         multicast logical ports that include a logical port on a remote
         hypervisor.  Each flow's actions implement sending a packet to the port
         it matches.  For unicast logical output ports on remote hypervisors,
         the actions set the tunnel key to the correct value, then send the
         packet on the tunnel port to the correct hypervisor.  (When the remote
         hypervisor receives the packet, table 0 there will recognize it as a
-        tunneled packet and pass it along to table 43.)  For multicast logical
+        tunneled packet and pass it along to table 56.)  For multicast logical
         output ports, the actions send one copy of the packet to each remote
         hypervisor, in the same way as for unicast destinations.  If a
         multicast group includes a logical port or ports on the local
-        hypervisor, then its actions also resubmit to table 43.  Table 42 also
+        hypervisor, then its actions also resubmit to table 56.  Table 54 also
         includes:
       </p>
 
@@ -1500,7 +1500,7 @@
         <li>
           A higher-priority rule to match packets received from ramp switch
           tunnels, based on flag MLF_RCV_FROM_RAMP, and resubmit these packets
-          to table 43 for local delivery.  Packets received from ramp switch
+          to table 56 for local delivery.  Packets received from ramp switch
           tunnels reach here because of a lack of logical output port field in
           the tunnel key and thus these packets needed to be submitted to table
           8 to determine the output port.
@@ -1508,7 +1508,7 @@
         <li>
           A higher-priority rule to match packets received from ports of type
           <code>localport</code>, based on the logical input port, and resubmit
-          these packets to table 43 for local delivery.  Ports of type
+          these packets to table 56 for local delivery.  Ports of type
           <code>localport</code> exist on every hypervisor and by definition
           their traffic should never go out through a tunnel.
         </li>
@@ -1523,48 +1523,48 @@
           packets, the packets only need to be delivered to local ports.
         </li>
         <li>
-          A fallback flow that resubmits to table 43 if there is no other
+          A fallback flow that resubmits to table 56 if there is no other
           match.
         </li>
       </ul>
 
       <p>
-        Flows in table 43 resemble those in table 42 but for logical ports that
+        Flows in table 56 resemble those in table 54 but for logical ports that
         reside locally rather than remotely.  For unicast logical output ports
-        on the local hypervisor, the actions just resubmit to table 44.  For
+        on the local hypervisor, the actions just resubmit to table 57.  For
         multicast output ports that include one or more logical ports on the
         local hypervisor, for each such logical port <var>P</var>, the actions
         change the logical output port to <var>P</var>, then resubmit to table
-        44.
+        57.
       </p>
 
       <p>
         A special case is that when a localnet port exists on the datapath,
         remote port is connected by switching to the localnet port. In this
-        case, instead of adding a flow in table 42 to reach the remote port, a
-        flow is added in table 43 to switch the logical outport to the localnet
-        port, and resubmit to table 43 as if it were unicasted to a logical
+        case, instead of adding a flow in table 54 to reach the remote port, a
+        flow is added in table 56 to switch the logical outport to the localnet
+        port, and resubmit to table 56 as if it were unicasted to a logical
         port on the local hypervisor.
       </p>
 
       <p>
-        Table 44 matches and drops packets for which the logical input and
+        Table 57 matches and drops packets for which the logical input and
         output ports are the same and the MLF_ALLOW_LOOPBACK flag is not
         set. It also drops MLF_LOCAL_ONLY packets directed to a localnet port,
         provided they aren't RAs sent from a gateway or distributed router
         which is checked via the presence of the bitflag
-        MLF_OVERRIDE_LOCAL_ONLY. It resubmits other packets to table 46.
+        MLF_OVERRIDE_LOCAL_ONLY. It resubmits other packets to table 62.
       </p>
     </li>
 
     <li>
       <p>
-        OpenFlow tables 45 through 62 execute the logical egress pipeline from
+        OpenFlow tables 62 through 77 execute the logical egress pipeline from
         the <code>Logical_Flow</code> table in the OVN Southbound database.
         The egress pipeline can perform a final stage of validation before
         packet delivery.  Eventually, it may execute an <code>output</code>
         action, which <code>ovn-controller</code> implements by resubmitting to
-        table 64.  A packet for which the pipeline never executes
+        table 88.  A packet for which the pipeline never executes
         <code>output</code> is effectively dropped (although it may have been
         transmitted through a tunnel across a physical network).
       </p>
@@ -1577,21 +1577,21 @@
 
     <li>
      <p>
-       Table 64 bypasses OpenFlow loopback when MLF_ALLOW_LOOPBACK is set.
-       Logical loopback was handled in table 44, but OpenFlow by default also
+       Table 88 bypasses OpenFlow loopback when MLF_ALLOW_LOOPBACK is set.
+       Logical loopback was handled in table 57, but OpenFlow by default also
        prevents loopback to the OpenFlow ingress port.  Thus, when
-       MLF_ALLOW_LOOPBACK is set, OpenFlow table 64 saves the OpenFlow ingress
-       port, sets it to zero, resubmits to table 65 for logical-to-physical
+       MLF_ALLOW_LOOPBACK is set, OpenFlow table 88 saves the OpenFlow ingress
+       port, sets it to zero, resubmits to table 89 for logical-to-physical
        transformation, and then restores the OpenFlow ingress port,
        effectively disabling OpenFlow loopback prevents.  When
-       MLF_ALLOW_LOOPBACK is unset, table 64 flow simply resubmits to table
-       65.
+       MLF_ALLOW_LOOPBACK is unset, table 88 flow simply resubmits to table
+       89.
      </p>
     </li>
 
     <li>
       <p>
-        OpenFlow table 65 performs logical-to-physical translation, the
+        OpenFlow table 89 performs logical-to-physical translation, the
         opposite of table 0.  It matches the packet's logical egress port.  Its
         actions output the packet to the port attached to the OVN integration
         bridge that represents that logical port.  If the logical egress port
@@ -1613,17 +1613,17 @@
   <p>
     Consider a packet sent from one virtual machine or container to another
     VM or container that resides on a different subnet.  The packet will
-    traverse tables 0 to 65 as described in the previous section
+    traverse tables 0 to 89 as described in the previous section
     <code>Architectural Physical Life Cycle of a Packet</code>, using the
     logical datapath representing the logical switch that the sender is
-    attached to.  At table 42, the packet will use the fallback flow that
-    resubmits locally to table 43 on the same hypervisor.  In this case,
-    all of the processing from table 0 to table 65 occurs on the hypervisor
+    attached to.  At table 54, the packet will use the fallback flow that
+    resubmits locally to table 56 on the same hypervisor.  In this case,
+    all of the processing from table 0 to table 89 occurs on the hypervisor
     where the sender resides.
   </p>
 
   <p>
-    When the packet reaches table 65, the logical egress port is a
+    When the packet reaches table 89, the logical egress port is a
     logical patch port.  <code>ovn-controller</code> implements output
     to the logical patch is packet by cloning and resubmitting
     directly to the first OpenFlow flow table in the ingress pipeline,
@@ -1634,22 +1634,22 @@
 
   <p>
     The packet re-enters the ingress pipeline in order to traverse tables
-    8 to 65 again, this time using the logical datapath representing the
+    8 to 89 again, this time using the logical datapath representing the
     logical router.  The processing continues as described in the previous
     section <code>Architectural Physical Life Cycle of a Packet</code>.
-    When the packet reaches table 65, the logical egress port will once
+    When the packet reaches table 89, the logical egress port will once
     again be a logical patch port.  In the same manner as described above,
     this logical patch port will cause the packet to be resubmitted to
-    OpenFlow tables 8 to 65, this time using the logical datapath
+    OpenFlow tables 8 to 89, this time using the logical datapath
     representing the logical switch that the destination VM or container
     is attached to.
   </p>
 
   <p>
-    The packet traverses tables 8 to 65 a third and final time.  If the
+    The packet traverses tables 8 to 89 a third and final time.  If the
     destination VM or container resides on a remote hypervisor, then table
-    39 will send the packet on a tunnel port from the sender's hypervisor
-    to the remote hypervisor.  Finally table 65 will output the packet
+    54 will send the packet on a tunnel port from the sender's hypervisor
+    to the remote hypervisor.  Finally table 89 will output the packet
     directly to the destination VM or container.
   </p>
 
@@ -1675,9 +1675,9 @@
     When a hypervisor processes a packet on a logical datapath
     representing a logical switch, and the logical egress port is a
     <code>l3gateway</code> port representing connectivity to a gateway
-    router, the packet will match a flow in table 42 that sends the
+    router, the packet will match a flow in table 54 that sends the
     packet on a tunnel port to the chassis where the gateway router
-    resides.  This processing in table 42 is done in the same manner as
+    resides.  This processing in table 54 is done in the same manner as
     for VIFs.
   </p>
 
@@ -1770,21 +1770,21 @@
     chassis, one additional mechanism is required.  When a packet
     leaves the ingress pipeline and the logical egress port is the
     distributed gateway port, one of two different sets of actions is
-    required at table 42:
+    required at table 54:
   </p>
 
   <ul>
     <li>
       If the packet can be handled locally on the sender's hypervisor
       (e.g. one-to-one NAT traffic), then the packet should just be
-      resubmitted locally to table 43, in the normal manner for
+      resubmitted locally to table 56, in the normal manner for
       distributed logical patch ports.
     </li>
 
     <li>
       However, if the packet needs to be handled on the chassis
       associated with the distributed gateway port (e.g. one-to-many
-      SNAT traffic or non-NAT traffic), then table 42 must send the
+      SNAT traffic or non-NAT traffic), then table 54 must send the
       packet on a tunnel port to that chassis.
     </li>
   </ul>
@@ -1796,11 +1796,11 @@
     egress port to the type <code>chassisredirect</code> logical port is
     simply a way to indicate that although the packet is destined for
     the distributed gateway port, it needs to be redirected to a
-    different chassis.  At table 42, packets with this logical egress
-    port are sent to a specific chassis, in the same way that table 42
+    different chassis.  At table 54, packets with this logical egress
+    port are sent to a specific chassis, in the same way that table 54
     directs packets whose logical egress port is a VIF or a type
     <code>l3gateway</code> port to different chassis.  Once the packet
-    arrives at that chassis, table 43 resets the logical egress port to
+    arrives at that chassis, table 56 resets the logical egress port to
     the value representing the distributed gateway port.  For each
     distributed gateway port, there is one type
     <code>chassisredirect</code> port, in addition to the distributed
diff --git a/tests/ovn-macros.at b/tests/ovn-macros.at
index 8744ff6b3..c4f80642d 100644
--- a/tests/ovn-macros.at
+++ b/tests/ovn-macros.at
@@ -1617,36 +1617,37 @@ m4_define([OVN_SKIP_MEM_LEAK],[
 
 m4_define([OFTABLE_PHY_TO_LOG], [0])
 m4_define([OFTABLE_LOG_INGRESS_PIPELINE], [8])
-m4_define([OFTABLE_OUTPUT_LARGE_PKT_DETECT], [42])
-m4_define([OFTABLE_OUTPUT_LARGE_PKT_PROCESS], [43])
-m4_define([OFTABLE_REMOTE_OUTPUT], [44])
-m4_define([OFTABLE_REMOTE_VTEP_OUTPUT], [45])
-m4_define([OFTABLE_LOCAL_OUTPUT], [46])
-m4_define([OFTABLE_LOG_EGRESS_PIPELINE], [48])
-m4_define([OFTABLE_SAVE_INPORT], [64])
-m4_define([OFTABLE_LOG_TO_PHY], [65])
-m4_define([OFTABLE_MAC_BINDING], [66])
-m4_define([OFTABLE_MAC_LOOKUP], [67])
-m4_define([OFTABLE_CHK_LB_HAIRPIN], [68])
-m4_define([OFTABLE_CHK_LB_HAIRPIN_REPLY], [69])
-m4_define([OFTABLE_CT_SNAT_HAIRPIN], [70])
-m4_define([OFTABLE_GET_FDB], [71])
-m4_define([OFTABLE_LOOKUP_FDB], [72])
-m4_define([OFTABLE_CHK_IN_PORT_SEC], [73])
-m4_define([OFTABLE_CHK_IN_PORT_SEC_ND], [74])
-m4_define([OFTABLE_CHK_OUT_PORT_SEC], [75])
-m4_define([OFTABLE_ECMP_NH_MAC], [76])
-m4_define([OFTABLE_ECMP_NH], [77])
-m4_define([OFTABLE_CHK_LB_AFFINITY], [78])
-m4_define([OFTABLE_MAC_CACHE_USE], [79])
-m4_define([OFTABLE_CT_ZONE_LOOKUP], [80])
-m4_define([OFTABLE_CT_ORIG_NW_DST_LOAD], [81])
-m4_define([OFTABLE_CT_ORIG_IP6_DST_LOAD], [82])
-m4_define([OFTABLE_CT_ORIG_TP_DST_LOAD], [83])
-m4_define([OFTABLE_FLOOD_REMOTE_CHASSIS], [84])
-m4_define([OFTABLE_CT_STATE_SAVE], [85])
-m4_define([OFTABLE_CT_ORIG_PROTO_LOAD], [86])
-m4_define([OFTABLE_GET_REMOTE_FDB], [87])
-m4_define([OFTABLE_LEARN_REMOTE_FDB], [88])
+m4_define([OFTABLE_OUTPUT_LARGE_PKT_DETECT], [52])
+m4_define([OFTABLE_OUTPUT_LARGE_PKT_PROCESS], [53])
+m4_define([OFTABLE_REMOTE_OUTPUT], [54])
+m4_define([OFTABLE_REMOTE_VTEP_OUTPUT], [55])
+m4_define([OFTABLE_LOCAL_OUTPUT], [56])
+m4_define([OFTABLE_CHECK_LOOPBACK], [57])
+m4_define([OFTABLE_LOG_EGRESS_PIPELINE], [62])
+m4_define([OFTABLE_SAVE_INPORT], [88])
+m4_define([OFTABLE_LOG_TO_PHY], [89])
+m4_define([OFTABLE_MAC_BINDING], [90])
+m4_define([OFTABLE_MAC_LOOKUP], [91])
+m4_define([OFTABLE_CHK_LB_HAIRPIN], [92])
+m4_define([OFTABLE_CHK_LB_HAIRPIN_REPLY], [93])
+m4_define([OFTABLE_CT_SNAT_HAIRPIN], [94])
+m4_define([OFTABLE_GET_FDB], [95])
+m4_define([OFTABLE_LOOKUP_FDB], [96])
+m4_define([OFTABLE_CHK_IN_PORT_SEC], [97])
+m4_define([OFTABLE_CHK_IN_PORT_SEC_ND], [98])
+m4_define([OFTABLE_CHK_OUT_PORT_SEC], [99])
+m4_define([OFTABLE_ECMP_NH_MAC], [100])
+m4_define([OFTABLE_ECMP_NH], [101])
+m4_define([OFTABLE_CHK_LB_AFFINITY], [102])
+m4_define([OFTABLE_MAC_CACHE_USE], [103])
+m4_define([OFTABLE_CT_ZONE_LOOKUP], [104])
+m4_define([OFTABLE_CT_ORIG_NW_DST_LOAD], [105])
+m4_define([OFTABLE_CT_ORIG_IP6_DST_LOAD], [106])
+m4_define([OFTABLE_CT_ORIG_TP_DST_LOAD], [107])
+m4_define([OFTABLE_FLOOD_REMOTE_CHASSIS], [108])
+m4_define([OFTABLE_CT_STATE_SAVE], [109])
+m4_define([OFTABLE_CT_ORIG_PROTO_LOAD], [110])
+m4_define([OFTABLE_GET_REMOTE_FDB], [111])
+m4_define([OFTABLE_LEARN_REMOTE_FDB], [112])
 
 m4_define([OFTABLE_SAVE_INPORT_HEX], [m4_eval(OFTABLE_SAVE_INPORT, 16)])
diff --git a/tests/ovn.at b/tests/ovn.at
index 1009dd55c..272346dd7 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -43702,8 +43702,6 @@ OVN_FOR_EACH_NORTHD([
 AT_SETUP([requested-tnl-key-recompute])
 AT_KEYWORDS([requested-tnl-key-recompute])
 
-m4_define([OFTABLE_LOG_TO_PHY], [65])
-
 ovn_start
 net_add n1
 
-- 
2.54.0

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

Reply via email to