On Wed, Aug 6, 2025 at 12:53 PM Dumitru Ceara <dce...@redhat.com> wrote:

> Hi Ales,
>
> Overall this patch looks good to me.  I only have a few minor comments
> below.
>

Hi Dumitru,

thank you for the review.


>
> On 7/25/25 8:03 AM, Ales Musil wrote:
> > In order to get the VTEP setup listeners for each special interface
> > that is dedicated to given vni. Those interfaces need to be
>
> Nit: s/to given vni/to a given VNI/
>
> > part of the VRF, created by CMS. Once those listeners are in place
> > ovn-controller will receive notifications about remote VTEPs.
> >
>
> I think, maybe as follow up or in later revisions (if we get a chance
> to), we should add a small document (tutorial?) describing how the
> integration bits should be set up.
>

Let's try it for v3, possibly a follow up patch to not delay v2.

>
> > Create remote VTEP representation based on the data received from
> > netlink neighbor table. There are three key attributes that
> > uniquely identify each remote VTEP:
> > 1) IP of the remote tunnel.
> > 2) Destination port of the remote tunnel.
> > 3) VNI.
> >
> > Crate map of all remote VTEPs based on those three attributes.
>
> Typo: "Crate".  I'd say "Create a map of..".
>
> > The map will be used later on to crate the EVPN binding. One
> > thing to note is that all of this is specific to each ovn-controller.
> > This is one of the reasons why those data are local to each
> > ovn-controller, the second reason is scalability as we would have
> > possibly duplicate SB entries differentiated only by residing
> > chassis.
> >
> > Note that there isn't any way to set vni for given LS that will
> > be part of future patch.
> >
>
> Maybe explicitly mention the option name here? ("dynamic-routing-vni")
>
> > Signed-off-by: Ales Musil <amu...@redhat.com>
> > ---
> >  controller/neighbor-exchange-stub.c |  12 +++
> >  controller/neighbor-exchange.c      | 116 ++++++++++++++++++++++++++--
> >  controller/neighbor-exchange.h      |  22 +++++-
> >  controller/neighbor.c               |  98 +++++++++++++++++++----
> >  controller/neighbor.h               |  11 +++
> >  controller/ovn-controller.c         | 108 +++++++++++++++++++++++---
> >  lib/ovn-util.c                      |   6 ++
> >  lib/ovn-util.h                      |   2 +
> >  8 files changed, 346 insertions(+), 29 deletions(-)
> >
> > diff --git a/controller/neighbor-exchange-stub.c
> b/controller/neighbor-exchange-stub.c
> > index a42df84c2..d314543be 100644
> > --- a/controller/neighbor-exchange-stub.c
> > +++ b/controller/neighbor-exchange-stub.c
> > @@ -28,3 +28,15 @@ neighbor_exchange_status_run(void)
> >  {
> >      return 0;
> >  }
> > +
> > +void
> > +evpn_remote_vteps_clear(struct hmap *remote_vteps OVS_UNUSED)
> > +{
> > +}
> > +
> > +void
> > +evpn_remote_vtep_list(struct unixctl_conn *conn OVS_UNUSED,
> > +                      int argc OVS_UNUSED, const char *argv[]
> OVS_UNUSED,
> > +                      void *data_ OVS_UNUSED)
> > +{
> > +}
> > diff --git a/controller/neighbor-exchange.c
> b/controller/neighbor-exchange.c
> > index 4750d4f88..0fec5e59d 100644
> > --- a/controller/neighbor-exchange.c
> > +++ b/controller/neighbor-exchange.c
> > @@ -15,12 +15,30 @@
> >
> >  #include <config.h>
> >
> > +#include <linux/neighbour.h>
> > +
> >  #include "host-if-monitor.h"
> >  #include "neighbor.h"
> >  #include "neighbor-exchange.h"
> >  #include "neighbor-exchange-netlink.h"
> >  #include "neighbor-table-notify.h"
> > +#include "openvswitch/vlog.h"
> > +#include "ovn-util.h"
> > +#include "packets.h"
> >  #include "vec.h"
> > +#include "unixctl.h"
> > +
> > +VLOG_DEFINE_THIS_MODULE(neighbor_exchange);
> > +
> > +static bool neighbor_is_valid_remote_vtep(struct ne_nl_received_neigh
> *);
> > +static uint32_t evpn_remote_vtep_hash(const struct in6_addr *ip,
> > +                                      uint16_t port, uint32_t vni);
> > +static void evpn_remote_vtep_add(struct hmap *remote_vteps, struct
> in6_addr ip,
> > +                                 uint16_t port, uint32_t vni);
> > +static struct evpn_remote_vtep *evpn_remote_vtep_find(
> > +    const struct hmap *remote_vteps, struct in6_addr *ip,
> > +    uint16_t port, uint32_t vni);
> > +
> >
> >  /* Last neighbor_exchange netlink operation. */
> >  static int neighbor_exchange_nl_status;
> > @@ -66,12 +84,19 @@ neighbor_exchange_run(const struct
> neighbor_exchange_ctx_in *n_ctx_in,
> >                               &received_neighbors)
> >          );
> >
> > -        /* XXX: TODO GLUE: sync received neighbors to:
> > -         * - SB: for remote vtep entries
> > -         *   https://issues.redhat.com/browse/FDP-1385
> > -         * - in memory table for remote neighbor entries
> > -         *   https://issues.redhat.com/browse/FDP-1387
> > -         */
> > +        if (nim->type == NEIGH_IFACE_VXLAN) {
> > +            struct ne_nl_received_neigh *ne;
> > +            VECTOR_FOR_EACH_PTR (&received_neighbors, ne) {
> > +                if (neighbor_is_valid_remote_vtep(ne)) {
> > +                    uint16_t port = ne->port ? ne->port :
> DEFAULT_VXLAN_PORT;
> > +                    if (!evpn_remote_vtep_find(n_ctx_out->remote_vteps,
> > +                                               &ne->addr, port,
> nim->vni)) {
> > +                        evpn_remote_vtep_add(n_ctx_out->remote_vteps,
> ne->addr,
> > +                                             port, nim->vni);
> > +                    }
> > +                }
> > +            }
> > +        }
> >
> >
> neighbor_table_add_watch_request(&n_ctx_out->neighbor_table_watches,
> >                                           if_index, nim->if_name);
> > @@ -84,3 +109,82 @@ neighbor_exchange_status_run(void)
> >  {
> >      return neighbor_exchange_nl_status;
> >  }
> > +
> > +static bool
> > +neighbor_is_valid_remote_vtep(struct ne_nl_received_neigh *ne)
>
> Nit: I think this should be part of neighbor-exchange-netlink.[ch].
> We're checking netlink/linux specific flags, it feels like it fits
> better there.  Also we already have ne_is_ovn_owned() there so we have a
> precedent.
>
> > +{
> > +    return eth_addr_is_zero(ne->lladdr) && ne->state & NUD_NOARP &&
> > +           ne->state & NUD_PERMANENT;
>
> Nit: the mix of && and & makes me a bit uneasy, can you please add some
> extra parenthesis?
>
> Also, a comment explaining that remote vtep neighbor entries are
>
> > +}
> > +
> > +void
> > +evpn_remote_vteps_clear(struct hmap *remote_vteps)
> > +{
> > +    struct evpn_remote_vtep *vtep;
> > +    HMAP_FOR_EACH_POP (vtep, hmap_node, remote_vteps) {
> > +        free(vtep);
> > +    }
> > +}
> > +
> > +void
> > +evpn_remote_vtep_list(struct unixctl_conn *conn, int argc OVS_UNUSED,
>
> Super nit: the 'conn' argument name can be skipped.
>
> > +                      const char *argv[] OVS_UNUSED, void *data_)
> > +{
> > +    struct hmap *remote_vteps = data_;
> > +    struct ds ds = DS_EMPTY_INITIALIZER;
> > +
> > +    struct evpn_remote_vtep *vtep;
> > +    HMAP_FOR_EACH (vtep, hmap_node, remote_vteps) {
> > +        ds_put_cstr(&ds, "IP: ");
> > +        ipv6_format_mapped(&vtep->ip, &ds);
> > +        ds_put_format(&ds, ", port: %"PRIu16", vni: %"PRIu32"\n",
> > +                      vtep->port, vtep->vni);
> > +    }
> > +
> > +    unixctl_command_reply(conn, ds_cstr_ro(&ds));
> > +    ds_destroy(&ds);
> > +}
> > +
> > +static void
> > +evpn_remote_vtep_add(struct hmap *remote_vteps, struct in6_addr ip,
> > +                     uint16_t port, uint32_t vni)
> > +{
> > +    struct evpn_remote_vtep *vtep = xmalloc(sizeof *vtep);
> > +    *vtep = (struct evpn_remote_vtep) {
> > +        .ip = ip,
> > +        .port = port,
> > +        .vni = vni,
> > +    };
> > +
> > +    hmap_insert(remote_vteps, &vtep->hmap_node,
> > +                evpn_remote_vtep_hash(&ip, port, vni));
> > +}
> > +
> > +static struct evpn_remote_vtep *
> > +evpn_remote_vtep_find(const struct hmap *remote_vteps, struct in6_addr
> *ip,
>
> Nit: const struct in6_addr *ip
>
> > +                      uint16_t port, uint32_t vni)
> > +{
> > +    uint32_t hash = evpn_remote_vtep_hash(ip, port, vni);
> > +
> > +    struct evpn_remote_vtep *vtep;
> > +    HMAP_FOR_EACH_WITH_HASH (vtep, hmap_node, hash, remote_vteps) {
> > +        if (ipv6_addr_equals(&vtep->ip, ip) &&
> > +            vtep->port == port && vtep->vni == vni) {
> > +            return vtep;
> > +        }
> > +    }
> > +
> > +    return NULL;
> > +}
> > +
> > +static uint32_t
> > +evpn_remote_vtep_hash(const struct in6_addr *ip, uint16_t port,
> > +                      uint32_t vni)
> > +{
> > +    uint32_t hash = 0;
> > +    hash = hash_add_in6_addr(hash, ip);
> > +    hash = hash_add(hash, port);
> > +    hash = hash_add(hash, vni);
> > +
> > +    return hash;
> > +}
> > diff --git a/controller/neighbor-exchange.h
> b/controller/neighbor-exchange.h
> > index afbbe9811..dba97fdb9 100644
> > --- a/controller/neighbor-exchange.h
> > +++ b/controller/neighbor-exchange.h
> > @@ -16,9 +16,14 @@
> >  #ifndef NEIGHBOR_EXCHANGE_H
> >  #define NEIGHBOR_EXCHANGE_H 1
> >
> > -#include "lib/sset.h"
> > +#include <netinet/in.h>
> > +
> >  #include "openvswitch/hmap.h"
> >
> > +#define DEFAULT_VXLAN_PORT 4789
> > +
> > +struct unixctl_conn;
> > +
> >  struct neighbor_exchange_ctx_in {
> >      /* Contains struct neighbor_interface_monitor pointers. */
> >      const struct vector *monitored_interfaces;
> > @@ -27,10 +32,25 @@ struct neighbor_exchange_ctx_in {
> >  struct neighbor_exchange_ctx_out {
> >      /* Contains struct neighbor_table_watch_request. */
> >      struct hmap neighbor_table_watches;
> > +    /* Contains 'struct evpn_remote_vtep'. */
> > +    struct hmap *remote_vteps;
> > +};
> > +
> > +struct evpn_remote_vtep {
> > +    struct hmap_node hmap_node;
> > +    /* IP address of the remote tunnel. */
> > +    struct in6_addr ip;
> > +    /* Destination port of the remote tunnel. */
> > +    uint16_t port;
> > +    /* VNI of the VTEP. */
> > +    uint32_t vni;
> >  };
> >
> >  void neighbor_exchange_run(const struct neighbor_exchange_ctx_in *,
> >                             struct neighbor_exchange_ctx_out *);
> >  int neighbor_exchange_status_run(void);
> > +void evpn_remote_vteps_clear(struct hmap *remote_vteps);
> > +void evpn_remote_vtep_list(struct unixctl_conn *conn, int argc,
> > +                           const char *argv[], void *data_);
> >
> >  #endif  /* NEIGHBOR_EXCHANGE_H */
> > diff --git a/controller/neighbor.c b/controller/neighbor.c
> > index 53e8999ed..ee77d02d6 100644
> > --- a/controller/neighbor.c
> > +++ b/controller/neighbor.c
> > @@ -18,11 +18,26 @@
> >  #include "lib/hash.h"
> >  #include "lib/packets.h"
> >  #include "lib/sset.h"
> > +#include "local_data.h"
> > +#include "ovn-sb-idl.h"
> >
> >  #include "neighbor.h"
> >
> > +static const char *neighbor_interface_prefixes[] = {
> > +    [NEIGH_IFACE_BRIDGE] = "br-",
> > +    [NEIGH_IFACE_VXLAN] = "vxlan-",
> > +    [NEIGH_IFACE_LOOPBACK] = "lo-",
> > +};
> > +
> >  static void neighbor_interface_monitor_destroy(
> >      struct neighbor_interface_monitor *);
> > +static bool neighbor_interface_with_vni_exists(
> > +    struct vector *monitored_interfaces,
> > +    uint32_t vni);
> > +static struct neighbor_interface_monitor *
> > +neighbor_interface_monitor_alloc(enum neighbor_family family,
> > +                                 enum neighbor_interface_type type,
> > +                                 uint32_t vni);
> >
> >  uint32_t
> >  advertise_neigh_hash(const struct eth_addr *eth, const struct in6_addr
> *ip)
> > @@ -31,20 +46,46 @@ advertise_neigh_hash(const struct eth_addr *eth,
> const struct in6_addr *ip)
> >  }
> >
> >  void
> > -neighbor_run(struct neighbor_ctx_in *n_ctx_in OVS_UNUSED,
> > -             struct neighbor_ctx_out *n_ctx_out OVS_UNUSED)
> > +neighbor_run(struct neighbor_ctx_in *n_ctx_in,
> > +             struct neighbor_ctx_out *n_ctx_out)
> >  {
> > -    /* XXX: Not implemented yet. */
> > -
> > -    /* XXX: TODO GLUE: get information from (n_ctx_in) SB
> (runtime-data) about:
> > -     * - local datapath vni (and listen on br-$vni, lo-$vni and
> vxlan-$vni)
> > -     *   for which we want to enable neighbor monitoring
> > -     *   https://issues.redhat.com/browse/FDP-1385
> > -     * - what FDB/neighbor entries to advertise
> > -     *   https://issues.redhat.com/browse/FDP-1389
> > -     *
> > -     * And populate that in n_ctx_out.
> > -     */
> > +    struct local_datapath *ld;
> > +    HMAP_FOR_EACH (ld, hmap_node, n_ctx_in->local_datapaths) {
> > +        if (!ld->is_switch) {
> > +            continue;
> > +        }
> > +
> > +        int64_t vni = ovn_smap_get_llong(&ld->datapath->external_ids,
> > +                                         "dynamic-routing-vni", -1);
> > +        if (!ovn_is_valid_vni(vni)) {
> > +            continue;
> > +        }
> > +
> > +        if
> (neighbor_interface_with_vni_exists(n_ctx_out->monitored_interfaces,
> > +                                               vni)) {
> > +            continue;
> > +        }
> > +
> > +        struct neighbor_interface_monitor *vxlan =
> > +            neighbor_interface_monitor_alloc(NEIGH_AF_BRIDGE,
> > +                                             NEIGH_IFACE_VXLAN, vni);
> > +        vector_push(n_ctx_out->monitored_interfaces, &vxlan);
> > +
> > +        struct neighbor_interface_monitor *lo =
> > +            neighbor_interface_monitor_alloc(NEIGH_AF_BRIDGE,
> > +                                             NEIGH_IFACE_LOOPBACK, vni);
> > +        vector_push(n_ctx_out->monitored_interfaces, &lo);
> > +
> > +        struct neighbor_interface_monitor *br_v4 =
> > +            neighbor_interface_monitor_alloc(NEIGH_AF_INET,
> > +                                             NEIGH_IFACE_BRIDGE, vni);
> > +        vector_push(n_ctx_out->monitored_interfaces, &br_v4);
> > +
> > +        struct neighbor_interface_monitor *br_v6 =
> > +            neighbor_interface_monitor_alloc(NEIGH_AF_INET6,
> > +                                             NEIGH_IFACE_BRIDGE, vni);
> > +        vector_push(n_ctx_out->monitored_interfaces, &br_v6);
> > +    }
> >  }
> >
> >  void
> > @@ -67,3 +108,34 @@ neighbor_interface_monitor_destroy(struct
> neighbor_interface_monitor *nim)
> >      }
> >      free(nim);
> >  }
> > +
> > +static bool
> > +neighbor_interface_with_vni_exists(struct vector *monitored_interfaces,
> > +                                   uint32_t vni)
> > +{
> > +    const struct neighbor_interface_monitor *nim;
> > +    VECTOR_FOR_EACH (monitored_interfaces, nim) {
> > +        if (nim->vni == vni) {
> > +            return true;
> > +        }
> > +    }
> > +
> > +    return false;
> > +}
> > +
> > +static struct neighbor_interface_monitor *
> > +neighbor_interface_monitor_alloc(enum neighbor_family family,
> > +                                 enum neighbor_interface_type type,
> > +                                 uint32_t vni)
> > +{
> > +    struct neighbor_interface_monitor *nim = xmalloc(sizeof *nim);
> > +    *nim = (struct neighbor_interface_monitor) {
> > +        .family = family,
> > +        .announced_neighbors =
> HMAP_INITIALIZER(&nim->announced_neighbors),
> > +        .type = type,
> > +        .vni = vni,
> > +    };
> > +    snprintf(nim->if_name, sizeof nim->if_name, "%s%"PRIu32,
> > +             neighbor_interface_prefixes[type], vni);
> > +    return nim;
> > +}
> > diff --git a/controller/neighbor.h b/controller/neighbor.h
> > index 3abc6e923..3dc21938b 100644
> > --- a/controller/neighbor.h
> > +++ b/controller/neighbor.h
> > @@ -40,6 +40,8 @@ enum neighbor_family {
> >  };
> >
> >  struct neighbor_ctx_in {
> > +    /* Contains 'struct local_datapath'. */
> > +    const struct hmap *local_datapaths;
> >  };
> >
> >  struct neighbor_ctx_out {
> > @@ -47,9 +49,18 @@ struct neighbor_ctx_out {
> >      struct vector *monitored_interfaces;
> >  };
> >
> > +enum neighbor_interface_type {
> > +    NEIGH_IFACE_BRIDGE,
> > +    NEIGH_IFACE_VXLAN,
> > +    NEIGH_IFACE_LOOPBACK,
> > +};
> > +
> > +
>
> Nit: one newline too many.
>
> >  struct neighbor_interface_monitor {
> >      enum neighbor_family family;
> >      char if_name[IFNAMSIZ + 1];
> > +    enum neighbor_interface_type type;
> > +    uint32_t vni;
> >
> >      /* Contains struct advertise_neighbor_entry - the entries that OVN
> >       * advertises on this interface. */
> > diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> > index 1842d0184..90ef6011a 100644
> > --- a/controller/ovn-controller.c
> > +++ b/controller/ovn-controller.c
> > @@ -5737,7 +5737,10 @@ static enum engine_node_state
> >  en_neighbor_run(struct engine_node *node OVS_UNUSED, void *data)
> >  {
> >      struct ed_type_neighbor *ne_data = data;
> > +    struct ed_type_runtime_data *rt_data =
> > +        engine_get_input_data("runtime_data", node);
> >      struct neighbor_ctx_in n_ctx_in = {
> > +        .local_datapaths = &rt_data->local_datapaths,
> >      };
> >
> >      struct neighbor_ctx_out n_ctx_out = {
> > @@ -5747,13 +5750,73 @@ en_neighbor_run(struct engine_node *node
> OVS_UNUSED, void *data)
> >      neighbor_cleanup(&ne_data->monitored_interfaces);
> >      neighbor_run(&n_ctx_in, &n_ctx_out);
> >
> > -    /* XXX: This should return EN_UPDATED once we actually process real
> SB
> > -     * changes, i.e.:
> > -     *
> > -     * return EN_UPDATED;
> > -     */
> > +    return EN_UPDATED;
> > +}
> >
> > -    return EN_UNCHANGED;
> > +static enum engine_input_handler_result
> > +neighbor_runtime_data_handler(struct engine_node *node, void *data
> OVS_UNUSED)
> > +{
> > +    struct ed_type_runtime_data *rt_data =
> > +        engine_get_input_data("runtime_data", node);
> > +
> > +    /* There are no tracked data. Fall back to full recompute. */
> > +    if (!rt_data->tracked) {
> > +        return EN_UNHANDLED;
> > +    }
> > +
> > +    struct tracked_datapath *tdp;
> > +    HMAP_FOR_EACH (tdp, node, &rt_data->tracked_dp_bindings) {
> > +        struct local_datapath *ld =
> > +            get_local_datapath(&rt_data->local_datapaths,
> tdp->dp->tunnel_key);
> > +        if (!ld) {
> > +            continue;
> > +        }
> > +
> > +        int64_t vni = ovn_smap_get_llong(&tdp->dp->external_ids,
> > +                                         "dynamic-routing-vni", -1);
> > +        if (!ovn_is_valid_vni(vni)) {
> > +            continue;
> > +        }
> > +
> > +        if (tdp->tracked_type == TRACKED_RESOURCE_NEW ||
> > +            tdp->tracked_type == TRACKED_RESOURCE_REMOVED) {
> > +            return EN_UNHANDLED;
> > +        }
> > +    }
> > +
> > +    return EN_HANDLED_UNCHANGED;
> > +}
> > +
> > +static enum engine_input_handler_result
> > +neighbor_sb_datapath_binding_handler(struct engine_node *node,
> > +                                     void *data OVS_UNUSED)
> > +{
> > +    const struct sbrec_datapath_binding_table *dp_table =
> > +        EN_OVSDB_GET(engine_get_input("SB_datapath_binding", node));
> > +    struct ed_type_runtime_data *rt_data =
> > +        engine_get_input_data("runtime_data", node);
> > +
> > +    const struct sbrec_datapath_binding *dp;
> > +    SBREC_DATAPATH_BINDING_TABLE_FOR_EACH_TRACKED (dp, dp_table) {
> > +        if (sbrec_datapath_binding_is_new(dp) ||
> > +            sbrec_datapath_binding_is_deleted(dp)) {
> > +            /* The removal and addition is handled via runtime_data. */
> > +           return EN_HANDLED_UNCHANGED;
> > +        }
> > +
> > +        struct local_datapath *ld =
> > +            get_local_datapath(&rt_data->local_datapaths,
> dp->tunnel_key);
> > +        if (!ld || !ld->is_switch) {
> > +            continue;
> > +        }
> > +
> > +        if (sbrec_datapath_binding_is_updated(
> > +                dp, SBREC_DATAPATH_BINDING_COL_EXTERNAL_IDS)) {
> > +            return EN_UNHANDLED;
> > +        }
> > +    }
> > +
> > +    return EN_HANDLED_UNCHANGED;
> >  }
> >
> >  struct ed_type_neighbor_table_notify {
> > @@ -5794,30 +5857,47 @@ en_neighbor_table_notify_run(struct engine_node
> *node OVS_UNUSED,
> >      return state;
> >  }
> >
> > +struct ed_type_neighbor_exchange {
> > +    /* Contains 'struct evpn_remote_vtep'. */
> > +    struct hmap remote_vteps;
> > +};
> > +
> >  static void *
> >  en_neighbor_exchange_init(struct engine_node *node OVS_UNUSED,
> >                            struct engine_arg *arg OVS_UNUSED)
> >  {
> > -    return NULL;
> > +    struct ed_type_neighbor_exchange *data = xmalloc(sizeof *data);
> > +    *data = (struct ed_type_neighbor_exchange) {
> > +        .remote_vteps = HMAP_INITIALIZER(&data->remote_vteps),
> > +    };
> > +
> > +    return data;
> >  }
> >
> >  static void
> > -en_neighbor_exchange_cleanup(void *data OVS_UNUSED)
> > +en_neighbor_exchange_cleanup(void *data_)
> >  {
> > +    struct ed_type_neighbor_exchange *data = data_;
> > +    evpn_remote_vteps_clear(&data->remote_vteps);
> > +    hmap_destroy(&data->remote_vteps);
> >  }
> >
> >  static enum engine_node_state
> > -en_neighbor_exchange_run(struct engine_node *node, void *data
> OVS_UNUSED)
> > +en_neighbor_exchange_run(struct engine_node *node, void *data_)
> >  {
> > +    struct ed_type_neighbor_exchange *data = data_;
> >      const struct ed_type_neighbor *neighbor_data =
> >          engine_get_input_data("neighbor", node);
> >
> > +    evpn_remote_vteps_clear(&data->remote_vteps);
> > +
> >      struct neighbor_exchange_ctx_in n_ctx_in = {
> >          .monitored_interfaces = &neighbor_data->monitored_interfaces,
> >      };
> >      struct neighbor_exchange_ctx_out n_ctx_out = {
> >          .neighbor_table_watches =
> >              HMAP_INITIALIZER(&n_ctx_out.neighbor_table_watches),
> > +        .remote_vteps = &data->remote_vteps,
> >      };
> >
> >      neighbor_exchange_run(&n_ctx_in, &n_ctx_out);
> > @@ -6402,6 +6482,10 @@ main(int argc, char *argv[])
> >      engine_add_input(&en_garp_rarp, &en_runtime_data,
> >                       garp_rarp_runtime_data_handler);
> >
> > +    engine_add_input(&en_neighbor, &en_runtime_data,
> > +                     neighbor_runtime_data_handler);
> > +    engine_add_input(&en_neighbor, &en_sb_datapath_binding,
> > +                     neighbor_sb_datapath_binding_handler);
> >      engine_add_input(&en_neighbor_exchange, &en_neighbor, NULL);
> >      engine_add_input(&en_neighbor_exchange, &en_host_if_monitor, NULL);
> >      engine_add_input(&en_neighbor_exchange, &en_neighbor_table_notify,
> NULL);
> > @@ -6487,6 +6571,8 @@ main(int argc, char *argv[])
> >          engine_get_internal_data(&en_lb_data);
> >      struct mac_cache_data *mac_cache_data =
> >              engine_get_internal_data(&en_mac_cache);
> > +    struct ed_type_neighbor_exchange *ne_data =
> > +        engine_get_internal_data(&en_neighbor_exchange);
> >
> >      ofctrl_init(&lflow_output_data->group_table,
> >                  &lflow_output_data->meter_table);
> > @@ -6503,6 +6589,10 @@ main(int argc, char *argv[])
> >                               ct_zone_list,
> >                               &ct_zones_data->ctx.current);
> >
> > +    unixctl_command_register("evpn/remote-vtep-list", "", 0, 0,
> > +                             evpn_remote_vtep_list,
> > +                             &ne_data->remote_vteps);
> > +
> >      struct pending_pkt pending_pkt = { .conn = NULL };
> >      unixctl_command_register("inject-pkt", "MICROFLOW", 1, 1,
> inject_pkt,
> >                               &pending_pkt);
> > diff --git a/lib/ovn-util.c b/lib/ovn-util.c
> > index d7e236059..c12de4da9 100644
> > --- a/lib/ovn-util.c
> > +++ b/lib/ovn-util.c
> > @@ -1484,3 +1484,9 @@ ovn_mirror_port_name(const char *datapath_name,
> >  {
> >      return xasprintf("mp-%s-%s", datapath_name, port_name);
> >  }
> > +
> > +bool
> > +ovn_is_valid_vni(int64_t vni)
> > +{
> > +    return vni >= 0 && (vni <= (1 << 24) - 1);
> > +}
> > diff --git a/lib/ovn-util.h b/lib/ovn-util.h
> > index c05bfc53b..f31eba344 100644
> > --- a/lib/ovn-util.h
> > +++ b/lib/ovn-util.h
> > @@ -500,6 +500,8 @@ bool find_prefix_in_set(const struct in6_addr
> *prefix, unsigned int plen,
> >
> >  void ovn_debug_commands_register(void);
> >
> > +bool ovn_is_valid_vni(int64_t vni);
> > +
> >  const struct sbrec_port_binding *lport_lookup_by_name(
> >      struct ovsdb_idl_index *sbrec_port_binding_by_name,
> >      const char *name);
>
> Regards,
> Dumitru
>
>
Everything else should be addressed in v2.

Thanks,
Ales
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to