Mickey Spiegel/San Jose/IBM wrote on 20/07/2016 08:53:42 AM:

> From: Mickey Spiegel/San Jose/IBM
> To: Liran Schour/Haifa/IBM@IBMIL
> Cc: Ben Pfaff <b...@ovn.org>, dev@openvswitch.org
> Date: 20/07/2016 08:53 AM
> Subject: Re: [ovs-dev] [PATCH monitor_cond V10] RFC OVN: 
> Implementation of conditional monitoring usage
> 
> Comments inline as <Mickey>
> 
> -----"dev" <dev-boun...@openvswitch.org> wrote: -----
> To: Ben Pfaff <b...@ovn.org>
> From: Liran Schour 
> Sent by: "dev" 
> Date: 07/19/2016 01:45AM
> Cc: dev@openvswitch.org
> Subject: [ovs-dev] [PATCH monitor_cond V10] RFC OVN: Implementation 
> of conditional monitoring usage

> Conditional monitor of: Port_Binding, Logical_Flow, Multicast_Group
> MAC_Binding tables. As a result ovn-controller will be notified only 
about
> records belongs to a datapath that is being served by this hypervisor.
> 
> Performance evaluation:
> OVN is the main candidate for conditional monitoring usage. It is clear 
that
> conditional monitoring reduces computation on the ovn-controller 
(client) side
> due to the reduced size of flow tables and update messages. Performance
> evaluation shows up to 75% computation reduction.
> However, performance evaluation shows also a reduction in 
> computation on the SB
> ovsdb-server side proportional to the degree that each logical network 
is
> spread over physical hosts in the DC. Evaluation shows that in a 
realistic
> scenarios there is a computation reduction also in the server side.
> 
> <Mickey> Before getting into details, please confirm whether I have 
> a proper understanding how this works:
> When a hypervisor first comes up, it gets no port bindings.
> When a VIF comes up on the hypervisor, this will trigger filter_port
> on that VIF, which causes the port binding for that VIF to come down
> to the controller.
> Upon receipt of that port binding, the controller will add the 
> datapath for the VIF's logical switch to local datapaths, which will
> trigger filter_datapath.
> This will cause all of the port bindings, MAC bindings, logical 
> flows, and multicast groups for the VIF's logical switch to come 
> down to the controller.
> Following the patch ports from the VIF's logical switch, this will 
> trigger filter_port for all peer patch ports.
> The port bindings for those peer patch ports will trigger 
> filter_datapath for all logical router datapaths connected to the 
> logical switch.
> This will cause all of the port bindings, MAC bindings, logical 
> flows, and multicast groups for those datapaths to come down to the 
> controller.
> If those datapaths have patch ports to additional datapaths, 
> following the patch ports, eventually all of the SB info for all 
> connected datapaths will come down to the controller.
> Is this correct?
> 

Yes. One small addition: to minimize the number of filters, the code will 
unfilter_lport when the lport is already included in a flittered datapath.

> <Mickey> Do you have any information about the latency involved in 
> this process?
> 

No, I did not test it. I will write it in my TODO list.

