The code proposed below puts the logical port to physical endpoint binding directly in the Port_Binding table. At least for the "localnet" case, I wonder if this provides sufficient separation between logical and physical.
If it can really be two different CMSes or two different users who are responsible for logical versus physical, then shouldn't we allow the information to be provided in any order? And shouldn't that information be persisted separately? With the current proposal, after the logical port to physical endpoint binding is entered, if someone on the logical side blows away the "localnet" port (e.g. OpenStack external network is deleted), then won't the logical port to physical endpoint binding be blown away as well? If someone later recreates the "localnet" port, then wouldn't the logical port to physical endpoint binding have to be entered all over again? The alternative is to use an indirection. This indirection is already defined and used by the existing approach. The "localnet" ports are required to specify a "network_name" in the "options". On each hypervisor, "ovn-bridge-mappings" maps from the "network_name" to a local bridge. Rather than add "phys_endpt" directly in the "Port_Binding" table, perhaps a new table should be defined mapping "network_name" to "phys_endpt". This would also allow for many bindings to be specified for the same "network_name", one for each chassis, thus moving the "ovn-bridge-mappings" configuration on each hypervisor to southbound instead. Even if a new table is defined based on "network_name", we still have cases where we would like to allow chassis and chassis_port to be left unspecified, as suggested by Justin. Mickey -----"dev" <dev-boun...@openvswitch.org> wrote: ----- To: dev@openvswitch.org From: Darrell Ball Sent by: "dev" Date: 03/01/2016 10:40AM Subject: [ovs-dev] [PATCH 3/4] Update sbctl to support OVN SB physical endpoint table usage and associated changes in the port binding table Signed-off-by: Darrell Ball <db...@vmware.com> --- ovn/utilities/ovn-sbctl.c | 263 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 259 insertions(+), 4 deletions(-) diff --git a/ovn/utilities/ovn-sbctl.c b/ovn/utilities/ovn-sbctl.c index b9e3c10..aba7e01 100644 --- a/ovn/utilities/ovn-sbctl.c +++ b/ovn/utilities/ovn-sbctl.c @@ -311,11 +311,24 @@ Chassis commands:\n\ and ENCAP-IP\n\ chassis-del CHASSIS delete CHASSIS and all of its encaps\n\ and gateway_ports\n\ +Physical Endpoint commands:\n\ + phys-endpt-add PHYS-ENDPT CHASSIS PORT TYPE ING-ENC EGR-ENC\n\ + create a new phys endpt named\n\ + PHYS-ENDPT on CHASSIS/PORT\n\ + with TYPE encap\n\ + and encap values ING-ENC EGR-ENC\n\ + phys-endpt-del PHYS-ENDPT delete PHYS-ENDPT \n\ \n\ Port binding commands:\n\ lport-bind LPORT CHASSIS bind logical port LPORT to CHASSIS\n\ lport-unbind LPORT reset the port binding of logical port LPORT\n\ \n\ +Port binding Phys Endpt commands:\n\ + lport-bind-phys-endpt LPORT PHYS-ENDPT\n\ + bind logical port LPORT to PHYS-ENDPT\n\ + lport-unbind-phys-endpt LPORT\n\ + reset the binding of LPORT to PHYS-ENDPT\n\ +\n\ Logical flow commands:\n\ lflow-list [DATAPATH] List logical flows for all or a single datapath\n\ dump-flows [DATAPATH] Alias for lflow-list\n\ <snip> +static void +cmd_lport_bind_phys_endpt(struct ctl_context *ctx) +{ + struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); + bool may_exist = shash_find(&ctx->options, "--may-exist") != NULL; + struct sbctl_port_binding *sbctl_bd; + struct sbctl_physical_endpoint *phys_endpt_lrec; + char *lport_name, *phys_endpt_name; + + /* port_binding must exist, chassis must exist! */ + lport_name = ctx->argv[1]; + phys_endpt_name = ctx->argv[2]; + + sbctl_context_populate_cache(ctx); + sbctl_bd = find_port_binding(sbctl_ctx, lport_name, true); + phys_endpt_lrec = + find_phys_endpt(sbctl_ctx, phys_endpt_name, true); + + + if ((strcmp(sbctl_bd->bd_cfg->type, "localnet")) && + (strcmp(sbctl_bd->bd_cfg->type, "vtep"))) { + ctl_fatal("lport (%s) type must be localnet or vtep ", + lport_name); + } + if (sbctl_bd->bd_cfg->phys_endpt) { + if (may_exist && + sbctl_bd->bd_cfg->phys_endpt == + phys_endpt_lrec->phys_endpt_db_rec) { + return; + } else { + ctl_fatal("lport (%s) already bound to phys_endpt (%s)", + lport_name, + phys_endpt_lrec->phys_endpt_db_rec->name); + } + } + sbrec_port_binding_set_phys_endpt( + sbctl_bd->bd_cfg, + phys_endpt_lrec->phys_endpt_db_rec); + sbctl_context_invalidate_cache(ctx); +} + +static void +cmd_lport_unbind_phys_endpt(struct ctl_context *ctx) +{ + struct sbctl_context *sbctl_ctx = sbctl_context_cast(ctx); + bool must_exist = !shash_find(&ctx->options, "--if-exists"); + struct sbctl_port_binding *sbctl_bd; + char *lport_name; + + lport_name = ctx->argv[1]; + sbctl_context_populate_cache(ctx); + sbctl_bd = find_port_binding(sbctl_ctx, lport_name, must_exist); + if (sbctl_bd) { + sbrec_port_binding_set_phys_endpt(sbctl_bd->bd_cfg, NULL); + } +} + enum { PL_INGRESS, PL_EGRESS, @@ -771,6 +1008,11 @@ static const struct ctl_table_class tables[] = { {{&sbrec_table_port_binding, &sbrec_port_binding_col_logical_port, NULL}, {NULL, NULL, NULL}}}, + {&sbrec_table_physical_endpoint, + {{&sbrec_table_physical_endpoint, + &sbrec_physical_endpoint_col_name, NULL}, + {NULL, NULL, NULL}}}, + {NULL, {{NULL, NULL, NULL}, {NULL, NULL, NULL}}} }; @@ -1007,17 +1249,30 @@ sbctl_exit(int status) static const struct ctl_command_syntax sbctl_commands[] = { /* Chassis commands. */ + {"chassis-add", 3, 3, "CHASSIS ENCAP-TYPE ENCAP-IP", pre_get_info, cmd_chassis_add, NULL, "--may-exist", RW}, {"chassis-del", 1, 1, "CHASSIS", pre_get_info, cmd_chassis_del, NULL, "--if-exists", RW}, + /* Physical Endpoint commands */ + {"phys-endpt-add", 6, 6, "PHYS-ENDPT CHASSIS PORT TYPE ING-ENC EGR-ENC", + pre_get_info, cmd_phys_endpt_add, NULL, "--may-exist", RW}, + {"phys-endpt-del", 1, 1, "PHYS-ENDPT", + pre_get_info, cmd_phys_endpt_del, NULL, "--if-exists", RW}, + /* Port binding commands. */ {"lport-bind", 2, 2, "LPORT CHASSIS", pre_get_info, cmd_lport_bind, NULL, "--may-exist", RW}, {"lport-unbind", 1, 1, "LPORT", pre_get_info, cmd_lport_unbind, NULL, "--if-exists", RW}, + /* Port to physical endpoint binding */ + {"lport-bind-phys-endpt", 2, 2, "LPORT PHYS-ENDPT", pre_get_info, + cmd_lport_bind_phys_endpt, NULL, "--may-exist", RW}, + {"lport-unbind-phys-endpt", 1, 1, "LPORT", pre_get_info, + cmd_lport_unbind_phys_endpt, NULL, "--if-exists", RW}, + /* Logical flow commands */ {"lflow-list", 0, 1, "[DATAPATH]", pre_get_info, cmd_lflow_list, NULL, "", RO}, -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev