On Wed, Jun 17, 2026 at 01:31:00PM -0400, Mike Pattrick wrote:
> On Mon, Jun 8, 2026 at 4:56 AM Adrian Moreno via dev <
> [email protected]> wrote:
>
> > We are relying on netlink notifications for netdev status changes.
> >
> > However, given we periodically have to send RTM_GETLINK anyways to get
> > the stats, it seems a good opportunity to double-check the status and
> > update netdevs if something changed.
> >
> > Signed-off-by: Adrian Moreno <[email protected]>
> > ---
> >  lib/netdev-afxdp.c         |  2 +-
> >  lib/netdev-linux-private.h |  5 ++--
> >  lib/netdev-linux.c         | 48 ++++++++++++++++++++++++++++++++++----
> >  3 files changed, 48 insertions(+), 7 deletions(-)
> >
> > diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c
> > index 8ef2ac192..fc0196cc0 100644
> > --- a/lib/netdev-afxdp.c
> > +++ b/lib/netdev-afxdp.c
> > @@ -1254,7 +1254,7 @@ netdev_afxdp_get_stats(const struct netdev *netdev,
> >
> >      ovs_mutex_lock(&dev->mutex);
> >
> > -    error = get_stats_via_netlink(netdev, &dev_stats);
> > +    error = get_stats_via_netlink(dev, &dev_stats);
> >      if (error) {
> >          VLOG_WARN_RL(&rl, "%s: Error getting AF_XDP statistics.",
> >                       netdev_get_name(netdev));
> > diff --git a/lib/netdev-linux-private.h b/lib/netdev-linux-private.h
> > index cf4a021d3..d7a2620c2 100644
> > --- a/lib/netdev-linux-private.h
> > +++ b/lib/netdev-linux-private.h
> > @@ -36,6 +36,7 @@
> >  #include "ovs-atomic.h"
> >  #include "timer.h"
> >
> > +struct netdev_linux;
> >  struct netdev;
> >
> >  /* The maximum packet length is 16 bits */
> > @@ -52,10 +53,10 @@ struct netdev_rxq_linux {
> >  int netdev_linux_construct(struct netdev *);
> >  int netdev_linux_get_status(const struct netdev *, struct smap *);
> >  void netdev_linux_run(const struct netdev_class *);
> > -
> > -int get_stats_via_netlink(const struct netdev *netdev_,
> > +int get_stats_via_netlink(struct netdev_linux *netdev,
> >                            struct netdev_stats *stats);
> >
> > +
> >  struct netdev_linux {
> >      struct netdev up;
> >
> > diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
> > index faef1134a..7ce3ee5ba 100644
> > --- a/lib/netdev-linux.c
> > +++ b/lib/netdev-linux.c
> > @@ -819,6 +819,37 @@ netdev_linux_wait(const struct netdev_class
> > *netdev_class OVS_UNUSED)
> >      }
> >  }
> >
> > +
> > +/* Check whether the current state of the netdev is the same as the one
> > + * reported by netlink. */
> > +static bool
> > +netdev_linux_check(struct netdev_linux *dev,
> > +                   const struct rtnetlink_change *change)
> > +    OVS_REQUIRES(dev->mutex)
> > +{
> > +    bool result = true;
> > +
> > +    if (dev->ifi_flags != change->ifi_flags) {
> > +        result = false;
> > +    }
> > +    if (dev->mtu != change->mtu) {
> > +        result = false;
> > +    }
> > +    if (!eth_addr_is_zero(change->mac) &&
> > +        !eth_addr_equals(dev->etheraddr, change->mac)) {
> > +        result = false;
> > +    }
> > +    if (dev->ifindex != change->if_index) {
> > +        result = false;
> > +    }
> > +    if (dev->is_lag_primary != (change->primary &&
> > +        netdev_linux_kind_is_lag(change->primary))) {
> > +        result = false;
> > +    }
> > +
> > +    return result;
> >
>
> Nit, but every use of netdev_linux_check inverts the return value of this
> function. Currently it returns true when the netdev has not changed, but
> the callers all care to check if the netdev has changed. Why not just flip
> all the boolean values in this function and rebrand it on a check of if the
> netdev has changed?
>

Good idea! Thanks.

> -M
>
>
> > +}
> > +
> >  static void
> >  netdev_linux_changed(struct netdev_linux *dev, unsigned int mask)
> >      OVS_REQUIRES(dev->mutex)
> > @@ -2279,7 +2310,7 @@ netdev_linux_get_stats(const struct netdev *netdev_,
> >
> >      ovs_mutex_lock(&netdev->mutex);
> >      get_stats_via_vport(netdev_, stats);
> > -    error = get_stats_via_netlink(netdev_, &dev_stats);
> > +    error = get_stats_via_netlink(netdev, &dev_stats);
> >      if (error) {
> >          if (!netdev->vport_stats_error) {
> >              error = 0;
> > @@ -2318,7 +2349,7 @@ netdev_tap_get_stats(const struct netdev *netdev_,
> > struct netdev_stats *stats)
> >
> >      ovs_mutex_lock(&netdev->mutex);
> >      get_stats_via_vport(netdev_, stats);
> > -    error = get_stats_via_netlink(netdev_, &dev_stats);
> > +    error = get_stats_via_netlink(netdev, &dev_stats);
> >      if (error) {
> >          if (!netdev->vport_stats_error) {
> >              error = 0;
> > @@ -6754,7 +6785,9 @@ netdev_stats_from_rtnl_link_stats64(struct
> > netdev_stats *dst,
> >  }
> >
> >  int
> > -get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats
> > *stats)
> > +get_stats_via_netlink(struct netdev_linux *netdev,
> > +                      struct netdev_stats *stats)
> > +    OVS_REQUIRES(netdev->mutex)
> >  {
> >      struct rtnetlink_change change = {0};
> >      struct rtnl_link_stats64 _stats64;
> > @@ -6771,7 +6804,7 @@ get_stats_via_netlink(const struct netdev *netdev_,
> > struct netdev_stats *stats)
> >                          sizeof(struct ifinfomsg) + NL_ATTR_SIZE(IFNAMSIZ),
> >                          RTM_GETLINK, NLM_F_REQUEST);
> >      ofpbuf_put_zeros(&request, sizeof(struct ifinfomsg));
> > -    nl_msg_put_string(&request, IFLA_IFNAME, netdev_get_name(netdev_));
> > +    nl_msg_put_string(&request, IFLA_IFNAME,
> > netdev_get_name(&netdev->up));
> >      error = nl_transact(NETLINK_ROUTE, &request, &reply);
> >      ofpbuf_uninit(&request);
> >      if (error) {
> > @@ -6791,6 +6824,13 @@ get_stats_via_netlink(const struct netdev *netdev_,
> > struct netdev_stats *stats)
> >              VLOG_WARN_RL(&rl, "RTM_GETLINK reply lacks stats");
> >              error = EPROTO;
> >          }
> > +
> > +        /* Verify the internal state of netdevs matches the one given by
> > +         * netlink. */
> > +        if (!netdev_linux_check(netdev, &change)) {
> > +            netdev_linux_update__(netdev, &change);
> > +        }
> > +
> >      } else {
> >          VLOG_WARN_RL(&rl, "invalid RTM_GETLINK reply");
> >          error = EPROTO;
> > --
> > 2.54.0
> >
> > _______________________________________________
> > dev mailing list
> > [email protected]
> > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> >
> >

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to