From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 262824C651E for ; Wed, 14 Oct 2026 12:40:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981604; cv=none; b=DtkXag4gI39JkTZYmr8aJ28dU129hxQQDTJFPo02yNJDB2BvBpMW+Mbp7XENwBiy9KAbYXbYXg3Kzxr+Y28Yo0L4cGJysQZODL/NoYOTyKTr0NMryXtEd5NE6gqdsqz6tGnKxcLgJrtgg8dtueEBZmCeLINXtpTE0SK7WY7bays= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981604; c=relaxed/simple; bh=rkcA+Jt2EHcsgiHO2SpiPIETk+jNu8tDWoLY60yV/b4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BPatkkzkK16WqPrzk6O7ilJ8QAh3JCgG5SJFBFiZI4owDdvu9ToeIi+YZqvlJdjjKKYf9ISDCNbqW41on38w29YRQ8lbcHT8IlEVw/MaVr3K5e/XvxHNft5Oc4iWkJt3/5vp669Zdl1pT0fbPoiHlzlEEjOfB1UVSH72xjER31g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=J/S8zjyz; arc=none smtp.client-ip=209.85.128.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J/S8zjyz" Received: by mail-wm1-f48.google.com with SMTP id 5b1f17b1804b1-4a0213948d3so24970365e9.2 for ; Wed, 14 Oct 2026 05:40:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981599; x=1792586399; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=eJnBLC+e56rl7jB9mQI+MGWyd+9ndujkrii0QT8LXII=; b=J/S8zjyzSHqD+QUMuSwI4bg80znCuKw/wO1qF/6WwCniqaUAiwSGjtFeI0r+ESFIvo miL7SbRhpwZmFK1Z5U1Xfl3NEg/QRnv50byOVsPyxlF6HcNWbrbf6xZBwaOB8HHvIYKr d9KSS1sRaGHrHSrUyLSebXrGMoK+1VpLvhG7KWZMPK1t/TfYBTYxzhf3USs3+o5Bf7Py 6NuA9vGmSeWJlKnqsAqvD3wboxXwTar/0gI/IJTtL7K4iJ+hVq7o07e8CPAuvrc64yKZ kINzZQSXtNqo5Z8TLpyZzGivUrYVm2okSpXAJ3xYumVsMB4nTwZiyOlAecIM8n5B3v8s ViDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981599; x=1792586399; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=eJnBLC+e56rl7jB9mQI+MGWyd+9ndujkrii0QT8LXII=; b=luZTnAYk0u34zpex7P3p0PTKKmpHiabNHOsHccw5w+Lz/W1L7PApZRaQUbkCI3KfuY Yd0RKvQeMiJVaPCde1+NAAdHm7qcOacw4ibmA71ZAeE3XZOobPv0zTsyteCyPn0bZSTE vdp5V+okaJeCqDczVNrl6zkJetqNdpUw5RpXeH2wAq7/J6YhqlQkO2B7gIj3QfPtKayz 01fVGKGxj3DHLLVtbkxYDsDo8L4FpdCsmu1BLGvWbIF+S5asqD/3nSHFxmGOkGyExgql YkDaXUy6fFmGgW8q4YRbMsqpsWwZAIuWvvds/YS+CCOnQlUEAny8rsUAQk8m3+IB6EPf jP6A== X-Forwarded-Encrypted: i=1; AKwUvBw6pb3aBdHGNEKgJyz5FlgbyyXzC8C4k2sjixrrvengQOnTjmnh3g6KvlAgKi7wjOsdIYUKihWOj10ZdkI=@vger.kernel.org X-Gm-Message-State: AFq9FYJfUn1MdqEW5KumlZjW8hLFYlG31GF0hvdPfKSYmQT/uUQJTpLd NZCcyuxFgVyfXp+NiMUXVvsnBCiMU+vR8oGsoajI/te2IIg/cHacbHGp X-Gm-Gg: AYBFou2daEwnN7I4n9Q4j3+yrFg1y0VOW0AhOH/bfkRmzfQEImvwzoIWn0FESec49Af uKk+N0GkzKLuHAPKwYwrjToicka9EeQ88jCaKtz87lcvyWoHTptdJtppqhUftL8PKGMKYtbn4F2 lrBtKigmluhNk/SktE6wN+6QrmSVZVXl9Y6436zux8/7uh9whbr2T0ccxWxE6VtnPA8Vwc4/Je8 lbL6wY6Z6lqihdOVi5rhEnAOGFMSI33djpFCZa4+yFkBYLvHwW02RaHPiFcLHXa2Ri0oR6UQ5W4 hf/lLTbMBtZEJClmltG/xlaF8+LLVyrEruQpo9bXhMOotYFd6/LdGfUzRn3LdmBSzD/LP2yRu7/ 9Xqxcosryl2/AL5LCr4IX1tMVg0QF8bVswz7rZWU05VSKEWGkCL4KDaxsaNJDBsIVkl4FernfLz tLowIBjoBk5MhLNulp2Uo3Cd5bqMhABTbaBRRfJfdO4dp+lHrE6O6ku+wUogFRhkKHKj2hIrcbn g== X-Received: by 2002:a05:600c:83c6:b0:4a1:7093:40c7 with SMTP id 5b1f17b1804b1-4a18e493048mr286173745e9.8.1791981599094; Wed, 14 Oct 2026 05:39:59 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.39.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:39:58 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 1/7] vxlan: vnifilter: validate the VXLAN_VNIFILTER_ENTRY nest Date: Wed, 14 Oct 2026 15:38:08 +0300 Message-ID: <20261014123814.388557-2-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" vxlan_vnifilter_process() parses the message with vni_filter_policy, whose VXLAN_VNIFILTER_ENTRY is a bare NLA_NESTED with no nested policy attached. The entry attributes are therefore validated only later, one entry at a time, by the nla_parse_nested() inside vxlan_process_vni_filter(). Entries are parsed as they are dispatched: in a message whose first entry is valid and whose second is not, the first entry is applied and its RTM_NEWTUNNEL notification sent before the second is rejected. Link the nest to vni_filter_entry_policy with NLA_POLICY_NESTED() so every entry is checked against the entry policy up front, before any entry is acted on. A message whose entry the policy rejects -- a malformed attribute, or, with the next patch, an out-of-range endpoint -- is now refused as a unit and installs nothing. Faults the policy does not cover, such as a device or handler error raised on a later entry, are unchanged: entries are still dispatched and applied one at a time. This reorders two faults. The nest is validated before the device is looked up and before the vnifilter flag is checked, so a request rejected by the entry policy, aimed at a missing or non-vnifilter device, now returns that policy error where it previously returned -ENODEV or -EOPNOTSUPP. The request was invalid either way; only the errno an operator sees changes. The nla_parse_nested() in vxlan_process_vni_filter() stays: it is what fills the per-entry attribute table the handler reads. It can no longer fail on a message that has reached it. Suggested-by: Jakub Kicinski Link: https://lore.kernel.org/netdev/20260921150904.65a704eb@kernel.org/ Assisted-by: LLM Signed-off-by: Ali Firas --- v4: scope the "rejected as a unit" claim to policy-rejected entries; rebased onto net-next. drivers/net/vxlan/vxlan_vnifilter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_= vnifilter.c index 41095096b698..124ba47758e9 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -499,7 +499,7 @@ static const struct nla_policy vni_filter_entry_policy[= VXLAN_VNIFILTER_ENTRY_MAX }; =20 static const struct nla_policy vni_filter_policy[VXLAN_VNIFILTER_MAX + 1] = =3D { - [VXLAN_VNIFILTER_ENTRY] =3D { .type =3D NLA_NESTED }, + [VXLAN_VNIFILTER_ENTRY] =3D NLA_POLICY_NESTED(vni_filter_entry_policy), }; =20 bool vxlan_vnifilter_has_multicast(const struct vxlan_dev *vxlan) base-commit: 05b5019b01fb9443b09ae4ed34af1135a80a84c8 --=20 2.53.0 From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C73554E50B1 for ; Wed, 14 Oct 2026 12:40:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981605; cv=none; b=NvBZHvMdarP7bjlauc766fsBnMCcX13Z46ec/5nCLK83KiLbn1tSwTVvLVeTvl2q5jesL9piUwuLM6UI79Qodk/8uzIAUzDrLvwRvgkI9poCKEep7VVKZU9n2+xtT47dhXsXbTau1ZJkPIOlW7TD1i+nhVZ1PPIEIAGtMRQfxVo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981605; c=relaxed/simple; bh=Ksp4EgliF7QzcdXzGDFAVUiL11TloA7f+lfEnZXBD2s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q8kiBI9zZEnO1T+F8x7mOOiQidXsp+DYRmLH893rk9KvjIHHNMRaaAe8GNyNA5bZIJw+x1veVmShWsvSaJPlmdbOzeDgzaZwwQuFOr6QOu0mDSK2sBaRVTLoWsc2UyT4i2OY8McgcJyOUJex0zuEPYObyDD6EIe1I2I8tddqnQg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=fkR+McFU; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fkR+McFU" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4a01933b584so35758015e9.0 for ; Wed, 14 Oct 2026 05:40:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981602; x=1792586402; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hXNpyqm5jy+6hjKyKFpoJe12RqunxSVKiBFsjy58fn0=; b=fkR+McFUqxCMgh/LtJQdKB5dtMWul3fmc9y1nbPzTFnGvO2a0wepY9DtguRNkvUQqh qvCWiCfYemdwB/yZ0FMxZ34CRZX/fEulp4wm20wURv7v8pSP1ifnylx5HIRj8cvQXx5W B++2Ta/yc4kFlbUz7WKYaccuf4rEtASR5n9lGkY2sjPvnY6bcXVaR0+J38GMZ6ye5Bbf rFO+1je63hWWw11IJe+p/LGP30gYvNOTMmsdf1UjXUqeF+XJEI73z6BGL8XtW22dhKds t+0u+xQ+OnvgHqRo+dWLEALmeK51KHgT54UpaAGziLWuBfmxHpJ92E5qrfsaO9ErflqC PWuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981602; x=1792586402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=hXNpyqm5jy+6hjKyKFpoJe12RqunxSVKiBFsjy58fn0=; b=zMFvzfogin5zggdJz1QS9GaGXDB8BAyFiwk4D+mAJFzwAQeOG4xlCbUFGcNJiVgDlr YRuL//D/jcEOU+E4onrC8KdP48aJSFlZQOZmEd2Jx4nGz9/8FG6A34JcBiqQkNb00L/d ofhGILynjQ/U1muGqYhA3f/9MTSbaT+0WCM+JtqTlAwyITj0db27zGnb3WDACdkbo1uF duTVlMkswkuBRCgOnEjfX6H+/0zAZdjcNs+6I5xzm1zbpm3m77Net8fIFEL/mUWwWaT8 jFAvdL4RnksFKCJFB6b6kyrSgscdFwRcGggOcgYdS8rkzf3OG2NH/l1KYdY1P1nOZVzV bgWw== X-Forwarded-Encrypted: i=1; AKwUvBy23IbOqBdVkySfwbxF61uF2IsCEx61AeNbzgnC0EplSLRNAsFcDGawUxRyYH9ydy392YAB6ovvvtCctW4=@vger.kernel.org X-Gm-Message-State: AFq9FYLgPV4XWfgfAC3SD4CQAp7oMmz8w4wM70qN3sl2pgf97FGS0GYP 5PD3El65/ue/7aqNJ1QJ4xl4mFmLNeFJnC5sH8/WXBc4rJnDiD8fLZ5O X-Gm-Gg: AYBFou2IpTTf7beWqXwWoruI3fV9TGUpHHMwOdVwnNU8GFQlsm9KGUX/Mkm492AYGGT 177nSN5zgxUVq8yCn3Euq7RDSRIOCaJCGE9z8wYrEgBnSwtVfeFJ/nShTswwGksVugvFLLl+Sj0 WNIBOR4EECS3SiCwMnUXJilk7PrsXVL8VI5UzkgLnfzXIvemd1QC/UmRYjDpvtnzs5GNBIi7Dle sNlADVzwQ/A4l802f9ogtgMYDYuW7MZPaL8rzS7eCNaW3sMdIM2L01BaehsaOGfyMIHZTdgRAV+ xmpmT3VudRwWawtMKTLVqyXDhjaKjmovg9kSpidLKhOQkfNYPkvdbT19n9IH02+xbgPo0lvEeZt pSEGMNeAj52CQ2NF6HGPAw/N1Auk+G8QmkR5n+2JEmuV/w95uEULLMBKLuI5HPhQSm0zCoeAX3c /UeRZg/W4bQmR7yYpMK7bjkybwl/d7VSHsiTAXtLRX8BlDCMoiqtoXVI2IpsjAZ59WVjpjUmLtb Q== X-Received: by 2002:a05:600c:c113:b0:4a1:985b:83a9 with SMTP id 5b1f17b1804b1-4a1985b87f5mr174078275e9.4.1791981601878; Wed, 14 Oct 2026 05:40:01 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.39.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:40:01 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 2/7] vxlan: vnifilter: reject VNIs outside the 24-bit space Date: Wed, 14 Oct 2026 15:38:09 +0300 Message-ID: <20261014123814.388557-3-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" VXLAN_VNIFILTER_ENTRY_START and VXLAN_VNIFILTER_ENTRY_END are bare NLA_U32, so neither is bounded before vxlan_process_vni_filter() hands them to vxlan_vni_add_del(): int v, err =3D 0; ... for (v =3D start_vni; v <=3D end_vni; v++) v is int and end_vni is __u32, so the comparison is done unsigned. A request carrying only START=3D0xffffffff has vni_start =3D=3D vni_end =3D= =3D 0xffffffff and looks like a single VNI; v is then -1, the comparison promotes it to 0xffffffff and passes, v++ makes v 0, and the loop walks the space upwards from there, creating a VNI node and a per-CPU stats block per iteration under rtnl_lock. Any range ending at 0xffffffff behaves the same way. Separately, a VNI at or above VXLAN_N_VID is accepted and stored even though the VXLAN header carries only 24 bits: vxlan_vni_field() shifts without masking, so such an entry keeps its own rhashtable slot while being truncated on the wire. Range-validate both attributes against the 24-bit space, as vxlan_mdb.c already does for its own VNI attributes. With the nest now linked to this policy, an out-of-range endpoint is rejected during netlink policy validation, before vxlan_process_vni_filter() runs and before anything is allocated. How many VNIs a single in-range request may span is a separate question, bounded by the next patch; that limit is not a policy check and does run in the handler. Make the loop counter u32 as well. With the range bounded it is no longer what keeps the loop finite, but it drops the undefined signed overflow past INT_MAX and matches the u32 vni that vxlan_vni_add() and vxlan_vni_del() already take. Assisted-by: LLM Signed-off-by: Ali Firas --- v4: no functional change; rebased onto net-next. drivers/net/vxlan/vxlan_vnifilter.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_= vnifilter.c index 124ba47758e9..9e15f4de75c9 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -491,9 +491,15 @@ static int vxlan_vnifilter_dump(struct sk_buff *skb, s= truct netlink_callback *cb return err; } =20 +static const struct netlink_range_validation vni_filter_vni_range =3D { + .max =3D VXLAN_N_VID - 1, +}; + static const struct nla_policy vni_filter_entry_policy[VXLAN_VNIFILTER_ENT= RY_MAX + 1] =3D { - [VXLAN_VNIFILTER_ENTRY_START] =3D { .type =3D NLA_U32 }, - [VXLAN_VNIFILTER_ENTRY_END] =3D { .type =3D NLA_U32 }, + [VXLAN_VNIFILTER_ENTRY_START] =3D NLA_POLICY_FULL_RANGE(NLA_U32, + &vni_filter_vni_range), + [VXLAN_VNIFILTER_ENTRY_END] =3D NLA_POLICY_FULL_RANGE(NLA_U32, + &vni_filter_vni_range), [VXLAN_VNIFILTER_ENTRY_GROUP] =3D NLA_POLICY_EXACT_LEN(sizeof_field(struc= t iphdr, daddr)), [VXLAN_VNIFILTER_ENTRY_GROUP6] =3D NLA_POLICY_EXACT_LEN(sizeof(struct in6= _addr)), }; @@ -914,7 +920,8 @@ static int vxlan_vni_add_del(struct vxlan_dev *vxlan, _= _u32 start_vni, int cmd, struct netlink_ext_ack *extack) { struct vxlan_vni_group *vg; - int v, err =3D 0; + int err =3D 0; + u32 v; =20 vg =3D rtnl_dereference(vxlan->vnigrp); =20 --=20 2.53.0 From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A35A4E80BF for ; Wed, 14 Oct 2026 12:40:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981608; cv=none; b=YjUdoJTBQhD6DBcjCb7INPdK8kC70kpE7O2ANP1+0B2E6xzwnV+CGR3wmkNiRkJQGaiF05LU2hwwy3aYzfMTdT4QTpzOoO/dRwP8H7aySyEvh4lf+daFEHJwuurFv9mnyc+8m68+1CDtXdq2TAcdYYCdSdSOhks8BV6ttprvSp8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981608; c=relaxed/simple; bh=4Piv2CI9sadBoT7rMKzK0vTXaF/jRiPd6olpiWlGh6A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qjYRxvafhMELTlBZrpTiomy0o69+vw78qeacAuLlTaBAk2KMhUzL+db6CenlOVAlSjj7iKALjWl7ljIGJrIL3rYO/42bjrcuxv6hYj5n8ZfPF9SRAF2irl4fwykoEg47BXK0XakfRcxzqtonGGI89U6uUBVS/277y0uIT0j6DHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=JukPAsZG; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="JukPAsZG" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-4a16af2a232so32143595e9.1 for ; Wed, 14 Oct 2026 05:40:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981605; x=1792586405; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=IKmAPboELViMedd9OF97VZ6G4NUnBVl906J/PIlmbd8=; b=JukPAsZGT0OhYoK3/iTRzP9/oHOEzZmGEpKNJb4y2boP6IOu9Lfxgvc2vTF6m7gJY8 xZueKByIsplIRgLGMPmo8bGgwcxm6pA55RMUh4RBHVWKoDwfSiSa5lu+8sq1gQw3LYp5 WdwoY6Fz61Ise4CB0sJ3G4GyFniNwi9ObHKjeb0yrPOQcbe4bP4oJkxmaGbeMtVqGQDd knpDvlxke7EPzbtTm2FpdgVNPCJFAgMJcvO571AkylI+8bMhWJmTcCCX5y0VOMomUYW+ mbMzs6VTUzYdz/fQaZfj22FsStoynVLYptaozt7QaRQ6Ok5Q6D3ecOwYNjd2iS8UfBGa rn/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981605; x=1792586405; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=IKmAPboELViMedd9OF97VZ6G4NUnBVl906J/PIlmbd8=; b=yFKoRZqk3ZJ0IzSLHLnNUmFZYfWbeLXAWxkqzksKO3ox6olgxG8FkeGu1G9ldnonl4 AO5YfmX0hNQIE1ggWA6I0fLaFtmkZGZXBVF5HX+kDVPtc36qvoJXkzLx6uiZRfH5CpTR plEJAH37E6eTDkQWff57dNQNbZQcvHr+wVihZmc53pmRaPpYDi3nhwgY7Ej9FekwTDG+ 2z5PrP7QzwTm785ua3cfLJ0Ll1MfvP0xVu7j3iY1xB/C+lYIvwc064uH2ojYWbFqKj+S IdJvHx5NCXUiXA76boGZQhm72mno8uwAzebQZeMN/YTa7iZP1K8l4BTDx+ILFHsiAXr/ eHiA== X-Forwarded-Encrypted: i=1; AKwUvByYMm3U5VriAYDPZQ7bBaJOpR5naHtjJ8iwY24aO3RQv8+M/rAtnBLIWFEHlakbtH9gMk51zOn8VwYbvtQ=@vger.kernel.org X-Gm-Message-State: AFq9FYLMogCK75qifIV2JCgcHLZUT5aQROLamnZTtRn7Z6a20wOE1ZCC I9L+kdgqYU8AkRMu4GktOJFbmd/PVmvBgyj0OuUxPhvYJJE/kKiL2jYN X-Gm-Gg: AYBFou3SAovK7qwt/qZeoIK05y3H1T4OmqH7Msx3NR/aD2CXZ3eVvBrNVajhfQXDs7C RA4K70TZQF472dGM1LV3Xqt49OlRKMf0uYfWUbsWW8MnX3Ji29DC62DljCq1+LU5HHReE/34aG0 ZVMeotQ5CWagIq5v+KzAogg/bU9PaRDnI18JmxsKM1BmF4iKvsmiNbwDej4AroGLFMVdoHc2OYo SmIuFPWEoZt+EgD51FwyiUvnKi8Bp1ZNSEsEiC0fx2wp4zK+a4qsZa5kaacK7wlEfQfa3VeCSTm hg5gV0GZdAzJloMQ/fqI8f7IMbtiFLbbTZsyOvNiCLuD3VuFSbUEMRpgmdJzzQdXPR2pjSyIx3O BT+YR4/tHBsGoyA82sckvtSZBsN69K8LvI9c3S617ZPUU+/JOyrYcsF/ybi/H5QB90zI+J3WjfO Omsu8zqe0n9yo+a2BZ5DKxprxmhKToClYoPhG9ZG3cY6ZCFWO01O4nB/gzQGgFWCBr4FCIz12qV A== X-Received: by 2002:a05:600c:4e01:b0:49f:ce78:3567 with SMTP id 5b1f17b1804b1-4a18e4afc3amr300571905e9.24.1791981604576; Wed, 14 Oct 2026 05:40:04 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.40.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:40:04 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 3/7] vxlan: vnifilter: clamp the dumped VNI range to the request limit Date: Wed, 14 Oct 2026 15:38:10 +0300 Message-ID: <20261014123814.388557-4-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" vxlan_vnifilter_dump_dev() coalesces a contiguous run of VNIs sharing a remote into one VXLAN_VNIFILTER_ENTRY, and packs as many entries into a netlink message as the skb holds, with no bound on either. A later patch bounds a single request to VXLAN_VNI_FILTER_MSG_MAX VNIs summed over its entries; without a matching bound on the dump, a device holding more than that -- populated by several requests -- would dump a run, or a message, that the input path then refuses on replay. Introduce VXLAN_VNI_FILTER_MSG_MAX here and clamp the dump to it first, so the series never passes through a commit where the kernel reports a range its own input path rejects. Bound the two ways the dump can exceed the limit: - end a coalesced run once it reaches the limit, in the merge condition, even when the next VNI is contiguous and shares the remote; and - carry a per-message VNI budget, ending the message once its entries would sum past the limit, the same way the loop already ends it when the skb is full. cb->args[1] continues to count the VNI nodes already dumped and is advanced only when a completed entry is written, so the budget break and the skb-full break share one resume path; a run stays a gapless block, so the dump never drops a VNI and never emits one twice. Assisted-by: LLM Signed-off-by: Ali Firas --- v4: moved before the input cap; now introduces VXLAN_VNI_FILTER_MSG_MAX and adds a per-message VNI budget (v3 clamped per entry only), so the dump never emits a message the input path rejects. drivers/net/vxlan/vxlan_vnifilter.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_= vnifilter.c index 9e15f4de75c9..5beec29eb84a 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -17,6 +17,13 @@ =20 #include "vxlan_private.h" =20 +/* The dump coalesces a contiguous run of VNIs into entries, and packs ent= ries + * into netlink messages, of at most this many VNIs each, so every message= the + * dump emits stays within what the input path will accept on replay. A la= ter + * patch bounds a single RTM_NEWTUNNEL/RTM_DELTUNNEL request to the same n= umber. + */ +#define VXLAN_VNI_FILTER_MSG_MAX 4096 + static inline int vxlan_vni_cmp(struct rhashtable_compare_arg *arg, const void *ptr) { @@ -342,6 +349,7 @@ static int vxlan_vnifilter_dump_dev(const struct net_de= vice *dev, struct nlmsghdr *nlh; int idx =3D 0, s_idx; bool dump_stats; + u32 vnis =3D 0; int err =3D 0; =20 if (cb->args[2] !=3D dev->ifindex) { @@ -388,15 +396,29 @@ static int vxlan_vnifilter_dump_dev(const struct net_= device *dev, continue; } if (!dump_stats && vnirange(vend, v) =3D=3D 1 && + vnirange(vbegin, v) < VXLAN_VNI_FILTER_MSG_MAX && vxlan_addr_equal(&v->remote_ip, &vend->remote_ip)) { goto update_end; } else { + u32 sz =3D vnirange(vbegin, vend) + 1; + + /* End this message on its VNI budget the same way we + * end it when the skb is full, so a dumped message + * never sums to more VNIs than the input path accepts + * in one request. Resume re-emits this run as the + * first entry of the next message. + */ + if (vnis + sz > VXLAN_VNI_FILTER_MSG_MAX) { + err =3D -EMSGSIZE; + break; + } if (!vxlan_fill_vni_filter_entry(skb, vbegin, vend, dump_stats)) { err =3D -EMSGSIZE; break; } - idx +=3D vnirange(vbegin, vend) + 1; + vnis +=3D sz; + idx +=3D sz; vbegin =3D v; } update_end: @@ -404,7 +426,10 @@ static int vxlan_vnifilter_dump_dev(const struct net_d= evice *dev, } =20 if (!err && vbegin) { - if (!vxlan_fill_vni_filter_entry(skb, vbegin, vend, dump_stats)) + if (vnis + vnirange(vbegin, vend) + 1 > VXLAN_VNI_FILTER_MSG_MAX) + err =3D -EMSGSIZE; + else if (!vxlan_fill_vni_filter_entry(skb, vbegin, vend, + dump_stats)) err =3D -EMSGSIZE; } =20 --=20 2.53.0 From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63E1D4E9C03 for ; Wed, 14 Oct 2026 12:40:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981617; cv=none; b=ETYtEpbtEeea/mbScwcA7uGvMDNAfwAIvvv2FPEytvnLWStuYpYYEQLWJ3z6JsTSjQbCOeHx1Nhj/77e/lGc3DaVAm7PoXEj8AgLTWT8Vrf7b1iY+qd6fpwrvn2Bd0UPAlwkLNvEYVldp9eXAG2Us7fkEpBlRbkra1z/f4fr184= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981617; c=relaxed/simple; bh=xBZsWg657O0Kzvpg78Nn4idAJHQmNUGX/Dguk5wqE5I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OaSV/P3P2qswc08AXNH5ScBiqVeb5bGYFxRcRPnaS/l8zMjXJsvLw+xNrzUUMdYVwHHyqYlVq+2BOFsSzmRz055t7V9XalD0KNJf5IlUHv+F5wwCYOjKmSqXUbxggiv6TU1ynfn4u7f8UZDUC2rahVsdbyiTyk+9Zz6F2LvMDlM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=oTWTwB/P; arc=none smtp.client-ip=209.85.128.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oTWTwB/P" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-4a022fee0caso38102885e9.1 for ; Wed, 14 Oct 2026 05:40:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981607; x=1792586407; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=7j8lPCn9h1uuA3yPP/goaFyMU1vXNQ0kqv5qfig57c8=; b=oTWTwB/PphcFSQeYz+4CjijfFO7mTevKds5hwY9pTUDls4MIk87n2a4mlOfvwnmfQ1 sHbqjFnPptVawAXk72tUJBxucGi7IMOO5VRdHR/ufnDbdp5Nm+5sZwXxLi/x68Tecj5s 2F/yGvPIxStwasiwwrHSngiqIU/DRr+jCeQPEtv03hS9FjPIQ5eqJtfem6W7fiaOi6L9 jmuLlxSHYWUzQ24gBMUtc/tUyqPOEDOHEee3XMouFys2xPAyQezbX8muTxK+agijp+71 hZEUag6ofcFuXkwOwBXf49BcnRpz//p/cfmz/YOyxcijTKF7PAl5bZtGhsRFnUXTY2gc WRIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981607; x=1792586407; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=7j8lPCn9h1uuA3yPP/goaFyMU1vXNQ0kqv5qfig57c8=; b=ANQ4AIVAlfNMWpb4Yy/zLu9jKBNcxZudDF0Aon5CSAI/1EL9X1V0q+WAdoDoMo1EK0 RzVKYpLqyQ9jP1SiWf/wCsWFhesudxAEXKccj1yYBi7Fv8gEbzifj19AdR2Mo5ucqH/9 LbvyTgK9W8586/HfjrLCPcuu1WrVc3BibZCHLJMqf9/Wys84/qCtsmikfomZC+ytqeJg lOiU8PE6gMQI/Mvhm9ydSnl1vYhoZU7N2XDE1lcjHypZSIlMER/XucU2sz2OW7qbnsLH HtJ9mSDwY/rhlwb1NUccdsLYR/+Q9/W5DKY/guSwn4sadSKLnj1rB6HCcdQPGd72oGnw FwtA== X-Forwarded-Encrypted: i=1; AKwUvBzYBJ+oNkR3GbmcnzE3MlhsWtcDxRP8uJsYDXEAXJY8d+S8CxnwOC1CIy4e3+YwQZO4Z5xNoV0Ew13o/LI=@vger.kernel.org X-Gm-Message-State: AFq9FYJRX0Nf8kPD1oIONWRiCMWgA1TJegyJm2wL2X6ziHCwD9K/dPsJ 86ULqCTmGtXQFRgPI7BNGjG1iMNi3OYbYaCQ56JhqmZcnrIaAdFr4FR2 X-Gm-Gg: AYBFou1mbqNa1Id4Jo4y7sNA6xS7cqulX9UIzl0tEL+hwdrt7GDpaKNjJIIeddSsY9e P2+KQBHz560gyhdAqs1eIYH1Z0ZohUgVTT0J0YdcXEpZPNoE8tD7OoKcC/O7bKmbucHYx/+bMbr CLWuZSM7jhfDsCLhoH9G235I1aUXRW3Sm8zm7jDtQPKjE+G4sl7xS8zEtPdMZil/HD8FX13SVY2 QNCgqT1etRW9zX3t2nj+ITc+7bRXO3fGD1O9urBcbE90STtYl+0G7jzifx2T9Lc/OlLtpBT69jb KumjMMLk4aFPcma+Tq4EJLH6O0gTuV0nB65tfoO75TV0F8X67+jzK95Kped6KhptmnCUkrCwpnD W6sWSOEw8XKNAECU5SiBdJEZU5MhvQru68pUEtS3xE3rYDR126zNJpKa0A1RumSsrQDX1STMFnf 7lrV7+p3v/JXZfZrela74/nxxEdwG2xxzkbPiTfSPj0xdWBBDSE95RgBQVls1XS602OwfBGPfbA w== X-Received: by 2002:a05:600c:5493:b0:4a1:78da:d271 with SMTP id 5b1f17b1804b1-4a18e4ee976mr343394145e9.30.1791981607167; Wed, 14 Oct 2026 05:40:07 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.40.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:40:06 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 4/7] vxlan: vnifilter: bound the number of VNIs one request may touch Date: Wed, 14 Oct 2026 15:38:11 +0300 Message-ID: <20261014123814.388557-5-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A single RTM_NEWTUNNEL or RTM_DELTUNNEL message can ask for the whole 24-bit space in one range. vxlan_vni_add_del() then walks it one VNI at a time under rtnl_lock, holding the lock for the length of the walk. That walk is the cost being bounded, not the memory: an add allocates a VNI node and a per-CPU stats block per VNI, a delete creates neither, but both walk the same span and hold rtnl the same way, so both are bounded. The span of one VXLAN_VNIFILTER_ENTRY is not the quantity to bound. An entry carrying just START and END is 20 bytes on the wire and a message may carry many of them, vxlan_process_vni_filter() being called once per entry, so bounding each entry alone would still let one message ask for thousands of times the limit. Sum the spans of every entry and reject the message as a whole in vxlan_vnifilter_check_msg(), before the dispatch loop: entries are applied and notified one at a time, so a limit enforced during dispatch would return an error only after every preceding entry had been acted on. The range extraction is factored into vxlan_vni_filter_entry_range() so the count and the range later acted on cannot drift. The limit, VXLAN_VNI_FILTER_MSG_MAX (4096), is the one the preceding patch introduced for the dump; it follows the usable VLAN ID space, since vnifilter is mainly used on bridged devices where the VNI is derived from the VLAN. It bounds one request, not how many VNIs a device may hold: the whole space can still be installed in more than one request, and a device holding it is still torn down in one step by vxlan_vnigroup_uninit(), which is device teardown, not a netlink message, and is not subject to this cap. This is a policy narrowing of what a single message may ask for, not a fix for a crash or corruption, and is not a backport candidate. Suggested-by: Ido Schimmel Assisted-by: LLM Signed-off-by: Ali Firas --- v4: use the constant the dump patch introduces; rebased. drivers/net/vxlan/vxlan_vnifilter.c | 80 ++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_= vnifilter.c index 5beec29eb84a..2999dd536625 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -971,13 +971,79 @@ static int vxlan_vni_add_del(struct vxlan_dev *vxlan,= __u32 start_vni, return err; } =20 +/* Derive the VNI range one VXLAN_VNIFILTER_ENTRY selects. Shared so that = the + * count taken by vxlan_vnifilter_check_msg() cannot drift from the range + * vxlan_process_vni_filter() then acts on. + */ +static void vxlan_vni_filter_entry_range(struct nlattr **vattrs, u32 *vni_= start, + u32 *vni_end) +{ + *vni_start =3D 0; + *vni_end =3D 0; + + if (vattrs[VXLAN_VNIFILTER_ENTRY_START]) { + *vni_start =3D nla_get_u32(vattrs[VXLAN_VNIFILTER_ENTRY_START]); + *vni_end =3D *vni_start; + } + + if (vattrs[VXLAN_VNIFILTER_ENTRY_END]) + *vni_end =3D nla_get_u32(vattrs[VXLAN_VNIFILTER_ENTRY_END]); +} + +/* Reject a request touching more than VXLAN_VNI_FILTER_MSG_MAX VNIs befor= e any + * of its entries is acted on. Both add and delete walk the span one VNI a= t a + * time under rtnl_lock, so both are bounded. Entries are applied one at a= time + * and each one notifies as it goes, so a limit checked inside the dispatc= h loop + * would leave the entries ahead of the offending one already applied. + */ +static int vxlan_vnifilter_check_msg(const struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) +{ + struct nlattr *vattrs[VXLAN_VNIFILTER_ENTRY_MAX + 1]; + struct nlattr *attr; + u32 vnis =3D 0; + int err, rem; + + nlmsg_for_each_attr_type(attr, VXLAN_VNIFILTER_ENTRY, nlh, + sizeof(struct tunnel_msg), rem) { + u32 vni_start, vni_end; + + err =3D nla_parse_nested(vattrs, VXLAN_VNIFILTER_ENTRY_MAX, attr, + vni_filter_entry_policy, extack); + if (err) + return err; + + vxlan_vni_filter_entry_range(vattrs, &vni_start, &vni_end); + + /* A start above the end selects no VNI and costs nothing; + * leave it behaving as it does today. + */ + if (vni_end < vni_start) + continue; + + /* vni_filter_entry_policy has already bounded both endpoints + * below VXLAN_N_VID, so one entry adds at most VXLAN_N_VID and + * vnis cannot wrap before the test below rejects it. + */ + vnis +=3D vni_end - vni_start + 1; + if (vnis > VXLAN_VNI_FILTER_MSG_MAX) { + NL_SET_ERR_MSG_ATTR_FMT(extack, attr, + "Request asks for more than %u VNIs", + VXLAN_VNI_FILTER_MSG_MAX); + return -EINVAL; + } + } + + return 0; +} + static int vxlan_process_vni_filter(struct vxlan_dev *vxlan, struct nlattr *nlvnifilter, int cmd, struct netlink_ext_ack *extack) { struct nlattr *vattrs[VXLAN_VNIFILTER_ENTRY_MAX + 1]; const struct vxlan_config *cfg; - u32 vni_start =3D 0, vni_end =3D 0; + u32 vni_start, vni_end; union vxlan_addr group; int err; =20 @@ -988,13 +1054,7 @@ static int vxlan_process_vni_filter(struct vxlan_dev = *vxlan, if (err) return err; =20 - if (vattrs[VXLAN_VNIFILTER_ENTRY_START]) { - vni_start =3D nla_get_u32(vattrs[VXLAN_VNIFILTER_ENTRY_START]); - vni_end =3D vni_start; - } - - if (vattrs[VXLAN_VNIFILTER_ENTRY_END]) - vni_end =3D nla_get_u32(vattrs[VXLAN_VNIFILTER_ENTRY_END]); + vxlan_vni_filter_entry_range(vattrs, &vni_start, &vni_end); =20 if (!vni_start && !vni_end) { NL_SET_ERR_MSG_ATTR(extack, nlvnifilter, @@ -1104,6 +1164,10 @@ static int vxlan_vnifilter_process(struct sk_buff *s= kb, struct nlmsghdr *nlh, if (!(cfg->flags & VXLAN_F_VNIFILTER)) return -EOPNOTSUPP; =20 + err =3D vxlan_vnifilter_check_msg(nlh, extack); + if (err) + return err; + nlmsg_for_each_attr_type(attr, VXLAN_VNIFILTER_ENTRY, nlh, sizeof(*tmsg), rem) { err =3D vxlan_process_vni_filter(vxlan, attr, nlh->nlmsg_type, --=20 2.53.0 From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42C4D4E50D5 for ; Wed, 14 Oct 2026 12:40:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981618; cv=none; b=uInqkuJv3YwmhywzNs4KVA9tit6k8CHtuzcMPZYeihiHr5mJr5mOVPSMDl6a5sGd5hBmfCICfpFJstdfuPA/bI2ssRFFwijqrlj/47Cj/s5ghkFJoHTnlpSnV9cNsALv8DCyX/NSCVCHBVfBNgPJJy1iGK0NGQqgETrkcx7n190= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981618; c=relaxed/simple; bh=wNXTzoBCRrjBH+Z97Yn4B/LpSXjRiTvMR9N5NBkt17M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GkeMUa/o7d2lsj7ue139NKGqGGpvBPr2vFXwfZdtXJwVzvxoDfceuN6Ssr1buVRb+DIz4iX9wuHenUTo6vPl/6sgLDJMi2zV+e7wNPrYO2Nr1FALQvWyM0Y+ePmbILxtqVYzKmKwBIwp7VY3EdZLexpAuOqdM9XOkCiOIwrkfZw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=g8DlRiAq; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="g8DlRiAq" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-4a018792ab3so33534885e9.0 for ; Wed, 14 Oct 2026 05:40:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981610; x=1792586410; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=z3ZOxRV/kduEE71z1H7/WaoBF6Ffe2PveVQAPTO2Vls=; b=g8DlRiAqfuNYNJfRC5/WVTksJwPTfv/UnVx/FW6s/UoV6mJ5B6guBEbQQI5ZlHTmsW yEuR9GjIr1/hngWF1YPv7QqeRDq7mv8g2YB8PpRBSQKeSR9Lx3a5cAqt5vdHFkuLaIM6 ZZXFfKAKm+/HcuEtZNwUEplX7uHKOm2yVNlCt7Pzqh4/wRj58qWarG/+nKk17/w6VoXk TyTyGHiH42j8+M4+PLuJK39i2sMVKtf6g113NfpFJWubp6Pm4p0gJHgVbxjflnurGBZX O9jszhm20cLqRFf92QbsD1fLoePYZEO0c1MfpK9vB1oPRcrjmhnqrsuxZXfnwoQyQS6M egfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981610; x=1792586410; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=z3ZOxRV/kduEE71z1H7/WaoBF6Ffe2PveVQAPTO2Vls=; b=NdZW94C8TsbEU3na7Yadi2gdsNDvOfdTI5hz/3sMv/VgnEdE8UFaPCVm9Zklt8FPRp 0Z+bWsvunFGp7HPNQG+YKNiU6Ae0CNKEqMPKu9qLmZqbbEtFb3wVzXdMWLQl56M0TYWT t/8lLGjpOyX1isuI//h2RgRNrTrFlP9iLgpxxInCaVCRjWcqGpVr7T9U8OPHO5lRna/q rcLs3lzyPFbNzVmdFGKjQT2LA4uYsvaYWquD/pNv11LzfgYooHfeKm/QdDh9kPdrNlso s2vkzWYWLFW4J5PWOpv/ZbsfdIKklT/kiG5hNL3Ns0FpFp+U3CeLdozcdy+MnVxo0UDA 9ygA== X-Forwarded-Encrypted: i=1; AKwUvBy5mJPgwCJ1KNcR0hAWkorD4ATO5PdIS7IbOlZytGCXm0YCdTS2m/IZiYxoszEcCeFRVTX1Woqy4fgaWtU=@vger.kernel.org X-Gm-Message-State: AFq9FYLmbDKKyzHo3O3u0DR9kPNDh3qA1l5h1IJYB9volhCpXjFQFrt1 boMWTzp6SLUOrD2jTvnCnye2z1lxX0kRZDEyZseNSjJly7v5mjzK6pHK X-Gm-Gg: AYBFou19Z31D9NkDSrgTuAspAm69ZT+FVZUdUadNFeczfkfgdc3o4JN9oEONcZL4N2D K9mxFSoULe0GbFFYLUaO29BD5a1vRHtukcXQBSQT1DRTmW6ns/nVg2u1kKwx1mkucBhwl6twF3j xjLPdovnpiZA4bJqBtqsTjoWAO0C6dhrnEexbbsQXrsY53CrU/ZYOnSjUiBgN39oEz0BycHrWCo 0nqWK5gjJKOwFA7w1mO11njiTuF5KCakt8aki+Vo8SfSNUgEUQJFdLmDTJ6uWyfjgihCsKAlk4g 14EZv8wjJHWIFzEJxjTv9wIHvANNHfNLtfdiS5Vh7KECLxrPujvLa+DVKnM2RRj6Np8DYsjYy/7 AV5JMawZGWhxaJZ25ckCOex3fVxYseNQhP3c8QNow9UANx4y2RJgpSUCJZdWAHh9s0yc5OlpK40 yguF+C/QaDjQFXEau/HXuAxY9muOQHlXj4A2FBbGlnhVgCH4CFm6mk1tqpugJr3gM= X-Received: by 2002:a05:600c:8b65:b0:49e:6683:d23c with SMTP id 5b1f17b1804b1-4a18e3ef1bdmr287671205e9.0.1791981610296; Wed, 14 Oct 2026 05:40:10 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.40.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:40:09 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 5/7] vxlan: vnifilter: account per-VNI memory to memcg Date: Wed, 14 Oct 2026 15:38:12 +0300 Message-ID: <20261014123814.388557-6-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" vxlan_vni_alloc() allocates a struct vxlan_vni_node and a per-CPU stats block for every VNI, both with plain GFP_KERNEL, so neither is charged to the cgroup of the process that created the VNI. A netdevice's own struct and its Tx/Rx queues are already GFP_KERNEL_ACCOUNT in alloc_netdev_mqs() (commit c948f51c1654 ("memcg: enable accounting for net_device and Tx/Rx queues")), so these per-VNI allocations are an unaccounted part of a device that a cgroup can grow one VNI at a time. Charge both to the caller's cgroup with GFP_KERNEL_ACCOUNT in vxlan_vni_alloc(). __GFP_ACCOUNT only charges an allocation made from a task in a non-root memcg, so the sole caller, which already handles a NULL return, is unaffected outside a memcg. The charge lands in the caller's memcg: adding VNIs from inside one moves each node into the accounted slab and raises the cgroup's per-CPU memory. This covers the node and its stats only; a VNI carrying a group or remote also installs a default FDB entry, whose allocations are not charged here and are accounted by the next patch. Assisted-by: LLM Signed-off-by: Ali Firas --- v4: reworded to cover the node and stats only; the c948f51c1654 reference narrowed to net_device and its Tx/Rx queues; rebased. drivers/net/vxlan/vxlan_vnifilter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_= vnifilter.c index 2999dd536625..4a631fcdf23a 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -825,10 +825,11 @@ static struct vxlan_vni_node *vxlan_vni_alloc(struct = vxlan_dev *vxlan, { struct vxlan_vni_node *vninode; =20 - vninode =3D kzalloc_obj(*vninode); + vninode =3D kzalloc_obj(*vninode, GFP_KERNEL_ACCOUNT); if (!vninode) return NULL; - vninode->stats =3D netdev_alloc_pcpu_stats(struct vxlan_vni_stats_pcpu); + vninode->stats =3D __netdev_alloc_pcpu_stats(struct vxlan_vni_stats_pcpu, + GFP_KERNEL_ACCOUNT); if (!vninode->stats) { kfree(vninode); return NULL; --=20 2.53.0 From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 531E14E56E3 for ; Wed, 14 Oct 2026 12:40:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981620; cv=none; b=S2Z1k7B5V8q7LPy90ibGKMTopCW2DXVFfGFxzrMO8E+Xml2dgAQEt4f96T49fRofAsoe9ZxRT1Eb/+9MKJ/xjhDa4500gJGcjqjn5mlxbRwlSopptMj5izgL2tcAPVR2DQlPFD9urHI86eOQYrnhvA9HfO/XW7oLpLVyLbOkcW4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981620; c=relaxed/simple; bh=y0KNGeCtSjD1ACxF+bydrIxkgyBwc9qs4SPLuP098Z4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oDV+LTHQYG842jHuh1zLVvynkDQENRy4pCD+UTvsmGyobiRZwkSZgUAFTiEQPRJmSrfXxx98PJNSjRelOtjs4tR/jlMblxXNJDEa2hBxEfj+zv3tbnUyRCLH+BwJJwGdCASAc/nSbRvYxdGDFlKflrxgwgsPNUIG44xUql/3fCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kMMAlKze; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kMMAlKze" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-4a0286c981dso8412515e9.2 for ; Wed, 14 Oct 2026 05:40:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981613; x=1792586413; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=N7kWYfk+xokLUPXcyOfskQM732fHT0KCZAHVmHMKllY=; b=kMMAlKzedoP//1K31JmHhwQnoyUZKrUZ9xUVRA4Sbnpkfp/9nsSsHcWscfI4NLyilB f1Dh496j99g+zxFUC8uVq0X5ffe2/NnIxCb3hKNCg2morgcsshG0QYXXqs/kOWPrIRZZ YmSQ5Zy2obu8+xoL44vAcBew1a9kAega7q56EETIUVnp97giqH46gxEgWcm7tDNolU+x PVv7bZZq4pSf5tS5f4QNITBhi7hM391ZeP0eAys3iHloxG0aY3pG+hIkANckM5iclClw AaJOoskq5SRo42dEBj3F3Z5tDdCoqLjmRhS49IFDz622qbzUwrZDL513llEY74GTPQst LYcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981613; x=1792586413; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=N7kWYfk+xokLUPXcyOfskQM732fHT0KCZAHVmHMKllY=; b=H35YS/Mx3mYf7sMw9HmTRq24yRJSV/oMDaiOYC8wfm32PRieYugWEHYpEXelxpiQ1j v/mvHKYaFyFx86PDVJyWsjTVGsvvWE5cQeN3O0h0jBTATUQy8OUPehAVod8quQ2QBioR eAhCGIBkNWJ7cMA5jtiouAmZzHxOo4wpWitUytcbF2Q19qQKBduOTjT8bq6u/ellMipC r1PQ7tkAUZj+G+gBLfMDgXsh1lAPjQ9J10lSJaYIsS8zMOC7zA24kRTY1k1SFCoeDvTp uRdvcH0zvaTGL1DRikTCMmQOM9IS/SPRu3ur5YNgHG4aQJSrl3Qr8wbD8gmmzQ32vd/W OHOw== X-Forwarded-Encrypted: i=1; AKwUvBw6PYduNWvtufjEQ0apPPv7f4lpnAuXh+ywUMOajsA8DmT7zLPqI+K6fMREMz0b11TZpZ7jcdKi3C+8owM=@vger.kernel.org X-Gm-Message-State: AFq9FYJmPiJS13T/8hWTzJvpzbLZdkfU+ZysvRqyyTSnv/Vfzf8qG+0h 2K+n6u4HQkkrzsWveInEkykJECv8BkewOnXbnSSMR2+kwzyZKEhrY57T X-Gm-Gg: AYBFou2jUcyi1bY+a0mrg52frdlk+uSdVgfdbVXaFo2lGQVN7E1pffyYkq5iIBElqk0 d33BxBMS89NZ9OujFBCKfRW6+gkVwJ4A1JgBMReTaLG/oS3xl8yQ7WMgwUU4eARsocjU3aRtiCT S5VWtiau3IIdmMHTOJBVHBdX2/Nj417tIGHcScrZ2dHl/3VUA5/qySyTXUNkNNgTw5E/K7zfNew HB702WJmVIsTeIXAa4JnEIpgonliNYLDoVEanIg6lLgxWLzExAFy+WfUYIk3Adynt5uqy9jg9A6 STXx9Bg6WYeglJb0se1fc2UOpR2KTYkn8gDuuHUEsdQyVauJCkKNvTxKBiMPFzK+Mv1Whqxlj/X 3oxR0PrQk9En7Rndn4mh95qMFT+x6XFLXcGzNI0eA0ZgXE0bc3fFfgCOhKBApC/sbyHmcvZpuNK tFgHLLEg1hK4THjl6nuoG2Dk1f12c37rEPtrSB9tpdmRY4HT2VOGppn80LmvzIBq4= X-Received: by 2002:a05:600c:8105:b0:4a1:83f0:7c8a with SMTP id 5b1f17b1804b1-4a18e4433d6mr310145795e9.1.1791981613429; Wed, 14 Oct 2026 05:40:13 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.40.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:40:12 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 6/7] vxlan: vnifilter: account the default FDB entry to memcg Date: Wed, 14 Oct 2026 15:38:13 +0300 Message-ID: <20261014123814.388557-7-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A VNI added through the vnifilter interface with a group or remote installs a default FDB entry for that VNI: vxlan_vni_update_group() calls vxlan_update_default_fdb_entry(), which calls vxlan_fdb_update() and vxlan_fdb_create(). The entry allocates a struct vxlan_fdb and, per remote, a struct vxlan_rdst plus its per-CPU dst cache, all with GFP_ATOMIC and none charged to a memory cgroup. The previous patch accounts the per-VNI node and its stats; these FDB objects are the rest of what one vnifilter request allocates per VNI. Charge them to the caller, as commit c948f51c1654 ("memcg: enable accounting for net_device and Tx/Rx queues") and commit e2c8d550a973 ("netfilter: ebtables: account ebt_table_info to kmemcg") do: the lifetime of this memory is the net namespace, not the allocating task, so the OOM killer cannot reclaim it and it must be charged to the cgroup of the task whose request allocates it. Thread a gfp argument through vxlan_fdb_update() to vxlan_fdb_alloc()/vxlan_fdb_append() on both paths it can take -- the create path (vxlan_fdb_update_create() -> vxlan_fdb_create()) and the path that changes an existing entry's remote (vxlan_fdb_update_existing()) -- and a second gfp through vxlan_update_default_fdb_entry(), so each caller chooses it. Every non-vnifilter caller of vxlan_fdb_update() -- vxlan_fdb_add(), vxlan_snoop(), vxlan_dev_create(), vxlan_changelink() and the switchdev vxlan_fdb_external_learn_add() -- keeps plain GFP_ATOMIC, so the data path and unrelated callers are unchanged. dst_cache_init() already takes a gfp argument, so no change outside the driver is needed. A per-request add or change of a VNI's remote (RTM_NEWTUNNEL, via vxlan_vni_update_group()) passes GFP_NOWAIT | __GFP_ACCOUNT. These allocations run under the hash spinlock and cannot sleep, but a configuration path does not need the atomic reserves GFP_ATOMIC grants, and GFP_NOWAIT makes the memcg charge hard-bounded rather than force-charged: a cgroup at its limit fails the add or change there with -ENOMEM instead of pushing memory.current past memory.max. The failure is clean -- the new entry is allocated before the old is freed, so an add that fails leaves the existing entry intact and returns the error; no established FDB state is destroyed and no false success is returned. Creating a VNI is gated the same way by the previous patch's node and stats (GFP_KERNEL_ACCOUNT, hard-bounded). Measured on production builds at 2 and 8 vCPU in an 8 MiB cgroup: over-limit adds and changes return -ENOMEM and memory.current does not exceed memory.max. The device-wide default-remote change (RTM_NEWLINK, via vxlan_vnilist_update_group()) keeps GFP_ATOMIC | __GFP_ACCOUNT. That walk touches every VNI inheriting the device default in one message, outside the per-request cap, and its existing error unwind re-installs entries; hard-bounding it would turn a cgroup limit into a mid-walk failure that the unwind cannot cleanly reverse. Bounding and unwinding that pre-existing walk is left to a separate change; here it stays force-charged, as before this series, and is charged to the task issuing the RTM_NEWLINK. This adds no new failure path on the data or learning paths: their allocations already existed and keep GFP_ATOMIC; only the vnifilter configuration path gains an -ENOMEM return, which its callers already propagate. Assisted-by: LLM Signed-off-by: Ali Firas --- v4: new patch. drivers/net/vxlan/vxlan_core.c | 47 ++++++++++++++++------------- drivers/net/vxlan/vxlan_private.h | 7 +++-- drivers/net/vxlan/vxlan_vnifilter.c | 14 ++++++--- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 278d41f58d89..7991b544af5a 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -577,7 +577,7 @@ static int vxlan_fdb_replace(struct vxlan_fdb *f, /* Add/update destinations for multicast */ static int vxlan_fdb_append(struct vxlan_fdb *f, union vxlan_addr *ip, __be16 port, __be32 vni, - __u32 ifindex, struct vxlan_rdst **rdp) + __u32 ifindex, struct vxlan_rdst **rdp, gfp_t gfp) { struct vxlan_rdst *rd; =20 @@ -585,14 +585,14 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, if (rd) return 0; =20 - rd =3D kmalloc_obj(*rd, GFP_ATOMIC); + rd =3D kmalloc_obj(*rd, gfp); if (rd =3D=3D NULL) return -ENOMEM; =20 /* The driver can work correctly without a dst cache, so do not treat * dst cache initialization errors as fatal. */ - dst_cache_init(&rd->dst_cache, GFP_ATOMIC | __GFP_NOWARN); + dst_cache_init(&rd->dst_cache, gfp | __GFP_NOWARN); =20 rd->remote_ip =3D *ip; rd->remote_port =3D port; @@ -779,11 +779,11 @@ static int vxlan_gpe_gro_complete(struct sock *sk, st= ruct sk_buff *skb, int nhof =20 static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8= *mac, __u16 state, __be32 src_vni, - __u16 ndm_flags) + __u16 ndm_flags, gfp_t gfp) { struct vxlan_fdb *f; =20 - f =3D kmalloc_obj(*f, GFP_ATOMIC); + f =3D kmalloc_obj(*f, gfp); if (!f) return NULL; memset(&f->key, 0, sizeof(f->key)); @@ -869,7 +869,7 @@ int vxlan_fdb_create(struct vxlan_dev *vxlan, __u16 state, __be16 port, __be32 src_vni, __be32 vni, __u32 ifindex, __u16 ndm_flags, u32 nhid, struct vxlan_fdb **fdb, - struct netlink_ext_ack *extack) + struct netlink_ext_ack *extack, gfp_t gfp) { const struct vxlan_config *cfg =3D rcu_dereference_rtnl(vxlan->cfg); struct vxlan_rdst *rd =3D NULL; @@ -881,14 +881,14 @@ int vxlan_fdb_create(struct vxlan_dev *vxlan, return -ENOSPC; =20 netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip); - f =3D vxlan_fdb_alloc(vxlan, mac, state, src_vni, ndm_flags); + f =3D vxlan_fdb_alloc(vxlan, mac, state, src_vni, ndm_flags, gfp); if (!f) return -ENOMEM; =20 if (nhid) rc =3D vxlan_fdb_nh_update(vxlan, f, nhid, extack); else - rc =3D vxlan_fdb_append(f, ip, port, vni, ifindex, &rd); + rc =3D vxlan_fdb_append(f, ip, port, vni, ifindex, &rd, gfp); if (rc < 0) goto errout; =20 @@ -984,7 +984,7 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *= vxlan, __u32 ifindex, __u16 ndm_flags, struct vxlan_fdb *f, u32 nhid, bool swdev_notify, - struct netlink_ext_ack *extack) + struct netlink_ext_ack *extack, gfp_t gfp) { __u16 fdb_flags =3D (ndm_flags & ~NTF_USE); struct vxlan_rdst *rd =3D NULL; @@ -1047,7 +1047,8 @@ static int vxlan_fdb_update_existing(struct vxlan_dev= *vxlan, if ((flags & NLM_F_APPEND) && (is_multicast_ether_addr(f->key.eth_addr) || is_zero_ether_addr(f->key.eth_addr))) { - rc =3D vxlan_fdb_append(f, ip, port, vni, ifindex, &rd); + rc =3D vxlan_fdb_append(f, ip, port, vni, ifindex, &rd, + gfp); =20 if (rc < 0) return rc; @@ -1088,7 +1089,7 @@ static int vxlan_fdb_update_create(struct vxlan_dev *= vxlan, __be16 port, __be32 src_vni, __be32 vni, __u32 ifindex, __u16 ndm_flags, u32 nhid, bool swdev_notify, - struct netlink_ext_ack *extack) + struct netlink_ext_ack *extack, gfp_t gfp) { __u16 fdb_flags =3D (ndm_flags & ~NTF_USE); struct vxlan_fdb *f; @@ -1101,7 +1102,7 @@ static int vxlan_fdb_update_create(struct vxlan_dev *= vxlan, =20 netdev_dbg(vxlan->dev, "add %pM -> %pIS\n", mac, ip); rc =3D vxlan_fdb_create(vxlan, mac, ip, state, port, src_vni, - vni, ifindex, fdb_flags, nhid, &f, extack); + vni, ifindex, fdb_flags, nhid, &f, extack, gfp); if (rc < 0) return rc; =20 @@ -1124,7 +1125,7 @@ int vxlan_fdb_update(struct vxlan_dev *vxlan, __be16 port, __be32 src_vni, __be32 vni, __u32 ifindex, __u16 ndm_flags, u32 nhid, bool swdev_notify, - struct netlink_ext_ack *extack) + struct netlink_ext_ack *extack, gfp_t gfp) { struct vxlan_fdb *f; =20 @@ -1138,7 +1139,8 @@ int vxlan_fdb_update(struct vxlan_dev *vxlan, =20 return vxlan_fdb_update_existing(vxlan, ip, state, flags, port, vni, ifindex, ndm_flags, f, - nhid, swdev_notify, extack); + nhid, swdev_notify, extack, + gfp); } else { if (!(flags & NLM_F_CREATE)) return -ENOENT; @@ -1146,7 +1148,7 @@ int vxlan_fdb_update(struct vxlan_dev *vxlan, return vxlan_fdb_update_create(vxlan, mac, ip, state, flags, port, src_vni, vni, ifindex, ndm_flags, nhid, swdev_notify, - extack); + extack, gfp); } } =20 @@ -1287,7 +1289,7 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nl= attr *tb[], err =3D vxlan_fdb_update(vxlan, addr, &ip, ndm->ndm_state, flags, port, src_vni, vni, ifindex, ndm->ndm_flags | NTF_VXLAN_ADDED_BY_USER, - nhid, true, extack); + nhid, true, extack, GFP_ATOMIC); spin_unlock_bh(&vxlan->hash_lock); =20 if (!err) @@ -1507,7 +1509,8 @@ static enum skb_drop_reason vxlan_snoop(struct net_de= vice *dev, cfg->dst_port, vni, cfg->vni, - ifindex, NTF_SELF, 0, true, NULL); + ifindex, NTF_SELF, 0, true, NULL, + GFP_ATOMIC); spin_unlock(&vxlan->hash_lock); } =20 @@ -4154,7 +4157,7 @@ static int vxlan_dev_create(struct net *net, struct n= et_device *dev, cfg->vni, cfg->vni, cfg->remote_ifindex, - NTF_SELF, 0, true, extack); + NTF_SELF, 0, true, extack, GFP_ATOMIC); spin_unlock_bh(&vxlan->hash_lock); if (err) goto unlink; @@ -4617,7 +4620,8 @@ static int vxlan_changelink(struct net_device *dev, s= truct nlattr *tb[], cfg->dst_port, conf.vni, conf.vni, conf.remote_ifindex, - NTF_SELF, 0, true, extack); + NTF_SELF, 0, true, extack, + GFP_ATOMIC); if (err) { spin_unlock_bh(&vxlan->hash_lock); if (lowerdev_changed) @@ -4652,7 +4656,8 @@ static int vxlan_changelink(struct net_device *dev, s= truct nlattr *tb[], &cfg->remote_ip, conf.remote_ifindex, cfg->remote_ifindex, - NULL); + NULL, + GFP_ATOMIC | __GFP_ACCOUNT); if (lowerdev_changed) netdev_adjacent_change_abort(vxlan->lowerdev, lowerdev, dev); @@ -4972,7 +4977,7 @@ vxlan_fdb_external_learn_add(struct net_device *dev, fdb_info->remote_vni, fdb_info->remote_ifindex, NTF_USE | NTF_SELF | NTF_EXT_LEARNED, - 0, false, extack); + 0, false, extack, GFP_ATOMIC); spin_unlock_bh(&vxlan->hash_lock); =20 return err; diff --git a/drivers/net/vxlan/vxlan_private.h b/drivers/net/vxlan/vxlan_pr= ivate.h index f0ee85f83732..b5a80ed3eff2 100644 --- a/drivers/net/vxlan/vxlan_private.h +++ b/drivers/net/vxlan/vxlan_private.h @@ -192,7 +192,7 @@ int vxlan_fdb_create(struct vxlan_dev *vxlan, __u16 state, __be16 port, __be32 src_vni, __be32 vni, __u32 ifindex, __u16 ndm_flags, u32 nhid, struct vxlan_fdb **fdb, - struct netlink_ext_ack *extack); + struct netlink_ext_ack *extack, gfp_t gfp); int __vxlan_fdb_delete(struct vxlan_dev *vxlan, const unsigned char *addr, union vxlan_addr ip, __be16 port, __be32 src_vni, __be32 vni, @@ -202,7 +202,8 @@ int vxlan_fdb_update(struct vxlan_dev *vxlan, __u16 state, __u16 flags, __be16 port, __be32 src_vni, __be32 vni, __u32 ifindex, __u16 ndm_flags, u32 nhid, - bool swdev_notify, struct netlink_ext_ack *extack); + bool swdev_notify, struct netlink_ext_ack *extack, + gfp_t gfp); void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, const struct vxlan_config *cfg, __be32 default_vni, struct vxlan_rdst *rdst, bool did_rsc); @@ -229,7 +230,7 @@ int vxlan_update_default_fdb_entry(struct vxlan_dev *vx= lan, __be32 vni, const union vxlan_addr *old_remote_ip, const union vxlan_addr *remote_ip, u32 old_ifindex, u32 new_ifindex, - struct netlink_ext_ack *extack); + struct netlink_ext_ack *extack, gfp_t gfp); int vxlan_vnilist_update_group(struct vxlan_dev *vxlan, const union vxlan_addr *old_remote_ip, const union vxlan_addr *new_remote_ip, diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_= vnifilter.c index 4a631fcdf23a..4b43674cceff 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -553,7 +553,7 @@ int vxlan_update_default_fdb_entry(struct vxlan_dev *vx= lan, __be32 vni, const union vxlan_addr *old_remote_ip, const union vxlan_addr *remote_ip, u32 old_ifindex, u32 new_ifindex, - struct netlink_ext_ack *extack) + struct netlink_ext_ack *extack, gfp_t gfp) { const struct vxlan_config *cfg =3D rtnl_dereference(vxlan->cfg); int err =3D 0; @@ -575,7 +575,8 @@ int vxlan_update_default_fdb_entry(struct vxlan_dev *vx= lan, __be32 vni, vni, vni, new_ifindex, - NTF_SELF, 0, true, extack); + NTF_SELF, 0, true, extack, + gfp); if (err && extack) { spin_unlock_bh(&vxlan->hash_lock); return err; @@ -636,7 +637,8 @@ static int vxlan_vni_update_group(struct vxlan_dev *vxl= an, oldrip, newrip, cfg->remote_ifindex, cfg->remote_ifindex, - extack); + extack, + GFP_NOWAIT | __GFP_ACCOUNT); if (ret) goto out; =20 @@ -707,7 +709,8 @@ int vxlan_vnilist_update_group(struct vxlan_dev *vxlan, ret =3D vxlan_update_default_fdb_entry(vxlan, vent->vni, oldrip, newrip, old_ifindex, new_ifindex, - extack); + extack, + GFP_ATOMIC | __GFP_ACCOUNT); if (ret) goto err_unwind; } @@ -729,7 +732,8 @@ int vxlan_vnilist_update_group(struct vxlan_dev *vxlan, vxlan_update_default_fdb_entry(vxlan, vent->vni, newrip, oldrip, new_ifindex, old_ifindex, - NULL); + NULL, + GFP_ATOMIC | __GFP_ACCOUNT); } return ret; } --=20 2.53.0 From nobody Sun Nov 1 02:22:27 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 38D724E5332 for ; Wed, 14 Oct 2026 12:40:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981621; cv=none; b=XoPukszucusGIzp9Jh1352wrG7iFcKg3vdrkM+Nuz2A+0kL2ZDcYOtS/4pi9iVhoBF6qHx1S9nrtQrH5ZN6VHZ0toI8QyvxsC6EUQXlm3+dZzMIKPkxflZPAZuRZSJBRkSfpBWn0SSa6Jyhk1IukrVuEMIKHvUd5z4i3mmeaM04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791981621; c=relaxed/simple; bh=3TZQ+HlcGjCGA3F/2zGyQPW/1sgKKdWUwMizSTdv6LM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bHqXdodCNkakWVkCJgqI4vNSp5qnwBYG22BNaQM2AEqD9XmEZ7ITkZAnrsLZCegsAoXKlqBK7/hGcQV5hOsmWdAnzNCleyP4P75df/cmrWk/WE3qvmmzlY6YgHhOAknRnM7253BLRNhfLQ5OmNvePrwmwXtpcO7W3elmzQel9D0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=nj84rAdf; arc=none smtp.client-ip=209.85.128.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="nj84rAdf" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-4a16c1608faso53252545e9.0 for ; Wed, 14 Oct 2026 05:40:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791981617; x=1792586417; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=aOKE8b/KvX2bdCRB6QWafpMhNH6cuJzRy6nqCP30ARo=; b=nj84rAdf8EGlbvO7JsUQsWSZ7r7hMiN/imZjyYZU4sOoUE7wp41E0glAmx11bsmnHj 37vsbf9SJ1ZyhAJSdZYF0c3kuLMKKRXP6bgGau0UhbCD2qi5RMQzDwHkPmUpmhhIyuht RmAx6bl4nqlwTxPcwqoCYMKUfgmxzp0VDyujeb2mB/wvjKpANRjk5jkhO86XQ+wPekIS Rds9dGf29XWs1qncb45+jdzHqC7FdF0Jv/dLLfT6393Wlu/sDdFsCFFrtA7UAUISvh7U LBq+4dd56FoN1JyiMMyHY7ZrPBVTiOqzoez0irD1uu43XczTt4ODLGR5JxFfYUOQmVe9 /nQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791981617; x=1792586417; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=aOKE8b/KvX2bdCRB6QWafpMhNH6cuJzRy6nqCP30ARo=; b=GE9LsWzH77B4ZLRri13Yo9wTDi9PRn63uC+HQ+YBkUUNMdF1ncSXCkw3/cRz9aHcU7 +uu8Dr0Wcl7xFtcqmSg0s2MeoGnTbUkmR5Vm5Vg4Xa6ZjDmapqdO0EWP9MR42PfYSrVa kSgyUer6VtnSWBvLuYyCG1GXPOrzBn2P30Hy6HzZkCWKD5KggrzvHNupebFk13ht5GyV AGecsL7DBNx4xgVNtW0Zc5KgvxDKKjgX24VUxRzmaXANG7z+fH2v0frTYx+9enth6nYm EtVJhlVQvgOn1q0aEIKJNhGxupj3SwceeXMvdwT2kpLZCT9g1lIDQAa76oeGt8AOxy0y tmhw== X-Forwarded-Encrypted: i=1; AKwUvBy2ixV9GFFYi36a0680d3RWfEuJ7Ik07c+5LYn1VZgQC6PBURH4OkGz5K19leu8sOwgrF1LE/tCoTXve94=@vger.kernel.org X-Gm-Message-State: AFq9FYK79/qseCkrRVWQjmzev3PteSWhhZr8hmnnpA9M+0BZRJHaUraS kDugBCnnHM6TstJlE1AhwBvzxXRqsT5rFYyGa5b96mC0G9ZHd9xMUgSb X-Gm-Gg: AYBFou1lBlgT8MWTkidxh0My6oMMVfUTZAA53TflLcWHUaJjtHplmHbv4X9tmaYIJlt 89bzjmiK/1HguyHd0YlbyB4rh13Ib3qZe9GzY/9ix0bxWVWqnbRNSDxkjXFavMK8503X/tg3sjD pDPbIC5neODPXvsxgvQWCa5Xp4lwjQl4hSfEQE9rcDQJtJO05eK66y3wzt2OcqInMppZlW7OyQy t0kqFJ+IelU5j0VKZ+kJOmJDHAQvqygwy4gKBkpsdmiY1ll8kFiG9bmVBIi1zdpPA8pbn7TBjeg 1taydsUJkwjP2ZC8KQXzkvLAhnnYRMDY4Jxw9qjTakJdGg/oSMBj89VlyOc16Oe+CrxZ3MTJBGQ L11n/G8k2YO1HUTDu799XXLQjicGEdgk7kW2FeaALAHas2blOM99TSLqWL3Wsj85/Ekf3xYEm9o 7RwEnpn0X7i3uliQOtUaWDhi6J623oYvphSuWlImNMWGQNON24UW5PcY+rc46h4HU= X-Received: by 2002:a05:600c:810a:b0:4a0:ec5:46d9 with SMTP id 5b1f17b1804b1-4a18e3ef100mr294242195e9.0.1791981616695; Wed, 14 Oct 2026 05:40:16 -0700 (PDT) Received: from kali ([169.224.126.44]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4a1b2ec47fcsm54163165e9.1.2026.10.14.05.40.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Oct 2026 05:40:15 -0700 (PDT) From: Ali Firas To: netdev@vger.kernel.org, idosch@nvidia.com Cc: kuba@kernel.org, pabeni@redhat.com, davem@davemloft.net, edumazet@google.com, andrew+netdev@lunn.ch, horms@kernel.org, razor@blackwall.org, roopa@nvidia.com, shuah@kernel.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, Ali Firas Subject: [PATCH net-next v4 7/7] selftests: net: test the vxlan vnifilter request limit and dump replay Date: Wed, 14 Oct 2026 15:38:14 +0300 Message-ID: <20261014123814.388557-8-alishmery18@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261014123814.388557-1-alishmery18@gmail.com> References: <20261014123814.388557-1-alishmery18@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the vnifilter tests for the request-size limit, the 24-bit VNI range, and the dump/replay round trip the limit requires. The API test gains: the largest accepted add and one VNI past it; a rejected oversized add and a rejected multi-entry add whose entries are each under the limit but sum over it, each checked to install nothing (the range is asserted absent first, since vxlan_vni_add() folds an existing VNI into the update path and would return 0 either way). The cap is symmetric, so it also checks a maximum-size delete accepted and a max+1 delete rejected, with every VNI in the max+1 range installed first so the refusal can only come from the cap; a within-cap delete of a never-installed range, which must fail on the missing VNI; an inverted range accepted as a no-op; and the 24-bit bound exercised through END, not only START. bridge(8) places one VXLAN_VNIFILTER_ENTRY per comma-separated item into a single message, so the multi-entry case is reachable without a hand-built netlink message. vxlan_vnifilter_dump_replay() builds a contiguous run twice the limit from two requests, then replays every range the dump reports into a second device and requires all to be accepted and the two dumps to match. Without the dump clamp the run dumps as one over-limit entry that replay rejects; with it the run dumps as limit-sized entries that replay. vxlan_vnifilter_api() had no teardown of its own device and namespace; add veth-host and the test netns to cleanup(), which runs on EXIT, so a failing case does not leave them or its entries behind. Suggested-by: Ido Schimmel Assisted-by: LLM Signed-off-by: Ali Firas --- v4: assert the dump is non-empty before replay, so the replay case cannot pass vacuously; rebased. .../selftests/net/test_vxlan_vnifiltering.sh | 119 +++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/test_vxlan_vnifiltering.sh b/tools= /testing/selftests/net/test_vxlan_vnifiltering.sh index 6fb5af013dac..bb35e89d2d03 100755 --- a/tools/testing/selftests/net/test_vxlan_vnifiltering.sh +++ b/tools/testing/selftests/net/test_vxlan_vnifiltering.sh @@ -84,6 +84,7 @@ ret=3D0 # all tests in this script. Can be overridden with -t option TESTS=3D" vxlan_vnifilter_api + vxlan_vnifilter_dump_replay vxlan_vnifilter_datapath vxlan_vnifilter_datapath_pervni vxlan_vnifilter_datapath_mgroup @@ -139,8 +140,9 @@ check_vm_connectivity() { cleanup() { ip link del veth-hv-1 2>/dev/null || true ip link del vethhv-11 vethhv-12 vethhv-21 vethhv-22 2>/dev/null || true + ip link del veth-host 2>/dev/null || true =20 - cleanup_ns $hv_1 $hv_2 $vm_11 $vm_21 $vm_12 $vm_22 $vm_31 $vm_32 + cleanup_ns $hv_1 $hv_2 $vm_11 $vm_21 $vm_12 $vm_22 $vm_31 $vm_32 $testns } =20 trap cleanup EXIT @@ -347,6 +349,121 @@ vxlan_vnifilter_api() # change vxlan vnifilter flag run_cmd "ip -netns $testns link set dev vxlan-ext1 type vxlan external no= vnifilter" log_test $? 2 "Cannot unset vnifilter flag on a device" + + # A single request may add at most 4096 VNIs. bridge(8) puts one + # VXLAN_VNIFILTER_ENTRY per comma-separated item into a single message, + # so both the single-entry and the multi-entry paths are reachable here. + + # The largest accepted add, and one VNI more rejected. + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 10000-14095" + log_test $? 0 "Add a request of the maximum VNI count" + + # The rejected oversized add must install nothing. Assert the range is + # absent first: vxlan_vni_add() folds an already-present VNI into the + # update path and returns 0, so a later probe cannot tell "installed + # nothing" from "installed part" unless it started absent. + run_cmd "bridge -netns $testns vni show dev vxlan-ext1 | grep -qw 20000" + log_test $? 1 "VNI 20000 absent before the oversized add" + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 20000-24096" + log_test $? 255 "Cannot add a request over the maximum VNI count" + run_cmd "bridge -netns $testns vni show dev vxlan-ext1 | grep -qw 20000" + log_test $? 1 "The rejected oversized add installed nothing" + + # Two entries each under the limit but summing over it: the per-message + # total is what is bounded, not the span of one entry. This is the shape + # a per-entry check would have let through. + run_cmd "bridge -netns $testns vni show dev vxlan-ext1 | grep -qw 30000" + log_test $? 1 "VNI 30000 absent before the oversized multi-entry add" + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 30000-32047,320= 48-34097" + log_test $? 255 "Cannot add a multi-entry request summing over the maximu= m" + run_cmd "bridge -netns $testns vni show dev vxlan-ext1 | grep -qw 30000" + log_test $? 1 "The rejected multi-entry add installed nothing" + + # The cap is symmetric: a delete may touch at most the maximum too. + # Install a maximum-size range and the VNI past it, so the max+1 delete + # below has every VNI present and can only be refused by the cap, not by + # a missing VNI. + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 40000-44095" + log_test $? 0 "Populate a maximum-size range to delete" + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 44096" + log_test $? 0 "Add the VNI past the maximum range" + run_cmd "bridge -netns $testns vni del dev vxlan-ext1 vni 40000-44096" + log_test $? 255 "Cannot delete a request over the maximum VNI count" + run_cmd "bridge -netns $testns vni del dev vxlan-ext1 vni 40000-44095" + log_test $? 0 "Delete a request of the maximum VNI count" + run_cmd "bridge -netns $testns vni del dev vxlan-ext1 vni 44096" + log_test $? 0 "Delete the VNI past the maximum range" + + # A within-cap delete of a never-installed range reaches the handler and + # fails there on the missing VNI, not on the cap. + run_cmd "bridge -netns $testns vni del dev vxlan-ext1 vni 50000-50010" + log_test $? 255 "Cannot delete a range that was never installed" + + # A start above the end selects nothing and is accepted as a no-op. + # Use a VNI no earlier case installs, so the absence check is meaningful. + run_cmd "bridge -netns $testns vni show dev vxlan-ext1 | grep -qw 55000" + log_test $? 1 "VNI 55000 absent before the inverted range" + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 55000-50000" + log_test $? 0 "An inverted range is accepted as a no-op" + run_cmd "bridge -netns $testns vni show dev vxlan-ext1 | grep -qw 55000" + log_test $? 1 "The inverted range installed nothing" + + # The VXLAN header carries 24 bits. The bound is on both endpoints, so a + # range whose END alone leaves the space is rejected too. + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 16777215" + log_test $? 0 "Add the highest VNI the header can carry" + run_cmd "bridge -netns $testns vni del dev vxlan-ext1 vni 16777215" + log_test $? 0 "Delete the highest VNI the header can carry" + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 16777215-167772= 16" + log_test $? 255 "Cannot add a range whose END leaves the 24-bit space" + run_cmd "bridge -netns $testns vni add dev vxlan-ext1 vni 100-4294967295" + log_test $? 255 "Cannot add a range whose END wraps past the 24-bit space" +} + +# A device may hold a contiguous run longer than one request's limit, built +# from several requests. The dump coalesces it, so the dump must break the= run +# into entries each no larger than the limit, or the configuration it repo= rts +# cannot be replayed. Install such a run, then feed every range the dump +# reports back into a second device and require all to be accepted. +vxlan_vnifilter_dump_replay() +{ + local opts=3D"external vnifilter local 172.16.0.1 dev veth-testns" + local range rc=3D0 src_ranges dst_ranges + + cleanup_vnifilter_api &>/dev/null + setup_vnifilter_api + + # The destination is on a different dstport so re-adding the same VNIs + # does not collide with the source under vxlan_vni_in_use(). + run_cmd "ip -netns $testns link add vxlan-src type vxlan $opts dstport 47= 89" + log_test $? 0 "dump/replay: create source device" + run_cmd "ip -netns $testns link add vxlan-dst type vxlan $opts dstport 47= 90" + log_test $? 0 "dump/replay: create destination device" + + # 8192 contiguous VNIs sharing the default remote: one run, twice the + # limit, installed in two accepted requests. + run_cmd "bridge -netns $testns vni add dev vxlan-src vni 10000-14095" + run_cmd "bridge -netns $testns vni add dev vxlan-src vni 14096-18191" + log_test $? 0 "dump/replay: populate a run larger than the limit" + + # Assert the dump is non-empty before replaying it, so an empty or + # failed dump cannot let the replay check below pass without testing + # anything. + src_ranges=3D$(bridge -netns $testns vni show dev vxlan-src | \ + grep -oE '[0-9]+-[0-9]+|[0-9]{2,}' | sort) + test -n "$src_ranges" + log_test $? 0 "dump/replay: source dump is non-empty" + + for range in $src_ranges; do + bridge -netns $testns vni add dev vxlan-dst vni "$range" \ + 2>/dev/null || rc=3D$? + done + log_test $rc 0 "dump/replay: every dumped entry is accepted on replay" + + dst_ranges=3D$(bridge -netns $testns vni show dev vxlan-dst | \ + grep -oE '[0-9]+-[0-9]+|[0-9]{2,}' | sort) + [ "$src_ranges" =3D "$dst_ranges" ] + log_test $? 0 "dump/replay: source and destination dump the same ranges" } =20 # Sanity test vnifilter datapath --=20 2.53.0