From patchwork Wed Mar 11 06:05:19 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208876 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fgRLUXn1; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0bz5LvTz1y1R for ; Wed, 11 Mar 2026 17:05:51 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 035BA411F7; Wed, 11 Mar 2026 06:05:49 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id OMuqmz9Ygn10; Wed, 11 Mar 2026 06:05:47 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org E308D411F2 Authentication-Results: smtp2.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fgRLUXn1 Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTPS id E308D411F2; Wed, 11 Mar 2026 06:05:46 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BCBBEC1366; Wed, 11 Mar 2026 06:05:46 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id CCDCAC003D for ; Wed, 11 Mar 2026 06:05:45 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id B313A61606 for ; Wed, 11 Mar 2026 06:05:45 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id BfSp2ia_cIH6 for ; Wed, 11 Mar 2026 06:05:44 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org 9562360F14 Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 9562360F14 Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=fgRLUXn1 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 9562360F14 for ; Wed, 11 Mar 2026 06:05:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209142; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sW1QZV48j5+2c5YLfWxcTR8WWLi11ZXzuDbrPenlpkE=; b=fgRLUXn15TaPk2C/Gw98RVgKRbqQWr16jfAEHC2VBG7iB4I6CdSaD44sH/v1UPsb5Wve3p n/CSaJ9GcIp8FgqcIUp2THBwH7AbXe+a3rSG8KL2WpuFKyZ/OOFu9Qpo1hNG1sHcG1H09v xryXYhbXu6XXTCpqe+sKrmTlXtv15ms= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-210-we_jzZ9ENzSBHDIAbm24iw-1; Wed, 11 Mar 2026 02:05:40 -0400 X-MC-Unique: we_jzZ9ENzSBHDIAbm24iw-1 X-Mimecast-MFC-AGG-ID: we_jzZ9ENzSBHDIAbm24iw_1773209139 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9EF131956096 for ; Wed, 11 Mar 2026 06:05:39 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8102F1800107; Wed, 11 Mar 2026 06:05:38 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:19 +0100 Message-ID: <20260311060533.52598-2-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Scnf5xOje6E2yGNsicDkC9ZvuPnjsE3XozenYQGksCE_1773209139 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 1/8] netdev_linux: Refactor netdev flag update. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Currently, flags from an expected-to-be-local netdev are read using get_flags(), which is commonly called with &netdev->ifi_flags as argument. Refactor it into its own function and rename "update_flags" to "modify_flags" to increase clarity. As an additional benefit, this patch makes "update_flags" actually report errors when the device is not accessible. Signed-off-by: Adrian Moreno --- lib/netdev-linux.c | 36 +++++++++++++++++++++--------------- tests/system-interface.at | 2 ++ tests/system-tap.at | 5 ++++- tests/system-traffic.at | 3 ++- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 47faea8c6..66153bf49 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -564,7 +564,8 @@ static int netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *, int cmd, const char *cmd_name); static int get_flags(const struct netdev *, unsigned int *flags); static int set_flags(const char *, unsigned int flags); -static int update_flags(struct netdev_linux *netdev, enum netdev_flags off, +static int update_flags_local(struct netdev_linux *); +static int modify_flags(struct netdev_linux *netdev, enum netdev_flags off, enum netdev_flags on, enum netdev_flags *old_flagsp) OVS_REQUIRES(netdev->mutex); static int get_ifindex(const struct netdev *, int *ifindexp); @@ -826,11 +827,10 @@ netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED) SHASH_FOR_EACH (node, &device_shash) { struct netdev *netdev_ = node->data; struct netdev_linux *netdev = netdev_linux_cast(netdev_); - unsigned int flags; ovs_mutex_lock(&netdev->mutex); - get_flags(netdev_, &flags); - netdev_linux_changed(netdev, flags, 0); + update_flags_local(netdev); + netdev_linux_changed(netdev, netdev->ifi_flags, 0); ovs_mutex_unlock(&netdev->mutex); netdev_close(netdev_); @@ -991,7 +991,7 @@ netdev_linux_construct(struct netdev *netdev_) netdev_linux_set_ol(netdev_); } - error = get_flags(&netdev->up, &netdev->ifi_flags); + error = update_flags_local(netdev); if (error == ENODEV) { if (netdev->up.netdev_class != &netdev_internal_class) { /* The device does not exist, so don't allow it to be opened. */ @@ -1038,7 +1038,7 @@ netdev_linux_construct_tap(struct netdev *netdev_) } /* Create tap device. */ - get_flags(&netdev->up, &netdev->ifi_flags); + update_flags_local(netdev); if (ovsthread_once_start(&once)) { if (ioctl(netdev->tap_fd, TUNGETFEATURES, &up) == -1) { @@ -1907,7 +1907,7 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, const struct eth_addr mac) /* Tap devices must be brought down before setting the address. */ if (is_tap_netdev(netdev_)) { - update_flags(netdev, NETDEV_UP, 0, &old_flags); + modify_flags(netdev, NETDEV_UP, 0, &old_flags); } error = set_etheraddr(netdev_get_name(netdev_), mac); if (!error || error == ENODEV) { @@ -1919,7 +1919,7 @@ netdev_linux_set_etheraddr(struct netdev *netdev_, const struct eth_addr mac) } if (is_tap_netdev(netdev_) && old_flags & NETDEV_UP) { - update_flags(netdev, 0, NETDEV_UP, &old_flags); + modify_flags(netdev, 0, NETDEV_UP, &old_flags); } exit: @@ -3846,7 +3846,14 @@ iff_to_nd_flags(unsigned int iff) } static int -update_flags(struct netdev_linux *netdev, enum netdev_flags off, +update_flags_local(struct netdev_linux *netdev) + OVS_REQUIRES(netdev->mutex) +{ + return get_flags(&netdev->up, &netdev->ifi_flags); +} + +static int +modify_flags(struct netdev_linux *netdev, enum netdev_flags off, enum netdev_flags on, enum netdev_flags *old_flagsp) OVS_REQUIRES(netdev->mutex) { @@ -3858,7 +3865,7 @@ update_flags(struct netdev_linux *netdev, enum netdev_flags off, new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on); if (new_flags != old_flags) { error = set_flags(netdev_get_name(&netdev->up), new_flags); - get_flags(&netdev->up, &netdev->ifi_flags); + update_flags_local(netdev); } return error; @@ -3878,14 +3885,13 @@ netdev_linux_update_flags(struct netdev *netdev_, enum netdev_flags off, error = EOPNOTSUPP; goto exit; } - error = update_flags(netdev, off, on, old_flagsp); + error = modify_flags(netdev, off, on, old_flagsp); } else { /* Try reading flags over netlink, or fall back to ioctl. */ - if (!netdev_linux_update_via_netlink(netdev)) { - *old_flagsp = iff_to_nd_flags(netdev->ifi_flags); - } else { - error = update_flags(netdev, off, on, old_flagsp); + if (netdev_linux_update_via_netlink(netdev)) { + error = update_flags_local(netdev); } + *old_flagsp = iff_to_nd_flags(netdev->ifi_flags); } exit: diff --git a/tests/system-interface.at b/tests/system-interface.at index 20a882d1c..ea6753f30 100644 --- a/tests/system-interface.at +++ b/tests/system-interface.at @@ -17,6 +17,7 @@ AT_CHECK([ip link add ovs-veth0 type veth peer name ovs-veth1]) AT_CHECK([ovs-vsctl del-port br0 ovs-veth0]) OVS_TRAFFIC_VSWITCHD_STOP(["dnl +/failed to get flags for network device ovs-veth0/d /could not open network device ovs-veth0/d /cannot get .*STP status on nonexistent port/d /ethtool command .*on network device ovs-veth0 failed/d @@ -177,6 +178,7 @@ AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl OVS_TRAFFIC_VSWITCHD_STOP([" /could not open network device ovs-veth0 (No such device)/d + /failed to get flags for network device ovs-veth0: No such device/d "]) AT_CLEANUP diff --git a/tests/system-tap.at b/tests/system-tap.at index 03ec01270..fe237ad10 100644 --- a/tests/system-tap.at +++ b/tests/system-tap.at @@ -29,6 +29,9 @@ NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -W 2 10.1.1.2 | FORMAT_PING], [0], OVS_START_L7([at_ns1], [http]) NS_CHECK_EXEC([at_ns0], OVS_GET_HTTP([10.1.1.2]), [0], [ignore], [ignore]) -OVS_TRAFFIC_VSWITCHD_STOP(["/.*ethtool command ETHTOOL_G.*/d"]) +OVS_TRAFFIC_VSWITCHD_STOP(["dnl +/.*ethtool command ETHTOOL_G.*/d +/.*failed to get flags for network device/d +"]) AT_CLEANUP diff --git a/tests/system-traffic.at b/tests/system-traffic.at index 8f4fdf8b1..007b00859 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -4297,7 +4297,8 @@ tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src= OVS_TRAFFIC_VSWITCHD_STOP(["dnl /ioctl(SIOCGIFINDEX) on .* device failed: No such device/d -/removing policing failed: No such device/d"]) +/removing policing failed: No such device/d +/failed to get flags for network device/d"]) AT_CLEANUP AT_SETUP([conntrack - ct_mark]) From patchwork Wed Mar 11 06:05:20 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208877 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=cqyUXbGt; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0c04Jm4z1yZR for ; Wed, 11 Mar 2026 17:05:52 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 4195E6160D; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id TQG0ERHHMfsO; Wed, 11 Mar 2026 06:05:49 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org DF85F61609 Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=cqyUXbGt Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp3.osuosl.org (Postfix) with ESMTPS id DF85F61609; Wed, 11 Mar 2026 06:05:48 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id BA492C0070; Wed, 11 Mar 2026 06:05:48 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 6A7F5C003D for ; Wed, 11 Mar 2026 06:05:46 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 4E90D60F14 for ; Wed, 11 Mar 2026 06:05:46 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 1Gwb3o9KSxNY for ; Wed, 11 Mar 2026 06:05:45 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org 7F23561605 Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 7F23561605 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id 7F23561605 for ; Wed, 11 Mar 2026 06:05:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209144; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cZwWieiHQHnWJ7mUG5nNy5GRQrUJTzKH4mKkBMTufl0=; b=cqyUXbGtwV6688L+Jd74ul75dvy3HOBAwLAoGRc55kG+cTzAQzG4llHb4qsmE/v6tUuo0c zFbIK3Xl/focutB9uZBDZA+N4RVD2jjFxPxhA++91UGqm75LcG3zyRI6nVXJ1Mqo5bPkvp E3I7gwaZWT4GYdd+XhN2jEl3WQ75P84= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-360-vLAIANPnMDeGOGEoWISKvw-1; Wed, 11 Mar 2026 02:05:42 -0400 X-MC-Unique: vLAIANPnMDeGOGEoWISKvw-1 X-Mimecast-MFC-AGG-ID: vLAIANPnMDeGOGEoWISKvw_1773209142 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E438E1956080 for ; Wed, 11 Mar 2026 06:05:41 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 35818180049D; Wed, 11 Mar 2026 06:05:39 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:20 +0100 Message-ID: <20260311060533.52598-3-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 2pKlo8XGN_hfgM1GdMuRunjmCbAD1kvWQqGol3GQkvU_1773209142 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 2/8] netdev-linux: Cache netdev flags. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Netdev flags are queried multiple times per poll loop. Sending a GETLINK command for each can be very inefficient if there is RTNL lock contention. Cache the result of the query as we do with other netdev attributes. Signed-off-by: Adrian Moreno --- lib/netdev-linux.c | 15 ++++++++++++--- lib/tnl-ports.c | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 66153bf49..e6127240b 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -265,6 +265,7 @@ enum { VALID_DRVINFO = 1 << 6, VALID_FEATURES = 1 << 7, VALID_NUMA_ID = 1 << 8, + VALID_FLAGS = 1 << 9, }; /* Linux 4.4 introduced the ability to skip the internal stats gathering @@ -830,7 +831,7 @@ netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED) ovs_mutex_lock(&netdev->mutex); update_flags_local(netdev); - netdev_linux_changed(netdev, netdev->ifi_flags, 0); + netdev_linux_changed(netdev, netdev->ifi_flags, VALID_FLAGS); ovs_mutex_unlock(&netdev->mutex); netdev_close(netdev_); @@ -910,6 +911,7 @@ netdev_linux_update__(struct netdev_linux *dev, dev->ifindex = change->if_index; dev->cache_valid |= VALID_IFINDEX; + dev->cache_valid |= VALID_FLAGS; dev->get_ifindex_error = 0; dev->present = true; } else { @@ -3849,7 +3851,11 @@ static int update_flags_local(struct netdev_linux *netdev) OVS_REQUIRES(netdev->mutex) { - return get_flags(&netdev->up, &netdev->ifi_flags); + int error = get_flags(&netdev->up, &netdev->ifi_flags); + if (!error) { + netdev->cache_valid |= VALID_FLAGS; + } + return error; } static int @@ -3888,7 +3894,8 @@ netdev_linux_update_flags(struct netdev *netdev_, enum netdev_flags off, error = modify_flags(netdev, off, on, old_flagsp); } else { /* Try reading flags over netlink, or fall back to ioctl. */ - if (netdev_linux_update_via_netlink(netdev)) { + if (!(netdev->cache_valid & VALID_FLAGS) && + netdev_linux_update_via_netlink(netdev)) { error = update_flags_local(netdev); } *old_flagsp = iff_to_nd_flags(netdev->ifi_flags); @@ -6955,6 +6962,8 @@ netdev_linux_update_via_netlink(struct netdev_linux *netdev) netdev->ifi_flags = change->ifi_flags; changed = true; } + netdev->cache_valid |= VALID_FLAGS; + if (change->mtu && change->mtu != netdev->mtu) { netdev->mtu = change->mtu; netdev->cache_valid |= VALID_MTU; diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c index 56119b300..67b6ebcf7 100644 --- a/lib/tnl-ports.c +++ b/lib/tnl-ports.c @@ -402,13 +402,13 @@ insert_ipdev__(struct netdev *dev, ip_dev = xzalloc(sizeof *ip_dev); ip_dev->dev = netdev_ref(dev); - ip_dev->change_seq = netdev_get_change_seq(dev); error = netdev_get_etheraddr(ip_dev->dev, &ip_dev->mac); if (error) { goto err_free_ipdev; } ip_dev->addr = addr; ip_dev->n_addr = n_addr; + ip_dev->change_seq = netdev_get_change_seq(dev); ovs_strlcpy(ip_dev->dev_name, netdev_get_name(dev), sizeof ip_dev->dev_name); ovs_list_insert(&addr_list, &ip_dev->node); map_insert_ipdev(ip_dev); From patchwork Wed Mar 11 06:05:21 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208878 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Ldx+4DTx; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [140.211.166.136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0c36VsQz1xy3 for ; Wed, 11 Mar 2026 17:05:55 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 8BB2061621; Wed, 11 Mar 2026 06:05:51 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id j-A5BpFHpkR6; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 756E861611 Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Ldx+4DTx Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id 756E861611; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 5AE69C0070; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) by lists.linuxfoundation.org (Postfix) with ESMTP id EF420C1367 for ; Wed, 11 Mar 2026 06:05:48 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id D130384219 for ; Wed, 11 Mar 2026 06:05:48 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id KD_SqeEqvRle for ; Wed, 11 Mar 2026 06:05:48 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org E5EE784234 Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org E5EE784234 Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Ldx+4DTx Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id E5EE784234 for ; Wed, 11 Mar 2026 06:05:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209145; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lDduRJUZrJEGBrfC49FIUjcKe5AHCdq3C/nNfgO8LJc=; b=Ldx+4DTx5SEgfn3daKs3Pdt7ZPR2MUOv+L88Fzf4OAV3BWgefD2DwGVZei+51BKeyW+bLa nFpl4QOW1mG4hpHrXAHw40Wf19v2NCDqjj5/FCZAV0YKH1+NIAAbCLSbgpHTjqUZge+SLX /IBPhQ8IgmOIv/67dG6uPfrLMBTDSyc= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-460-2ml-uOCGO5aFHNkDc00eCw-1; Wed, 11 Mar 2026 02:05:44 -0400 X-MC-Unique: 2ml-uOCGO5aFHNkDc00eCw-1 X-Mimecast-MFC-AGG-ID: 2ml-uOCGO5aFHNkDc00eCw_1773209143 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id A134A195605F for ; Wed, 11 Mar 2026 06:05:43 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 74C65180049D; Wed, 11 Mar 2026 06:05:42 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:21 +0100 Message-ID: <20260311060533.52598-4-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ayE126oXgEM6nyXDwJx8JuqNkPxtjJM4kGTYJtl46D0_1773209143 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 3/8] netlink-notifier: Drain socket on overflow. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" If the netlink socket overflows, we report an empty change to let all notifiers know some events are lost and therefore they can no longer trust their known state. This acts as a kind of reset. Draining the socket makes sense here so that partial events are not sent afterwards. Signed-off-by: Adrian Moreno Acked-by: Mike Pattrick --- lib/netlink-notifier.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/netlink-notifier.c b/lib/netlink-notifier.c index 7ea5a4181..ea4742a90 100644 --- a/lib/netlink-notifier.c +++ b/lib/netlink-notifier.c @@ -200,6 +200,7 @@ nln_run(struct nln *nln) return; } else { if (error == ENOBUFS) { + nl_sock_drain(nln->notify_sock); /* The socket buffer might be full, there could be too many * notifications, so it makes sense to call nln_report() */ nln_report(nln, NULL, 0); From patchwork Wed Mar 11 06:05:22 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208881 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QN9Ktp7w; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0cP2DBCz1xy3 for ; Wed, 11 Mar 2026 17:06:13 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id B5C8741ECA; Wed, 11 Mar 2026 06:06:10 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id GfGBCZOTNV8L; Wed, 11 Mar 2026 06:06:06 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 8F09041EB4 Authentication-Results: smtp2.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QN9Ktp7w Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp2.osuosl.org (Postfix) with ESMTPS id 8F09041EB4; Wed, 11 Mar 2026 06:06:06 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id EF074C1367; Wed, 11 Mar 2026 06:06:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 04DD7C136A for ; Wed, 11 Mar 2026 06:06:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id B3790420F9 for ; Wed, 11 Mar 2026 06:05:55 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id vaEfumLUvv29 for ; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org 937B341FCB Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 937B341FCB Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QN9Ktp7w Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 937B341FCB for ; Wed, 11 Mar 2026 06:05:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209148; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bWE19BUJz+LBPjRBRhgK7R825CEz/8LbUvEcGUGnJ6g=; b=QN9Ktp7w1K6CPdaBuayJUO1eVew5EK6eCd+sPYfYzVd+RYpJU8szwQGiarEGgveL1b9ZmE mVjfPJy5/D9VUkhXSicJUWpe37hcqOeR8fEyAF72or15/6rz+luISXs1rb3uJbqM1hy7VS D9/B3VCUYK5ooqIZS+DZHOfC+4jD4vk= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-601-YkZ64iQZMRq_nNDpp0ALFQ-1; Wed, 11 Mar 2026 02:05:46 -0400 X-MC-Unique: YkZ64iQZMRq_nNDpp0ALFQ-1 X-Mimecast-MFC-AGG-ID: YkZ64iQZMRq_nNDpp0ALFQ_1773209145 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 496231956095 for ; Wed, 11 Mar 2026 06:05:45 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 2A44E180075E; Wed, 11 Mar 2026 06:05:43 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:22 +0100 Message-ID: <20260311060533.52598-5-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: B-zM4Y1tCnR00TcawniABIuhNKdXCzdBBrXpvvcfwao_1773209145 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 4/8] netlink-notifier: Include nsid in callbacks. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Use a flag to request notifications form all network namespaces and include the namespace id from which notification came from in the parsing callback. Signed-off-by: Adrian Moreno --- lib/if-notifier.c | 3 ++- lib/netlink-notifier.c | 14 +++++++++++--- lib/netlink-notifier.h | 6 ++++-- lib/netnsid.h | 1 + lib/route-table.c | 12 ++++++------ lib/route-table.h | 2 +- lib/rtnetlink.c | 14 +++++++++++--- lib/rtnetlink.h | 5 +++-- tests/test-lib-route-table.c | 9 ++++++++- tests/test-netlink-conntrack.c | 9 +++++++-- 10 files changed, 54 insertions(+), 21 deletions(-) diff --git a/lib/if-notifier.c b/lib/if-notifier.c index f2d7157b9..5b3ba8b69 100644 --- a/lib/if-notifier.c +++ b/lib/if-notifier.c @@ -16,6 +16,7 @@ #include #include "if-notifier.h" +#include "netnsid.h" #include "rtnetlink.h" #include "util.h" @@ -30,7 +31,7 @@ if_notifier_cb(const struct rtnetlink_change *change, void *aux) { struct if_notifier *notifier; - if (change && change->irrelevant) { + if (change && (change->irrelevant || change->nsid != NETNSID_LOCAL)) { return; } diff --git a/lib/netlink-notifier.c b/lib/netlink-notifier.c index ea4742a90..6ecb4392b 100644 --- a/lib/netlink-notifier.c +++ b/lib/netlink-notifier.c @@ -25,6 +25,7 @@ #include "coverage.h" #include "netlink.h" #include "netlink-socket.h" +#include "netnsid.h" #include "openvswitch/ofpbuf.h" #include "openvswitch/vlog.h" @@ -41,6 +42,7 @@ struct nln { int protocol; /* Protocol passed to nl_sock_create(). */ nln_parse_func *parse; /* Message parsing function. */ void *change; /* Change passed to parse. */ + bool all_netns; /* Whether to listen on all namespaces. */ }; struct nln_notifier { @@ -55,10 +57,11 @@ struct nln_notifier { /* Creates an nln handle which may be used to manage change notifications. The * created handle will listen for netlink messages on 'multicast_group' using * netlink protocol 'protocol' (e.g. NETLINK_ROUTE, NETLINK_GENERIC, ...). + * If 'all_netns', it will listen for events on all network namespaces. * Incoming messages will be parsed with 'parse' which will be passed 'change' * as an argument. */ struct nln * -nln_create(int protocol, nln_parse_func *parse, void *change) +nln_create(int protocol, bool all_netns, nln_parse_func *parse, void *change) { struct nln *nln; @@ -68,6 +71,7 @@ nln_create(int protocol, nln_parse_func *parse, void *change) nln->parse = parse; nln->change = change; nln->has_run = false; + nln->all_netns = all_netns; ovs_list_init(&nln->all_notifiers); return nln; @@ -112,6 +116,9 @@ nln_notifier_create(struct nln *nln, int multicast_group, nln_notify_func *cb, ovs_strerror(error)); return NULL; } + if (nln->all_netns) { + nl_sock_listen_all_nsid(sock, true); + } nln->notify_sock = sock; } else { /* Catch up on notification work so that the new notifier won't @@ -181,13 +188,14 @@ nln_run(struct nln *nln) nln->has_run = true; for (;;) { uint64_t buf_stub[4096 / 8]; + int nsid = NETNSID_UNSET; struct ofpbuf buf; int error; ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); - error = nl_sock_recv(nln->notify_sock, &buf, NULL, false); + error = nl_sock_recv(nln->notify_sock, &buf, &nsid, false); if (!error) { - int group = nln->parse(&buf, nln->change); + int group = nln->parse(&buf, nsid, nln->change); if (group != 0) { nln_report(nln, nln->change, group); diff --git a/lib/netlink-notifier.h b/lib/netlink-notifier.h index dd0c183de..8b6c32048 100644 --- a/lib/netlink-notifier.h +++ b/lib/netlink-notifier.h @@ -37,11 +37,13 @@ typedef void nln_notify_func(const void *change, void *aux); /* Function called to parse incoming nln notifications. The 'buf' message * should be parsed into 'change' as specified in nln_create(). + * 'nsid` is the network namespace id from which the netlink event came from. * Returns the multicast_group the change belongs to, or 0 for a parse error. */ -typedef int nln_parse_func(struct ofpbuf *buf, void *change); +typedef int nln_parse_func(struct ofpbuf *buf, int nsid, void *change); -struct nln *nln_create(int protocol, nln_parse_func *, void *change); +struct nln *nln_create(int protocol, bool all_netns, nln_parse_func *, + void *change); void nln_destroy(struct nln *); struct nln_notifier *nln_notifier_create(struct nln *, int multicast_group, nln_notify_func *, void *aux); diff --git a/lib/netnsid.h b/lib/netnsid.h index 1d5ab83c5..47f55ee6c 100644 --- a/lib/netnsid.h +++ b/lib/netnsid.h @@ -18,6 +18,7 @@ #define NETNSID_H 1 #include +#include "util.h" #ifdef HAVE_LINUX_NET_NAMESPACE_H #include diff --git a/lib/route-table.c b/lib/route-table.c index 2a13a5cc7..5cb6f7842 100644 --- a/lib/route-table.c +++ b/lib/route-table.c @@ -33,6 +33,7 @@ #include "netlink.h" #include "netlink-notifier.h" #include "netlink-socket.h" +#include "netnsid.h" #include "openvswitch/list.h" #include "openvswitch/ofpbuf.h" #include "ovs-router.h" @@ -84,7 +85,7 @@ static struct nln_notifier *name_notifier = NULL; static bool route_table_valid = false; static bool rules_valid = false; -static int route_nln_parse(struct ofpbuf *, void *change); +static int route_nln_parse(struct ofpbuf *, int nsid, void *change); static void rule_handle_msg(const struct route_table_msg *); static int rule_parse(struct ofpbuf *, void *change); @@ -137,7 +138,7 @@ route_table_init(void) ovs_assert(!rule6_notifier); ovs_router_init(); - nln = nln_create(NETLINK_ROUTE, route_nln_parse, &nln_rtmsg_change); + nln = nln_create(NETLINK_ROUTE, false, route_nln_parse, &nln_rtmsg_change); route_notifier = nln_notifier_create(nln, RTNLGRP_IPV4_ROUTE, @@ -295,7 +296,7 @@ rule_handle_msg(const struct route_table_msg *change) } static int -route_nln_parse(struct ofpbuf *buf, void *change_) +route_nln_parse(struct ofpbuf *buf, int nsid OVS_UNUSED, void *change_) { const struct nlmsghdr *nlmsg = buf->data; @@ -795,10 +796,9 @@ name_table_init(void) static void -name_table_change(const struct rtnetlink_change *change, - void *aux OVS_UNUSED) +name_table_change(const struct rtnetlink_change *change, void *aux OVS_UNUSED) { - if (change && change->irrelevant) { + if (change && (change->nsid != NETNSID_LOCAL || change->irrelevant)) { return; } diff --git a/lib/route-table.h b/lib/route-table.h index b49fbb14e..e4edcb307 100644 --- a/lib/route-table.h +++ b/lib/route-table.h @@ -79,7 +79,7 @@ * static struct route_table_msg nln_change; * static struct nln *nln = NULL; * - * nln = nln_create(NETLINK_ROUTE, route_table_parse, NULL); + * nln = nln_create(NETLINK_ROUTE, false, nln_route_table_parse, NULL); * * route6_notifier = * nln_notifier_create(nln, RTNLGRP_IPV6_ROUTE, diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c index 37078d00e..6b63afa06 100644 --- a/lib/rtnetlink.c +++ b/lib/rtnetlink.c @@ -24,6 +24,7 @@ #include "netlink.h" #include "netlink-notifier.h" +#include "netnsid.h" #include "openvswitch/ofpbuf.h" #include "packets.h" @@ -89,6 +90,7 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) bool parsed = false; change->irrelevant = false; + change->nsid = NETNSID_UNSET; if (rtnetlink_type_is_rtnlgrp_link(nlmsg->nlmsg_type)) { /* Policy for RTNLGRP_LINK messages. @@ -190,9 +192,14 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) /* Return RTNLGRP_LINK on success, 0 on parse error. */ static int -rtnetlink_parse_cb(struct ofpbuf *buf, void *change) +rtnetlink_parse_cb(struct ofpbuf *buf, int nsid, void *change) { - return rtnetlink_parse(buf, change) ? RTNLGRP_LINK : 0; + bool ret = rtnetlink_parse(buf, change); + if (ret) { + ((struct rtnetlink_change *) change)->nsid = nsid; + return RTNLGRP_LINK; + } + return 0; } /* Registers 'cb' to be called with auxiliary data 'aux' with network device @@ -210,7 +217,8 @@ struct nln_notifier * rtnetlink_notifier_create(rtnetlink_notify_func *cb, void *aux) { if (!nln) { - nln = nln_create(NETLINK_ROUTE, rtnetlink_parse_cb, &rtn_change); + nln = nln_create(NETLINK_ROUTE, false, rtnetlink_parse_cb, + &rtn_change); } return nln_notifier_create(nln, RTNLGRP_LINK, (nln_notify_func *) cb, aux); diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h index cf3f600f0..9b2397b4e 100644 --- a/lib/rtnetlink.h +++ b/lib/rtnetlink.h @@ -39,6 +39,8 @@ struct rtnetlink_change { /* Common attributes. */ int if_index; /* Index of network device. */ const char *ifname; /* Name of network device. */ + int nsid; /* Network namespace id of the from which + the event comes from. */ /* Network device link status. */ int master_ifindex; /* Ifindex of datapath master (0 if none). */ @@ -63,8 +65,7 @@ struct rtnetlink_change { * have changed. 'aux' is as specified in the call to * rtnetlink_notifier_register(). */ typedef -void rtnetlink_notify_func(const struct rtnetlink_change *change, - void *aux); +void rtnetlink_notify_func(const struct rtnetlink_change *change, void *aux); bool rtnetlink_type_is_rtnlgrp_link(uint16_t type); bool rtnetlink_type_is_rtnlgrp_addr(uint16_t type); diff --git a/tests/test-lib-route-table.c b/tests/test-lib-route-table.c index f99f056c8..c5126426b 100644 --- a/tests/test-lib-route-table.c +++ b/tests/test-lib-route-table.c @@ -129,6 +129,13 @@ test_lib_route_table_change(struct route_table_msg *change, route_data_destroy(&change->rd); } +static int +test_lib_route_table_parse(struct ofpbuf *buf, int nsid OVS_UNUSED, + void *change) +{ + return route_table_parse(buf, change); +} + static void test_lib_route_table_monitor(int argc, char *argv[]) { @@ -143,7 +150,7 @@ test_lib_route_table_monitor(int argc, char *argv[]) exit(EXIT_FAILURE); } - nln = nln_create(NETLINK_ROUTE, route_table_parse, &rtmsg); + nln = nln_create(NETLINK_ROUTE, false, test_lib_route_table_parse, &rtmsg); route_notifier = nln_notifier_create(nln, RTNLGRP_IPV4_ROUTE, diff --git a/tests/test-netlink-conntrack.c b/tests/test-netlink-conntrack.c index 2a62615b2..a8bcadc4d 100644 --- a/tests/test-netlink-conntrack.c +++ b/tests/test-netlink-conntrack.c @@ -22,6 +22,7 @@ #include "ct-dpif.h" #include "netlink-conntrack.h" #include "netlink-notifier.h" +#include "netnsid.h" #include "ovstest.h" #include "openvswitch/poll-loop.h" @@ -32,10 +33,14 @@ struct test_change { }; static int -event_parse(struct ofpbuf *buf, void *change_) +event_parse(struct ofpbuf *buf, int nsid, void *change_) { struct test_change *change = change_; + if (nsid != NETNSID_LOCAL) { + return 0; + } + if (nl_ct_parse_entry(buf, &change->entry, &change->type)) { switch (change->type) { case NL_CT_EVENT_NEW: @@ -80,7 +85,7 @@ test_nl_ct_monitor(struct ovs_cmdl_context *ctx OVS_UNUSED) unsigned i; - nln = nln_create(NETLINK_NETFILTER, event_parse, &change); + nln = nln_create(NETLINK_NETFILTER, false, event_parse, &change); for (i = 0; i < ARRAY_SIZE(groups); i++) { notifiers[i] = nln_notifier_create(nln, groups[i], event_print, NULL); From patchwork Wed Mar 11 06:05:23 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208880 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=N0Rvdklf; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0cM0W7Rz1xy3 for ; Wed, 11 Mar 2026 17:06:11 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id A8DCC421FC; Wed, 11 Mar 2026 06:06:09 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 3Z7UIsW3lPdM; Wed, 11 Mar 2026 06:06:06 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 43E6A421B3 Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=N0Rvdklf Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 43E6A421B3; Wed, 11 Mar 2026 06:05:57 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 13F31C1368; Wed, 11 Mar 2026 06:05:57 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0F56CC0070 for ; Wed, 11 Mar 2026 06:05:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 9668D42175 for ; Wed, 11 Mar 2026 06:05:54 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id azin0BB6X5-R for ; Wed, 11 Mar 2026 06:05:51 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org B2B3F42032 Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org B2B3F42032 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id B2B3F42032 for ; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209149; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=o9ayle4W7qZcsYbCRgz3AEblWgBarLQ7TZ5A+ju6H4c=; b=N0Rvdklfr1sZscpFzwiwlqG3dHeSZt11bN2VHmL96iCMGz9TvR2jqZzM6wrOLSIaiKdV9P ILBsVm8yKzEYaxRZo2oCfFzgmFE765ZcInw3JS8HlliOJDAdzs7NEFodjhmZIfFkdBJyI3 PLcpsg73sNb0yjb79vckQcx9ghe1Hpc= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-486-K0nRzJz8NjOwW7VmB1NdEA-1; Wed, 11 Mar 2026 02:05:48 -0400 X-MC-Unique: K0nRzJz8NjOwW7VmB1NdEA-1 X-Mimecast-MFC-AGG-ID: K0nRzJz8NjOwW7VmB1NdEA_1773209147 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 485FC1956052 for ; Wed, 11 Mar 2026 06:05:47 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0FC98180049D; Wed, 11 Mar 2026 06:05:45 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:23 +0100 Message-ID: <20260311060533.52598-6-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: JD-k-D84AkII6Do-74DiYk6gFbVBRxO42yfheF7j3lA_1773209147 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 5/8] netdev-linux: Use rtnetlink to update state. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Now that netdev-linux flags are also cached, we need to ensure they are updated correctly. Currently, there are subsystems that rely on link state changes via rtnetlink notifiers (e.g: iface-notifier, route-table). In parallel, netdev-linux creates its own netlink socket to listen for link notifications based on which netdev's states are updated. This creates a potential race: some subsystems might be notified that a link changed but the internal netdev representation is still old. If we want to both cache netdev internal state (e.g: flags, ether_addr) effectively we need to use the same callback chain, i.e: we need to use rtnetlink to update netdev-linux netdevs as well when links change. The order of callbacks cannot be guaranteed so it could still be possible to have another subsystem be notified before netdev-linux has been given a chance to update its state. However, subsystems would likely want to aggregate reconfigurations and will likely have their own "_run()" function to operate. Therefore, it could be reasonalbe to assume the other subsystems would use the callback to set a flag that is then used to trigger reconfigurations in their own periodic "_run()" functions (this is exactly the case of the two existing users: iface-notifier, route-table). This patch makes netdev-linux use rtnetlink notifier for interface updates and independent nln notifiers for address changes. Signed-off-by: Adrian Moreno --- lib/netdev-linux.c | 214 ++++++++++++++++++++--------------------- lib/netdev-linux.h | 1 + lib/netlink-notifier.h | 3 +- lib/rtnetlink.c | 12 ++- lib/rtnetlink.h | 1 + 5 files changed, 118 insertions(+), 113 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index e6127240b..97be563f7 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -298,6 +298,10 @@ static struct ovs_mutex lag_mutex = OVS_MUTEX_INITIALIZER; static struct shash lag_shash OVS_GUARDED_BY(lag_mutex) = SHASH_INITIALIZER(&lag_shash); +static struct rtnetlink_change netlink_change; +static struct nln *nln = NULL; +static struct nln_notifier *notifiers[4] = {NULL, NULL, NULL, NULL}; + /* Traffic control. */ /* An instance of a traffic control class. Always associated with a particular @@ -648,40 +652,6 @@ static void netdev_linux_changed(struct netdev_linux *netdev, unsigned int ifi_flags, unsigned int mask) OVS_REQUIRES(netdev->mutex); -/* Returns a NETLINK_ROUTE socket listening for RTNLGRP_LINK, - * RTNLGRP_IPV4_IFADDR and RTNLGRP_IPV6_IFADDR changes, or NULL - * if no such socket could be created. */ -static struct nl_sock * -netdev_linux_notify_sock(void) -{ - static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; - static struct nl_sock *sock; - unsigned int mcgroups[] = {RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, - RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_IFINFO}; - - if (ovsthread_once_start(&once)) { - int error; - - error = nl_sock_create(NETLINK_ROUTE, &sock); - if (!error) { - size_t i; - - nl_sock_listen_all_nsid(sock, true); - for (i = 0; i < ARRAY_SIZE(mcgroups); i++) { - error = nl_sock_join_mcgroup(sock, mcgroups[i]); - if (error) { - nl_sock_destroy(sock); - sock = NULL; - break; - } - } - } - ovsthread_once_done(&once); - } - - return sock; -} - static bool netdev_linux_miimon_enabled(void) { @@ -699,7 +669,7 @@ netdev_linux_kind_is_lag(const char *kind) } static void -netdev_linux_update_lag(struct rtnetlink_change *change) +netdev_linux_update_lag(const struct rtnetlink_change *change) OVS_REQUIRES(lag_mutex) { struct linux_lag_member *lag; @@ -763,101 +733,128 @@ netdev_linux_update_lag(struct rtnetlink_change *change) } } -void -netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED) +static void +netdev_linux_rtnetlink_update(const struct rtnetlink_change *change, + void *aux OVS_UNUSED) { - struct nl_sock *sock; - int error; + struct netdev *netdev_ = NULL; - if (netdev_linux_miimon_enabled()) { - netdev_linux_miimon_run(); - } + if (change && change->irrelevant) { + return; + } else if (!change) { + struct shash device_shash; + struct shash_node *node; - sock = netdev_linux_notify_sock(); - if (!sock) { + shash_init(&device_shash); + netdev_get_devices(&netdev_linux_class, &device_shash); + SHASH_FOR_EACH (node, &device_shash) { + struct netdev_linux *netdev = netdev_linux_cast(netdev_); + netdev_ = node->data; + int error; + + ovs_mutex_lock(&netdev->mutex); + error = update_flags_local(netdev); + netdev_linux_changed(netdev, netdev->ifi_flags, + error ? 0 : VALID_FLAGS); + ovs_mutex_unlock(&netdev->mutex); + + netdev_close(netdev_); + } + shash_destroy(&device_shash); return; } - do { - uint64_t buf_stub[4096 / 8]; - int nsid; - struct ofpbuf buf; + if (change->ifname) { + netdev_ = netdev_from_name(change->ifname); + } - ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); - error = nl_sock_recv(sock, &buf, &nsid, false); - if (!error) { - struct rtnetlink_change change; + if (netdev_ && is_netdev_linux_class(netdev_->netdev_class)) { + struct netdev_linux *netdev = netdev_linux_cast(netdev_); - if (rtnetlink_parse(&buf, &change) && !change.irrelevant) { - struct netdev *netdev_ = NULL; - char dev_name[IFNAMSIZ]; + ovs_mutex_lock(&netdev->mutex); + netdev_linux_update(netdev, change->nsid, change); + ovs_mutex_unlock(&netdev->mutex); + } - if (!change.ifname) { - change.ifname = if_indextoname(change.if_index, dev_name); - } + if (change->ifname && + rtnetlink_type_is_rtnlgrp_link(change->nlmsg_type)) { - if (change.ifname) { - netdev_ = netdev_from_name(change.ifname); - } - if (netdev_ && is_netdev_linux_class(netdev_->netdev_class)) { - struct netdev_linux *netdev = netdev_linux_cast(netdev_); + /* Need to try updating the LAG information. */ + ovs_mutex_lock(&lag_mutex); + netdev_linux_update_lag(change); + ovs_mutex_unlock(&lag_mutex); + } + netdev_close(netdev_); +} - ovs_mutex_lock(&netdev->mutex); - netdev_linux_update(netdev, nsid, &change); - ovs_mutex_unlock(&netdev->mutex); - } +static void +netdev_linux_nln_cb(const void *change, void *aux) +{ + netdev_linux_rtnetlink_update(change, aux); +} - if (change.ifname && - rtnetlink_type_is_rtnlgrp_link(change.nlmsg_type)) { +static void +netdev_linux_rtnetlink_config(void) +{ + static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER; - /* Need to try updating the LAG information. */ - ovs_mutex_lock(&lag_mutex); - netdev_linux_update_lag(&change); - ovs_mutex_unlock(&lag_mutex); - } - netdev_close(netdev_); - } - } else if (error == ENOBUFS) { - struct shash device_shash; - struct shash_node *node; + if (ovsthread_once_start(&once)) { + unsigned int extra_mcgroups[] = {RTNLGRP_IPV4_IFADDR, + RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_IFINFO}; + struct nln_notifier *notifier; + int i; - nl_sock_drain(sock); + ovs_assert(ARRAY_SIZE(notifiers) == ARRAY_SIZE(extra_mcgroups) + 1); - shash_init(&device_shash); - netdev_get_devices(&netdev_linux_class, &device_shash); - SHASH_FOR_EACH (node, &device_shash) { - struct netdev *netdev_ = node->data; - struct netdev_linux *netdev = netdev_linux_cast(netdev_); - - ovs_mutex_lock(&netdev->mutex); - update_flags_local(netdev); - netdev_linux_changed(netdev, netdev->ifi_flags, VALID_FLAGS); - ovs_mutex_unlock(&netdev->mutex); - - netdev_close(netdev_); - } - shash_destroy(&device_shash); - } else if (error != EAGAIN) { - static struct vlog_rate_limit rll = VLOG_RATE_LIMIT_INIT(1, 5); - VLOG_WARN_RL(&rll, "error reading or parsing netlink (%s)", - ovs_strerror(error)); + nln = nln_create(NETLINK_ROUTE, true, rtnetlink_parse_cb, + &netlink_change); + if (!nln) { + VLOG_ERR("failed to create nln notifier"); } - ofpbuf_uninit(&buf); - } while (!error); + + for (i = 0; i < ARRAY_SIZE(extra_mcgroups); i++) { + notifier = nln_notifier_create(nln, extra_mcgroups[i], + netdev_linux_nln_cb, NULL); + if (!notifier) { + VLOG_ERR("failed to create nln notifier for mcgroup %d", + extra_mcgroups[i]); + } + notifiers[i] = notifier; + } + + notifier = rtnetlink_notifier_create(netdev_linux_rtnetlink_update, + NULL); + if (!notifier) { + VLOG_ERR("failed to create rtnetlink notifier"); + } + notifiers[i] = notifier; + + ovsthread_once_done(&once); + } +} + +void +netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED) +{ + rtnetlink_run(); + if (nln) { + nln_run(nln); + } + if (netdev_linux_miimon_enabled()) { + netdev_linux_miimon_run(); + } } static void netdev_linux_wait(const struct netdev_class *netdev_class OVS_UNUSED) { - struct nl_sock *sock; - + rtnetlink_wait(); + if (nln) { + nln_wait(nln); + } if (netdev_linux_miimon_enabled()) { netdev_linux_miimon_wait(); } - sock = netdev_linux_notify_sock(); - if (sock) { - nl_sock_wait(sock, POLLIN); - } } static void @@ -900,9 +897,6 @@ netdev_linux_update__(struct netdev_linux *dev, dev->etheraddr = change->mac; dev->cache_valid |= VALID_ETHERADDR; dev->ether_addr_error = 0; - - /* The mac addr has been changed, report it now. */ - rtnetlink_report_link(); } if (change->primary && netdev_linux_kind_is_lag(change->primary)) { @@ -968,6 +962,8 @@ netdev_linux_common_construct(struct netdev *netdev_) return ENAMETOOLONG; } + netdev_linux_rtnetlink_config(); + /* The device could be in the same network namespace or in another one. */ netnsid_unset(&netdev->netnsid); ovs_mutex_init(&netdev->mutex); diff --git a/lib/netdev-linux.h b/lib/netdev-linux.h index ec19b0ded..81a5634f6 100644 --- a/lib/netdev-linux.h +++ b/lib/netdev-linux.h @@ -25,6 +25,7 @@ * Linux-specific code. */ struct netdev; +struct rtnetlink_change; int netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag, const char *flag_name, bool enable); diff --git a/lib/netlink-notifier.h b/lib/netlink-notifier.h index 8b6c32048..d52e5f56c 100644 --- a/lib/netlink-notifier.h +++ b/lib/netlink-notifier.h @@ -1,5 +1,4 @@ -/* - * Copyright (c) 2009 Nicira, Inc. +/* Copyright (c) 2009 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c index 6b63afa06..4ae050ff0 100644 --- a/lib/rtnetlink.c +++ b/lib/rtnetlink.c @@ -191,7 +191,7 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) } /* Return RTNLGRP_LINK on success, 0 on parse error. */ -static int +int rtnetlink_parse_cb(struct ofpbuf *buf, int nsid, void *change) { bool ret = rtnetlink_parse(buf, change); @@ -212,12 +212,20 @@ rtnetlink_parse_cb(struct ofpbuf *buf, int nsid, void *change) * * xxx Joins more multicast groups when needed. * + * Callbacks might find that netdev-linux netdevs still hold outdated cached + * information. If the notification has to trigger some kind of reconfiguration + * that requires up-to-date netdev cache, it should do it asynchronously, for + * instance by setting a flag in the callback and acting on it during the + * normal "*_run()" operation. + * + * Notifications might come from any network namespace. + * * Returns an initialized nln_notifier if successful, NULL otherwise. */ struct nln_notifier * rtnetlink_notifier_create(rtnetlink_notify_func *cb, void *aux) { if (!nln) { - nln = nln_create(NETLINK_ROUTE, false, rtnetlink_parse_cb, + nln = nln_create(NETLINK_ROUTE, true, rtnetlink_parse_cb, &rtn_change); } diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h index 9b2397b4e..f0b49bf1a 100644 --- a/lib/rtnetlink.h +++ b/lib/rtnetlink.h @@ -76,4 +76,5 @@ void rtnetlink_notifier_destroy(struct nln_notifier *); void rtnetlink_run(void); void rtnetlink_wait(void); void rtnetlink_report_link(void); +int rtnetlink_parse_cb(struct ofpbuf *buf, int nsid, void *change); #endif /* rtnetlink.h */ From patchwork Wed Mar 11 06:05:24 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208882 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=icxFhizi; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0cS5shnz1xy3 for ; Wed, 11 Mar 2026 17:06:16 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 712DF42142; Wed, 11 Mar 2026 06:06:15 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id YK3_AgyolSqL; Wed, 11 Mar 2026 06:06:13 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 5A0BC4216A Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=icxFhizi Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp4.osuosl.org (Postfix) with ESMTPS id 5A0BC4216A; Wed, 11 Mar 2026 06:06:04 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id EE30FC1368; Wed, 11 Mar 2026 06:06:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2B82EC003D for ; Wed, 11 Mar 2026 06:06:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 82F5B84297 for ; Wed, 11 Mar 2026 06:05:53 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id r5AF4XthbtEV for ; Wed, 11 Mar 2026 06:05:52 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp1.osuosl.org 54EE98426E Authentication-Results: smtp1.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 54EE98426E Authentication-Results: smtp1.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=icxFhizi Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp1.osuosl.org (Postfix) with ESMTPS id 54EE98426E for ; Wed, 11 Mar 2026 06:05:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209151; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QbJmziTqfwycSxe1ekQLRTVjMaWGLukAKSEUuWkdKyc=; b=icxFhizi5yKgI2eBdK6plbyR5iD6ALNJj89E7sNDYhWNU++S56fNKsVuyo7QbruD39ShzB 1uWwqqKILq+EYHJiSbwJhu878Vwd3K4V0xPUElUGdD21RCXwhubMWq15zMAr9Jug4pypnJ 223TYFtPun9K8JsUPI6CCHV2X4H82pQ= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-6-SimU6z9gORS5mHluQIf58A-1; Wed, 11 Mar 2026 02:05:49 -0400 X-MC-Unique: SimU6z9gORS5mHluQIf58A-1 X-Mimecast-MFC-AGG-ID: SimU6z9gORS5mHluQIf58A_1773209149 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id E19001956080 for ; Wed, 11 Mar 2026 06:05:48 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B8C5C180075F; Wed, 11 Mar 2026 06:05:47 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:24 +0100 Message-ID: <20260311060533.52598-7-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: eYdxnlQ_t_lqNLx5nRIQGSA6kDf_8TdlvM3aVoz2PgU_1773209149 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 6/8] netdev-linux: Consolidate RTM_GETLINK parsing. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Move parsing of IFLA_STATS{,64} to rtnetlink_parse() where the rest of the RTM_GETLINK reply is already being parsed. Signed-off-by: Adrian Moreno --- lib/netdev-linux.c | 78 +++++++++------------------------------------- lib/rtnetlink.c | 16 ++++++++++ lib/rtnetlink.h | 50 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 63 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 97be563f7..bf247478e 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -207,46 +207,6 @@ static inline uint32_t rpl_ethtool_cmd_speed(const struct ethtool_cmd *ep) #define SPEED_100000 100000 #endif -/* Linux 2.6.35 introduced IFLA_STATS64 and rtnl_link_stats64. - * - * Tests for rtnl_link_stats64 don't seem to consistently work, e.g. on - * 2.6.32-431.29.2.el6.x86_64 (see report at - * https://mail.openvswitch.org/pipermail/ovs-dev/2014-October/291521.html). - * Maybe if_link.h is not self-contained on those kernels. It is easiest to - * unconditionally define a replacement. */ -#ifndef IFLA_STATS64 -#define IFLA_STATS64 23 -#endif -#define rtnl_link_stats64 rpl_rtnl_link_stats64 -struct rtnl_link_stats64 { - uint64_t rx_packets; - uint64_t tx_packets; - uint64_t rx_bytes; - uint64_t tx_bytes; - uint64_t rx_errors; - uint64_t tx_errors; - uint64_t rx_dropped; - uint64_t tx_dropped; - uint64_t multicast; - uint64_t collisions; - - uint64_t rx_length_errors; - uint64_t rx_over_errors; - uint64_t rx_crc_errors; - uint64_t rx_frame_errors; - uint64_t rx_fifo_errors; - uint64_t rx_missed_errors; - - uint64_t tx_aborted_errors; - uint64_t tx_carrier_errors; - uint64_t tx_fifo_errors; - uint64_t tx_heartbeat_errors; - uint64_t tx_window_errors; - - uint64_t rx_compressed; - uint64_t tx_compressed; -}; - /* Linux 3.19 introduced virtio_types.h. It might be missing * if we are using old kernel. */ #ifndef HAVE_VIRTIO_TYPES @@ -6784,6 +6744,9 @@ netdev_stats_from_rtnl_link_stats64(struct netdev_stats *dst, int get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats) { + struct rtnetlink_change change = {0}; + struct rtnl_link_stats64 _stats64; + struct rtnl_link_stats _stats; struct ofpbuf request; struct ofpbuf *reply; int error; @@ -6803,35 +6766,24 @@ get_stats_via_netlink(const struct netdev *netdev_, struct netdev_stats *stats) return error; } - if (ofpbuf_try_pull(reply, NLMSG_HDRLEN + sizeof(struct ifinfomsg))) { - const struct nlattr *a = nl_attr_find(reply, 0, IFLA_STATS64); - if (a && nl_attr_get_size(a) >= sizeof(struct rtnl_link_stats64)) { - const struct rtnl_link_stats64 *lstats = nl_attr_get(a); - struct rtnl_link_stats64 aligned_lstats; - - if (!IS_PTR_ALIGNED(lstats)) { - memcpy(&aligned_lstats, (void *) lstats, - sizeof aligned_lstats); - lstats = &aligned_lstats; - } - netdev_stats_from_rtnl_link_stats64(stats, lstats); + change.stats = &_stats; + change.stats64 = &_stats64; + if (rtnetlink_parse(reply, &change)) { + if (change.stats_present == RTNL_LINK_STATS64) { + netdev_stats_from_rtnl_link_stats64(stats, &_stats64); + error = 0; + } else if (change.stats_present == RTNL_LINK_STATS) { + netdev_stats_from_rtnl_link_stats(stats, &_stats); error = 0; } else { - a = nl_attr_find(reply, 0, IFLA_STATS); - if (a && nl_attr_get_size(a) >= sizeof(struct rtnl_link_stats)) { - netdev_stats_from_rtnl_link_stats(stats, nl_attr_get(a)); - error = 0; - } else { - VLOG_WARN_RL(&rl, "RTM_GETLINK reply lacks stats"); - error = EPROTO; - } + VLOG_WARN_RL(&rl, "RTM_GETLINK reply lacks stats"); + error = EPROTO; } } else { - VLOG_WARN_RL(&rl, "short RTM_GETLINK reply"); + VLOG_WARN_RL(&rl, "invalid RTM_GETLINK reply"); error = EPROTO; } - ofpbuf_delete(reply); return error; } @@ -6916,7 +6868,7 @@ netdev_linux_update_via_netlink(struct netdev_linux *netdev) { struct ofpbuf request; struct ofpbuf *reply; - struct rtnetlink_change chg; + struct rtnetlink_change chg = {0}; struct rtnetlink_change *change = &chg; int error; diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c index 4ae050ff0..b65b80016 100644 --- a/lib/rtnetlink.c +++ b/lib/rtnetlink.c @@ -91,6 +91,7 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) change->irrelevant = false; change->nsid = NETNSID_UNSET; + change->stats_present = RTNL_LINK_NO_STATS; if (rtnetlink_type_is_rtnlgrp_link(nlmsg->nlmsg_type)) { /* Policy for RTNLGRP_LINK messages. @@ -104,6 +105,8 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) [IFLA_ADDRESS] = { .type = NL_A_UNSPEC, .optional = true }, [IFLA_LINKINFO] = { .type = NL_A_NESTED, .optional = true }, [IFLA_WIRELESS] = { .type = NL_A_UNSPEC, .optional = true }, + [IFLA_STATS] = { .type = NL_A_UNSPEC, .optional = true }, + [IFLA_STATS64] = { .type = NL_A_UNSPEC, .optional = true }, }; struct nlattr *attrs[ARRAY_SIZE(policy)]; @@ -159,6 +162,19 @@ rtnetlink_parse(struct ofpbuf *buf, struct rtnetlink_change *change) change->primary = NULL; change->sub = NULL; } + + if (change->stats64 && attrs[IFLA_STATS64] && + nl_attr_get_size(attrs[IFLA_STATS64]) >= + sizeof *change->stats64) { + memcpy(change->stats64, nl_attr_get(attrs[IFLA_STATS64]), + sizeof *change->stats64); + change->stats_present = RTNL_LINK_STATS64; + } else if (change->stats && attrs[IFLA_STATS] && + nl_attr_get_size(attrs[IFLA_STATS]) >= sizeof *change->stats) { + memcpy(change->stats, nl_attr_get(attrs[IFLA_STATS]), + sizeof *change->stats); + change->stats_present = RTNL_LINK_STATS; + } } } else if (rtnetlink_type_is_rtnlgrp_addr(nlmsg->nlmsg_type)) { /* Policy for RTNLGRP_IPV4_IFADDR/RTNLGRP_IPV6_IFADDR messages. diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h index f0b49bf1a..357578e3b 100644 --- a/lib/rtnetlink.h +++ b/lib/rtnetlink.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "openvswitch/types.h" @@ -29,6 +30,46 @@ struct nln_notifier; /* These functions are Linux specific, so they should be used directly only by * Linux-specific code. */ +/* Linux 2.6.35 introduced IFLA_STATS64 and rtnl_link_stats64. + * + * Tests for rtnl_link_stats64 don't seem to consistently work, e.g. on + * 2.6.32-431.29.2.el6.x86_64 (see report at + * https://mail.openvswitch.org/pipermail/ovs-dev/2014-October/291521.html). + * Maybe if_link.h is not self-contained on those kernels. It is easiest to + * unconditionally define a replacement. */ +#ifndef IFLA_STATS64 +#define IFLA_STATS64 23 +#endif +#define rtnl_link_stats64 rpl_rtnl_link_stats64 +struct rtnl_link_stats64 { + uint64_t rx_packets; + uint64_t tx_packets; + uint64_t rx_bytes; + uint64_t tx_bytes; + uint64_t rx_errors; + uint64_t tx_errors; + uint64_t rx_dropped; + uint64_t tx_dropped; + uint64_t multicast; + uint64_t collisions; + + uint64_t rx_length_errors; + uint64_t rx_over_errors; + uint64_t rx_crc_errors; + uint64_t rx_frame_errors; + uint64_t rx_fifo_errors; + uint64_t rx_missed_errors; + + uint64_t tx_aborted_errors; + uint64_t tx_carrier_errors; + uint64_t tx_fifo_errors; + uint64_t tx_heartbeat_errors; + uint64_t tx_window_errors; + + uint64_t rx_compressed; + uint64_t tx_compressed; +}; + /* A digested version of an rtnetlink_link message sent down by the kernel to * indicate that a network device's status (link or address) has been changed. */ @@ -57,6 +98,15 @@ struct rtnetlink_change { /* Link bonding info. */ const char *primary; /* Kind of primary (NULL if not primary). */ const char *sub; /* Kind of subordinate (NULL if not sub). */ + + struct rtnl_link_stats64 *stats64; /* Optional storage for IFLA_STATS64. */ + struct rtnl_link_stats *stats; /* Optional storage for IFLA_STATS. */ + enum { + RTNL_LINK_NO_STATS = 0, + RTNL_LINK_STATS64, + RTNL_LINK_STATS, + } stats_present; /* Flag indicating what kind of stats + where present in the message. */ }; /* Function called to report that a netdev has changed. 'change' describes the From patchwork Wed Mar 11 06:05:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208879 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=E7JPa32o; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0cH33GVz1xy3 for ; Wed, 11 Mar 2026 17:06:07 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 74C0F84219; Wed, 11 Mar 2026 06:06:04 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id UIomwiANjaNh; Wed, 11 Mar 2026 06:06:03 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 5BDF1842A3 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=E7JPa32o Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 5BDF1842A3; Wed, 11 Mar 2026 06:06:03 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 43320C1366; Wed, 11 Mar 2026 06:06:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 02351C003D for ; Wed, 11 Mar 2026 06:06:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 01F8961625 for ; Wed, 11 Mar 2026 06:05:55 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id fdn4Lr6nZDdo for ; Wed, 11 Mar 2026 06:05:54 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.133.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org C280C6161E Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org C280C6161E Authentication-Results: smtp3.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=E7JPa32o Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp3.osuosl.org (Postfix) with ESMTPS id C280C6161E for ; Wed, 11 Mar 2026 06:05:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209152; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qn12ODHPVMq8Nm8pa0nDL6kIFsr6zreSYZpJifMVKrM=; b=E7JPa32oYr09OFShbnT59bcZKjtPJdPsYKvfQzYMfwuK8b2ZB5ZRtvcauAagdZIn3VbhvV 51rMZIypadXUtWRhzODBVUrMR4CbI86KpJ9LJ5u5LP9xXpzdKQbiJoIaMvV6ur7rDspawp fbEuCstQI3RR1esYmE5aHo2y87mwGoA= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-180-w5s9_tuhPdeBcWgFHjefgQ-1; Wed, 11 Mar 2026 02:05:51 -0400 X-MC-Unique: w5s9_tuhPdeBcWgFHjefgQ-1 X-Mimecast-MFC-AGG-ID: w5s9_tuhPdeBcWgFHjefgQ_1773209150 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9BC601956066 for ; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7D2151800107; Wed, 11 Mar 2026 06:05:49 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:25 +0100 Message-ID: <20260311060533.52598-8-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: XdiYpmWQd5yOoFlDgCbE6RO6mXkJuorgKobAc7L6-aM_1773209150 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 7/8] linux-netdev: Check status when reading stats. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" 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 --- 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 bf247478e..fd9110848 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -817,6 +817,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; +} + static void netdev_linux_changed(struct netdev_linux *dev, unsigned int ifi_flags, unsigned int mask) @@ -2281,7 +2312,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; @@ -2320,7 +2351,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; @@ -6742,7 +6773,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; @@ -6759,7 +6792,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) { @@ -6779,6 +6812,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; From patchwork Wed Mar 11 06:05:26 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Adri=C3=A1n_Moreno?= X-Patchwork-Id: 2208883 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Tu85xUxf; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::133; helo=smtp2.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4fW0dK3Kp8z1xy3 for ; Wed, 11 Mar 2026 17:07:01 +1100 (AEDT) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 18337411EE; Wed, 11 Mar 2026 06:07:00 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id ubcVW_AFy5hc; Wed, 11 Mar 2026 06:06:59 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 351C241384 Authentication-Results: smtp2.osuosl.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Tu85xUxf Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp2.osuosl.org (Postfix) with ESMTPS id 351C241384; Wed, 11 Mar 2026 06:06:59 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0AECAC0070; Wed, 11 Mar 2026 06:06:59 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 04AD6C003D for ; Wed, 11 Mar 2026 06:06:58 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 7FB3D421F2 for ; Wed, 11 Mar 2026 06:06:07 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id nqMLDrZg80_k for ; Wed, 11 Mar 2026 06:06:06 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=170.10.129.124; helo=us-smtp-delivery-124.mimecast.com; envelope-from=amorenoz@redhat.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org ECC854209E Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org ECC854209E Authentication-Results: smtp4.osuosl.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Tu85xUxf Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id ECC854209E for ; Wed, 11 Mar 2026 06:05:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773209154; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=d1L2oR+pVSxqKLtGXWKVl+Cfe5rBq5/z5ksOWYVLkso=; b=Tu85xUxfvJ4QV93QnBprAPUNWBwEkAsdIJlSvJwZ8X3kPLwQ4X6VuxIqU5Nv7IJiQC6RdY PtjiurYdpP7fpz5zZLhvhke5QRytPspDkoEdUPe0b9G/+lC4UaU8Xj3Mjsqf2ci6/ddmy1 ttPoWrJZvLpZZbSEd08as0Ezb7hjSMc= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-503-OfLZ7oxtN_KTLdQAmAyy6Q-1; Wed, 11 Mar 2026 02:05:53 -0400 X-MC-Unique: OfLZ7oxtN_KTLdQAmAyy6Q-1 X-Mimecast-MFC-AGG-ID: OfLZ7oxtN_KTLdQAmAyy6Q_1773209152 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 56A16180047F for ; Wed, 11 Mar 2026 06:05:52 +0000 (UTC) Received: from antares.redhat.com (unknown [10.45.224.13]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 29D601800107; Wed, 11 Mar 2026 06:05:50 +0000 (UTC) To: dev@openvswitch.org Date: Wed, 11 Mar 2026 07:05:26 +0100 Message-ID: <20260311060533.52598-9-amorenoz@redhat.com> In-Reply-To: <20260311060533.52598-1-amorenoz@redhat.com> References: <20260311060533.52598-1-amorenoz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: TUv6WQlpQUM0IVVsaKdmj9AsQfTHjAJw7cKUEHr3mrM_1773209152 X-Mimecast-Originator: redhat.com Subject: [ovs-dev] [PATCH v2 8/8] netdev-linux: Consolidate netlink updates. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adrian Moreno via dev From: =?utf-8?q?Adri=C3=A1n_Moreno?= Reply-To: Adrian Moreno Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Updating the netdev's information on demand or via stats is pretty much the same thing. Remove duplicated code. Signed-off-by: Adrian Moreno --- lib/netdev-linux.c | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index fd9110848..5b74825e9 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -6905,6 +6905,7 @@ get_ifindex(const struct netdev *netdev_, int *ifindexp) static int netdev_linux_update_via_netlink(struct netdev_linux *netdev) + OVS_REQUIRES(netdev->mutex) { struct ofpbuf request; struct ofpbuf *reply; @@ -6938,44 +6939,8 @@ netdev_linux_update_via_netlink(struct netdev_linux *netdev) if (rtnetlink_parse(reply, change) && !change->irrelevant && change->nlmsg_type == RTM_NEWLINK) { - bool changed = false; - error = 0; - - /* Update netdev from rtnl msg and increment its seq if needed. */ - if ((change->ifi_flags ^ netdev->ifi_flags) & IFF_RUNNING) { - netdev->carrier_resets++; - changed = true; - } - if (change->ifi_flags != netdev->ifi_flags) { - netdev->ifi_flags = change->ifi_flags; - changed = true; - } - netdev->cache_valid |= VALID_FLAGS; - - if (change->mtu && change->mtu != netdev->mtu) { - netdev->mtu = change->mtu; - netdev->cache_valid |= VALID_MTU; - netdev->netdev_mtu_error = 0; - changed = true; - } - if (!eth_addr_is_zero(change->mac) - && !eth_addr_equals(change->mac, netdev->etheraddr)) { - netdev->etheraddr = change->mac; - netdev->cache_valid |= VALID_ETHERADDR; - netdev->ether_addr_error = 0; - changed = true; - } - if (change->if_index != netdev->ifindex) { - netdev->ifindex = change->if_index; - netdev->cache_valid |= VALID_IFINDEX; - netdev->get_ifindex_error = 0; - changed = true; - } - if (change->primary && netdev_linux_kind_is_lag(change->primary)) { - netdev->is_lag_primary = true; - } - if (changed) { - netdev_change_seq_changed(&netdev->up); + if (!netdev_linux_check(netdev, change)) { + netdev_linux_update__(netdev, change); } } else { error = EINVAL;