Thx for the review~, adopted both suggestions, and applied to master, On Sun, Aug 16, 2015 at 2:43 PM, Russell Bryant <rbry...@redhat.com> wrote:
> On 08/09/2015 10:50 PM, Alex Wang wrote: > > This commit adds the binding module to ovn-controller-vtep. The > > module will scan through the Port_Binding table in ovnsb. If there is > > a port binding entry for a logical switch on the vtep gateway chassis's > > "vtep_logical_switches", sets the port binding's chassis column to the > > vtep gateway chassis. > > > > Signed-off-by: Alex Wang <al...@nicira.com> > > I had a couple of tiny suggestions, but they're not important. > > Acked-by: Russell Bryant <rbry...@redhat.com> > > > > > --- > > V5->V6: > > - avoid iterating Port_Binding table for each vtep physical switch. > > - refine code based on Russell's comments. > > > > V4->V5: > > - rebase on top of master. > > - change to use port binding type, and options when finding bindings > > for vtep gateway chassis. > > > > V3->V4: > > - rebase to master. > > > > V2->V3: > > - since ovn-sb schema changes (removal of Gateway table), the binding > > module code needs to be adapted. > > > > PATCH->V2: > > - split into separate commit. > > - disallow and warn if more than one logical port from one 'vlan_map' > > are attached to the same logical datapath. > > --- > > ovn/controller-vtep/automake.mk | 2 + > > ovn/controller-vtep/binding.c | 273 > +++++++++++++++++++++++++++++ > > ovn/controller-vtep/binding.h | 27 +++ > > ovn/controller-vtep/ovn-controller-vtep.c | 4 + > > tests/ovn-controller-vtep.at | 112 ++++++++++++ > > 5 files changed, 418 insertions(+) > > create mode 100644 ovn/controller-vtep/binding.c > > create mode 100644 ovn/controller-vtep/binding.h > > > > diff --git a/ovn/controller-vtep/automake.mk b/ovn/controller-vtep/ > automake.mk > > index 514cafa..33f063f 100644 > > --- a/ovn/controller-vtep/automake.mk > > +++ b/ovn/controller-vtep/automake.mk > > @@ -1,5 +1,7 @@ > > bin_PROGRAMS += ovn/controller-vtep/ovn-controller-vtep > > ovn_controller_vtep_ovn_controller_vtep_SOURCES = \ > > + ovn/controller-vtep/binding.c \ > > + ovn/controller-vtep/binding.h \ > > ovn/controller-vtep/gateway.c \ > > ovn/controller-vtep/gateway.h \ > > ovn/controller-vtep/ovn-controller-vtep.c \ > > diff --git a/ovn/controller-vtep/binding.c > b/ovn/controller-vtep/binding.c > > new file mode 100644 > > index 0000000..36bf02f > > --- /dev/null > > +++ b/ovn/controller-vtep/binding.c > > @@ -0,0 +1,273 @@ > > +/* Copyright (c) 2015 Nicira, Inc. > > + * > > + * 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 "binding.h" > > + > > +#include "lib/shash.h" > > +#include "lib/smap.h" > > +#include "lib/util.h" > > +#include "openvswitch/vlog.h" > > +#include "ovn-controller-vtep.h" > > +#include "ovn/lib/ovn-sb-idl.h" > > +#include "vtep/vtep-idl.h" > > + > > +VLOG_DEFINE_THIS_MODULE(binding); > > + > > +/* > > + * This module scans through the Port_Binding table in ovnsb. If there > is a > > + * logical port binding entry for logical switch in vtep gateway > chassis's > > + * 'vtep_logical_switches' column, sets the binding's chassis column to > the > > + * corresponding vtep gateway chassis. > > + * > > + */ > > + > > + > > +/* Returns true if the vtep logical switch specified by > 'port_binding_rec' > > + * has already been bound to another port binding entry, and resets > > + * 'port_binding_rec''s chassis column. Otherwise, updates 'ls_to_pb' > > + * and returns false. */ > > +static bool > > +check_pb_conflict(struct shash *ls_to_pb, > > + const struct sbrec_port_binding *port_binding_rec, > > + const char *chassis_name) > > +{ > > + const char *vtep_lswitch = > > + smap_get(&port_binding_rec->options, "vtep-logical-switch"); > > + const struct sbrec_port_binding *pb_conflict = > > + shash_find_data(ls_to_pb, vtep_lswitch); > > + > > + if (pb_conflict) { > > + VLOG_WARN("logical switch (%s), on vtep gateway chassis " > > + "(%s) has already been associated with logical " > > + "port (%s), ignore logical port (%s)", > > + vtep_lswitch, chassis_name, > > + pb_conflict->logical_port, > > + port_binding_rec->logical_port); > > + sbrec_port_binding_set_chassis(port_binding_rec, NULL); > > + > > + return true; > > + } > > + > > + shash_replace(ls_to_pb, vtep_lswitch, port_binding_rec); > > + return false; > > +} > > + > > +/* Returns true if the vtep logical switch specified by > 'port_binding_rec' > > + * has already been bound to a different datapath, and resets > > + * 'port_binding_rec''s chassis column. Otherwise, updates 'ls_to_db' > and > > + * returns false. */ > > +static bool > > +check_db_conflict(struct shash *ls_to_db, > > + const struct sbrec_port_binding *port_binding_rec, > > + const char *chassis_name) > > +{ > > + const char *vtep_lswitch = > > + smap_get(&port_binding_rec->options, "vtep-logical-switch"); > > + const struct sbrec_datapath_binding *db_conflict = > > + shash_find_data(ls_to_db, vtep_lswitch); > > + > > + if (db_conflict && db_conflict != port_binding_rec->datapath) { > > + VLOG_WARN("logical switch (%s), on vtep gateway chassis " > > + "(%s) has already been associated with logical " > > + "datapath (with tunnel key %"PRId64"), ignore " > > + "logical port (%s) which belongs to logical " > > + "datapath (with tunnel key %"PRId64")", > > + vtep_lswitch, chassis_name, > > + db_conflict->tunnel_key, > > + port_binding_rec->logical_port, > > + port_binding_rec->datapath->tunnel_key); > > + sbrec_port_binding_set_chassis(port_binding_rec, NULL); > > + > > + return true; > > + } > > + > > + shash_replace(ls_to_db, vtep_lswitch, port_binding_rec->datapath); > > + return false; > > +} > > + > > +/* Updates the 'port_binding_rec''s chassis column to 'chassis_rec'. */ > > +static void > > +update_pb_chassis(const struct sbrec_port_binding *port_binding_rec, > > + const struct sbrec_chassis *chassis_rec) > > +{ > > + if (port_binding_rec->chassis != chassis_rec) { > > + if (chassis_rec && port_binding_rec->chassis) { > > + VLOG_DBG("Changing chassis association of logical " > > + "port (%s) from (%s) to (%s)", > > + port_binding_rec->logical_port, > > + port_binding_rec->chassis->name, > > + chassis_rec->name); > > + } > > + sbrec_port_binding_set_chassis(port_binding_rec, chassis_rec); > > + } > > +} > > + > > + > > +/* Checks and updates logical port to vtep logical switch bindings for > each > > + * physical switch in VTEP. */ > > +void > > +binding_run(struct controller_vtep_ctx *ctx) > > +{ > > + if (!ctx->ovnsb_idl_txn) { > > + return; > > + } > > + > > + /* 'ls_to_db' > > + * > > + * Maps vtep logical switch name to the datapath binding entry. > This is > > + * used to guarantee that each vtep logical switch is only included > > + * in only one ovn datapath (ovn logical switch). See > check_db_conflict() > > + * for details. > > + * > > + * 'ls_to_pb' > > + * > > + * Maps vtep logical switch name to the port binding entry. This > is used > > + * to guarantee that each vtep logical switch on a vtep physical > switch > > + * is only bound to one logical port. See check_pb_conflict() for > > + * details. > > + * > > + */ > > + struct shash ls_to_db = SHASH_INITIALIZER(&ls_to_db); > > + const struct vteprec_logical_switch *vteprec_ls; > > + VTEPREC_LOGICAL_SWITCH_FOR_EACH (vteprec_ls, ctx->vtep_idl) { > > + shash_add(&ls_to_db, vteprec_ls->name, NULL); > > + } > > It looks like you could just skip pre-populating ls_to_db. In > check_db_conflict, if you use shash_add() instead of shash_replace(), I > think you end up with the same behavior you want but without needing > this loop. > > > + > > + /* Stores the 'chassis' and the 'ls_to_pb' map related to > > + * a vtep physcial switch. */ > > + struct ps { > > + const struct sbrec_chassis *chassis_rec; > > + struct shash ls_to_pb; > > + }; > > + struct shash ps_map = SHASH_INITIALIZER(&ps_map); > > + const struct vteprec_physical_switch *pswitch; > > + VTEPREC_PHYSICAL_SWITCH_FOR_EACH (pswitch, ctx->vtep_idl) { > > + const struct sbrec_chassis *chassis_rec > > + = get_chassis_by_name(ctx->ovnsb_idl, pswitch->name); > > + struct ps *ps = xmalloc(sizeof *ps); > > + size_t i; > > + > > + /* 'chassis_rec' must exist. */ > > + ovs_assert(chassis_rec); > > + ps->chassis_rec = chassis_rec; > > + shash_init(&ps->ls_to_pb); > > + for (i = 0; i < chassis_rec->n_vtep_logical_switches; i++) { > > + shash_add(&ps->ls_to_pb, > chassis_rec->vtep_logical_switches[i], > > + NULL); > > + } > > + shash_add(&ps_map, chassis_rec->name, ps); > > + } > > + > > + ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn, > > + "ovn-controller-vtep: updating bindings"); > > + > > + const struct sbrec_port_binding *port_binding_rec; > > + /* Port binding for vtep gateway chassis must have type "vtep", > > + * and matched physical switch name and logical switch name. */ > > + SBREC_PORT_BINDING_FOR_EACH(port_binding_rec, ctx->ovnsb_idl) { > > + const char *type = port_binding_rec->type; > > + const char *vtep_pswitch = smap_get(&port_binding_rec->options, > > + "vtep-physical-switch"); > > + const char *vtep_lswitch = smap_get(&port_binding_rec->options, > > + "vtep-logical-switch"); > > + struct ps *ps > > + = vtep_pswitch ? shash_find_data(&ps_map, vtep_pswitch) : > NULL; > > + bool found_ls > > + = ps && vtep_lswitch && shash_find(&ps->ls_to_pb, > vtep_lswitch); > > + > > + if (!strcmp(type, "vtep") && found_ls) { > > + bool pb_conflict, db_conflict; > > + > > + pb_conflict = check_pb_conflict(&ps->ls_to_pb, > port_binding_rec, > > + ps->chassis_rec->name); > > check_pb_conflict() does a smap_get() for the "vtep-logical_switch" > option, but you already have that from above, so you could just pass it > in and save another smap_get() call. > > > + db_conflict = check_db_conflict(&ls_to_db, port_binding_rec, > > + ps->chassis_rec->name); > > + /* Updates port binding's chassis column when there > > + * is no conflict. */ > > + if (!pb_conflict && !db_conflict) { > > + update_pb_chassis(port_binding_rec, ps->chassis_rec); > > + } > > + } else if (port_binding_rec->chassis > > + && shash_find(&ps_map, > port_binding_rec->chassis->name)) { > > + /* Resets 'port_binding_rec' since it is no longer bound to > > + * any vtep logical switch. */ > > + update_pb_chassis(port_binding_rec, NULL); > > + } > > + } > > + > > + struct shash_node *iter, *next; > > + SHASH_FOR_EACH_SAFE (iter, next, &ps_map) { > > + struct ps *ps = iter->data; > > + struct shash_node *node; > > + > > + SHASH_FOR_EACH (node, &ps->ls_to_pb) { > > + if (!node->data) { > > + static struct vlog_rate_limit rl = > VLOG_RATE_LIMIT_INIT(1, 5); > > + VLOG_DBG_RL(&rl, "No port binding entry for logical > switch (%s)" > > + "on vtep gateway chassis (%s)", node->name, > > + ps->chassis_rec->name); > > + } > > + } > > + shash_delete(&ps_map, iter); > > + shash_destroy(&ps->ls_to_pb); > > + free(ps); > > + } > > + shash_destroy(&ls_to_db); > > + shash_destroy(&ps_map); > > +} > > + > > +/* Removes all port binding association with vtep gateway chassis. > > + * Returns true when all done. */ > > +bool > > +binding_cleanup(struct controller_vtep_ctx *ctx) > > +{ > > + if (!ctx->ovnsb_idl_txn) { > > + return false; > > + } > > + > > + struct shash ch_to_pb = SHASH_INITIALIZER(&ch_to_pb); > > + const struct sbrec_port_binding *port_binding_rec; > > + bool all_done = true; > > + /* Hashs all port binding entries using the associated chassis > name. */ > > + SBREC_PORT_BINDING_FOR_EACH(port_binding_rec, ctx->ovnsb_idl) { > > + if (port_binding_rec->chassis) { > > + shash_add(&ch_to_pb, port_binding_rec->chassis->name, > > + port_binding_rec); > > + } > > + } > > + > > + ovsdb_idl_txn_add_comment(ctx->ovnsb_idl_txn, > > + "ovn-controller-vtep: removing bindings"); > > + > > + const struct vteprec_physical_switch *pswitch; > > + VTEPREC_PHYSICAL_SWITCH_FOR_EACH (pswitch, ctx->vtep_idl) { > > + const struct sbrec_chassis *chassis_rec > > + = get_chassis_by_name(ctx->ovnsb_idl, pswitch->name); > > + > > + for (;;) { > > + port_binding_rec = shash_find_and_delete(&ch_to_pb, > > + chassis_rec->name); > > + if (!port_binding_rec) { > > + break; > > + } > > + all_done = false; > > + update_pb_chassis(port_binding_rec, NULL); > > + } > > + } > > + shash_destroy(&ch_to_pb); > > + > > + return all_done; > > +} > > diff --git a/ovn/controller-vtep/binding.h > b/ovn/controller-vtep/binding.h > > new file mode 100644 > > index 0000000..374c1cc > > --- /dev/null > > +++ b/ovn/controller-vtep/binding.h > > @@ -0,0 +1,27 @@ > > +/* Copyright (c) 2015 Nicira, Inc. > > + * > > + * 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. > > + */ > > + > > + > > +#ifndef OVN_BINDING_H > > +#define OVN_BINDING_H 1 > > + > > +#include <stdbool.h> > > + > > +struct controller_vtep_ctx; > > + > > +void binding_run(struct controller_vtep_ctx *); > > +bool binding_cleanup(struct controller_vtep_ctx *); > > + > > +#endif /* ovn/controller-gw/binding.h */ > > diff --git a/ovn/controller-vtep/ovn-controller-vtep.c > b/ovn/controller-vtep/ovn-controller-vtep.c > > index 93a0458..a3b0f96 100644 > > --- a/ovn/controller-vtep/ovn-controller-vtep.c > > +++ b/ovn/controller-vtep/ovn-controller-vtep.c > > @@ -37,6 +37,7 @@ > > #include "ovn/lib/ovn-sb-idl.h" > > #include "vtep/vtep-idl.h" > > > > +#include "binding.h" > > #include "gateway.h" > > #include "ovn-controller-vtep.h" > > > > @@ -95,6 +96,7 @@ main(int argc, char *argv[]) > > }; > > > > gateway_run(&ctx); > > + binding_run(&ctx); > > unixctl_server_run(unixctl); > > > > unixctl_server_wait(unixctl); > > @@ -119,6 +121,7 @@ main(int argc, char *argv[]) > > /* Run all of the cleanup functions, even if one of them > returns false. > > * We're done if all of them return true. */ > > done = gateway_cleanup(&ctx); > > + done = binding_cleanup(&ctx) && done; > > if (done) { > > poll_immediate_wake(); > > } > > @@ -129,6 +132,7 @@ main(int argc, char *argv[]) > > } > > > > unixctl_server_destroy(unixctl); > > + > > ovsdb_idl_loop_destroy(&vtep_idl_loop); > > ovsdb_idl_loop_destroy(&ovnsb_idl_loop); > > > > diff --git a/tests/ovn-controller-vtep.at b/tests/ovn-controller-vtep.at > > index ed9cc50..3ff0b93 100644 > > --- a/tests/ovn-controller-vtep.at > > +++ b/tests/ovn-controller-vtep.at > > @@ -84,7 +84,19 @@ m4_define([OVN_CONTROLLER_VTEP_STOP], > > AT_CHECK([ovs-appctl -t ovn-controller-vtep exit]) > > AT_CHECK([ovs-appctl -t ovs-vswitchd exit])]) > > > > +# Adds logical port for a vtep gateway chassis in ovn-nb database. > > +# > > +# $1: logical switch name in ovn-nb database > > +# $2: logical port name > > +# $3: physical vtep gateway name > > +# $4: logical switch name on vtep gateway chassis > > +m4_define([OVN_NB_ADD_VTEP_PORT], [ > > +AT_CHECK([ovn-nbctl lport-add $1 $2]) > > +AT_CHECK([ovn-nbctl lport-set-type $2 vtep]) > > +AT_CHECK([ovn-nbctl lport-set-options $2 vtep-physical-switch=$3 > vtep-logical-switch=$4]) > > +]) > > > > +############################################## > > > > # tests chassis related updates. > > AT_SETUP([ovn-controller-vtep - test chassis]) > > @@ -150,3 +162,103 @@ AT_CHECK([ovn-sbctl > --columns=vtep_logical_switches list Chassis | cut -d ':' -f > > > > OVN_CONTROLLER_VTEP_STOP(["/Chassis for VTEP physical switch (br-vtep) > disappears/d"]) > > AT_CLEANUP > > + > > + > > +# Tests binding updates. > > +AT_SETUP([ovn-controller-vtep - test binding 1]) > > +OVN_CONTROLLER_VTEP_START > > + > > +# adds logical switch 'lswitch0' and vlan_bindings. > > +AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0 > -- bind-ls br-vtep p1 300 lswitch0]) > > +# adds lport in ovn-nb db, and sets the type and options. > > +OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], > [lswitch0]) > > +OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep > br-vtep_lswitch0`"]) > > +# should see one binding. > > +chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d > ':' -f2 | tr -d ' ') > > +AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding > br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl > > +${chassis_uuid} > > +]) > > + > > +# adds another logical switch 'lswitch1' and vlan_bindings. > > +AT_CHECK([vtep-ctl add-ls lswitch1 -- bind-ls br-vtep p0 200 lswitch1]) > > +# adds lport in ovn-nb db for lswitch1. > > +OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch1], [br-vtep], > [lswitch1]) > > +OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep -- > br-vtep_lswitch1`"]) > > +# This is allowed, but not recommended. > > +AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut > -d ':' -f2 | tr -d ' ' | sort -d], [0], [dnl > > + > > +${chassis_uuid} > > +${chassis_uuid} > > +]) > > + > > +# adds another lport in ovn-nb db for lswitch0. > > +OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0_dup], [br-vtep], > [lswitch0]) > > +OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep -- > br-vtep_lswitch0_dup`"]) > > +# This is not allowed, so should still see only two port_binding > entries bound. > > +AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut > -d ':' -f2 | tr -d ' ' | sort -d], [0], [dnl > > + > > + > > +[[]] > > +${chassis_uuid} > > +${chassis_uuid} > > +]) > > +# confirms the warning log. > > +AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | > sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g' | uniq], [0], [dnl > > +|WARN|logical switch (), on vtep gateway chassis () has already been > associated with logical port (), ignore logical port () > > +]) > > + > > +# deletes physical ports from vtep. > > +AT_CHECK([ovs-vsctl del-port p0 -- del-port p1]) > > +AT_CHECK([vtep-ctl del-port br-vtep p0 -- del-port br-vtep p1]) > > +OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Chassis | grep -- > br-vtep_lswitch`"]) > > +# should see empty chassis column in both binding entries. > > +AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding | cut > -d ':' -f2 | tr -d ' ' | sort], [0], [dnl > > + > > + > > +[[]] > > +[[]] > > +[[]] > > +]) > > + > > +OVN_CONTROLLER_VTEP_STOP(["/has already been associated with logical > port/d"]) > > +AT_CLEANUP > > + > > + > > +# Tests corner case: Binding the vtep logical switch from two different > > +# datapath. > > +AT_SETUP([ovn-controller-vtep - test binding 2]) > > +OVN_CONTROLLER_VTEP_START > > + > > +# adds logical switch 'lswitch0' and vlan_bindings. > > +AT_CHECK([vtep-ctl add-ls lswitch0 -- bind-ls br-vtep p0 100 lswitch0]) > > +# adds lport in ovn-nb db, and sets the type and options. > > +OVN_NB_ADD_VTEP_PORT([br-test], [br-vtep_lswitch0], [br-vtep], > [lswitch0]) > > +OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep > br-vtep_lswitch0`"]) > > + > > +# adds another lswitch 'br-void' in ovn-nb database. > > +AT_CHECK([ovn-nbctl lswitch-add br-void]) > > +# adds another vtep pswitch 'br-vtep-void' in vtep database. > > +AT_CHECK([vtep-ctl add-ps br-vtep-void -- add-port br-vtep-void p0-void > -- bind-ls br-vtep-void p0-void 100 lswitch0]) > > +# adds a conflicting logical port (both br-vtep_lswitch0 and > br-vtep-void_lswitch0 > > +# are bound to the same logical switch, but they are on different > datapath). > > +OVN_NB_ADD_VTEP_PORT([br-void], [br-vtep-void_lswitch0], > [br-vtep-void], [lswitch0]) > > +OVS_WAIT_UNTIL([test -n "`ovn-sbctl list Port_Binding | grep > br-vtep-void_lswitch0`"]) > > +OVS_WAIT_UNTIL([test -n "`grep WARN ovn-controller-vtep.log`"]) > > +# confirms the warning log. > > +AT_CHECK([sed -n 's/^.*\(|WARN|.*\)$/\1/p' ovn-controller-vtep.log | > sed 's/([[-_0-9a-z]][[-_0-9a-z]]*)/()/g;s/(with tunnel key > [[0-9]][[0-9]]*)/()/g' | uniq], [0], [dnl > > +|WARN|logical switch (), on vtep gateway chassis () has already been > associated with logical datapath (), ignore logical port () which belongs > to logical datapath () > > +]) > > + > > +# then deletes 'br-void' and 'br-vtep-void', should see > 'br-vtep_lswitch0' > > +# bound correctly. > > +AT_CHECK([ovn-nbctl lswitch-del br-void]) > > +# adds another vtep pswitch 'br-vtep-void' in vtep database. > > +AT_CHECK([vtep-ctl del-ps br-vtep-void]) > > +OVS_WAIT_UNTIL([test -z "`ovn-sbctl list Port_Binding | grep > br-vtep-void_lswitch0`"]) > > +chassis_uuid=$(ovn-sbctl --columns=_uuid list Chassis br-vtep | cut -d > ':' -f2 | tr -d ' ') > > +AT_CHECK_UNQUOTED([ovn-sbctl --columns=chassis list Port_Binding > br-vtep_lswitch0 | cut -d ':' -f2 | tr -d ' '], [0], [dnl > > +${chassis_uuid} > > +]) > > + > > +OVN_CONTROLLER_VTEP_STOP(["/has already been associated with logical > datapath/d"]) > > +AT_CLEANUP > > > > > -- > Russell Bryant > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev