As an addition to this, I've uploaded the tests here:

https://github.com/mangelajo/ovs/commit/065ddf514167eb6da871813786e5615f0bf811ba#diff-97d4cf929e4894ef95c4bfde3f896c34

I will send-mail that change on next version.

On Thu, Jun 8, 2017 at 4:05 PM, <[email protected]> wrote:

> From: Miguel Angel Ajo <[email protected]>
>
> is_chassis_active now is only true for redirect-chassis ports
> in the case of the specific lport being active on the
> local chassis.
>
> This will naturally make the ARP responder / redirection openflow
> rules automatically inserted/removed when a router goes active/backup.
>
> Signed-off-by: Miguel Angel Ajo <[email protected]>
> ---
>  ovn/controller/binding.c        | 21 +++++---------------
>  ovn/controller/binding.h        |  2 +-
>  ovn/controller/lflow.c          | 38 ++++++++++++++++++++++++++----------
>  ovn/controller/lflow.h          |  4 +++-
>  ovn/controller/lport.c          | 43 ++++++++++++++++++++++++++++++
> ++++++++++-
>  ovn/controller/lport.h          |  7 ++++++-
>  ovn/controller/ovn-controller.c |  6 ++++--
>  7 files changed, 89 insertions(+), 32 deletions(-)
>
> diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
> index a2d375c..7ec7c70 100644
> --- a/ovn/controller/binding.c
> +++ b/ovn/controller/binding.c
> @@ -430,17 +430,8 @@ consider_local_datapath(struct controller_ctx *ctx,
>
>          if (redirect_chassis &&
>             redirect_chassis_contains(redirect_chassis, chassis_rec)) {
> -            struct redirect_chassis *rc;
> -            LIST_FOR_EACH (rc, node, redirect_chassis) {
> -                if (!strcmp(rc->chassis_id, chassis_rec->name)) {
> -                    /* sb_rec_port_binding->chassis should reflect master
> */
> -                    our_chassis = true;
> -                    break;
> -                }
> -                if (sset_contains(active_tunnels, rc->chassis_id)) {
> -                    break;
> -                }
> -            }
> +            our_chassis = redirect_chassis_is_active(
> +                    redirect_chassis, chassis_rec, active_tunnels);
>              add_local_datapath(ldatapaths, lports, binding_rec->datapath,
>                                 false, local_datapaths, our_chassis);
>          }
> @@ -491,7 +482,7 @@ binding_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
>              const struct sbrec_chassis *chassis_rec,
>              const struct ldatapath_index *ldatapaths,
>              const struct lport_index *lports, struct hmap
> *local_datapaths,
> -            struct sset *local_lports)
> +            struct sset *local_lports, struct sset *active_tunnels)
>  {
>      if (!chassis_rec) {
>          return;
> @@ -500,13 +491,12 @@ binding_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
>      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);
> -    struct sset active_tunnels = SSET_INITIALIZER(&active_tunnels);
>      struct hmap qos_map;
>
>      hmap_init(&qos_map);
>      if (br_int) {
>          get_local_iface_ids(br_int, &lport_to_iface, local_lports,
> -                            &egress_ifaces, &active_tunnels);
> +                            &egress_ifaces, active_tunnels);
>      }
>
>      /* Run through each binding record to see if it is resident on this
> @@ -517,7 +507,7 @@ binding_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
>                                  chassis_rec, binding_rec,
>                                  sset_is_empty(&egress_ifaces) ? NULL :
>                                  &qos_map, local_datapaths,
> &lport_to_iface,
> -                                local_lports, &active_tunnels);
> +                                local_lports, active_tunnels);
>
>      }
>      if (!sset_is_empty(&egress_ifaces)
> @@ -530,7 +520,6 @@ binding_run(struct controller_ctx *ctx, const struct
> ovsrec_bridge *br_int,
>
>      shash_destroy(&lport_to_iface);
>      sset_destroy(&egress_ifaces);
> -    sset_destroy(&active_tunnels);
>      hmap_destroy(&qos_map);
>  }
>
> diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h
> index 2b88ec5..99c5225 100644
> --- a/ovn/controller/binding.h
> +++ b/ovn/controller/binding.h
> @@ -32,7 +32,7 @@ void binding_register_ovs_idl(struct ovsdb_idl *);
>  void binding_run(struct controller_ctx *, const struct ovsrec_bridge
> *br_int,
>                   const struct sbrec_chassis *, const struct
> ldatapath_index *,
>                   const struct lport_index *, struct hmap *local_datapaths,
> -                 struct sset *all_lports);
> +                 struct sset *all_lports, struct sset *active_tunnels);
>  void bfd_run(struct controller_ctx *ctx, const struct ovsrec_bridge
> *br_int,
>               const struct sbrec_chassis *chassis_rec,
>               struct hmap *local_datapaths);
> diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
> index b7d1bcb..f901bea 100644
> --- a/ovn/controller/lflow.c
> +++ b/ovn/controller/lflow.c
> @@ -53,6 +53,7 @@ struct lookup_port_aux {
>  struct condition_aux {
>      const struct lport_index *lports;
>      const struct sbrec_chassis *chassis;
> +    const struct sset *active_tunnels;
>  };
>
>  static void consider_logical_flow(const struct lport_index *lports,
> @@ -65,7 +66,8 @@ static void consider_logical_flow(const struct
> lport_index *lports,
>                                    struct hmap *dhcpv6_opts,
>                                    uint32_t *conj_id_ofs,
>                                    const struct shash *addr_sets,
> -                                  struct hmap *flow_table);
> +                                  struct hmap *flow_table,
> +                                  struct sset *active_tunnels);
>
>  static bool
>  lookup_port_cb(const void *aux_, const char *port_name, unsigned int
> *portp)
> @@ -96,10 +98,23 @@ is_chassis_resident_cb(const void *c_aux_, const char
> *port_name)
>
>      const struct sbrec_port_binding *pb
>          = lport_lookup_by_name(c_aux->lports, port_name);
> -    if (pb && pb->chassis && pb->chassis == c_aux->chassis) {
> -        return true;
> +    if (!pb) {
> +        return false;
> +    }
> +    if (strcmp(pb->type, "chassisredirect")) {
> +        /* for non-chassisredirect ports */
> +        return pb->chassis && pb->chassis == c_aux->chassis;
>      } else {
> -        return pb_redirect_chassis_contains(pb, c_aux->chassis);
> +        struct ovs_list *redirect_chassis;
> +        redirect_chassis = parse_redirect_chassis(pb);
> +        if (redirect_chassis) {
> +            bool active = redirect_chassis_is_active(redirect_chassis,
> +                                                     c_aux->chassis,
> +
>  c_aux->active_tunnels);
> +            redirect_chassis_destroy(redirect_chassis);
> +            return active;
> +        }
> +        return false;
>      }
>  }
>
> @@ -127,7 +142,8 @@ add_logical_flows(struct controller_ctx *ctx, const
> struct lport_index *lports,
>                    struct group_table *group_table,
>                    const struct sbrec_chassis *chassis,
>                    const struct shash *addr_sets,
> -                  struct hmap *flow_table)
> +                  struct hmap *flow_table,
> +                  struct sset *active_tunnels)
>  {
>      uint32_t conj_id_ofs = 1;
>      const struct sbrec_logical_flow *lflow;
> @@ -151,7 +167,7 @@ add_logical_flows(struct controller_ctx *ctx, const
> struct lport_index *lports,
>          consider_logical_flow(lports, mcgroups, lflow, local_datapaths,
>                                group_table, chassis,
>                                &dhcp_opts, &dhcpv6_opts, &conj_id_ofs,
> -                              addr_sets, flow_table);
> +                              addr_sets, flow_table, active_tunnels);
>      }
>
>      dhcp_opts_destroy(&dhcp_opts);
> @@ -169,7 +185,8 @@ consider_logical_flow(const struct lport_index *lports,
>                        struct hmap *dhcpv6_opts,
>                        uint32_t *conj_id_ofs,
>                        const struct shash *addr_sets,
> -                      struct hmap *flow_table)
> +                      struct hmap *flow_table,
> +                      struct sset *active_tunnels)
>  {
>      /* Determine translation of logical table IDs to physical table IDs.
> */
>      bool ingress = !strcmp(lflow->pipeline, "ingress");
> @@ -266,7 +283,7 @@ consider_logical_flow(const struct lport_index *lports,
>          return;
>      }
>
> -    struct condition_aux cond_aux = { lports, chassis };
> +    struct condition_aux cond_aux = { lports, chassis, active_tunnels};
>      expr = expr_simplify(expr, is_chassis_resident_cb, &cond_aux);
>      expr = expr_normalize(expr);
>      uint32_t n_conjs = expr_to_matches(expr, lookup_port_cb, &aux,
> @@ -395,10 +412,11 @@ lflow_run(struct controller_ctx *ctx,
>            const struct hmap *local_datapaths,
>            struct group_table *group_table,
>            const struct shash *addr_sets,
> -          struct hmap *flow_table)
> +          struct hmap *flow_table,
> +          struct sset *active_tunnels)
>  {
>      add_logical_flows(ctx, lports, mcgroups, local_datapaths, group_table,
> -                      chassis, addr_sets, flow_table);
> +                      chassis, addr_sets, flow_table, active_tunnels);
>      add_neighbor_flows(ctx, lports, flow_table);
>  }
>
> diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
> index a23cde0..6c02216 100644
> --- a/ovn/controller/lflow.h
> +++ b/ovn/controller/lflow.h
> @@ -42,6 +42,7 @@ struct lport_index;
>  struct mcgroup_index;
>  struct sbrec_chassis;
>  struct simap;
> +struct sset;
>  struct uuid;
>
>  /* OpenFlow table numbers.
> @@ -69,7 +70,8 @@ void lflow_run(struct controller_ctx *,
>                 const struct hmap *local_datapaths,
>                 struct group_table *group_table,
>                 const struct shash *addr_sets,
> -               struct hmap *flow_table);
> +               struct hmap *flow_table,
> +               struct sset *active_tunnels);
>  void lflow_destroy(void);
>
>  #endif /* ovn/lflow.h */
> diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c
> index 52608a1..a0c403a 100644
> --- a/ovn/controller/lport.c
> +++ b/ovn/controller/lport.c
> @@ -15,11 +15,11 @@
>
>  #include <config.h>
>
> +#include "lib/sset.h"
>  #include "lport.h"
>  #include "hash.h"
>  #include "openvswitch/vlog.h"
>  #include "ovn/lib/ovn-sb-idl.h"
> -
>  VLOG_DEFINE_THIS_MODULE(lport);
>
>  static struct ldatapath *ldatapath_lookup_by_key__(
> @@ -356,3 +356,44 @@ pb_redirect_chassis_contains(const struct
> sbrec_port_binding *binding,
>      redirect_chassis_destroy(redirect_chassis);
>      return contained;
>  }
> +
> +bool
> +redirect_chassis_is_active(const struct ovs_list *redirect_chassis,
> +                           const struct sbrec_chassis *local_chassis,
> +                           const struct sset *active_tunnels)
> +{
> +    struct redirect_chassis *rc;
> +
> +    if (!redirect_chassis) {
> +        return false;
> +    }
> +    /* if there's only one chassis, and local chassis is on the list
> +     * it's not HA and it's the equivalent of being active */
> +    if (ovs_list_is_short(redirect_chassis) &&
> +       redirect_chassis_contains(redirect_chassis, local_chassis)) {
> +        return true;
> +    }
> +
> +    /* if there are no other tunnels active, we assume that the
> +     * connection providing tunneling is down, hence we're down */
> +    if (sset_is_empty(active_tunnels)) {
> +        return false;
> +    }
> +
> +    /* redirect_chassis is an ordered list, by priority, of chassis
> +     * hosting the redirect of the port */
> +    LIST_FOR_EACH (rc, node, redirect_chassis) {
> +        /* if we found the chassis on the list, and we didn't exit before
> +         * on the active_tunnels check for other higher priority chassis
> +         * being active, then this chassis is master. */
> +        if (!strcmp(rc->chassis_id, local_chassis->name)) {
> +            return true;
> +        }
> +        /* if we find this specific chassis on the list to have an active
> +         * tunnel, then 'local_chassis' is not master */
> +        if (sset_contains(active_tunnels, rc->chassis_id)) {
> +            return false;
> +        }
> +    }
> +    return false;
> +}
> diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h
> index 329a71f..e7abae4 100644
> --- a/ovn/controller/lport.h
> +++ b/ovn/controller/lport.h
> @@ -25,6 +25,8 @@ struct ovsdb_idl;
>  struct sbrec_chassis;
>  struct sbrec_datapath_binding;
>  struct sbrec_port_binding;
> +struct sset;
> +
>
>  /* Database indexes.
>   * =================
> @@ -120,5 +122,8 @@ void redirect_chassis_destroy(struct ovs_list *list);
>  bool pb_redirect_chassis_contains(
>          const struct sbrec_port_binding *binding,
>          const struct sbrec_chassis *chassis);
> -
> +bool redirect_chassis_is_active(
> +        const struct ovs_list *redirect_chassis,
> +        const struct sbrec_chassis *local_chassis,
> +        const struct sset *active_tunnels);
>  #endif /* ovn/lport.h */
> diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-
> controller.c
> index 7930b6e..10dfdfe 100644
> --- a/ovn/controller/ovn-controller.c
> +++ b/ovn/controller/ovn-controller.c
> @@ -613,6 +613,7 @@ main(int argc, char *argv[])
>           * l2gateway ports for which options:l2gateway-chassis designates
> the
>           * local hypervisor, and localnet ports. */
>          struct sset local_lports = SSET_INITIALIZER(&local_lports);
> +        struct sset active_tunnels = SSET_INITIALIZER(&active_tunnels);
>
>          const struct ovsrec_bridge *br_int = get_br_int(&ctx);
>          const char *chassis_id = get_chassis_id(ctx.ovs_idl);
> @@ -629,7 +630,7 @@ main(int argc, char *argv[])
>              chassis = chassis_run(&ctx, chassis_id, br_int);
>              encaps_run(&ctx, br_int, chassis_id);
>              binding_run(&ctx, br_int, chassis, &ldatapaths, &lports,
> -                        &local_datapaths, &local_lports);
> +                        &local_datapaths, &local_lports, &active_tunnels);
>          }
>
>          if (br_int && chassis) {
> @@ -651,7 +652,7 @@ main(int argc, char *argv[])
>                      struct hmap flow_table =
> HMAP_INITIALIZER(&flow_table);
>                      lflow_run(&ctx, chassis, &lports, &mcgroups,
>                                &local_datapaths, &group_table,
> -                              &addr_sets, &flow_table);
> +                              &addr_sets, &flow_table, &active_tunnels);
>
>                      bfd_run(&ctx, br_int, chassis, &local_datapaths);
>                      physical_run(&ctx, mff_ovn_geneve,
> @@ -705,6 +706,7 @@ main(int argc, char *argv[])
>          ldatapath_index_destroy(&ldatapaths);
>
>          sset_destroy(&local_lports);
> +        sset_destroy(&active_tunnels);
>
>          struct local_datapath *cur_node, *next_node;
>          HMAP_FOR_EACH_SAFE (cur_node, next_node, hmap_node,
> &local_datapaths) {
> --
> 1.8.3.1
>
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to