Hi Ales, Dumitru Thanks for the patch One comment below
Thanks Xavier On Wed, Aug 6, 2025 at 8:27 PM Ales Musil via dev <ovs-dev@openvswitch.org> wrote: > From: Dumitru Ceara <dce...@redhat.com> > > When monitoring and updating (Linux) neighbor tables through Netlink, > the interfaces in question are identified by if-index. It's more > CMS-friendly to allow OVN to be configured to track interfaces by name. > > In order to achieve that, we introduce a new host-if-monitor module > which tracks the if-index <-> if-name mapping for relevant interfaces. > > NOTE: OVS has the lib/if-notifier.[ch] module already. However, that is > not really useful for the OVN use case because it doesn't really pass > the struct rtnetlink_change message to its registered callbacks. > > Signed-off-by: Dumitru Ceara <dce...@redhat.com> > --- > controller/automake.mk | 5 +- > controller/host-if-monitor-stub.c | 43 +++++++++ > controller/host-if-monitor.c | 150 ++++++++++++++++++++++++++++++ > controller/host-if-monitor.h | 30 ++++++ > 4 files changed, 227 insertions(+), 1 deletion(-) > create mode 100644 controller/host-if-monitor-stub.c > create mode 100644 controller/host-if-monitor.c > create mode 100644 controller/host-if-monitor.h > > diff --git a/controller/automake.mk b/controller/automake.mk > index 6af6ee2a9..6eca5e8ed 100644 > --- a/controller/automake.mk > +++ b/controller/automake.mk > @@ -64,10 +64,12 @@ controller_ovn_controller_SOURCES = \ > controller/route.c \ > controller/garp_rarp.h \ > controller/garp_rarp.c \ > - controller/neighbor-table-notify.h > + controller/neighbor-table-notify.h \ > + controller/host-if-monitor.h > > if HAVE_NETLINK > controller_ovn_controller_SOURCES += \ > + controller/host-if-monitor.c \ > controller/neighbor-exchange-netlink.h \ > controller/neighbor-exchange-netlink.c \ > controller/neighbor-table-notify.c \ > @@ -77,6 +79,7 @@ controller_ovn_controller_SOURCES += \ > controller/route-table-notify.c > else > controller_ovn_controller_SOURCES += \ > + controller/host-if-monitor-stub.c \ > controller/neighbor-table-notify-stub.c \ > controller/route-exchange-stub.c \ > controller/route-table-notify-stub.c > diff --git a/controller/host-if-monitor-stub.c > b/controller/host-if-monitor-stub.c > new file mode 100644 > index 000000000..b174cf996 > --- /dev/null > +++ b/controller/host-if-monitor-stub.c > @@ -0,0 +1,43 @@ > +/* Copyright (c) 2025, 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 <stdbool.h> > + > +#include "openvswitch/compiler.h" > +#include "host-if-monitor.h" > + > +void > +host_if_monitor_wait(void) > +{ > +} > + > +bool > +host_if_monitor_run(void) > +{ > + return false; > +} > + > +void > +host_if_monitor_update_watches(const struct sset *if_names OVS_UNUSED) > +{ > +} > + > +int32_t > +host_if_monitor_ifname_toindex(const char *if_name OVS_UNUSED) > +{ > + return 0; > +} > diff --git a/controller/host-if-monitor.c b/controller/host-if-monitor.c > new file mode 100644 > index 000000000..26edb03d0 > --- /dev/null > +++ b/controller/host-if-monitor.c > @@ -0,0 +1,150 @@ > +/* Copyright (c) 2025, 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 <linux/rtnetlink.h> > +#include <net/if.h> > + > +#include "lib/rtnetlink.h" > +#include "lib/simap.h" > +#include "openvswitch/vlog.h" > + > +#include "host-if-monitor.h" > + > +VLOG_DEFINE_THIS_MODULE(host_if_monitor); > + > +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); > + > +struct host_if_monitor { > + struct nln_notifier *link_notifier; > + > + struct sset watched_interfaces; > + struct simap ifname_to_ifindex; > + > + bool changes_detected; > +}; > + > +static struct host_if_monitor monitor = (struct host_if_monitor) { > + .link_notifier = NULL, > + .watched_interfaces = SSET_INITIALIZER(&monitor.watched_interfaces), > + .ifname_to_ifindex = SIMAP_INITIALIZER(&monitor.ifname_to_ifindex), > + .changes_detected = false, > +}; > + > +static void if_notifier_cb(const struct rtnetlink_change *, void *aux); > + > +void > +host_if_monitor_wait(void) > +{ > + rtnetlink_wait(); > +} > + > +bool > +host_if_monitor_run(void) > +{ > + monitor.changes_detected = false; > + > + /* If any relevant interface if-index <-> if-name mapping changes are > + * dected, monitor.changes_detected will be updated accordingly by the > + * if_notifier_cb(). */ > + rtnetlink_run(); > + > + return monitor.changes_detected; > +} > + > +void > +host_if_monitor_update_watches(const struct sset *if_names) > +{ > + struct sset new_if_names = SSET_INITIALIZER(&new_if_names); > + const char *if_name; > + > + /* The notifier only triggers the callback on interface updates. > + * For newly added ones we need to fetch the initial if_index > ourselves. > + */ > + SSET_FOR_EACH (if_name, if_names) { > + if (!sset_contains(&monitor.watched_interfaces, if_name)) { > + sset_add(&new_if_names, if_name); > + } > + } > + > + if (!sset_equals(&monitor.watched_interfaces, if_names)) { > + sset_destroy(&monitor.watched_interfaces); > + sset_clone(&monitor.watched_interfaces, if_names); > + } > If/when interfaces are removed from monitor.watched_interfaces (e.g. datapath becoming not local), then monitor.ifname_to_ifindex will not be cleaned when interfaces are deleted. > + > + if (!sset_is_empty(&monitor.watched_interfaces)) { > + if (!monitor.link_notifier) { > + VLOG_INFO_RL(&rl, "Enabling host interface monitor"); > + monitor.link_notifier = > + rtnetlink_notifier_create(if_notifier_cb, &monitor); > + } > + /* Get initial state for new interfaces. > + * > + * NOTE: it's important that we have the initial state (if-index) > for > + * newly watched interfaces because of two reasons: > + * - we need to be able to reconcile and preserve still valid > learned > + * remote FDB entries and remote VTEPs > + * - the if_notifier_cb is called only on updates of interfaces > + * therefore if existing interfaces don't change the notifier > + * callback is not called. > + */ > + SSET_FOR_EACH (if_name, &new_if_names) { > + simap_put(&monitor.ifname_to_ifindex, if_name, > + if_nametoindex(if_name)); > + } > + } else { > + if (monitor.link_notifier) { > + VLOG_INFO_RL(&rl, "Disabling host interface monitor"); > + rtnetlink_notifier_destroy(monitor.link_notifier); > + monitor.link_notifier = NULL; > + } > + } > + > + sset_destroy(&new_if_names); > +} > + > +int32_t > +host_if_monitor_ifname_toindex(const char *if_name) > +{ > + return simap_get(&monitor.ifname_to_ifindex, if_name); > +} > + > +static void > +if_notifier_cb(const struct rtnetlink_change *change, void *aux > OVS_UNUSED) > +{ > + if (!change || change->irrelevant) { > + return; > + } > + > + switch (change->nlmsg_type) { > + case RTM_NEWLINK: > + if ((change->ifi_flags & IFF_UP) > + && sset_find(&monitor.watched_interfaces, change->ifname)) { > + simap_put(&monitor.ifname_to_ifindex, > + change->ifname, change->if_index); > + monitor.changes_detected = true; > + } > + break; > + case RTM_DELLINK: > + if (sset_find(&monitor.watched_interfaces, change->ifname)) { > + simap_find_and_delete(&monitor.ifname_to_ifindex, > change->ifname); > + monitor.changes_detected = true; > + } > + break; > + default: > + break; > + } > +} > diff --git a/controller/host-if-monitor.h b/controller/host-if-monitor.h > new file mode 100644 > index 000000000..a41c5869c > --- /dev/null > +++ b/controller/host-if-monitor.h > @@ -0,0 +1,30 @@ > +/* Copyright (c) 2025, 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 HOST_IF_MONITOR_H > +#define HOST_IF_MONITOR_H 1 > + > +#include <stdint.h> > +#include "lib/sset.h" > +#include "lib/smap.h" > + > +void host_if_monitor_wait(void); > +bool host_if_monitor_run(void); > + > +void host_if_monitor_update_watches(const struct sset *if_names); > + > +int32_t host_if_monitor_ifname_toindex(const char *if_name); > + > +#endif /* HOST_IF_MONITOR_H */ > -- > 2.50.1 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev