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> + +#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). + * 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_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 f0c1d7b71..b36c52ea5 100644 --- a/ic/ovn-ic.c +++ b/ic/ovn-ic.c @@ -3696,27 +3696,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); -} - + 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
