Hi Paulo,

AI noticed that all header files in this patch are missing the Apache
2.0 license header.


On Mon, Aug 31, 2026 at 1:04 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     |  11 +++
>  ic/en-dp-enum.c         |  68 ++++++++++++++++++
>  ic/en-dp-enum.h         |  30 ++++++++
>  ic/en-gateway.c         |  45 ++++++++++++
>  ic/en-gateway.h         |  10 +++
>  ic/en-ic.c              |   9 ++-
>  ic/en-port-binding.c    |  45 ++++++++++++
>  ic/en-port-binding.h    |  11 +++
>  ic/en-route.c           |  45 ++++++++++++
>  ic/en-route.h           |  10 +++
>  ic/en-service-monitor.c |  46 ++++++++++++
>  ic/en-service-monitor.h |  12 ++++
>  ic/en-tr.c              |  47 ++++++++++++
>  ic/en-tr.h              |  10 +++
>  ic/en-ts.c              |  47 ++++++++++++
>  ic/en-ts.h              |  10 +++
>  ic/inc-proc-ic.c        | 154 ++++++++++++++++++++++++++++++----------
>  ic/ovn-ic.c             |  21 ------
>  ic/ovn-ic.h             |   2 -
>  21 files changed, 630 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..3f74b24a5
> --- /dev/null
> +++ b/ic/en-address-set.h
> @@ -0,0 +1,11 @@
> +#ifndef EN_IC_ADDRESS_SET_H
> +#define EN_IC_ADDRESS_SET_H 1
> +
> +#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..206e6423c
> --- /dev/null
> +++ b/ic/en-dp-enum.h
> @@ -0,0 +1,30 @@
> +#ifndef EN_IC_DP_ENUM_H
> +#define EN_IC_DP_ENUM_H 1
> +
> +#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..d804d114f
> --- /dev/null
> +++ b/ic/en-gateway.h
> @@ -0,0 +1,10 @@
> +#ifndef EN_IC_GATEWAY_H
> +#define EN_IC_GATEWAY_H 1
> +
> +#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..d671e2cb0 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
> +     * and address_set).  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..030a470dd
> --- /dev/null
> +++ b/ic/en-port-binding.h
> @@ -0,0 +1,11 @@
> +#ifndef EN_IC_PORT_BINDING_H
> +#define EN_IC_PORT_BINDING_H 1
> +
> +#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..c03aed19e
> --- /dev/null
> +++ b/ic/en-route.h
> @@ -0,0 +1,10 @@
> +#ifndef EN_IC_ROUTE_H
> +#define EN_IC_ROUTE_H 1
> +
> +#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..55103635e
> --- /dev/null
> +++ b/ic/en-service-monitor.h
> @@ -0,0 +1,12 @@
> +#ifndef EN_IC_SERVICE_MONITOR_H
> +#define EN_IC_SERVICE_MONITOR_H 1
> +
> +#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..90c8c8c4a
> --- /dev/null
> +++ b/ic/en-tr.h
> @@ -0,0 +1,10 @@
> +#ifndef EN_IC_TR_H
> +#define EN_IC_TR_H 1
> +
> +#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..3c22f3b40
> --- /dev/null
> +++ b/ic/en-ts.h
> @@ -0,0 +1,10 @@
> +#ifndef EN_IC_TS_H
> +#define EN_IC_TS_H 1
> +
> +#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..a6f029e37 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,104 @@ 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_icsb_availability_zone, NULL);
> +    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_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 738685eaa..6e0d1b4e1 100644
> --- a/ic/ovn-ic.c
> +++ b/ic/ovn-ic.c
> @@ -3782,27 +3782,6 @@ 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);
> -}
> -
>  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