Hi Paulo,

Just a couple of minor nits on this patch. See below.

On Wed, Aug 12, 2026 at 10:56 PM Paulo Guilherme Silva
<[email protected]> wrote:
>
> Replace the single monolithic en_ic engine node (which ran the whole
> ovn_db_run() full recompute on any tracked change) with one engine node
> per subsystem: en_dp_enum, en_gateway, en_ts, en_tr, en_port_binding,
> en_route, en_service_monitor and en_address_set.  en_ic becomes a pure
> output node that only aggregates them.
>
> Each subsystem node still performs a full recompute in its run() method
> (no change handlers yet), but is now gated on only the table inputs it
> actually reads, so an unrelated change no longer forces every subsystem
> to recompute.  Change handlers are added incrementally in later commits.
>
> The transit switch/router datapath tunnel-key allocator and the transit
> switch/router datapath maps (previously built on the stack by
> enumerate_datapaths() and shared by ts_run()/tr_run()) are now owned by
> the en_dp_enum node.  en_dp_enum depends on every input that can trigger
> a tunnel-key allocation (IC-SB datapath bindings, transit switches,
> transit routers and vxlan_mode) so the allocator is always rebuilt from
> scratch in the same iteration as any allocation, preserving correctness.
>
> The address-set synchronization added by the "ovn-ic: Address set
> synchronization across AZs" upstream commit becomes the en_address_set
> node, gated on the NB/SB/IC-SB Address_Set tables and NB_Global.
>
> The ic_sb_global table is no longer modeled as an engine input: it only
> carries IC-SB sequence numbers written by update_sequence_numbers() in
> the main loop, outside the engine, and is not read by any subsystem.
>
> No functional change: all existing ovn-ic system tests pass.
>
> Assisted-by: Claude Opus 4.8, Claude Code
> Signed-off-by: Paulo Guilherme Silva <[email protected]>
> ---
>  ic/automake.mk          |  16 +++++
>  ic/en-address-set.c     |  45 ++++++++++++
>  ic/en-address-set.h     |  13 ++++
>  ic/en-dp-enum.c         |  68 ++++++++++++++++++
>  ic/en-dp-enum.h         |  32 +++++++++
>  ic/en-gateway.c         |  45 ++++++++++++
>  ic/en-gateway.h         |  12 ++++
>  ic/en-ic.c              |   9 ++-
>  ic/en-port-binding.c    |  45 ++++++++++++
>  ic/en-port-binding.h    |  13 ++++
>  ic/en-route.c           |  45 ++++++++++++
>  ic/en-route.h           |  12 ++++
>  ic/en-service-monitor.c |  46 ++++++++++++
>  ic/en-service-monitor.h |  14 ++++
>  ic/en-tr.c              |  47 ++++++++++++
>  ic/en-tr.h              |  12 ++++
>  ic/en-ts.c              |  47 ++++++++++++
>  ic/en-ts.h              |  12 ++++
>  ic/inc-proc-ic.c        | 153 ++++++++++++++++++++++++++++++----------
>  ic/ovn-ic.c             |  22 +-----
>  ic/ovn-ic.h             |   2 -
>  21 files changed, 646 insertions(+), 64 deletions(-)
>  create mode 100644 ic/en-address-set.c
>  create mode 100644 ic/en-address-set.h
>  create mode 100644 ic/en-dp-enum.c
>  create mode 100644 ic/en-dp-enum.h
>  create mode 100644 ic/en-gateway.c
>  create mode 100644 ic/en-gateway.h
>  create mode 100644 ic/en-port-binding.c
>  create mode 100644 ic/en-port-binding.h
>  create mode 100644 ic/en-route.c
>  create mode 100644 ic/en-route.h
>  create mode 100644 ic/en-service-monitor.c
>  create mode 100644 ic/en-service-monitor.h
>  create mode 100644 ic/en-tr.c
>  create mode 100644 ic/en-tr.h
>  create mode 100644 ic/en-ts.c
>  create mode 100644 ic/en-ts.h
>
> diff --git a/ic/automake.mk b/ic/automake.mk
> index a69b1030d..fd888d60c 100644
> --- a/ic/automake.mk
> +++ b/ic/automake.mk
> @@ -4,6 +4,22 @@ ic_ovn_ic_SOURCES = ic/ovn-ic.c \
>         ic/ovn-ic.h \
>         ic/en-ic.c \
>         ic/en-ic.h \
> +       ic/en-dp-enum.c \
> +       ic/en-dp-enum.h \
> +       ic/en-gateway.c \
> +       ic/en-gateway.h \
> +       ic/en-ts.c \
> +       ic/en-ts.h \
> +       ic/en-tr.c \
> +       ic/en-tr.h \
> +       ic/en-port-binding.c \
> +       ic/en-port-binding.h \
> +       ic/en-route.c \
> +       ic/en-route.h \
> +       ic/en-service-monitor.c \
> +       ic/en-service-monitor.h \
> +       ic/en-address-set.c \
> +       ic/en-address-set.h \
>         ic/inc-proc-ic.c \
>         ic/inc-proc-ic.h
>  ic_ovn_ic_LDADD = \
> diff --git a/ic/en-address-set.c b/ic/en-address-set.c
> new file mode 100644
> index 000000000..764dd71d2
> --- /dev/null
> +++ b/ic/en-address-set.c
> @@ -0,0 +1,45 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-address-set.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_address_set);
> +
> +enum engine_node_state
> +en_address_set_run(struct engine_node *node OVS_UNUSED, void *data 
> OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +
> +    address_set_run(ctx);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_address_set_init(struct engine_node *node OVS_UNUSED,
> +                    struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_address_set_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-address-set.h b/ic/en-address-set.h
> new file mode 100644
> index 000000000..c52086009
> --- /dev/null
> +++ b/ic/en-address-set.h
> @@ -0,0 +1,13 @@
> +#ifndef EN_IC_ADDRESS_SET_H
> +#define EN_IC_ADDRESS_SET_H 1
> +
> +#include <config.h>

I won't note every time this happens, but in this change and in every
other throughout this series, config.h is included in new header
files. config.h is only supposed to be included in source (.c) files.

> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_address_set_run(struct engine_node *node,
> +                                           void *data);
> +void *en_address_set_init(struct engine_node *node, struct engine_arg *arg);
> +void en_address_set_cleanup(void *data);
> +
> +#endif /* EN_IC_ADDRESS_SET_H */
> diff --git a/ic/en-dp-enum.c b/ic/en-dp-enum.c
> new file mode 100644
> index 000000000..fd447ab52
> --- /dev/null
> +++ b/ic/en-dp-enum.c
> @@ -0,0 +1,68 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-dp-enum.h"
> +#include "lib/inc-proc-eng.h"
> +#include "lib/ovn-util.h"
> +#include "openvswitch/hmap.h"
> +#include "openvswitch/shash.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_dp_enum);
> +
> +enum engine_node_state
> +en_dp_enum_run(struct engine_node *node OVS_UNUSED, void *data_)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +    struct ed_type_dp_enum *data = data_;
> +
> +    /* Clear the previous iteration's state and rebuild from the current 
> IC-SB
> +     * datapath bindings. */
> +    ovn_destroy_tnlids(&data->dp_tnlids);
> +    hmap_init(&data->dp_tnlids);
> +    shash_clear(&data->isb_ts_dps);
> +    shash_clear(&data->isb_tr_dps);
> +
> +    enumerate_datapaths(ctx, &data->dp_tnlids, &data->isb_ts_dps,
> +                        &data->isb_tr_dps);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_dp_enum_init(struct engine_node *node OVS_UNUSED,
> +                struct engine_arg *arg OVS_UNUSED)
> +{
> +    struct ed_type_dp_enum *data = xzalloc(sizeof *data);
> +
> +    hmap_init(&data->dp_tnlids);
> +    shash_init(&data->isb_ts_dps);
> +    shash_init(&data->isb_tr_dps);
> +
> +    return data;
> +}
> +
> +void
> +en_dp_enum_cleanup(void *data_)
> +{
> +    struct ed_type_dp_enum *data = data_;
> +
> +    ovn_destroy_tnlids(&data->dp_tnlids);
> +    shash_destroy(&data->isb_ts_dps);
> +    shash_destroy(&data->isb_tr_dps);
> +}
> diff --git a/ic/en-dp-enum.h b/ic/en-dp-enum.h
> new file mode 100644
> index 000000000..b843400e5
> --- /dev/null
> +++ b/ic/en-dp-enum.h
> @@ -0,0 +1,32 @@
> +#ifndef EN_IC_DP_ENUM_H
> +#define EN_IC_DP_ENUM_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/hmap.h"
> +#include "openvswitch/shash.h"
> +
> +/* Data maintained by the "dp_enum" engine node: the result of enumerating 
> the
> + * IC-SB datapath bindings.  It is the explicit, engine-visible form of the
> + * state that used to be built on the stack by enumerate_datapaths() inside
> + * ovn_db_run().  The transit-switch (en_ts) and transit-router (en_tr) nodes
> + * consume this data instead of rebuilding it themselves, which also keeps 
> the
> + * shared 'dp_tnlids' tunnel-key allocator consistent between them. */
> +struct ed_type_dp_enum {
> +    /* Set of tunnel keys already in use by IC-SB datapath bindings.  Holds
> +     * 'struct tnlid_node *' entries owned by this node. */
> +    struct hmap dp_tnlids;
> +    /* Transit-switch datapath bindings, keyed by transit switch name.  
> Values
> +     * are 'const struct icsbrec_datapath_binding *' owned by the IDL. */
> +    struct shash isb_ts_dps;
> +    /* Transit-router datapath bindings, keyed by NB IC UUID string.  Values
> +     * are 'const struct icsbrec_datapath_binding *' owned by the IDL. */
> +    struct shash isb_tr_dps;
> +};
> +
> +enum engine_node_state en_dp_enum_run(struct engine_node *node, void *data);
> +void *en_dp_enum_init(struct engine_node *node, struct engine_arg *arg);
> +void en_dp_enum_cleanup(void *data);
> +
> +#endif /* EN_IC_DP_ENUM_H */
> diff --git a/ic/en-gateway.c b/ic/en-gateway.c
> new file mode 100644
> index 000000000..f41166018
> --- /dev/null
> +++ b/ic/en-gateway.c
> @@ -0,0 +1,45 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-gateway.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_gateway);
> +
> +enum engine_node_state
> +en_gateway_run(struct engine_node *node OVS_UNUSED, void *data OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +
> +    gateway_run(ctx);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_gateway_init(struct engine_node *node OVS_UNUSED,
> +                struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_gateway_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-gateway.h b/ic/en-gateway.h
> new file mode 100644
> index 000000000..76d0b08a9
> --- /dev/null
> +++ b/ic/en-gateway.h
> @@ -0,0 +1,12 @@
> +#ifndef EN_IC_GATEWAY_H
> +#define EN_IC_GATEWAY_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_gateway_run(struct engine_node *node, void *data);
> +void *en_gateway_init(struct engine_node *node, struct engine_arg *arg);
> +void en_gateway_cleanup(void *data);
> +
> +#endif /* EN_IC_GATEWAY_H */
> diff --git a/ic/en-ic.c b/ic/en-ic.c
> index 2db9d3b84..a5224ed81 100644
> --- a/ic/en-ic.c
> +++ b/ic/en-ic.c
> @@ -29,11 +29,10 @@ VLOG_DEFINE_THIS_MODULE(en_ic);
>  enum engine_node_state
>  en_ic_run(struct engine_node *node OVS_UNUSED, void *data OVS_UNUSED)
>  {
> -    const struct engine_context *eng_ctx = engine_get_context();
> -    struct ic_context *ctx = eng_ctx->client_ctx;
> -
> -    ovn_db_run(ctx);
> -
> +    /* 'en_ic' is the engine's output node and only aggregates the per
> +     * subsystem nodes (gateway, ts, tr, port_binding, route, 
> service_monitor).

This is very nitpicky, but address_set is missing from this list.

> +     * Each of those nodes performs (and gates) its own work, so this node 
> has
> +     * nothing to compute itself. */
>      return EN_UPDATED;
>  }
>
> diff --git a/ic/en-port-binding.c b/ic/en-port-binding.c
> new file mode 100644
> index 000000000..8843d6cef
> --- /dev/null
> +++ b/ic/en-port-binding.c
> @@ -0,0 +1,45 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-port-binding.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_port_binding);
> +
> +enum engine_node_state
> +en_port_binding_run(struct engine_node *node OVS_UNUSED, void *data 
> OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +
> +    port_binding_run(ctx);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_port_binding_init(struct engine_node *node OVS_UNUSED,
> +                     struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_port_binding_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-port-binding.h b/ic/en-port-binding.h
> new file mode 100644
> index 000000000..1cf71eb9a
> --- /dev/null
> +++ b/ic/en-port-binding.h
> @@ -0,0 +1,13 @@
> +#ifndef EN_IC_PORT_BINDING_H
> +#define EN_IC_PORT_BINDING_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_port_binding_run(struct engine_node *node,
> +                                           void *data);
> +void *en_port_binding_init(struct engine_node *node, struct engine_arg *arg);
> +void en_port_binding_cleanup(void *data);
> +
> +#endif /* EN_IC_PORT_BINDING_H */
> diff --git a/ic/en-route.c b/ic/en-route.c
> new file mode 100644
> index 000000000..ec39d89d9
> --- /dev/null
> +++ b/ic/en-route.c
> @@ -0,0 +1,45 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-route.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_route);
> +
> +enum engine_node_state
> +en_route_run(struct engine_node *node OVS_UNUSED, void *data OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +
> +    route_run(ctx);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_route_init(struct engine_node *node OVS_UNUSED,
> +              struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_route_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-route.h b/ic/en-route.h
> new file mode 100644
> index 000000000..1ca8de359
> --- /dev/null
> +++ b/ic/en-route.h
> @@ -0,0 +1,12 @@
> +#ifndef EN_IC_ROUTE_H
> +#define EN_IC_ROUTE_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_route_run(struct engine_node *node, void *data);
> +void *en_route_init(struct engine_node *node, struct engine_arg *arg);
> +void en_route_cleanup(void *data);
> +
> +#endif /* EN_IC_ROUTE_H */
> diff --git a/ic/en-service-monitor.c b/ic/en-service-monitor.c
> new file mode 100644
> index 000000000..b85a36dc7
> --- /dev/null
> +++ b/ic/en-service-monitor.c
> @@ -0,0 +1,46 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-service-monitor.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_service_monitor);
> +
> +enum engine_node_state
> +en_service_monitor_run(struct engine_node *node OVS_UNUSED,
> +                       void *data OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +
> +    sync_service_monitor(ctx);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_service_monitor_init(struct engine_node *node OVS_UNUSED,
> +                        struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_service_monitor_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-service-monitor.h b/ic/en-service-monitor.h
> new file mode 100644
> index 000000000..021f3e6b8
> --- /dev/null
> +++ b/ic/en-service-monitor.h
> @@ -0,0 +1,14 @@
> +#ifndef EN_IC_SERVICE_MONITOR_H
> +#define EN_IC_SERVICE_MONITOR_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_service_monitor_run(struct engine_node *node,
> +                                              void *data);
> +void *en_service_monitor_init(struct engine_node *node,
> +                              struct engine_arg *arg);
> +void en_service_monitor_cleanup(void *data);
> +
> +#endif /* EN_IC_SERVICE_MONITOR_H */
> diff --git a/ic/en-tr.c b/ic/en-tr.c
> new file mode 100644
> index 000000000..4f05a4325
> --- /dev/null
> +++ b/ic/en-tr.c
> @@ -0,0 +1,47 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-dp-enum.h"
> +#include "en-tr.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_tr);
> +
> +enum engine_node_state
> +en_tr_run(struct engine_node *node, void *data OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +    struct ed_type_dp_enum *dp = engine_get_input_data("dp_enum", node);
> +
> +    tr_run(ctx, &dp->dp_tnlids, &dp->isb_tr_dps);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_tr_init(struct engine_node *node OVS_UNUSED,
> +           struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_tr_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-tr.h b/ic/en-tr.h
> new file mode 100644
> index 000000000..0a29de2e5
> --- /dev/null
> +++ b/ic/en-tr.h
> @@ -0,0 +1,12 @@
> +#ifndef EN_IC_TR_H
> +#define EN_IC_TR_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_tr_run(struct engine_node *node, void *data);
> +void *en_tr_init(struct engine_node *node, struct engine_arg *arg);
> +void en_tr_cleanup(void *data);
> +
> +#endif /* EN_IC_TR_H */
> diff --git a/ic/en-ts.c b/ic/en-ts.c
> new file mode 100644
> index 000000000..e8df1888a
> --- /dev/null
> +++ b/ic/en-ts.c
> @@ -0,0 +1,47 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include "en-dp-enum.h"
> +#include "en-ts.h"
> +#include "lib/inc-proc-eng.h"
> +#include "openvswitch/vlog.h"
> +#include "ovn-ic.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_ic_ts);
> +
> +enum engine_node_state
> +en_ts_run(struct engine_node *node, void *data OVS_UNUSED)
> +{
> +    const struct engine_context *eng_ctx = engine_get_context();
> +    struct ic_context *ctx = eng_ctx->client_ctx;
> +    struct ed_type_dp_enum *dp = engine_get_input_data("dp_enum", node);
> +
> +    ts_run(ctx, &dp->dp_tnlids, &dp->isb_ts_dps);
> +
> +    return EN_UPDATED;
> +}
> +
> +void *
> +en_ts_init(struct engine_node *node OVS_UNUSED,
> +           struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void
> +en_ts_cleanup(void *data OVS_UNUSED)
> +{
> +}
> diff --git a/ic/en-ts.h b/ic/en-ts.h
> new file mode 100644
> index 000000000..039b3196f
> --- /dev/null
> +++ b/ic/en-ts.h
> @@ -0,0 +1,12 @@
> +#ifndef EN_IC_TS_H
> +#define EN_IC_TS_H 1
> +
> +#include <config.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_ts_run(struct engine_node *node, void *data);
> +void *en_ts_init(struct engine_node *node, struct engine_arg *arg);
> +void en_ts_cleanup(void *data);
> +
> +#endif /* EN_IC_TS_H */
> diff --git a/ic/inc-proc-ic.c b/ic/inc-proc-ic.c
> index bbcbcdd17..8721c5673 100644
> --- a/ic/inc-proc-ic.c
> +++ b/ic/inc-proc-ic.c
> @@ -27,6 +27,14 @@
>  #include "openvswitch/vlog.h"
>  #include "inc-proc-ic.h"
>  #include "en-ic.h"
> +#include "en-dp-enum.h"
> +#include "en-gateway.h"
> +#include "en-ts.h"
> +#include "en-tr.h"
> +#include "en-port-binding.h"
> +#include "en-route.h"
> +#include "en-service-monitor.h"
> +#include "en-address-set.h"
>  #include "ovn-util.h"
>  #include "unixctl.h"
>  #include "util.h"
> @@ -108,8 +116,11 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic);
>      ICNB_NODES
>  #undef ICNB_NODE
>
> +/* Note: the ic_sb_global table is intentionally not modeled as an engine 
> input
> + * node.  It only carries IC-SB sequence numbers, which are written by
> + * update_sequence_numbers() in the main loop (outside the engine) and are 
> not
> + * read by any subsystem node. */
>  #define ICSB_NODES \
> -    ICSB_NODE(ic_sb_global, "ic_sb_global") \
>      ICSB_NODE(availability_zone, "availability_zone") \
>      ICSB_NODE(service_monitor, "service_monitor") \
>      ICSB_NODE(route, "route") \
> @@ -162,6 +173,14 @@ VLOG_DEFINE_THIS_MODULE(inc_proc_ic);
>
>  /* Define engine nodes for other nodes. They should be defined as static to
>   * avoid sparse errors. */
> +static ENGINE_NODE(dp_enum);
> +static ENGINE_NODE(gateway);
> +static ENGINE_NODE(ts);
> +static ENGINE_NODE(tr);
> +static ENGINE_NODE(port_binding);
> +static ENGINE_NODE(route);
> +static ENGINE_NODE(service_monitor);
> +static ENGINE_NODE(address_set);
>  static ENGINE_NODE(ic);
>
>  void inc_proc_ic_init(struct ovsdb_idl_loop *nb,
> @@ -169,41 +188,103 @@ void inc_proc_ic_init(struct ovsdb_idl_loop *nb,
>                        struct ovsdb_idl_loop *icnb,
>                        struct ovsdb_idl_loop *icsb)
>  {
> -    /* Define relationships between nodes where first argument is dependent
> -     * on the second argument */
> -    engine_add_input(&en_ic, &en_nb_nb_global, NULL);
> -    engine_add_input(&en_ic, &en_nb_logical_router_static_route, NULL);
> -    engine_add_input(&en_ic, &en_nb_logical_router, NULL);
> -    engine_add_input(&en_ic, &en_nb_logical_router_port, NULL);
> -    engine_add_input(&en_ic, &en_nb_logical_switch, NULL);
> -    engine_add_input(&en_ic, &en_nb_logical_switch_port, NULL);
> -    engine_add_input(&en_ic, &en_nb_load_balancer, NULL);
> -    engine_add_input(&en_ic, &en_nb_load_balancer_group, NULL);
> -    engine_add_input(&en_ic, &en_nb_address_set, NULL);
> -
> -    engine_add_input(&en_ic, &en_sb_sb_global, NULL);
> -    engine_add_input(&en_ic, &en_sb_chassis, NULL);
> -    engine_add_input(&en_ic, &en_sb_encap, NULL);
> -    engine_add_input(&en_ic, &en_sb_datapath_binding, NULL);
> -    engine_add_input(&en_ic, &en_sb_port_binding, NULL);
> -    engine_add_input(&en_ic, &en_sb_service_monitor, NULL);
> -    engine_add_input(&en_ic, &en_sb_learned_route, NULL);
> -    engine_add_input(&en_ic, &en_sb_address_set, NULL);
> -
> -    engine_add_input(&en_ic, &en_icnb_ic_nb_global, NULL);
> -    engine_add_input(&en_ic, &en_icnb_transit_switch, NULL);
> -    engine_add_input(&en_ic, &en_icnb_transit_router, NULL);
> -    engine_add_input(&en_ic, &en_icnb_transit_router_port, NULL);
> -
> -    engine_add_input(&en_ic, &en_icsb_encap, NULL);
> -    engine_add_input(&en_ic, &en_icsb_service_monitor, NULL);
> -    engine_add_input(&en_ic, &en_icsb_ic_sb_global, NULL);
> -    engine_add_input(&en_ic, &en_icsb_port_binding, NULL);
> -    engine_add_input(&en_ic, &en_icsb_availability_zone, NULL);
> -    engine_add_input(&en_ic, &en_icsb_gateway, NULL);
> -    engine_add_input(&en_ic, &en_icsb_route, NULL);
> -    engine_add_input(&en_ic, &en_icsb_datapath_binding, NULL);
> -    engine_add_input(&en_ic, &en_icsb_address_set, NULL);
> +    /* Define relationships between nodes where the first argument is 
> dependent
> +     * on the second argument.
> +     *
> +     * Each subsystem node below depends on the table input nodes it reads, 
> so
> +     * the engine only re-runs a subsystem when one of its inputs changed.  
> No
> +     * change handlers are wired yet: every dependency uses a NULL handler, 
> so
> +     * any tracked change to an input triggers a full recompute of just that
> +     * subsystem (run() method).  This preserves the previous behavior while
> +     * splitting the monolithic ovn_db_run() into independently-gated nodes.
> +     * Change handlers are added incrementally in a later step. */
> +
> +    /* en_dp_enum: enumerate IC-SB datapath bindings (tunnel-key allocator 
> and
> +     * transit switch/router datapath maps shared by en_ts and en_tr).
> +     *
> +     * en_ts and en_tr allocate datapath tunnel keys from the shared
> +     * 'dp_tnlids' set owned by this node, mutating it during their run.  To
> +     * keep that allocator correct, en_dp_enum must rebuild it from scratch 
> in
> +     * the same iteration as any allocation.  It therefore depends not only 
> on
> +     * the IC-SB datapath bindings themselves, but also on every input that 
> can
> +     * cause en_ts/en_tr to allocate a key: a new transit switch or router, 
> or
> +     * a change of vxlan_mode (which forces a tunnel-key refresh). */
> +    engine_add_input(&en_dp_enum, &en_icsb_datapath_binding, NULL);
> +    engine_add_input(&en_dp_enum, &en_icnb_transit_switch, NULL);
> +    engine_add_input(&en_dp_enum, &en_icnb_transit_router, NULL);
> +    engine_add_input(&en_dp_enum, &en_icnb_ic_nb_global, NULL);
> +
> +    /* en_gateway: sync gateways/chassis between SB and IC-SB. */
> +    engine_add_input(&en_gateway, &en_icsb_availability_zone, NULL);
> +    engine_add_input(&en_gateway, &en_icsb_gateway, NULL);
> +    engine_add_input(&en_gateway, &en_icsb_encap, NULL);
> +    engine_add_input(&en_gateway, &en_sb_chassis, NULL);
> +    engine_add_input(&en_gateway, &en_sb_encap, NULL);
> +
> +    /* en_ts: sync transit switches to NB and IC-SB datapath bindings. */
> +    engine_add_input(&en_ts, &en_dp_enum, NULL);
> +    engine_add_input(&en_ts, &en_icnb_ic_nb_global, NULL);
> +    engine_add_input(&en_ts, &en_icnb_transit_switch, NULL);
> +    engine_add_input(&en_ts, &en_nb_logical_switch, NULL);
> +    engine_add_input(&en_ts, &en_icsb_encap, NULL);
> +
> +    /* en_tr: sync transit routers to NB and IC-SB datapath bindings. */
> +    engine_add_input(&en_tr, &en_dp_enum, NULL);
> +    engine_add_input(&en_tr, &en_icnb_transit_router, NULL);
> +    engine_add_input(&en_tr, &en_nb_logical_router, NULL);
> +
> +    /* en_port_binding: sync cross-AZ port bindings. */
> +    engine_add_input(&en_port_binding, &en_icsb_availability_zone, NULL);
> +    engine_add_input(&en_port_binding, &en_icsb_port_binding, NULL);
> +    engine_add_input(&en_port_binding, &en_icnb_transit_switch, NULL);
> +    engine_add_input(&en_port_binding, &en_icnb_transit_router, NULL);
> +    engine_add_input(&en_port_binding, &en_icnb_transit_router_port, NULL);
> +    engine_add_input(&en_port_binding, &en_nb_logical_switch, NULL);
> +    engine_add_input(&en_port_binding, &en_nb_logical_switch_port, NULL);
> +    engine_add_input(&en_port_binding, &en_nb_logical_router, NULL);
> +    engine_add_input(&en_port_binding, &en_nb_logical_router_port, NULL);
> +    engine_add_input(&en_port_binding, &en_sb_port_binding, NULL);
> +    engine_add_input(&en_port_binding, &en_sb_chassis, NULL);
> +
> +    /* en_route: advertise/learn cross-AZ routes. */
> +    engine_add_input(&en_route, &en_icsb_availability_zone, NULL);
> +    engine_add_input(&en_route, &en_icsb_port_binding, NULL);
> +    engine_add_input(&en_route, &en_icsb_route, NULL);
> +    engine_add_input(&en_route, &en_icnb_transit_switch, NULL);
> +    engine_add_input(&en_route, &en_nb_nb_global, NULL);
> +    engine_add_input(&en_route, &en_nb_logical_router, NULL);
> +    engine_add_input(&en_route, &en_nb_logical_router_port, NULL);
> +    engine_add_input(&en_route, &en_nb_logical_router_static_route, NULL);
> +    engine_add_input(&en_route, &en_nb_logical_switch_port, NULL);
> +    engine_add_input(&en_route, &en_nb_load_balancer, NULL);
> +    engine_add_input(&en_route, &en_nb_load_balancer_group, NULL);
> +    engine_add_input(&en_route, &en_sb_datapath_binding, NULL);
> +    engine_add_input(&en_route, &en_sb_learned_route, NULL);
> +
> +    /* en_service_monitor: sync load-balancer health checks across AZs. */
> +    engine_add_input(&en_service_monitor, &en_icsb_availability_zone, NULL);
> +    engine_add_input(&en_service_monitor, &en_icsb_service_monitor, NULL);
> +    engine_add_input(&en_service_monitor, &en_sb_sb_global, NULL);
> +    engine_add_input(&en_service_monitor, &en_sb_service_monitor, NULL);
> +    engine_add_input(&en_service_monitor, &en_sb_port_binding, NULL);
> +
> +    /* en_address_set: advertise/learn address sets across AZs. */
> +    engine_add_input(&en_address_set, &en_nb_nb_global, NULL);
> +    engine_add_input(&en_address_set, &en_nb_address_set, NULL);
> +    engine_add_input(&en_address_set, &en_sb_address_set, NULL);
> +    engine_add_input(&en_address_set, &en_icsb_address_set, NULL);

en_address_set should have en_icsb_availability_zone as an input since
it relies on ctx->runned_az. This is only a problem in this patch
since patch 4 introduces en_az, and the dependency is resolved there.
However, we should strive to get it correct in this patch, just in
case we end up rolling back the incremental processing patches to this
point for some reason.

> +
> +    /* en_ic: output node aggregating all subsystems.  Order matches the
> +     * previous ovn_db_run() call order; in particular en_ts is added before
> +     * en_tr so they allocate datapath tunnel keys from the shared en_dp_enum
> +     * allocator in the same order as before. */
> +    engine_add_input(&en_ic, &en_gateway, NULL);
> +    engine_add_input(&en_ic, &en_ts, NULL);
> +    engine_add_input(&en_ic, &en_tr, NULL);
> +    engine_add_input(&en_ic, &en_port_binding, NULL);
> +    engine_add_input(&en_ic, &en_route, NULL);
> +    engine_add_input(&en_ic, &en_service_monitor, NULL);
> +    engine_add_input(&en_ic, &en_address_set, NULL);
>
>      struct engine_arg engine_arg = {
>          .nb_idl = nb->idl,
> diff --git a/ic/ovn-ic.c b/ic/ovn-ic.c
> index ab0f4c6fd..9f3e7cafd 100644
> --- a/ic/ovn-ic.c
> +++ b/ic/ovn-ic.c
> @@ -3667,27 +3667,7 @@ inc_proc_graph_dump(const char *end_node)
>      ovsdb_idl_loop_destroy(&ovnisb_idl_loop);
>  }
>
> -void
> -ovn_db_run(struct ic_context *ctx)
> -{
> -    struct hmap dp_tnlids = HMAP_INITIALIZER(&dp_tnlids);
> -    struct shash isb_ts_dps = SHASH_INITIALIZER(&isb_ts_dps);
> -    struct shash isb_tr_dps = SHASH_INITIALIZER(&isb_tr_dps);
> -
> -    gateway_run(ctx);
> -    enumerate_datapaths(ctx, &dp_tnlids, &isb_ts_dps, &isb_tr_dps);
> -    ts_run(ctx, &dp_tnlids, &isb_ts_dps);
> -    tr_run(ctx, &dp_tnlids, &isb_tr_dps);
> -    port_binding_run(ctx);
> -    route_run(ctx);
> -    sync_service_monitor(ctx);
> -    address_set_run(ctx);
> -
> -    ovn_destroy_tnlids(&dp_tnlids);
> -    shash_destroy(&isb_ts_dps);
> -    shash_destroy(&isb_tr_dps);
> -}
> -
> +

This deletion ends up resulting in a double blank line here.



>  static void
>  parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
>  {
> diff --git a/ic/ovn-ic.h b/ic/ovn-ic.h
> index 94a233f10..b06725373 100644
> --- a/ic/ovn-ic.h
> +++ b/ic/ovn-ic.h
> @@ -64,8 +64,6 @@ enum ic_port_binding_type { IC_SWITCH_PORT, IC_ROUTER_PORT, 
> IC_PORT_MAX };
>  struct hmap;
>  struct shash;
>
> -void ovn_db_run(struct ic_context *ctx);
> -
>  /* Per-subsystem entry points, invoked by the incremental-processing engine
>   * nodes (see ic/en-*.c).  Each performs a full recompute of its subsystem 
> and
>   * may be invoked independently when its engine inputs change. */
> --
> 2.34.1
>
>
> --
>
>
>
>
> _'Esta mensagem é direcionada apenas para os endereços constantes no
> cabeçalho inicial. Se você não está listado nos endereços constantes no
> cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa
> mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas estão
> imediatamente anuladas e proibidas'._
>
>
> * **'Apesar do Magazine Luiza tomar
> todas as precauções razoáveis para assegurar que nenhum vírus esteja
> presente nesse e-mail, a empresa não poderá aceitar a responsabilidade por
> quaisquer perdas ou danos causados por esse e-mail ou por seus anexos'.*
>
>
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>

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

Reply via email to