> <Mickey> Further comments on the details inline.
> 
> Evaluation on simulated environment of 50 hosts and 1000 logical ports 
shows
> the following results (cycles #):
> 
> LN spread over # hosts|    master    | patch        | change
> -------------------------------------------------------------
>             1         | 24597200127  | 24339235374  |  1.0%
>             6         | 23788521572  | 19145229352  | 19.5%
>            12         | 23886405758  | 17913143176  | 25.0%
>            18         | 25812686279  | 23675094540  |  8.2%
>            24         | 28414671499  | 24770202308  | 12.8%
>            30         | 31487218890  | 28397543436  |  9.8%
>            36         | 36116993930  | 34105388739  |  5.5%
>            42         | 37898342465  | 38647139083  | -1.9%
>            48         | 41637996229  | 41846616306  | -0.5%
>            50         | 41679995357  | 43455565977  | -4.2%
> 
> Signed-off-by: Liran Schour <lir...@il.ibm.com>
> ---
>  ovn/controller/automake.mk      |   4 +-
>  ovn/controller/binding.c        |  48 +++++++---
>  ovn/controller/binding.h        |   4 +-
>  ovn/controller/filter.c         | 207 +++++++++++++++++++++++++++++
> +++++++++++
>  ovn/controller/filter.h         |  36 +++++++
>  ovn/controller/ovn-controller.c |  14 ++-
>  ovn/controller/ovn-controller.h |   1 +
>  ovn/controller/patch.c          |   7 +-
>  tests/ovn-controller.at         |   3 +
>  tests/ovn.at                    |   1 +
>  10 files changed, 305 insertions(+), 20 deletions(-)
>  create mode 100644 ovn/controller/filter.c
>  create mode 100644 ovn/controller/filter.h
> 
> diff --git a/ovn/controller/automake.mk b/ovn/controller/automake.mk
> index cf57bbd..0318654 100644
> --- a/ovn/controller/automake.mk
> +++ b/ovn/controller/automake.mk
> @@ -19,7 +19,9 @@ ovn_controller_ovn_controller_SOURCES = \
>   ovn/controller/ovn-controller.c \
>   ovn/controller/ovn-controller.h \
>   ovn/controller/physical.c \
> - ovn/controller/physical.h
> + ovn/controller/physical.h \
> + ovn/controller/filter.c \
> + ovn/controller/filter.h
>  ovn_controller_ovn_controller_LDADD = ovn/lib/libovn.la 
lib/libopenvswitch.la
>  man_MANS += ovn/controller/ovn-controller.8
>  EXTRA_DIST += ovn/controller/ovn-controller.8.xml
> diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
> index bc6df32..dcc2a2f 100644
> --- a/ovn/controller/binding.c
> +++ b/ovn/controller/binding.c
> @@ -25,6 +25,8 @@
>  #include "openvswitch/vlog.h"
>  #include "ovn/lib/ovn-sb-idl.h"
>  #include "ovn-controller.h"
> +#include "lport.h"
> +#include "filter.h"
> 
>  VLOG_DEFINE_THIS_MODULE(binding);
> 
> @@ -64,7 +66,9 @@ binding_register_ovs_idl(struct ovsdb_idl *ovs_idl)
> 
>  static bool
>  get_local_iface_ids(const struct ovsrec_bridge *br_int,
> -                    struct shash *lport_to_iface)
> +                    struct shash *lport_to_iface,
> +                    struct lport_index *lports_index,
> +                    struct controller_ctx *ctx)
>  {
>      int i;
>      bool changed = false;
> @@ -90,6 +94,9 @@ get_local_iface_ids(const struct ovsrec_bridge 
*br_int,
>                  continue;
>              }
>              shash_add(lport_to_iface, iface_id, iface_rec);
> +            if (!lport_lookup_by_name(lports_index, iface_id)) {
> +                filter_lport(ctx, iface_id);
> +            }
>              if (!sset_find_and_delete(&old_local_ids, iface_id)) {
>                  sset_add(&local_ids, iface_id);
>                  changed = true;
> @@ -121,8 +128,11 @@ local_datapath_lookup_by_uuid(struct hmap 
> *hmap_p, const struct uuid *uuid)
>  }
> 
>  static void
> -remove_local_datapath(struct hmap *local_datapaths, struct 
> local_datapath *ld)
> +remove_local_datapath(struct controller_ctx *ctx, struct hmap 
> *local_datapaths,
> +                      struct local_datapath *ld)
>  {
> +    unfilter_datapath(ctx, ld->tunnel_key);
> +

> <Mickey> You have two different triggers for filter_datapath: One 
> from add_local_datapath, another from add_patched_datapath in 
> patch.c. If you call unfilter_datapath here, you might be blowing 
> away the trigger from add_patched_datapath as well. It will not 
> correct itself until another VIF, L2 gateway, L3 gateway on that 
> datapath is added, or a patch port to that datapath is added.
> 

You are right. I will fix this.

>      if (ld->logical_port) {
>          free(ld->logical_port);
>          ld->logical_port = NULL;
> @@ -133,7 +143,8 @@ remove_local_datapath(struct hmap 
> *local_datapaths, struct local_datapath *ld)
> 
>  static void
>  add_local_datapath(struct hmap *local_datapaths,
> -        const struct sbrec_port_binding *binding_rec)
> +                   const struct sbrec_port_binding *binding_rec,
> +                   struct controller_ctx *ctx)
>  {
>      if (get_local_datapath(local_datapaths,
>                             binding_rec->datapath->tunnel_key)) {
> @@ -143,8 +154,10 @@ add_local_datapath(struct hmap *local_datapaths,
>      struct local_datapath *ld = xzalloc(sizeof *ld);
>      ld->logical_port = xstrdup(binding_rec->logical_port);
>      memcpy(&ld->uuid, &binding_rec->header_.uuid, sizeof ld->uuid);
> +    ld->tunnel_key = binding_rec->datapath->tunnel_key;
>      hmap_insert(local_datapaths, &ld->hmap_node,
>                  binding_rec->datapath->tunnel_key);
> +    filter_datapath(ctx, binding_rec);
>  }

> <Mickey> Just noting that this should take care of L3 gateway as 
> well, once Chandra's "ovn: Add datapth of gateway port to 
local_datapaths
> " patch lands. The addition of "ctx" to add_local_datapaths will be 
> necessary, in whichever of the two patches lands later.
> 

Right.

>  static void
> @@ -160,6 +173,7 @@ update_qos(const struct ovsrec_interface *iface_rec,
> 
>  static void
>  consider_local_datapath(struct controller_ctx *ctx,
> +                        struct lport_index *lports_index,
>                          const struct sbrec_chassis *chassis_rec,
>                          const struct sbrec_port_binding *binding_rec,
>                          struct hmap *local_datapaths,
> @@ -171,7 +185,7 @@ consider_local_datapath(struct controller_ctx *ctx,
>      if (iface_rec
>          || (binding_rec->parent_port && binding_rec->parent_port[0] &&
>              sset_contains(&local_ids, binding_rec->parent_port))) {
> -        add_local_datapath(local_datapaths, binding_rec);
> +        add_local_datapath(local_datapaths, binding_rec, ctx);
>          if (iface_rec && ctx->ovs_idl_txn) {
>              update_qos(iface_rec, binding_rec);
>          }
> @@ -210,7 +224,7 @@ consider_local_datapath(struct controller_ctx *ctx,
>              VLOG_INFO("Claiming l2gateway port %s for this chassis.",
>                        binding_rec->logical_port);
>              sbrec_port_binding_set_chassis(binding_rec, chassis_rec);
> -            add_local_datapath(local_datapaths, binding_rec);
> +            add_local_datapath(local_datapaths, binding_rec, ctx);
>          }
>      } else if (chassis_rec && binding_rec->chassis == chassis_rec
>                 && strcmp(binding_rec->type, "gateway")) {
> @@ -220,11 +234,18 @@ consider_local_datapath(struct controller_ctx 
*ctx,
>              sbrec_port_binding_set_chassis(binding_rec, NULL);
>          }
>      }
> +    const char *peer = smap_get(&binding_rec->options, "peer");
> +    if (peer) {
> +        if (!lport_lookup_by_name(lports_index, peer)) {
> +            filter_lport(ctx, peer);
> +        }
> +    }
>  }

> <Mickey> If you follow patch ports here, where it applies for every 
> port binding that is received, you might be following a patch port 
> that does not apply to this chassis, such as a "gateway" patch port 
> to an L3 gateway router that is not local to this chassis. It would 
> be better to add this logic in patch.c, perhaps in 
> add_logical_patch_ports around where create_patch_port is called?
> 

Thanks, you are right.

>  void
>  binding_run(struct controller_ctx *ctx, const struct ovsrec_bridge 
*br_int,
> -            const char *chassis_id, struct hmap *local_datapaths)
> +            const char *chassis_id, struct lport_index *lports_index,
> +            struct hmap *local_datapaths)
>  {
>      const struct sbrec_chassis *chassis_rec;
>      const struct sbrec_port_binding *binding_rec;
> @@ -236,7 +257,8 @@ binding_run(struct controller_ctx *ctx, const 
> struct ovsrec_bridge *br_int,
>      }
> 
>      if (br_int) {
> -        if (ctx->ovnsb_idl_txn && get_local_iface_ids(br_int, 
> &lport_to_iface)) {
> +        if (ctx->ovnsb_idl_txn && get_local_iface_ids(br_int, 
> &lport_to_iface,
> +                                                      lports_index, 
ctx)) {
>              process_full_binding = true;
>          }
>      } else {
> @@ -252,8 +274,9 @@ binding_run(struct controller_ctx *ctx, const 
> struct ovsrec_bridge *br_int,
>          struct hmap keep_local_datapath_by_uuid =
>              HMAP_INITIALIZER(&keep_local_datapath_by_uuid);
>          SBREC_PORT_BINDING_FOR_EACH(binding_rec, ctx->ovnsb_idl) {
> -            consider_local_datapath(ctx, chassis_rec, binding_rec,
> -                                    local_datapaths, &lport_to_iface);
> +            consider_local_datapath(ctx, lports_index, chassis_rec,
> +                                    binding_rec, local_datapaths,
> +                                    &lport_to_iface);
>              struct local_datapath *ld = xzalloc(sizeof *ld);
>              memcpy(&ld->uuid, &binding_rec->header_.uuid, sizeof 
ld->uuid);
>              hmap_insert(&keep_local_datapath_by_uuid, 
&ld->uuid_hmap_node,
> @@ -263,7 +286,7 @@ binding_run(struct controller_ctx *ctx, const 
> struct ovsrec_bridge *br_int,
>          HMAP_FOR_EACH_SAFE (old_ld, next, hmap_node, local_datapaths) {
>              if 
(!local_datapath_lookup_by_uuid(&keep_local_datapath_by_uuid,
>                                                 &old_ld->uuid)) {
> -                remove_local_datapath(local_datapaths, old_ld);
> +                remove_local_datapath(ctx, local_datapaths, old_ld);
>              }
>          }
>          hmap_destroy(&keep_local_datapath_by_uuid);
> @@ -280,8 +303,9 @@ binding_run(struct controller_ctx *ctx, const 
> struct ovsrec_bridge *br_int,
>                      poll_immediate_wake();
>                  }
>              } else {
> -                consider_local_datapath(ctx, chassis_rec, binding_rec,
> -                                        local_datapaths, 
&lport_to_iface);
> +                consider_local_datapath(ctx, lports_index, chassis_rec,
> +                                        binding_rec, local_datapaths,
> +                                        &lport_to_iface);
>              }
>          }
>      }
> diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h
> index 8753d44..11e0c0f 100644
> --- a/ovn/controller/binding.h
> +++ b/ovn/controller/binding.h
> @@ -25,11 +25,13 @@ struct ovsdb_idl;
>  struct ovsrec_bridge;
>  struct simap;
>  struct sset;
> +struct lport_index;
> 
>  void binding_register_ovs_idl(struct ovsdb_idl *);
>  void binding_reset_processing(void);
>  void binding_run(struct controller_ctx *, const struct ovsrec_bridge 
*br_int,
> -                 const char *chassis_id, struct hmap *local_datapaths);
> +                 const char *chassis_id, struct lport_index 
*lports_index,
> +                 struct hmap *local_datapaths);
>  bool binding_cleanup(struct controller_ctx *, const char *chassis_id);
> 
>  #endif /* ovn/binding.h */
> diff --git a/ovn/controller/filter.c b/ovn/controller/filter.c
> new file mode 100644
> index 0000000..cc25737
> --- /dev/null
> +++ b/ovn/controller/filter.c
> @@ -0,0 +1,207 @@
> +/* Copyright (c) 2015, 2016 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 "filter.h"
> +
> +#include "openvswitch/vlog.h"
> +#include "ovn/lib/ovn-sb-idl.h"
> +#include "ovn-controller.h"
> +#include "lport.h"
> +
> +VLOG_DEFINE_THIS_MODULE(filter);
> +
> +static struct hmap filtered_dps = HMAP_INITIALIZER(&filtered_dps);
> +static struct hmap filtered_lps = HMAP_INITIALIZER(&filtered_lps);
> +
> +struct filtered_dp {
> +    struct hmap_node hmap_node;
> +    int64_t tunnel_key;
> +    struct sbrec_datapath_binding *datapath;
> +};
> +
> +struct filtered_lp {
> +    struct hmap_node hmap_node;
> +    const char *lport_name;
> +    bool used;
> +};
> +
> +void
> +filter_init(struct ovsdb_idl *idl)
> +{
> +    sbrec_port_binding_add_clause_false(idl);
> +    sbrec_mac_binding_add_clause_false(idl);
> +    sbrec_logical_flow_add_clause_false(idl);
> +    sbrec_multicast_group_add_clause_false(idl);
> +}
> +
> +void
> +filter_mark_unused(void)
> +{
> +    struct filtered_lp *lp;
> +
> +    HMAP_FOR_EACH(lp, hmap_node, &filtered_lps) {
> +        lp->used = false;
> +    }
> +}
> +
> +void
> +filter_clear(struct ovsdb_idl *idl)
> +{
> +    struct filtered_lp *lp, *next;
> +    struct filtered_lp *dp, *next_dp;
> +
> +    HMAP_FOR_EACH_SAFE(lp, next, hmap_node, &filtered_lps) {
> +        hmap_remove(&filtered_lps, &lp->hmap_node);
> +        free(lp);
> +    }
> +    HMAP_FOR_EACH_SAFE(dp, next_dp, hmap_node, &filtered_dps) {
> +        hmap_remove(&filtered_dps, &dp->hmap_node);
> +        free(dp);
> +    }
> +
> +    ovsdb_idl_condition_reset(idl,
> +                              &sbrec_table_port_binding);
> +    ovsdb_idl_condition_reset(idl,
> +                              &sbrec_table_logical_flow);
> +    ovsdb_idl_condition_reset(idl,
> +                              &sbrec_table_mac_binding);
> +    ovsdb_idl_condition_reset(idl,
> +                              &sbrec_table_multicast_group);
> +}
> +
> +static struct filtered_dp *
> +lookup_dp_by_key(int64_t tunnel_key)
> +{
> +    struct filtered_dp *dp;
> +
> +    HMAP_FOR_EACH_WITH_HASH(dp, hmap_node, tunnel_key,
> +                            &filtered_dps) {
> +        if (dp->tunnel_key == tunnel_key) {
> +            return dp;
> +        }
> +    }
> +    return NULL;
> +}
> +
> +void
> +filter_remove_unused_lports(struct controller_ctx *ctx,
> +                            const struct lport_index *lports_index)
> +{
> +    struct filtered_lp *lp, *next;
> +
> +    HMAP_FOR_EACH_SAFE(lp, next, hmap_node, &filtered_lps) {
> +        if (!lp->used) {
> +            const struct sbrec_port_binding *pb =
> +                lport_lookup_by_name(lports_index, lp->lport_name);
> +            if (!pb) {
> +                continue;
> +            }
> +            if (lookup_dp_by_key(pb->datapath->tunnel_key)) {
> +                VLOG_INFO("Unfilter Port %s", lp->lport_name);
> + sbrec_port_binding_remove_clause_logical_port(ctx->ovnsb_idl,
> + OVSDB_F_EQ,
> + 
> lp->lport_name);
> +                hmap_remove(&filtered_lps, &lp->hmap_node);
> +                free(lp);
> +            }
> +        }
> +    }
> +}
> +
> +void
> +filter_lport(struct controller_ctx *ctx, const char *lport_name)
> +{
> +    struct filtered_lp *lp;
> +    size_t hash = hash_bytes(lport_name, strlen(lport_name), 0);
> +
> +    HMAP_FOR_EACH_WITH_HASH(lp, hmap_node, hash, &filtered_lps) {
> +        if (!strcmp(lp->lport_name, lport_name)) {
> +            lp->used = true;
> +            return;
> +        }
> +    }
> +
> +    VLOG_INFO("Filter Port %s", lport_name);
> +
> +    sbrec_port_binding_add_clause_logical_port(ctx->ovnsb_idl,
> +                                               OVSDB_F_EQ,
> +                                               lport_name);
> +
> +    char *name = xmalloc(strlen(lport_name));
> +    lp = xmalloc(sizeof *lp);
> +
> +    strcpy(name, lport_name);
> +    lp->lport_name = name;
> +    lp->used = true;
> +    hmap_insert(&filtered_lps, &lp->hmap_node,
> +                hash);
> +}
> +
> +void
> +filter_datapath(struct controller_ctx *ctx,
> +             const struct sbrec_port_binding *pb)

> <Mickey> Since "pb" is only used as "pb->datapath", wondering if it 
> would be cleaner to change the second argument to 
> sbrec_datapath_binding instead?
> 

Will change it to sbrec_datapath_binding *.

> +{
> +    struct filtered_dp *dp;
> +
> +    dp = lookup_dp_by_key(pb->datapath->tunnel_key);
> +    if (dp) {
> +        return;
> +    }
> +
> +    VLOG_INFO("Filter DP "UUID_FMT, 
UUID_ARGS(&pb->datapath->header_.uuid));
> +    sbrec_port_binding_add_clause_datapath(ctx->ovnsb_idl,
> +                                           OVSDB_F_EQ,
> +                                           pb->datapath);
> +    sbrec_mac_binding_add_clause_datapath(ctx->ovnsb_idl,
> +                                          OVSDB_F_EQ,
> +                                          pb->datapath);
> +    sbrec_logical_flow_add_clause_logical_datapath(ctx->ovnsb_idl,
> +                                                   OVSDB_F_EQ,
> +                                                   pb->datapath);
> +    sbrec_multicast_group_add_clause_datapath(ctx->ovnsb_idl,
> +                                              OVSDB_F_EQ,
> +                                              pb->datapath);
> +
> +    dp = xmalloc(sizeof *dp);
> +    dp->tunnel_key = pb->datapath->tunnel_key;
> +    dp->datapath = pb->datapath;
> +    hmap_insert(&filtered_dps, &dp->hmap_node, 
pb->datapath->tunnel_key);
> +}
> +
> +void
> +unfilter_datapath(struct controller_ctx *ctx, int64_t tunnel_key)
> +{
> +    struct filtered_dp *dp = lookup_dp_by_key(tunnel_key);
> +
> +    if (dp) {
> +        VLOG_INFO("Unfilter DP "UUID_FMT,
> +                  UUID_ARGS(&dp->datapath->header_.uuid));
> +        sbrec_port_binding_remove_clause_datapath(ctx->ovnsb_idl,
> +                                                  OVSDB_F_EQ,
> +                                                  dp->datapath);
> +        sbrec_mac_binding_remove_clause_datapath(ctx->ovnsb_idl,
> +                                                 OVSDB_F_EQ,
> +                                                 dp->datapath);
> + sbrec_logical_flow_remove_clause_logical_datapath(ctx->ovnsb_idl,
> +                                                          OVSDB_F_EQ,
> + dp->datapath);
> +        sbrec_multicast_group_remove_clause_datapath(ctx->ovnsb_idl,
> +                                                     OVSDB_F_EQ,
> +                                                     dp->datapath);
> +        hmap_remove(&filtered_dps, &dp->hmap_node);
> +        free(dp);
> +    }
> +}
> diff --git a/ovn/controller/filter.h b/ovn/controller/filter.h
> new file mode 100644
> index 0000000..203689a
> --- /dev/null
> +++ b/ovn/controller/filter.h
> @@ -0,0 +1,36 @@
> +/* 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_FILTER_H
> +#define OVN_FILTER_H 1
> +
> +#include <stdint.h>
> +
> +struct controller_ctx;
> +struct ovsdb_idl;
> +struct sbrec_port_binding;
> +struct lport_index;
> +
> +void filter_init(struct ovsdb_idl *idl);
> +void filter_clear(struct ovsdb_idl *idl);
> +void filter_mark_unused(void);
> +void filter_remove_unused_lports(struct controller_ctx *ctx,
> +                                 const struct lport_index *lports);
> +void filter_lport(struct controller_ctx *ctx, const char *lport_name);
> +void filter_datapath(struct controller_ctx *ctx,
> +                     const struct sbrec_port_binding *pb);
> +void unfilter_datapath(struct controller_ctx *ctx, int64_t tunnel_key);
> +
> +#endif /* ovn/controller/filter.h */
> diff --git a/ovn/controller/ovn-controller.c 
b/ovn/controller/ovn-controller.c
> index 04684b2..2ad8523 100644
> --- a/ovn/controller/ovn-controller.c
> +++ b/ovn/controller/ovn-controller.c
> @@ -54,6 +54,7 @@
>  #include "stream.h"
>  #include "unixctl.h"
>  #include "util.h"
> +#include "filter.h"
> 
>  VLOG_DEFINE_THIS_MODULE(main);
> 
> @@ -379,6 +380,8 @@ main(int argc, char *argv[])
>      struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER(
>          ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
> 
> +    filter_init(ovnsb_idl_loop.idl);
> +
>      /* Track the southbound idl. */
>      ovsdb_idl_track_add_all(ovnsb_idl_loop.idl);
> 
> @@ -404,6 +407,7 @@ main(int argc, char *argv[])
>              binding_reset_processing();
>              lport_index_clear(&lports);
>              mcgroup_index_clear(&mcgroups);
> +            filter_clear(ovnsb_idl_loop.idl);
>          } else {
>              free(new_ovnsb_remote);
>          }
> @@ -422,19 +426,20 @@ main(int argc, char *argv[])
>          const struct ovsrec_bridge *br_int = get_br_int(&ctx);
>          const char *chassis_id = get_chassis_id(ctx.ovs_idl);
> 
> +        lport_index_fill(&lports, ctx.ovnsb_idl);
> +        mcgroup_index_fill(&mcgroups, ctx.ovnsb_idl);
> +        filter_mark_unused();
> +
>          if (chassis_id) {
>              chassis_run(&ctx, chassis_id);
>              encaps_run(&ctx, br_int, chassis_id);
> -            binding_run(&ctx, br_int, chassis_id, &local_datapaths);
> +            binding_run(&ctx, br_int, chassis_id, &lports, 
&local_datapaths);
>          }
> 
>          if (br_int && chassis_id) {
>              patch_run(&ctx, br_int, chassis_id, &local_datapaths,
>                        &patched_datapaths);
> 
> -            lport_index_fill(&lports, ctx.ovnsb_idl);
> -            mcgroup_index_fill(&mcgroups, ctx.ovnsb_idl);
> -
>              enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int);
> 
>              pinctrl_run(&ctx, &lports, br_int, chassis_id, 
&local_datapaths);
> @@ -452,6 +457,7 @@ main(int argc, char *argv[])
>              ofctrl_put(&group_table);
>          }
> 
> +        filter_remove_unused_lports(&ctx, &lports);
>          sset_destroy(&all_lports);
> 
>          unixctl_server_run(unixctl);
> diff --git a/ovn/controller/ovn-controller.h 
b/ovn/controller/ovn-controller.h
> index 470b1f5..3469fe5 100644
> --- a/ovn/controller/ovn-controller.h
> +++ b/ovn/controller/ovn-controller.h
> @@ -40,6 +40,7 @@ struct local_datapath {
>      struct hmap_node hmap_node;
>      struct hmap_node uuid_hmap_node;
>      struct uuid uuid;
> +    int64_t tunnel_key;
>      char *logical_port;
>      const struct sbrec_port_binding *localnet_port;
>  };
> diff --git a/ovn/controller/patch.c b/ovn/controller/patch.c
> index 52d9e8d..438dff5 100644
> --- a/ovn/controller/patch.c
> +++ b/ovn/controller/patch.c
> @@ -22,6 +22,7 @@
>  #include "lib/vswitch-idl.h"
>  #include "openvswitch/vlog.h"
>  #include "ovn-controller.h"
> +#include "filter.h"
> 
>  VLOG_DEFINE_THIS_MODULE(patch);
> 
> @@ -250,7 +251,8 @@ add_bridge_mappings(struct controller_ctx *ctx,
> 
>  static void
>  add_patched_datapath(struct hmap *patched_datapaths,
> -                     const struct sbrec_port_binding *binding_rec, 
> bool local)
> +                     const struct sbrec_port_binding *binding_rec, 
> bool local,
> +                     struct controller_ctx *ctx)
>  {
>      struct patched_datapath *pd = 
get_patched_datapath(patched_datapaths,
> binding_rec->datapath->tunnel_key);
> @@ -268,6 +270,7 @@ add_patched_datapath(struct hmap *patched_datapaths,
>      /* stale is set to false. */
>      hmap_insert(patched_datapaths, &pd->hmap_node,
>                  binding_rec->datapath->tunnel_key);
> +    filter_datapath(ctx, binding_rec);
>  }

> <Mickey> Should unfilter_datapath be called somewhere around line 
> 297? With a check against local_datapaths as well?
> 

Right, will fix that.

Thanks for the review,
- Liran

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to