Evaluates change for SB port-binding in runtime_data node. If the port-binding change has no impact for the runtime_data it will not trigger runtime_data change.
Signed-off-by: Han Zhou <hzh...@ebay.com> --- ovn/controller/binding.c | 92 +++++++++++++++++++++++++++++++++++++++++ ovn/controller/binding.h | 6 +++ ovn/controller/ovn-controller.c | 28 ++++++++++++- 3 files changed, 125 insertions(+), 1 deletion(-) diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c index 84ff4d6..0c5b47b 100644 --- a/ovn/controller/binding.c +++ b/ovn/controller/binding.c @@ -580,6 +580,98 @@ binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, hmap_destroy(&qos_map); } +static bool +is_our_chassis(const struct chassis_index *chassis_index, + struct sset *active_tunnels, + const struct sbrec_chassis *chassis_rec, + const struct sbrec_port_binding *binding_rec, + struct shash *lport_to_iface, + struct sset *local_lports) +{ + const struct ovsrec_interface *iface_rec + = shash_find_data(lport_to_iface, binding_rec->logical_port); + struct ovs_list *gateway_chassis = NULL; + + bool our_chassis = false; + if (iface_rec + || (binding_rec->parent_port && binding_rec->parent_port[0] && + sset_contains(local_lports, binding_rec->parent_port))) { + /* This port is in our chassis unless it is a localport. */ + if (strcmp(binding_rec->type, "localport")) { + our_chassis = true; + } + } else if (!strcmp(binding_rec->type, "l2gateway")) { + const char *chassis_id = smap_get(&binding_rec->options, + "l2gateway-chassis"); + our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); + } else if (!strcmp(binding_rec->type, "chassisredirect")) { + gateway_chassis = gateway_chassis_get_ordered(binding_rec, + chassis_index); + if (gateway_chassis && + gateway_chassis_contains(gateway_chassis, chassis_rec)) { + + our_chassis = gateway_chassis_is_active( + gateway_chassis, chassis_rec, active_tunnels); + + } + gateway_chassis_destroy(gateway_chassis); + } else if (!strcmp(binding_rec->type, "l3gateway")) { + const char *chassis_id = smap_get(&binding_rec->options, + "l3gateway-chassis"); + our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name); + } else if (!strcmp(binding_rec->type, "localnet")) { + our_chassis = false; + } + + return our_chassis; +} + +/* Returns true if port-binding changes potentially require flow changes on + * the current chassis. Returns false if we are sure there is no impact. */ +bool +binding_evaluate_port_binding_changes( + struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, + const struct sbrec_chassis *chassis_rec, + const struct chassis_index *chassis_index, + struct sset *active_tunnels, + struct sset *local_lports) +{ + if (!chassis_rec) { + return true; + } + + const struct sbrec_port_binding *binding_rec; + struct shash lport_to_iface = SHASH_INITIALIZER(&lport_to_iface); + struct sset egress_ifaces = SSET_INITIALIZER(&egress_ifaces); + if (br_int) { + get_local_iface_ids(br_int, &lport_to_iface, local_lports, + &egress_ifaces); + } + SBREC_PORT_BINDING_FOR_EACH_TRACKED (binding_rec, ctx->ovnsb_idl) { + /* XXX: currently OVSDB change tracking doesn't support getting old + * data when the operation is update, so if a port-binding moved from + * this chassis to another, we would not know it with this check. + * However, if the port is unbound from this chassis, the local ovsdb + * interface table will be updated, which will trigger recompute. + * If the port is still bound on this chassis, then below check + * is_our_chassis() will take care that case. */ + if (binding_rec->chassis == chassis_rec) { + return true; + } + if (is_our_chassis(chassis_index, + active_tunnels, chassis_rec, binding_rec, + &lport_to_iface, + local_lports) + || !strcmp(binding_rec->type, "patch") + || !strcmp(binding_rec->type, "localport") + || !strcmp(binding_rec->type, "vtep") + || !strcmp(binding_rec->type, "localnet")) { + return true; + } + } + return false; +} + /* Returns true if the database is all cleaned up, false if more work is * required. */ bool diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h index 89fc2ec..db8685d 100644 --- a/ovn/controller/binding.h +++ b/ovn/controller/binding.h @@ -34,5 +34,11 @@ void binding_run(struct controller_ctx *, const struct ovsrec_bridge *br_int, struct sset *active_tunnels, struct hmap *local_datapaths, struct sset *local_lports, struct sset *local_lport_ids); bool binding_cleanup(struct controller_ctx *, const struct sbrec_chassis *); +bool binding_evaluate_port_binding_changes( + struct controller_ctx *ctx, const struct ovsrec_bridge *br_int, + const struct sbrec_chassis *chassis_rec, + const struct chassis_index *chassis_index, + struct sset *active_tunnels, + struct sset *local_lports); #endif /* ovn/binding.h */ diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c index 1ff0532..2d021c4 100644 --- a/ovn/controller/ovn-controller.c +++ b/ovn/controller/ovn-controller.c @@ -741,6 +741,32 @@ runtime_data_run(struct engine_node *node) node->changed = true; } +static bool +runtime_data_sb_port_binding_handler(struct engine_node *node) +{ + struct controller_ctx *ctx = (struct controller_ctx *)node->context; + struct ed_type_runtime_data *data = + (struct ed_type_runtime_data *)node->data; + struct sset *local_lports = &data->local_lports; + struct sset *active_tunnels = &data->active_tunnels; + struct chassis_index *chassis_index = &data->chassis_index; + + const char *chassis_id = get_chassis_id(ctx->ovs_idl); + const struct ovsrec_bridge *br_int = get_br_int(ctx); + + ovs_assert(br_int && chassis_id); + const struct sbrec_chassis *chassis = NULL; + chassis = get_chassis(ctx->ovnsb_idl, chassis_id); + ovs_assert(chassis); + + bool changed = binding_evaluate_port_binding_changes( + ctx, br_int, chassis, + chassis_index, active_tunnels, + local_lports); + + return !changed; +} + struct ed_type_flow_output { /* desired flows */ struct ovn_desired_flow_table flow_table; @@ -970,7 +996,7 @@ main(int argc, char *argv[]) engine_add_input(&en_runtime_data, &en_sb_address_set, NULL); engine_add_input(&en_runtime_data, &en_sb_port_group, NULL); engine_add_input(&en_runtime_data, &en_sb_datapath_binding, NULL); - engine_add_input(&en_runtime_data, &en_sb_port_binding, NULL); + engine_add_input(&en_runtime_data, &en_sb_port_binding, runtime_data_sb_port_binding_handler); engine_add_input(&en_runtime_data, &en_sb_gateway_chassis, NULL); engine_init(&en_flow_output); -- 2.1.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev