On Mon, Aug 15, 2022 at 1:23 AM Dumitru Ceara <dce...@redhat.com> wrote:
>
> On 8/15/22 08:46, Numan Siddique wrote:
> > "
> >
> > On Mon, Aug 15, 2022 at 3:34 PM Han Zhou <zhou...@gmail.com> wrote:
> >>
> >> On Sun, Aug 14, 2022 at 8:30 PM Numan Siddique <num...@ovn.org> wrote:
> >>>
> >>> On Fri, Aug 12, 2022 at 12:21 AM Ales Musil <amu...@redhat.com> wrote:
> >>>>
> >>>> On Thu, Aug 11, 2022 at 2:45 PM Dumitru Ceara <dce...@redhat.com>
wrote:
> >>>>
> >>>>> On 8/10/22 18:37, Han Zhou wrote:
> >>>>>> On Tue, Aug 9, 2022 at 11:22 PM Ales Musil <amu...@redhat.com>
> >> wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> On Wed, Aug 10, 2022 at 8:04 AM Han Zhou <hz...@ovn.org> wrote:
> >>>>>>>
> >>>>>>> Hi Han,
> >>>>>>>
> >>>>>>> thank you for the review, see my reply inline below.
> >>>>>>>
> >>>>>>>> On Tue, Aug 9, 2022 at 4:05 AM Ales Musil <amu...@redhat.com>
> >> wrote:
> >>>>>>>>>
> >>>>>>>>> Add MAC binding aging mechanism, that utilizes
> >>>>>>>>> the timestamp column of MAC_Binding table.
> >>>>>>>>> When the MAC binding exceeds the threshold it is
> >>>>>>>>> removed from SB DB, this is postponed only in case
> >>>>>>>>> we receive update ARP with update to MAC address.
> >>>>>>>>>
> >>>>>>>>> The threshold is configurable via option
> >>>>>>>>> "mac_binding_age_threshold" that can be specified
> >>>>>>>>> for each logical router. The option is defaulting to
> >>>>>>>>> 0 which means that by default the aging is disabled
> >>>>>>>>> and the MAC binding rows will be persisted the same
> >>>>>>>>> way as before.
> >>>>>>>>>
> >>>>>>>>> Reported-at: https://bugzilla.redhat.com/2084668
> >>>>>>>>> Signed-off-by: Ales Musil <amu...@redhat.com>
> >>>>>>>>> ---
> >>>>>>>>> v3: Rebase on top of current main.
> >>>>>>>>>     Update according to the final conclusion.
> >>>>>>>>> v4: Rebase on top of current main.
> >>>>>>>>>     Skip one row instead of all if time elapsed is negative.
> >>>>>>>>>     Add note to NEWS.
> >>>>>>>>> ---
> >>>>>>>>>  NEWS                       |   3 +
> >>>>>>>>>  northd/automake.mk         |   2 +
> >>>>>>>>>  northd/inc-proc-northd.c   |  13 ++++
> >>>>>>>>>  northd/mac-binding-aging.c | 151
> >>>>> +++++++++++++++++++++++++++++++++++++
> >>>>>>>>>  northd/mac-binding-aging.h |  33 ++++++++
> >>>>>>>>>  ovn-nb.xml                 |   7 ++
> >>>>>>>>>  6 files changed, 209 insertions(+)
> >>>>>>>>>  create mode 100644 northd/mac-binding-aging.c
> >>>>>>>>>  create mode 100644 northd/mac-binding-aging.h
> >>>>>>>>>
> >>>>>>>>> diff --git a/NEWS b/NEWS
> >>>>>>>>> index 20cea579e..eff8e472a 100644
> >>>>>>>>> --- a/NEWS
> >>>>>>>>> +++ b/NEWS
> >>>>>>>>> @@ -14,6 +14,9 @@ Post v22.06.0
> >>>>>>>>>      NAT-T UDP encapsulation. Requires OVS support for IPsec
> >> custom
> >>>>>> tunnel
> >>>>>>>>>      options (which will be available in OVS 2.18).
> >>>>>>>>>    - Removed possibility of disabling logical datapath groups.
> >>>>>>>>> +  - Added MAC binding aging mechanism, that is disabled by
> >> default.
> >>>>>>>>> +    It can be enabled per logical router with option
> >>>>>>>>> +    "mac_binding_age_threshold".
> >>>>>>>>>
> >>>>>>>>>  OVN v22.06.0 - 03 Jun 2022
> >>>>>>>>>  --------------------------
> >>>>>>>>> diff --git a/northd/automake.mk b/northd/automake.mk
> >>>>>>>>> index 4862ec7b7..81582867d 100644
> >>>>>>>>> --- a/northd/automake.mk
> >>>>>>>>> +++ b/northd/automake.mk
> >>>>>>>>> @@ -1,6 +1,8 @@
> >>>>>>>>>  # ovn-northd
> >>>>>>>>>  bin_PROGRAMS += northd/ovn-northd
> >>>>>>>>>  northd_ovn_northd_SOURCES = \
> >>>>>>>>> +       northd/mac-binding-aging.c \
> >>>>>>>>> +       northd/mac-binding-aging.h \
> >>>>>>>>>         northd/northd.c \
> >>>>>>>>>         northd/northd.h \
> >>>>>>>>>         northd/ovn-northd.c \
> >>>>>>>>> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
> >>>>>>>>> index 43093cb5a..4a3699106 100644
> >>>>>>>>> --- a/northd/inc-proc-northd.c
> >>>>>>>>> +++ b/northd/inc-proc-northd.c
> >>>>>>>>> @@ -22,9 +22,11 @@
> >>>>>>>>>  #include "ip-mcast-index.h"
> >>>>>>>>>  #include "static-mac-binding-index.h"
> >>>>>>>>>  #include "lib/inc-proc-eng.h"
> >>>>>>>>> +#include "lib/mac-binding-index.h"
> >>>>>>>>>  #include "lib/ovn-nb-idl.h"
> >>>>>>>>>  #include "lib/ovn-sb-idl.h"
> >>>>>>>>>  #include "mcast-group-index.h"
> >>>>>>>>> +#include "northd/mac-binding-aging.h"
> >>>>>>>>>  #include "openvswitch/poll-loop.h"
> >>>>>>>>>  #include "openvswitch/vlog.h"
> >>>>>>>>>  #include "inc-proc-northd.h"
> >>>>>>>>> @@ -149,6 +151,8 @@ enum sb_engine_node {
> >>>>>>>>>   * avoid sparse errors. */
> >>>>>>>>>  static ENGINE_NODE(northd, "northd");
> >>>>>>>>>  static ENGINE_NODE(lflow, "lflow");
> >>>>>>>>> +static ENGINE_NODE(mac_binding_aging, "mac_binding_aging");
> >>>>>>>>> +static ENGINE_NODE(mac_binding_aging_waker,
> >>>>>> "mac_binding_aging_waker");
> >>>>>>>>>
> >>>>>>>>>  void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
> >>>>>>>>>                            struct ovsdb_idl_loop *sb)
> >>>>>>>>> @@ -211,12 +215,16 @@ void inc_proc_northd_init(struct
> >> ovsdb_idl_loop
> >>>>>> *nb,
> >>>>>>>>>      engine_add_input(&en_northd, &en_sb_load_balancer, NULL);
> >>>>>>>>>      engine_add_input(&en_northd, &en_sb_fdb, NULL);
> >>>>>>>>>      engine_add_input(&en_northd, &en_sb_static_mac_binding,
> >> NULL);
> >>>>>>>>> +    engine_add_input(&en_mac_binding_aging, &en_sb_mac_binding,
> >>>>> NULL);
> >>>>>>>>> +    engine_add_input(&en_mac_binding_aging, &en_northd, NULL);
> >>>>>>>>> +    engine_add_input(&en_mac_binding_aging,
> >>>>>> &en_mac_binding_aging_waker, NULL);
> >>>>>>>>>      engine_add_input(&en_lflow, &en_nb_bfd, NULL);
> >>>>>>>>>      engine_add_input(&en_lflow, &en_sb_bfd, NULL);
> >>>>>>>>>      engine_add_input(&en_lflow, &en_sb_logical_flow, NULL);
> >>>>>>>>>      engine_add_input(&en_lflow, &en_sb_multicast_group, NULL);
> >>>>>>>>>      engine_add_input(&en_lflow, &en_sb_igmp_group, NULL);
> >>>>>>>>>      engine_add_input(&en_lflow, &en_northd, NULL);
> >>>>>>>>> +    engine_add_input(&en_lflow, &en_mac_binding_aging, NULL);
> >>>>>>>>>
> >>>>>>>>>      struct engine_arg engine_arg = {
> >>>>>>>>>          .nb_idl = nb->idl,
> >>>>>>>>> @@ -235,6 +243,8 @@ void inc_proc_northd_init(struct
> >> ovsdb_idl_loop
> >>>>>> *nb,
> >>>>>>>>>          chassis_hostname_index_create(sb->idl);
> >>>>>>>>>      struct ovsdb_idl_index
*sbrec_static_mac_binding_by_lport_ip
> >>>>>>>>>          = static_mac_binding_index_create(sb->idl);
> >>>>>>>>> +    struct ovsdb_idl_index *sbrec_mac_binding_by_datapath
> >>>>>>>>> +        = mac_binding_by_datapath_index_create(sb->idl);
> >>>>>>>>>
> >>>>>>>>>      engine_init(&en_lflow, &engine_arg);
> >>>>>>>>>
> >>>>>>>>> @@ -256,6 +266,9 @@ void inc_proc_northd_init(struct
> >> ovsdb_idl_loop
> >>>>>> *nb,
> >>>>>>>>>      engine_ovsdb_node_add_index(&en_sb_static_mac_binding,
> >>>>>>>>>
> >>>>>>  "sbrec_static_mac_binding_by_lport_ip",
> >>>>>>>>>
> >>>>> sbrec_static_mac_binding_by_lport_ip);
> >>>>>>>>> +    engine_ovsdb_node_add_index(&en_sb_mac_binding,
> >>>>>>>>> +
 "sbrec_mac_binding_by_datapath",
> >>>>>>>>> +                                sbrec_mac_binding_by_datapath);
> >>>>>>>>>  }
> >>>>>>>>>
> >>>>>>>>>  void inc_proc_northd_run(struct ovsdb_idl_txn *ovnnb_txn,
> >>>>>>>>> diff --git a/northd/mac-binding-aging.c
> >> b/northd/mac-binding-aging.c
> >>>>>>>>> new file mode 100644
> >>>>>>>>> index 000000000..e8217e8bc
> >>>>>>>>> --- /dev/null
> >>>>>>>>> +++ b/northd/mac-binding-aging.c
> >>>>>>>>> @@ -0,0 +1,151 @@
> >>>>>>>>> +/* Copyright (c) 2022, Red Hat, 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 "lib/inc-proc-eng.h"
> >>>>>>>>> +#include "lib/ovn-nb-idl.h"
> >>>>>>>>> +#include "lib/ovn-sb-idl.h"
> >>>>>>>>> +#include "lib/timeval.h"
> >>>>>>>>> +#include "northd/mac-binding-aging.h"
> >>>>>>>>> +#include "northd/northd.h"
> >>>>>>>>> +#include "openvswitch/hmap.h"
> >>>>>>>>> +#include "openvswitch/poll-loop.h"
> >>>>>>>>> +#include "openvswitch/util.h"
> >>>>>>>>> +#include "openvswitch/vlog.h"
> >>>>>>>>> +
> >>>>>>>>> +VLOG_DEFINE_THIS_MODULE(mac_binding_aging);
> >>>>>>>>> +
> >>>>>>>>> +struct mac_binding_waker {
> >>>>>>>>> +    bool should_schedule;
> >>>>>>>>> +    long long next_wake_msec;
> >>>>>>>>> +};
> >>>>>>>>> +
> >>>>>>>>> +static struct mac_binding_waker waker;
> >>>>>>>>> +
> >>>>>>>>> +static void
> >>>>>>>>> +mac_binding_aging_run_for_datapath(const struct
> >>>>>> sbrec_datapath_binding *dp,
> >>>>>>>>> +                                   const struct
> >> nbrec_logical_router
> >>>>>> *nbr,
> >>>>>>>>> +                                   struct ovsdb_idl_index
> >>>>>> *mb_by_datapath,
> >>>>>>>>> +                                   int64_t now, int64_t
> >> *wake_delay)
> >>>>>>>>> +{
> >>>>>>>>> +    uint64_t threshold = smap_get_uint(&nbr->options,
> >>>>>>>>> +
> >> "mac_binding_age_threshold",
> >>>>>>>>> +                                         0) * 1000;
> >>>>>
> >>>>> Nit: indentation.
> >>>>>
> >>>>>>>>> +    if (!threshold) {
> >>>>>>>>> +        return;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    struct sbrec_mac_binding *mb_index_row =
> >>>>>>>>> +        sbrec_mac_binding_index_init_row(mb_by_datapath);
> >>>>>>>>> +    sbrec_mac_binding_index_set_datapath(mb_index_row, dp);
> >>>>>>>>> +
> >>>>>>>>> +    const struct sbrec_mac_binding *mb;
> >>>>>>>>> +    SBREC_MAC_BINDING_FOR_EACH_EQUAL (mb, mb_index_row,
> >>>>>> mb_by_datapath) {
> >>>>>>>>> +        int64_t elapsed = now - mb->timestamp;
> >>>>>>>>> +
> >>>>>>>>> +        if (elapsed < 0) {
> >>>>>>>>> +            continue;
> >>>>>>>>> +        } else if (elapsed >= threshold) {
> >>>>>>>>> +            sbrec_mac_binding_delete(mb);
> >>>>>>>>> +        } else {
> >>>>>>>>> +            *wake_delay = MIN(*wake_delay, threshold -
elapsed);
> >>>>>>>>> +        }
> >>>>>>>>> +    }
> >>>>>>>>> +    sbrec_mac_binding_index_destroy_row(mb_index_row);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +void
> >>>>>>>>> +en_mac_binding_aging_run(struct engine_node *node, void *data
> >>>>>> OVS_UNUSED)
> >>>>>>>>> +{
> >>>>>>>>> +    const struct engine_context *eng_ctx =
engine_get_context();
> >>>>>>>>> +
> >>>>>>>>> +    if (!eng_ctx->ovnsb_idl_txn) {
> >>>>>>>>> +        return;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    int64_t next_expire_msec = INT64_MAX;
> >>>>>>>>> +    int64_t now = time_wall_msec();
> >>>>>>>>> +    struct northd_data *northd_data =
> >> engine_get_input_data("northd",
> >>>>>> node);
> >>>>>>>>> +    struct ovsdb_idl_index *sbrec_mac_binding_by_datapath =
> >>>>>>>>> +
> >>>>>>  engine_ovsdb_node_get_index(engine_get_input("SB_mac_binding",
> >> node),
> >>>>>>>>> +
> >>  "sbrec_mac_binding_by_datapath");
> >>>>>>>>> +
> >>>>>>>>> +    struct ovn_datapath *od;
> >>>>>>>>> +    HMAP_FOR_EACH (od, key_node, &northd_data->datapaths) {
> >>>>>>>>> +        if (od->sb && od->nbr) {
> >>>>>>>>> +            mac_binding_aging_run_for_datapath(od->sb, od->nbr,
> >>>>>>>>> +
> >>>>>> sbrec_mac_binding_by_datapath,
> >>>>>>>>> +                                               now,
> >>>>>> &next_expire_msec);
> >>>>>>>>> +        }
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    if (next_expire_msec < INT64_MAX) {
> >>>>>>>>> +        waker.should_schedule = true;
> >>>>>>>>> +        waker.next_wake_msec = time_msec() + next_expire_msec;
> >>>>>>>>> +        /* Run the engine right after so the waker can reflect
> >> on the
> >>>>>> new wake
> >>>>>>>>> +         * time. */
> >>>>>>>>> +        poll_immediate_wake();
> >>>>>>>>
> >>>>>>>> Why would we immediately wake up? Wouldn't it cause busy-loop?
> >> Shall
> >>>>> we
> >>>>>> use poll_timer_wait_until? Sorry if I missed anything here and
> >> please
> >>>>>> correct me.
> >>>>>>>
> >>>>>>>
> >>>>>>> That's because of the dependency of the nodes, we need to run the
> >> waker
> >>>>>> that will schedule the sleep.
> >>>>>>> We could probably use poll_timer_wait_until as well and it should
> >> have
> >>>>>> the same effect.
> >>>>>>>
> >>>>>> Thanks, I think I did misunderstand a little and now I got the idea
> >> of
> >>>>> the
> >>>>>> waker node. It is an input node just to trigger the timer, which
> >> wakes up
> >>>>>> the aging processing when needed and at the same time avoids
> >> running the
> >>>>>> aging scanning when the process is woken up for other reasons. So
> >> the
> >>>>>> poll_immediate_wake() here won't cause busy-loop. However, it does
> >> wake
> >>>>> up
> >>>>>> the process at least one extra time for each run, although the cost
> >> may
> >>>>> be
> >>>>>> small. I'd still use poll_timer_wait_until() here since we already
> >> know
> >>>>> the
> >>>>>> next_wake_msec.
> >>>>>>
> >>>>>> In addition, it is a little weird from I-P engine's point of view
> >> that
> >>>>> the
> >>>>>> output node execution updates the input node's data, but for this
> >> timer
> >>>>> use
> >>>>>> case I think it should work and I haven't come up with anything
> >> better.
> >>>>> It
> >>>>>> would be helpful to leave some comments for the waker node to
> >> explain the
> >>>>>> motivation and make this part easier to understand.
> >>>>>>
> >>>>>
> >>>>> +1 for both points (comment + poll_timer_wait_until()).
> >>>>>
> >>>>> Also, can we at least use engine_get_input_data() to get the input
> >>>>> node's data?  This will make it more clear that we're using data
> >> that's
> >>>>> related to the waker node.  The 'waker' variable would have to be
> >> moved
> >>>>> inside the en_mac_binding_aging_waker data.
> >>>>>
> >>>>>> Thanks,
> >>>>>> Han
> >>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> +    } else {
> >>>>>>>>> +        waker.should_schedule = false;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    /* This node is part of lflow, but lflow does not depend on
> >> it.
> >>>>>> Setting
> >>>>>>>>> +     * state as unchanged does not trigger lflow node when it
> >> is not
> >>>>>> needed. */
> >>>>>>>>
> >>>>>>>> This should work, but it is like a hack. Ideally we should allow
> >> the
> >>>>> I-P
> >>>>>> engine to have multiple "root" nodes. This can be a future
> >> improvement
> >>>>>> though. Maybe add a "XXX" comment here (a TODO item).
> >>>>>>>
> >>>>>>>
> >>>>>>> Yes unfortunately this is not the cleanest solution, but I did not
> >> come
> >>>>>> with a better one. I will add a TODO comment here about moving it
> >> once we
> >>>>>> allow multiple root nodes.
> >>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> Thanks,
> >>>>>>>> Han
> >>>>>>>>
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>> Ales
> >>>>>>>
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>> +    engine_set_node_state(node, EN_UNCHANGED);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +void *
> >>>>>>>>> +en_mac_binding_aging_init(struct engine_node *node OVS_UNUSED,
> >>>>>>>>> +                          struct engine_arg *arg OVS_UNUSED)
> >>>>>>>>> +{
> >>>>>>>>> +    return NULL;
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +void
> >>>>>>>>> +en_mac_binding_aging_cleanup(void *data OVS_UNUSED)
> >>>>>>>>> +{
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +void
> >>>>>>>>> +en_mac_binding_aging_waker_run(struct engine_node *node, void
> >> *data
> >>>>>> OVS_UNUSED)
> >>>>>>>>> +{
> >>>>>>>>> +    if (!waker.should_schedule) {
> >>>>>>>>> +        return;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    if (time_msec() >= waker.next_wake_msec) {
> >>>>>>>>> +        waker.should_schedule = false;
> >>>>>>>>> +        engine_set_node_state(node, EN_UPDATED);
> >>>>>>>>> +        return;
> >>>>>>>>> +    }
> >>>>>>>>> +
> >>>>>>>>> +    engine_set_node_state(node, EN_UNCHANGED);
> >>>>>>>>> +    poll_timer_wait_until(waker.next_wake_msec);
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +void *
> >>>>>>>>> +en_mac_binding_aging_waker_init(struct engine_node *node
> >> OVS_UNUSED,
> >>>>>>>>> +                                struct engine_arg *arg
> >> OVS_UNUSED)
> >>>>>>>>> +{
> >>>>>>>>> +    waker.should_schedule = false;
> >>>>>>>>> +    waker.next_wake_msec = 0;
> >>>>>>>>> +    return NULL;
> >>>>>>>>> +}
> >>>>>>>>> +
> >>>>>>>>> +void
> >>>>>>>>> +en_mac_binding_aging_waker_cleanup(void *data OVS_UNUSED)
> >>>>>>>>> +{
> >>>>>>>>> +}
> >>>>>>>>> diff --git a/northd/mac-binding-aging.h
> >> b/northd/mac-binding-aging.h
> >>>>>>>>> new file mode 100644
> >>>>>>>>> index 000000000..296a7ab38
> >>>>>>>>> --- /dev/null
> >>>>>>>>> +++ b/northd/mac-binding-aging.h
> >>>>>>>>> @@ -0,0 +1,33 @@
> >>>>>>>>> +/* Copyright (c) 2022, Red Hat, 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 MAC_BINDING_AGING_H
> >>>>>>>>> +#define MAC_BINDING_AGING_H 1
> >>>>>>>>> +
> >>>>>>>>> +#include "lib/inc-proc-eng.h"
> >>>>>>>>> +
> >>>>>>>>> +/* The MAC binding aging node functions. */
> >>>>>>>>> +void en_mac_binding_aging_run(struct engine_node *node, void
> >> *data);
> >>>>>>>>> +void *en_mac_binding_aging_init(struct engine_node *node,
> >>>>>>>>> +                                struct engine_arg *arg);
> >>>>>>>>> +void en_mac_binding_aging_cleanup(void *data);
> >>>>>>>>> +
> >>>>>>>>> +/* The MAC binding aging waker node functions. */
> >>>>>>>>> +void en_mac_binding_aging_waker_run(struct engine_node *node,
> >> void
> >>>>>> *data);
> >>>>>>>>> +void *en_mac_binding_aging_waker_init(struct engine_node *node,
> >>>>>>>>> +                                      struct engine_arg *arg);
> >>>>>>>>> +void en_mac_binding_aging_waker_cleanup(void *data);
> >>>>>>>>> +
> >>>>>>>>> +#endif /* northd/mac-binding-aging.h */
> >>>>>>>>> diff --git a/ovn-nb.xml b/ovn-nb.xml
> >>>>>>>>> index e26afd83c..d3fba9bdc 100644
> >>>>>>>>> --- a/ovn-nb.xml
> >>>>>>>>> +++ b/ovn-nb.xml
> >>>>>>>>> @@ -2392,6 +2392,13 @@
> >>>>>>>>>          and other sources. This way, OVN and the other sources
> >> can
> >>>>>> make use of
> >>>>>>>>>          the same conntrack zone.
> >>>>>>>>>        </column>
> >>>>>>>>> +
> >>>>>>>>> +      <column name="options" key="mac_binding_age_threshold"
> >>>>>>>>> +              type='{"type": "integer", "minInteger": 0,
> >>>>>> "maxInteger": 4294967295}'>
> >>>>>>>>> +        MAC binding aging <code>threshold</code> value in secs.
> >> MAC
> >>>>>> binding
> >>>>>
> >>>>> Nit: I'd use 'seconds'.
> >>>>>
> >>>>> Thanks,
> >>>>> Dumitru
> >>>>>
> >>>>>>>>> +        exceeding this timeout will be automatically removed.
> >> The
> >>>>>> value
> >>>>>>>>> +        defaults to 0, which means disabled.
> >>>>>>>>> +      </column>
> >>>>>>>>>      </group>
> >>>>>>>>>
> >>>>>>>>>      <group title="Common Columns">
> >>>>>>>>> --
> >>>>>>>>> 2.37.1
> >>>>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>> --
> >>>>>>>
> >>>>>>> Ales Musil
> >>>>>>>
> >>>>>>> Senior Software Engineer - OVN Core
> >>>>>>>
> >>>>>>> Red Hat EMEA
> >>>>>>>
> >>>>>>> amu...@redhat.com    IM: amusil
> >>>>>>
> >>>>>
> >>>>>
> >>>> Thank you for the reviews.
> >>>>
> >>>> v5 should address most of the comments except the open one from Numan
> >> about
> >>>> upgrade.
> >>>>
> >>>
> >>> IMO upgrading one is very important.  As I mentioned earlier,
> >>> openstack neutron or ovn-kubernetes would not know
> >>> which OVN version is being run and if all the ovn-controllers are
> >>> upgraded to the version which has the mac_binding timestamp
> >>> support.  This config option is not something which an administrator
> >>> can enable or disable depending on the upgrade status.
> >>>
> >>> There have been a few  upgrade issues with OVN and because of which
> >>> openstack CMS had to do special handling.
> >>> This patch series can potentially affect the existing datapath traffic
> >>> after partial upgrades.  So I think its better we handle this
> >>> properly.
> >>>
> >>
> >> Hi Numan, I agree with you that upgrading is important. But for this
case,
> >> maybe I didn't understand the problem. The feature is disabled by
default,
> >> so as long as the CMS doesn't enable the aging setting for any LR
before
> >> the upgrade is completed, it should be fine, right?  This in practice
just
> >> means two separate changes to the production environment:
> >> 1. upgrade the OVN version, both central and controller components
> >> 2. change the aging setting to desired value for some (or all) LRs
> >
> > In my opinion, the step (2) you mentioned above is something which an
> > operator/admin cannot set
> > and it is most likely be set by openstack neutron or ovn-kubernetes or
> > any other CMS programmatically.
> > In the case of Openstack,  neutron is part of a bigger
> > system/deployment and it wont be so easy to do
> > Step 1 first and then step 2.  Tripleo installer for example will
> > upgrade OVN Northd services and Neutron
> > first before upgrading ovn-controllers on the compute nodes.
> >
>
> As far as I understand, OpenStack has recently added support to ensure
> that all ovn-controllers are upgraded before the central components are
> upgraded.  Adding Jakub to this thread.
>
> > This feature will most likely be available in OVN 22.09.  Lets say
> > openstack neutron
> > wants to use this feature and adds the necessary code to enable ageing
> > in some neutron
> > routers.  I don't know on what basis or what logic it would use to set
> > the option
> > "mac_binding_age_threshold" for a logical router.   Let's assume that
> > neutron  queries the
> > OVN Southbound schema to check for the presence of the column
> > "timestamp" in MAC_Binding table
> > before setting the logical router option - mac_binding_age_threshold.
> > And lets say neutron uses this feature
> > in the openstack release Zed (scheduled to release in October).  My
> > concern is how would neutron know
> > if all ovn-controllers are upgraded with this feature or not ? As I
> > mentioned above, It's possible for the openstack
> > installer/upgrade tool to upgrade OVN northd services first.  Until a
> > compute node 'N' is not upgraded with the
> > proper ovn-controller version, ovn-northd will immediately delete the
> > mac binding entries learnt by
> > ovn-controller in node 'N'.
> >
> > Let me know your thoughts.
> >
>
> I think that if neutron/tripleo/OpenStack indeed take care of performing
> upgrades in the OVN supported way (all ovn-controllers before
> SB/ovn-northd) then we should be OK with the current patch.
>

Thanks Numan and Dumitru, and now I understand the problem. Suppose Neutron
has a way to make sure ovn-controller are upgraded before ovn-central,
probably ovn-k8s still faces the problem?
For a simpler solution, I'd support the idea that don't delete the entry if
the timestamp is 0. Anything populated before the upgrade can be deleted as
a one-time cleanup manually at any time by the operator if desired.
The solution of checking features of all controllers is good, too, but just
a little complexity and an extra external-ids in the chassis table just for
the one-time use case.
A 3rd option depends on how CMS would integrate this feature. If the CMS
can implement a global option that enables/disables the feature, that would
work for the 2 steps I mentioned earlier: step1: upgrade OVN, step2: turn
on the CMS option.

> Regards,
> Dumitru
>
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to