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

Reply via email to