* [PATCH net] ipvs: reset full ip_vs_seq structs in ip_vs_conn_new
From: Yizhou Zhao @ 2026-07-02 11:28 UTC (permalink / raw)
To: netdev
Cc: Yizhou Zhao, Simon Horman, Julian Anastasov, Pablo Neira Ayuso,
Florian Westphal, Phil Sutter, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, lvs-devel, netfilter-devel, coreteam,
linux-kernel, stable, Yuxiang Yang, Ao Wang, Xuewei Feng, Qi Li,
Ke Xu
Commit 9a05475cebdd ("ipvs: avoid kmem_cache_zalloc in
ip_vs_conn_new") changed ip_vs_conn_new() to allocate an ip_vs_conn
object with kmem_cache_alloc(). The function then initializes many
fields explicitly, but only resets in_seq.delta and out_seq.delta in the
two struct ip_vs_seq members.
That leaves init_seq and previous_delta uninitialized. This is normally
harmless while the corresponding IP_VS_CONN_F_IN_SEQ or
IP_VS_CONN_F_OUT_SEQ flag is clear. For connections learned from a sync
message, however, ip_vs_proc_conn() preserves those flags from
IP_VS_CONN_F_BACKUP_MASK and passes opt=NULL when the message omits
IPVS_OPT_SEQ_DATA. In that case the new connection can be hashed with
SEQ flags set but with the rest of in_seq/out_seq still containing stale
slab data.
When a packet for such a connection is later handled by an IPVS
application helper, vs_fix_seq() and vs_fix_ack_seq() use
previous_delta and init_seq to rewrite TCP sequence numbers. A malformed
sync message can therefore make forwarded packets carry stale slab bytes
in their TCP seq/ack numbers, and can also corrupt the forwarded TCP
flow.
Reset both struct ip_vs_seq members completely before publishing the
connection. This matches the existing "reset struct ip_vs_seq" comment
and keeps the sequence-adjustment gates inactive unless valid sequence
data is installed later.
Fixes: 9a05475cebdd ("ipvs: avoid kmem_cache_zalloc in ip_vs_conn_new")
Cc: stable@vger.kernel.org
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Ao Wang <wangao@seu.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: Claude-Code:GLM-5.2
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
---
net/netfilter/ipvs/ip_vs_conn.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index cb36641f8d1c..6ed2622363f0 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -1420,8 +1420,8 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, int dest_af,
cp->app = NULL;
cp->app_data = NULL;
/* reset struct ip_vs_seq */
- cp->in_seq.delta = 0;
- cp->out_seq.delta = 0;
+ memset(&cp->in_seq, 0, sizeof(cp->in_seq));
+ memset(&cp->out_seq, 0, sizeof(cp->out_seq));
if (unlikely(flags & IP_VS_CONN_F_NO_CPORT)) {
int af_id = ip_vs_af_index(cp->af);
^ permalink raw reply related
* Re: [PATCH net-next v4 2/2] net: pse-pd: add Realtek/Broadcom PSE MCU driver
From: Jonas Jelonek @ 2026-07-02 11:22 UTC (permalink / raw)
To: Oleksij Rempel
Cc: Kory Maincent, Andrew Lunn, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, netdev, devicetree, linux-kernel, Daniel Golle,
Bjørn Mork
In-Reply-To: <akYPfkRbEzWFuC6j@pengutronix.de>
Hi Oleksij,
thanks for your review.
On 02.07.26 09:13, Oleksij Rempel wrote:
> Hi Jonas,
>
> On Tue, Jun 30, 2026 at 10:56:50AM +0000, Jonas Jelonek wrote:
>> [...]
>>
>> +struct rtpse_mcu_port_config {
>> + bool enable;
> in this struct we use only enable, do you plan to wire it somewhere
> later? I assume you wont to keep it as documentation. May be add some
> debug traces? And add some comments what do you already know about this
> fields.
>
>> + u8 function_mode;
>> + u8 detection_type;
>> + u8 cls_type;
>> + u8 disconnect_type;
>> + u8 pair_type;
>> +};
>> +
>> +struct rtpse_mcu_port_ext_config {
> Same here.
>
>> + u8 inrush_mode;
>> + u8 limit_type;
>> + u8 max_power;
>> + u8 priority;
>> + u8 chip_addr;
>> + u8 channel;
>> +};
This might be good for follow-up patches. Right now, I don't get
the full complexity of the pse-pd framework so I'll rather keep it
simple. I see that at least some of this information is reportable,
though not configurable (yet).
I suppose it's preferred to not add unused stuff so I should just
drop the unused fields and add them later as needed. There isn't
an urgent need to document it here either, the guide I based my
driver on is quite available here and there in the web. I haven't
actually dealt with all those fields close enough, so adding
half-baked comments about them isn't good either.
>> + break;
>> + msleep(RTPSE_MCU_BOOT_RETRY_MS);
>> + } while (time_before(jiffies, deadline));
>> + if (ret)
>> + return dev_err_probe(pse->dev, ret, "failed to read MCU info\n");
>> +
>> + switch (info->device_id) {
>> + case RTPSE_MCU_DEVICE_ID_RTL8238B:
>> + pse->chip = &rtl8238b_info;
>> + break;
>> + case RTPSE_MCU_DEVICE_ID_RTL8239:
>> + pse->chip = &rtl8239_info;
>> + break;
>> + case RTPSE_MCU_DEVICE_ID_RTL8239C:
>> + pse->chip = &rtl8239c_info;
>> + break;
>> + case RTPSE_MCU_DEVICE_ID_BCM59111:
>> + pse->chip = &bcm59111_info;
>> + break;
>> + case RTPSE_MCU_DEVICE_ID_BCM59121:
>> + pse->chip = &bcm59121_info;
>> + break;
>> + default:
>> + return dev_err_probe(pse->dev, -EINVAL, "unknown PSE id 0x%x\n",
>> + info->device_id);
>> + }
>> +
>> + if (!info->max_ports || info->max_ports > RTPSE_MCU_MAX_PORTS)
>> + return dev_err_probe(pse->dev, -EINVAL,
>> + "MCU reports invalid port count %u\n", info->max_ports);
>> +
>> + ret = rtpse_mcu_get_ext_config(pse, &ext_config);
>> + if (ret)
>> + return dev_err_probe(pse->dev, ret, "failed to read MCU ext config\n");
>> +
>> + dev_info(pse->dev, "%s MCU, %s (id 0x%04x), %u ports across %u PSE chip(s)\n",
>> + pse->dialect->mcu_type_str(info->mcu_type), pse->chip->name,
>> + info->device_id, info->max_ports, ext_config.num_of_pses);
> Reduce it to debug level print.
Is there any guideline about what drivers are allowed to print during
probe? Usually, I'm a fan of at least seeing an immediate sign of life
from a driver, even in success case. And I also see that from drivers in
other subsystems, e.g. fan controllers or GPIO expanders.
>> + return 0;
>> +}
>> +
> Best Regards,
> Oleksij
I'll address the other points I've not reacted to explicitly in the next
version then. Same for the low-severity sashiko-nipa issues.
Best regards,
Jonas
^ permalink raw reply
* [PATCH net-next 1/2] devlink: print controller prefix for non-zero controller
From: Tariq Toukan @ 2026-07-02 11:17 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Adithya Jayachandran, Chris Mi, Daniel Jurgens, Jiri Pirko,
Jonathan Corbet, Kees Cook, Leon Romanovsky, linux-doc,
linux-kernel, linux-rdma, Mark Bloch, Moshe Shemesh, Or Har-Toov,
Parav Pandit, Saeed Mahameed, Shay Drori, Shuah Khan,
Simon Horman, Tariq Toukan
In-Reply-To: <20260702111726.816985-1-tariqt@nvidia.com>
From: Moshe Shemesh <moshe@nvidia.com>
The controller prefix (c<N>) in phys_port_name is currently restricted
to external host controllers. This layout sufficed when DPUs only had a
single local controller and one or more external host controllers.
However, newer devices can have multiple controllers within the DPU
itself, even within a single host environment. To support these
topologies, allow drivers to report the controller number regardless of
the "external" flag status. Any non-zero controller number will now be
explicitly reported, even for single-host or local DPU controllers.
Existing ports with controller=0 are unaffected.
Update documentation and kdoc to clarify that a non-zero controller
number does not require the external flag to be set.
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Parav Pandit <parav@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
Documentation/networking/devlink/devlink-port.rst | 9 +++++++++
include/net/devlink.h | 6 +++---
net/devlink/port.c | 6 +++---
3 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/Documentation/networking/devlink/devlink-port.rst b/Documentation/networking/devlink/devlink-port.rst
index 9374ebe70f48..4211322d488b 100644
--- a/Documentation/networking/devlink/devlink-port.rst
+++ b/Documentation/networking/devlink/devlink-port.rst
@@ -107,6 +107,15 @@ doesn't have the eswitch. Local controller (identified by controller number = 0)
has the eswitch. The Devlink instance on the local controller has eswitch
devlink ports for both the controllers.
+A non-zero controller number may also be used for ports that are not external.
+For example, a SmartNIC may have additional local PCI physical functions
+that are managed by the eswitch but are not on an external host. These
+ports use a non-zero controller number to distinguish them from the eswitch
+manager's own functions, while the external flag remains unset.
+
+The ``phys_port_name`` includes the controller prefix (``c<controller_num>``)
+whenever the controller number is non-zero, regardless of the external flag.
+
Function configuration
======================
diff --git a/include/net/devlink.h b/include/net/devlink.h
index dd546dbd57cf..35bfdceeab9f 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -36,7 +36,7 @@ struct devlink_port_phys_attrs {
* struct devlink_port_pci_pf_attrs - devlink port's PCI PF attributes
* @controller: Associated controller number
* @pf: associated PCI function number for the devlink port instance
- * @external: when set, indicates if a port is for an external controller
+ * @external: when set, indicates if a port is for an external host controller.
*/
struct devlink_port_pci_pf_attrs {
u32 controller;
@@ -50,7 +50,7 @@ struct devlink_port_pci_pf_attrs {
* @pf: associated PCI function number for the devlink port instance
* @vf: associated PCI VF number of a PF for the devlink port instance;
* VF number starts from 0 for the first PCI virtual function
- * @external: when set, indicates if a port is for an external controller
+ * @external: when set, indicates if a port is for an external host controller.
*/
struct devlink_port_pci_vf_attrs {
u32 controller;
@@ -64,7 +64,7 @@ struct devlink_port_pci_vf_attrs {
* @controller: Associated controller number
* @sf: associated SF number of a PF for the devlink port instance
* @pf: associated PCI function number for the devlink port instance
- * @external: when set, indicates if a port is for an external controller
+ * @external: when set, indicates if a port is for an external host controller.
*/
struct devlink_port_pci_sf_attrs {
u32 controller;
diff --git a/net/devlink/port.c b/net/devlink/port.c
index 485029d43428..bde6d4125725 100644
--- a/net/devlink/port.c
+++ b/net/devlink/port.c
@@ -1529,7 +1529,7 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
WARN_ON(1);
return -EINVAL;
case DEVLINK_PORT_FLAVOUR_PCI_PF:
- if (attrs->pci_pf.external) {
+ if (attrs->pci_pf.external || attrs->pci_pf.controller) {
n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
if (n >= len)
return -EINVAL;
@@ -1539,7 +1539,7 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
break;
case DEVLINK_PORT_FLAVOUR_PCI_VF:
- if (attrs->pci_vf.external) {
+ if (attrs->pci_vf.external || attrs->pci_vf.controller) {
n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
if (n >= len)
return -EINVAL;
@@ -1550,7 +1550,7 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
attrs->pci_vf.pf, attrs->pci_vf.vf);
break;
case DEVLINK_PORT_FLAVOUR_PCI_SF:
- if (attrs->pci_sf.external) {
+ if (attrs->pci_sf.external || attrs->pci_sf.controller) {
n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
if (n >= len)
return -EINVAL;
--
2.44.0
^ permalink raw reply related
* [PATCH net-next 2/2] net/mlx5: Set satellite PF devlink ports as non-external
From: Tariq Toukan @ 2026-07-02 11:17 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Adithya Jayachandran, Chris Mi, Daniel Jurgens, Jiri Pirko,
Jonathan Corbet, Kees Cook, Leon Romanovsky, linux-doc,
linux-kernel, linux-rdma, Mark Bloch, Moshe Shemesh, Or Har-Toov,
Parav Pandit, Saeed Mahameed, Shay Drori, Shuah Khan,
Simon Horman, Tariq Toukan
In-Reply-To: <20260702111726.816985-1-tariqt@nvidia.com>
From: Moshe Shemesh <moshe@nvidia.com>
Satellite PFs are local to the DPU and are not on an external host.
Set their devlink port external attribute to false to reflect this.
For satellite PF SFs, distinguish them from host PF SFs by comparing
the SF controller number against the host PF controller
(hpf_host_number + 1). Only SFs whose controller matches the host PF
are marked external, since their PF resides on an external host.
Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
---
drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
index 6e50311faa27..4fcad15e7eb6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
@@ -74,7 +74,7 @@ static void mlx5_esw_offloads_pf_vf_devlink_port_attrs_set(struct mlx5_eswitch *
memcpy(dl_port->attrs.switch_id.id, ppid.id, ppid.id_len);
dl_port->attrs.switch_id.id_len = ppid.id_len;
devlink_port_attrs_pci_pf_set(dl_port, controller_num, pfnum,
- true);
+ false);
}
}
@@ -134,13 +134,16 @@ static void mlx5_esw_offloads_sf_devlink_port_attrs_set(struct mlx5_eswitch *esw
{
struct mlx5_core_dev *dev = esw->dev;
struct netdev_phys_item_id ppid = {};
+ u32 hpf_ctrl;
u16 pfnum;
pfnum = mlx5_esw_sf_controller_to_pfnum(dev, controller);
+ hpf_ctrl = mlx5_esw_get_hpf_host_number(dev) + 1;
mlx5_esw_get_port_parent_id(dev, &ppid);
memcpy(dl_port->attrs.switch_id.id, &ppid.id[0], ppid.id_len);
dl_port->attrs.switch_id.id_len = ppid.id_len;
- devlink_port_attrs_pci_sf_set(dl_port, controller, pfnum, sfnum, !!controller);
+ devlink_port_attrs_pci_sf_set(dl_port, controller, pfnum, sfnum,
+ controller == hpf_ctrl);
}
int mlx5_esw_offloads_sf_devlink_port_init(struct mlx5_eswitch *esw, struct mlx5_vport *vport,
--
2.44.0
^ permalink raw reply related
* [PATCH net-next 0/2] devlink: extend phys_port_name controller prefix to non-external ports
From: Tariq Toukan @ 2026-07-02 11:17 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
netdev, Paolo Abeni
Cc: Adithya Jayachandran, Chris Mi, Daniel Jurgens, Jiri Pirko,
Jonathan Corbet, Kees Cook, Leon Romanovsky, linux-doc,
linux-kernel, linux-rdma, Mark Bloch, Moshe Shemesh, Or Har-Toov,
Parav Pandit, Saeed Mahameed, Shay Drori, Shuah Khan,
Simon Horman, Tariq Toukan
Hi,
This series by Moshe includes the controller number in phys_port_name
for non-external ports with a non-zero controller, and updates the mlx5
driver to mark satellite PFs as non-external.
The controller prefix (c) in phys_port_name was previously only included
for ports marked as external. However, newer devices can have multiple
controllers within the DPU itself, even within a single host
environment. For example, a SmartNIC may have additional local PCI
physical functions that are managed by the eswitch but are not on an
external host. These ports use a non-zero controller number to
distinguish them from the eswitch manager's own functions, while the
external flag remains unset.
Patch 1 updates the devlink core to include the controller prefix in
phys_port_name for any non-zero controller, regardless of the external
flag. Documentation and kdoc are updated accordingly.
Patch 2 updates the mlx5 driver to set satellite PF devlink ports as
non-external, since they are local to the DPU. It also distinguishes
satellite PF SFs from host PF SFs when setting the external attribute.
Regards,
Tariq
Moshe Shemesh (2):
devlink: print controller prefix for non-zero controller
net/mlx5: Set satellite PF devlink ports as non-external
Documentation/networking/devlink/devlink-port.rst | 9 +++++++++
.../net/ethernet/mellanox/mlx5/core/esw/devlink_port.c | 7 +++++--
include/net/devlink.h | 6 +++---
net/devlink/port.c | 6 +++---
4 files changed, 20 insertions(+), 8 deletions(-)
base-commit: 1c664ec4b9ea827b609d296921ed5bad8a40a158
--
2.44.0
^ permalink raw reply
* Re: [Intel-wired-lan] [PATCH iwl-net 2/2] ice: fix stats array overflow via proper realloc
From: Przemek Kitszel @ 2026-07-02 11:18 UTC (permalink / raw)
To: Marcin Szycik
Cc: netdev, Tony Nguyen, Aleksandr Loktionov, Andrew Lunn,
David S. Miller, Michal Schmidt, intel-wired-lan, Eric Dumazet,
Paolo Abeni, Jakub Kicinski, Jedrzej Jagielski, Piotr Kwapulinski
In-Reply-To: <f2c285ba-8089-41a1-b28a-9062f2b584c8@linux.intel.com>
On 7/2/26 12:25, Marcin Szycik wrote:
>
>
> On 01.07.2026 12:41, Przemek Kitszel wrote:
>> Integrate ice_vsi_alloc_stat_arrays() with realloc variant.
>>
>> Instead of keeping two functions for stat arrays allocation, change the
>> ice_vsi_realloc_stat_arrays() to handle initial condition (no vsi_stat
>> entry) and replace ice_vsi_alloc_stat_arrays() by the more generic
>> ice_vsi_realloc_stat_arrays().
>>
>> Note that VSIs of ICE_VSI_CHNL type are ignored in realloc variant as they
>> were in the replaced ice_vsi_alloc_stat_arrays().
>>
>> This is a fix for stats array overflow that occurs when VF is given more
>> queues (an operation that will be more frequent, and by bigger increase,
>> when we will merge my "XLVF" series).
>>
>>
>> Fixes: 2a2cb4c6c181 ("ice: replace ice_vf_recreate_vsi() with ice_vf_reconfig_vsi()")
>> Closes: https://redhat.atlassian.net/browse/RHEL-164321
>
> Is there a simpler reproducer than the script attached in the ticket?
My original reproducer, but with XLVF series applied, is very simple:
Start VF as default, then let it use more queues.
The overflow is not always immediately visible for the user right now,
with up to 16 queues, often all of them assigned by default at VF init.
Anyway, the bug is real.
>
>> Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
>
> Reviewed-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Thank you.
^ permalink raw reply
* Re: [REGRESSION][BISECTED] tun/tap & vhost-net: multi-threaded network performance
From: Brett Sheffield @ 2026-07-02 11:07 UTC (permalink / raw)
To: Simon Schippers
Cc: Michael S. Tsirkin, regressions, netdev, Jakub Kicinski,
Tim Gebauer, Willem de Bruijn, Jason Wang, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, linux-kernel
In-Reply-To: <ef33f0a7-f0b7-4bc4-9263-10d2b480d717@tu-dortmund.de>
On 2026-07-02 09:24, Simon Schippers wrote:
> On 7/1/26 22:56, Michael S. Tsirkin wrote:
> > On Wed, Jul 01, 2026 at 09:16:48PM +0200, Brett Sheffield wrote:
> >> TL;DR - Commit 1d6e569b7d0c0b2736636749e4be0a27f3cefcb3 causes
> >> significant performance regressions with TAP interfaces and multithreaded
> >> network code. Please revert.
> >>
> >>
> >> Librecast is an IPv6 multicast library. One of the tests (0055) fails under
> >> Linux 7.2-rc1. The test performs data synchronization over IPv6 multicast using a TAP
> >> interface. This test has run successfully on every stable, LTS and mainline RC
> >> released in the past year. Every kernel with my Tested-by has run this test.
> >>
> >> There have been a bunch of changes to MLDv2 so I started bisecting there, but
> >> the culprit is actually 1d6e569b7d0c0b2736636749e4be0a27f3cefcb3 "tun/tap &
> >> vhost-net: avoid ptr_ring tail-drop when a qdisc is present"
> >>
> >> Reverting this commit fixes the test.
> >>
> >> To eliminate my code and any multicast weirdness, I ran tests with iperf3
> >> comparing the same host running 7.2-rc1 both with and without 1d6e569b7d0
> >> reverted.
>
> Thank you very much for your bisect!
>
> As the author, I am sorry for that regression!
No worries. That's why we test :-)
> > - does it help to increase the tun queue size?
>
> I agree, this would be great to know.
>
> However, even then we must act. I am considering IFF_BACKPRESSURE
> as a feature flag, defaulting to off. It would just enable/disable
> the stopping logic in tun_net_xmit() and the waking logic
> in __tun_wake_queue(). If disabled, it would result in the same logic
> as before.
>
> I could provide such a patch as [net] material.
I'm going to make myself a strong cup of tea and dig into it a bit more here and
will let you know if I find anything worth reporting.
If you need me to try re-testing with specific settings or test a patch I'm
happy to do so.
Cheers,
Brett
--
Brett Sheffield (he/him)
Librecast - Decentralising the Internet with Multicast
https://librecast.net/
https://blog.brettsheffield.com/
^ permalink raw reply
* Re: [PATCH bpf v3 4/4] selftests/bpf: Fail unbound UDP on sockmap update
From: Jakub Sitnicki @ 2026-07-02 11:01 UTC (permalink / raw)
To: Michal Luczaj
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan,
John Fastabend, Jiayuan Chen, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, David S. Miller, Jakub Kicinski,
Simon Horman, Cong Wang, bpf, linux-kselftest, linux-kernel,
netdev
In-Reply-To: <20260702-sockmap-lookup-udp-leak-v3-4-ff8de8782468@rbox.co>
On Thu, Jul 02, 2026 at 01:28 AM +02, Michal Luczaj wrote:
> sockmap now rejects unbound UDP sockets. Adjust test_maps. While at it,
> check socket()'s return value.
>
> This effectively reverts commit c39aa2159974 ("bpf, selftests: Fix
> test_maps now that sockmap supports UDP").
>
> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
> Signed-off-by: Michal Luczaj <mhal@rbox.co>
> ---
Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
^ permalink raw reply
* Re: [PATCH net-next v3 06/15] net: macb: allocate tieoff descriptor once across device lifetime
From: Nicolai Buchwitz @ 2026-07-02 10:54 UTC (permalink / raw)
To: Théo Lebrun
Cc: Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Richard Cochran, Russell King,
netdev, linux-kernel, Nicolas Ferre, Claudiu Beznea,
Paolo Valerio, Vladimir Kondratiev, Gregory CLEMENT,
Benoît Monin, Tawfik Bayouk, Thomas Petazzoni,
Maxime Chevallier
In-Reply-To: <20260701-macb-context-v3-6-00268d5b1502@bootlin.com>
Hi Théo
On 1.7.2026 17:59, Théo Lebrun wrote:
> The tieoff descriptor is a RX DMA descriptor ring of size one. It gets
> configured onto queues for Wake-on-LAN during system-wide suspend when
> hardware does not support disabling individual queues
> (MACB_CAPS_QUEUE_DISABLE).
>
> MACB/GEM driver allocates it alongside the main RX ring
> inside macb_alloc() at open. Free is done by macb_free() at close.
>
> Change to allocate once at probe and free on probe failure or device
> removal. This makes the tieoff descriptor lifetime much longer,
> avoiding repeating coherent buffer allocation on each open/close cycle.
>
> Main benefit: we dissociate its lifetime from the main ring's lifetime.
> That way there is less work to be doing on resources (re)alloc. This
> currently happens on close/open, but will soon also happen on context
> swap operations (set_ringparam, change_mtu, set_channels, etc).
>
> Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
> ---
> drivers/net/ethernet/cadence/macb_main.c | 75
> +++++++++++++++++---------------
> 1 file changed, 41 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/net/ethernet/cadence/macb_main.c
> b/drivers/net/ethernet/cadence/macb_main.c
> index 8b52122bc134..951a7f080225 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> [...]
> static void macb_init_rings(struct macb *bp)
> @@ -2832,8 +2801,6 @@ static void macb_init_rings(struct macb *bp)
> bp->queues[0].tx_head = 0;
> bp->queues[0].tx_tail = 0;
> desc->ctrl |= MACB_BIT(TX_WRAP);
> -
> - macb_init_tieoff(bp);
> }
>
> static void macb_reset_hw(struct macb *bp)
> @@ -5518,6 +5485,38 @@ static int eyeq5_init(struct platform_device
> *pdev)
> return ret;
> }
>
> +static int macb_alloc_tieoff(struct macb *bp)
> +{
> + /* Tieoff is a workaround in case HW cannot disable queues, for PM.
> */
> + if (bp->caps & MACB_CAPS_QUEUE_DISABLE)
> + return 0;
Before, the tieoff was allocated in macb_alloc(), which the at91ether
path
never called. Now it's allocated from macb_probe() for all variants,
gated only
on MACB_CAPS_QUEUE_DISABLE, so EMAC gets a coherent descriptor it never
uses.
Add MACB_CAPS_MACB_IS_EMAC to the if statement?
> [...]
Thanks
Nicolai
^ permalink raw reply
* RE: [PATCH net v4] rtase: Workaround for TX hang caused by short UDP packets entering hardware PTP parsing
From: Justin Lai @ 2026-07-02 10:52 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem@davemloft.net, edumazet@google.com, pabeni@redhat.com,
andrew+netdev@lunn.ch, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, stable@vger.kernel.org, horms@kernel.org,
richardcochran@gmail.com, david.laight.linux@gmail.com,
aleksander.lobakin@intel.com, Ping-Ke Shih, Larry Chiu
In-Reply-To: <20260630020126.2366786-1-kuba@kernel.org>
Jakub Kicinski <kuba@kernel.org> wrote:
>
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> rtase: Workaround for TX hang caused by short UDP packets entering
> hardware PTP parsing
>
> This commit attempts to work around a hardware TX hang caused by
> out-of-bounds
> reads during PTP parsing. It introduces logic to pad short UDP packets to a
> minimum transport data length before transmission.
>
> > diff --git a/drivers/net/ethernet/realtek/rtase/rtase_main.c
> b/drivers/net/ethernet/realtek/rtase/rtase_main.c
> > index 255667775f0e8..944ffe71b2d07 100644
> > --- a/drivers/net/ethernet/realtek/rtase/rtase_main.c
> > +++ b/drivers/net/ethernet/realtek/rtase/rtase_main.c
> [ ... ]
> > +static bool rtase_get_udp_offset(struct sk_buff *skb, u32 *udp_offset)
> > +{
> > + struct ipv6hdr *i6h, _i6h;
> > + struct iphdr *ih, _ih;
> > + __be16 proto;
> > + u32 no;
> > +
> > + if (!rtase_get_l3_proto(skb, &proto, &no))
> > + return false;
> > +
> > + switch (proto) {
> > + case htons(ETH_P_IP):
> > + ih = skb_header_pointer(skb, no, sizeof(_ih), &_ih);
> > + if (!ih)
> > + return false;
>
> [Severity: High]
> Does this skip the padding workaround if the IP header itself is truncated?
>
> If the packet is shorter than the IP header (e.g., less than 34 bytes),
> skb_header_pointer() will return false. This causes rtase_skb_pad() to
> return true, allowing the packet to skip padding. Could this small unpadded
> packet still trigger the hardware parser and cause the TX hang?
>
Thanks for pointing this out.
A truncated IPv4 header can also trigger the same hardware TX hang
issue.
We'll update the workaround to handle this case as well.
We'll also update the commit message to document this hardware
limitation.
> [ ... ]
> > +static bool rtase_skb_pad(struct sk_buff *skb)
> > +{
> > + __be16 *dest, _dest;
> > + u32 trans_data_len;
> > + u32 udp_offset;
> > + u16 dest_port;
> > + u32 pad_len;
> > +
> > + if (!rtase_get_udp_offset(skb, &udp_offset))
> > + return true;
> > +
> > + if (udp_offset > skb->len)
> > + return false;
> > +
> > + trans_data_len = skb->len - udp_offset;
> > + if (trans_data_len < offsetof(struct udphdr, len) ||
> > + trans_data_len >= RTASE_MIN_PAD_LEN)
> > + return true;
>
> [Severity: High]
> Can an attacker bypass the workaround if the transport payload is very small?
>
> By returning true when trans_data_len is less than
> offsetof(struct udphdr, len) (which is 4 bytes), the packet is passed to
> the hardware unpadded.
>
> If an attacker sends an IPv4 non-initial fragment with a very small payload,
> the hardware parser might identify the fragment as UDP and attempt to read
> the
> destination port at offset 2 from the payload. If this out-of-bounds read
> hits residual uninitialized memory in the TX FIFO containing PTP port values
> (319 or 320), the hardware could incorrectly classify it as a PTP packet,
> continue parsing out of bounds, and trigger the TX hang.
>
Thanks for the review.
The hardware fetches packet data according to the packet length
specified in the TX descriptor, so it does not fetch residual data
beyond the end of the packet during DMA.
The affected out-of-bounds access occurs after the packet has already
matched the PTP classification criteria (UDP destination port 319/320)
and entered the hardware PTP parsing path.
If the transport data is shorter than the destination port field
itself, the packet cannot match the affected PTP classification path,
so padding is not required for this case.
> > +
> > + dest = skb_header_pointer(skb,
> --
> pw-bot: cr
^ permalink raw reply
* Re: [PATCH bpf v3 3/4] selftests/bpf: Adapt sockmap update error handling
From: Jakub Sitnicki @ 2026-07-02 10:52 UTC (permalink / raw)
To: Michal Luczaj
Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Shuah Khan,
John Fastabend, Jiayuan Chen, Eric Dumazet, Kuniyuki Iwashima,
Paolo Abeni, Willem de Bruijn, David S. Miller, Jakub Kicinski,
Simon Horman, Cong Wang, bpf, linux-kselftest, linux-kernel,
netdev
In-Reply-To: <20260702-sockmap-lookup-udp-leak-v3-3-ff8de8782468@rbox.co>
On Thu, Jul 02, 2026 at 01:28 AM +02, Michal Luczaj wrote:
> Update sockmap_listen to accommodate the recent change in sockmap that
> rejects unbound UDP sockets.
>
> TCP: Reject unbound and bound (unless established or listening).
> UDP: Accept only bound sockets.
>
> While at it, migrate to ASSERT_* and enforce reverse xmas tree.
>
> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
> Signed-off-by: Michal Luczaj <mhal@rbox.co>
> ---
Reviewed-by: Jakub Sitnicki <jakub@cloudflare.com>
^ permalink raw reply
* [PATCH net-next 12/12] netfilter: nft_ct: support expectation creation for natted flows
From: Florian Westphal @ 2026-07-02 10:50 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
This feature only works for connections originating from the host
and only if there no source address rewrite.
Add the needed nat glue to have the expectation follow the original
nat binding.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nft_ct.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 03a88c77e0f0..358b9287e12e 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -1297,6 +1297,17 @@ static int nft_ct_expect_obj_dump(struct sk_buff *skb,
return 0;
}
+#if IS_ENABLED(CONFIG_NF_NAT)
+static void nft_ct_nat_follow_master(struct nf_conn *ct, struct nf_conntrack_expect *this)
+{
+ const struct nf_ct_helper_expectfn *expfn;
+
+ expfn = nf_ct_helper_expectfn_find_by_name("nat-follow-master");
+ if (expfn)
+ expfn->expectfn(ct, this);
+}
+#endif
+
static void nft_ct_expect_obj_eval(struct nft_object *obj,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
@@ -1342,6 +1353,13 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj,
priv->l4proto, NULL, &priv->dport);
exp->timeout += priv->timeout;
+#if IS_ENABLED(CONFIG_NF_NAT)
+ if (ct->status & IPS_NAT_MASK) {
+ exp->saved_proto.tcp.port = priv->dport;
+ exp->dir = !dir;
+ exp->expectfn = nft_ct_nat_follow_master;
+ }
+#endif
if (nf_ct_expect_related(exp, 0) != 0)
regs->verdict.code = NF_DROP;
@@ -1375,6 +1393,13 @@ static struct nft_object_type nft_ct_expect_obj_type __read_mostly = {
.owner = THIS_MODULE,
};
+#if IS_ENABLED(CONFIG_NF_NAT)
+static struct nf_ct_helper_expectfn nft_ct_nat __read_mostly = {
+ .name = "nft_ct-follow-master",
+ .expectfn = nft_ct_nat_follow_master,
+};
+#endif
+
static int __init nft_ct_module_init(void)
{
int err;
@@ -1400,6 +1425,9 @@ static int __init nft_ct_module_init(void)
err = nft_register_obj(&nft_ct_timeout_obj_type);
if (err < 0)
goto err4;
+#endif
+#if IS_ENABLED(CONFIG_NF_NAT)
+ nf_ct_helper_expectfn_register(&nft_ct_nat);
#endif
return 0;
@@ -1425,6 +1453,13 @@ static void __exit nft_ct_module_exit(void)
nft_unregister_obj(&nft_ct_helper_obj_type);
nft_unregister_expr(&nft_notrack_type);
nft_unregister_expr(&nft_ct_type);
+
+#if IS_ENABLED(CONFIG_NF_NAT)
+ nf_ct_helper_expectfn_unregister(&nft_ct_nat);
+ synchronize_rcu();
+ nf_ct_helper_expectfn_destroy(&nft_ct_nat);
+ synchronize_rcu();
+#endif
}
module_init(nft_ct_module_init);
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 11/12] netfilter: ebtables: bound num_counters like nentries in do_replace()
From: Florian Westphal @ 2026-07-02 10:50 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Jiayuan Chen <jiayuan.chen@linux.dev>
do_replace_finish() allocates the counter buffer before it is validated:
counterstmp = vmalloc_array(repl->num_counters, sizeof(*counterstmp));
do_replace() only checks num_counters against INT_MAX / sizeof(struct
ebt_counter), so vmalloc_array() can be asked for up to 134217726 * 16 =
2147483616 bytes (~2 GiB).
num_counters must in fact equal nentries: do_replace_finish() later
rejects the request when repl->num_counters != t->private->nentries.
get_counters() folds the per-CPU counters back into one entry per rule,
so what userspace gets is bounded by nentries, never by nentries *
nr_cpus. Apply the same upper bound used for nentries (MAX_EBT_ENTRIES)
to the incoming num_counters so the over-sized allocation can no longer
be requested.
The allocation is still kept outside the ebt_mutex, since vmalloc() may
sleep and trigger reclaim; only the bound is tightened.
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/bridge/netfilter/ebtables.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index f20c039e44c8..042d31278713 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -39,6 +39,8 @@
#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter)))
#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \
COUNTER_OFFSET(n) * cpu))
+#define MAX_EBT_ENTRIES (((INT_MAX - sizeof(struct ebt_table_info)) / \
+ NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
struct ebt_pernet {
struct list_head tables;
@@ -1124,10 +1126,9 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
return -EINVAL;
/* overflow check */
- if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) /
- NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+ if (tmp.nentries >= MAX_EBT_ENTRIES)
return -ENOMEM;
- if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+ if (tmp.num_counters >= MAX_EBT_ENTRIES)
return -ENOMEM;
tmp.name[sizeof(tmp.name) - 1] = 0;
@@ -2265,10 +2266,9 @@ static int compat_copy_ebt_replace_from_user(struct ebt_replace *repl,
if (tmp.entries_size == 0)
return -EINVAL;
- if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) /
- NR_CPUS - SMP_CACHE_BYTES) / sizeof(struct ebt_counter))
+ if (tmp.nentries >= MAX_EBT_ENTRIES)
return -ENOMEM;
- if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter))
+ if (tmp.num_counters >= MAX_EBT_ENTRIES)
return -ENOMEM;
memcpy(repl, &tmp, offsetof(struct ebt_replace, hook_entry));
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 10/12] netfilter: conntrack: remove obsolete module parameters
From: Florian Westphal @ 2026-07-02 10:50 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
helper autoassign was removed years ago, all the port numbers are
no longer functional.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/linux/netfilter/nf_conntrack_h323.h | 2 -
include/linux/netfilter/nf_conntrack_pptp.h | 2 -
include/linux/netfilter/nf_conntrack_sane.h | 2 -
include/linux/netfilter/nf_conntrack_tftp.h | 2 -
include/net/netfilter/nf_conntrack_helper.h | 1 -
net/ipv4/netfilter/nf_nat_snmp_basic_main.c | 2 +-
net/netfilter/nf_conntrack_amanda.c | 4 +-
net/netfilter/nf_conntrack_ftp.c | 32 +++++----------
net/netfilter/nf_conntrack_h323_main.c | 10 ++---
net/netfilter/nf_conntrack_helper.c | 6 +--
net/netfilter/nf_conntrack_irc.c | 27 ++++---------
net/netfilter/nf_conntrack_netbios_ns.c | 2 -
net/netfilter/nf_conntrack_pptp.c | 2 +-
net/netfilter/nf_conntrack_sane.c | 34 +++++-----------
net/netfilter/nf_conntrack_sip.c | 45 ++++++---------------
net/netfilter/nf_conntrack_snmp.c | 4 +-
net/netfilter/nf_conntrack_tftp.c | 33 +++++----------
17 files changed, 59 insertions(+), 151 deletions(-)
diff --git a/include/linux/netfilter/nf_conntrack_h323.h b/include/linux/netfilter/nf_conntrack_h323.h
index 81286c499325..b15f37604cde 100644
--- a/include/linux/netfilter/nf_conntrack_h323.h
+++ b/include/linux/netfilter/nf_conntrack_h323.h
@@ -9,8 +9,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#include <uapi/linux/netfilter/nf_conntrack_tuple_common.h>
-#define RAS_PORT 1719
-#define Q931_PORT 1720
#define H323_RTP_CHANNEL_MAX 4 /* Audio, video, FAX and other */
/* This structure exists only once per master */
diff --git a/include/linux/netfilter/nf_conntrack_pptp.h b/include/linux/netfilter/nf_conntrack_pptp.h
index c3bdb4370938..c0b305ce7c3c 100644
--- a/include/linux/netfilter/nf_conntrack_pptp.h
+++ b/include/linux/netfilter/nf_conntrack_pptp.h
@@ -50,8 +50,6 @@ struct nf_nat_pptp {
__be16 pac_call_id; /* NAT'ed PAC call id */
};
-#define PPTP_CONTROL_PORT 1723
-
#define PPTP_PACKET_CONTROL 1
#define PPTP_PACKET_MGMT 2
diff --git a/include/linux/netfilter/nf_conntrack_sane.h b/include/linux/netfilter/nf_conntrack_sane.h
index 46c7acd1b4a7..8501035d7335 100644
--- a/include/linux/netfilter/nf_conntrack_sane.h
+++ b/include/linux/netfilter/nf_conntrack_sane.h
@@ -3,8 +3,6 @@
#define _NF_CONNTRACK_SANE_H
/* SANE tracking. */
-#define SANE_PORT 6566
-
enum sane_state {
SANE_STATE_NORMAL,
SANE_STATE_START_REQUESTED,
diff --git a/include/linux/netfilter/nf_conntrack_tftp.h b/include/linux/netfilter/nf_conntrack_tftp.h
index 90b334bbce3c..e3d1739c557d 100644
--- a/include/linux/netfilter/nf_conntrack_tftp.h
+++ b/include/linux/netfilter/nf_conntrack_tftp.h
@@ -2,8 +2,6 @@
#ifndef _NF_CONNTRACK_TFTP_H
#define _NF_CONNTRACK_TFTP_H
-#define TFTP_PORT 69
-
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/types.h>
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index f3f0c1392e88..bc5427d239f4 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -94,7 +94,6 @@ void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
u8 l3num, u16 protonum, const char *name,
- u16 default_port, u16 spec_port, u32 id,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
int (*help)(struct sk_buff *skb, unsigned int protoff,
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
index 0ede138dfd29..e540b86bd15b 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic_main.c
@@ -213,7 +213,7 @@ static int __init nf_nat_snmp_basic_init(void)
RCU_INIT_POINTER(nf_nat_snmp_hook, help);
nf_ct_helper_init(&snmp_trap_helper, AF_INET, IPPROTO_UDP,
- "snmp_trap", SNMP_TRAP_PORT, SNMP_TRAP_PORT, SNMP_TRAP_PORT,
+ "snmp_trap",
&snmp_exp_policy, 0, help, NULL, THIS_MODULE);
err = nf_conntrack_helper_register(&snmp_trap_helper, &snmp_trap_helper_ptr);
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index f10ac2c49f4b..06d6ec12c86d 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -199,10 +199,10 @@ static int __init nf_conntrack_amanda_init(void)
}
nf_ct_helper_init(&amanda_helper[0], AF_INET, IPPROTO_UDP,
- HELPER_NAME, 10080, 10080, 10080,
+ HELPER_NAME,
&amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);
nf_ct_helper_init(&amanda_helper[1], AF_INET6, IPPROTO_UDP,
- HELPER_NAME, 10080, 10080, 10080,
+ HELPER_NAME,
&amanda_exp_policy, 0, amanda_help, NULL, THIS_MODULE);
ret = nf_conntrack_helpers_register(amanda_helper,
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 0847f845613d..f3944598c172 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -35,11 +35,6 @@ MODULE_ALIAS("ip_conntrack_ftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
static DEFINE_SPINLOCK(nf_ftp_lock);
-#define MAX_PORTS 8
-static u_int16_t ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-
static bool loose;
module_param(loose, bool, 0600);
@@ -560,8 +555,8 @@ static int nf_ct_ftp_from_nlattr(struct nlattr *attr, struct nf_conn *ct)
return 0;
}
-static struct nf_conntrack_helper ftp[MAX_PORTS * 2] __read_mostly;
-static struct nf_conntrack_helper *ftp_ptr[MAX_PORTS * 2] __read_mostly;
+static struct nf_conntrack_helper ftp __read_mostly;
+static struct nf_conntrack_helper *ftp_ptr __read_mostly;
static const struct nf_conntrack_expect_policy ftp_exp_policy = {
.max_expected = 1,
@@ -570,32 +565,23 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = {
static void __exit nf_conntrack_ftp_fini(void)
{
- nf_conntrack_helpers_unregister(ftp_ptr, ports_c * 2);
+ nf_conntrack_helper_unregister(ftp_ptr);
}
static int __init nf_conntrack_ftp_init(void)
{
- int i, ret = 0;
+ int ret = 0;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_ftp_master));
- if (ports_c == 0)
- ports[ports_c++] = FTP_PORT;
-
/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
are tracked or not - YK */
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP,
- HELPER_NAME, FTP_PORT, ports[i], ports[i],
- &ftp_exp_policy, 0, help,
- nf_ct_ftp_from_nlattr, THIS_MODULE);
- nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP,
- HELPER_NAME, FTP_PORT, ports[i], ports[i],
- &ftp_exp_policy, 0, help,
- nf_ct_ftp_from_nlattr, THIS_MODULE);
- }
+ nf_ct_helper_init(&ftp, NFPROTO_UNSPEC, IPPROTO_TCP,
+ HELPER_NAME,
+ &ftp_exp_policy, 0, help,
+ nf_ct_ftp_from_nlattr, THIS_MODULE);
- ret = nf_conntrack_helpers_register(ftp, ports_c * 2, ftp_ptr);
+ ret = nf_conntrack_helper_register(&ftp, &ftp_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 37b6314ca772..4cb1665bba02 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -1713,19 +1713,19 @@ static int __init h323_helper_init(void)
int ret;
nf_ct_helper_init(&nf_conntrack_helper_ras[0], AF_INET, IPPROTO_UDP,
- "RAS", RAS_PORT, RAS_PORT, RAS_PORT,
+ "RAS",
&ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_ras[1], AF_INET6, IPPROTO_UDP,
- "RAS", RAS_PORT, RAS_PORT, RAS_PORT,
+ "RAS",
&ras_exp_policy, 0, ras_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_h245, AF_UNSPEC, IPPROTO_UDP,
- "H.245", 0, 0, 0,
+ "H.245",
&h245_exp_policy, 0, h245_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_q931[0], AF_INET, IPPROTO_TCP,
- "Q.931", Q931_PORT, Q931_PORT, Q931_PORT,
+ "Q.931",
&q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);
nf_ct_helper_init(&nf_conntrack_helper_q931[1], AF_INET6, IPPROTO_TCP,
- "Q.931", Q931_PORT, Q931_PORT, Q931_PORT,
+ "Q.931",
&q931_exp_policy, 0, q931_help, NULL, THIS_MODULE);
ret = nf_conntrack_helper_register(&nf_conntrack_helper_h245,
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index b28986100db0..506c58034761 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -472,7 +472,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
u8 l3num, u16 protonum, const char *name,
- u16 default_port, u16 spec_port, u32 id,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
int (*help)(struct sk_buff *skb, unsigned int protoff,
@@ -493,10 +492,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,
snprintf(helper->nat_mod_name, sizeof(helper->nat_mod_name),
NF_NAT_HELPER_PREFIX "%s", name);
- if (spec_port == default_port)
- snprintf(helper->name, sizeof(helper->name), "%s", name);
- else
- snprintf(helper->name, sizeof(helper->name), "%s-%u", name, id);
+ snprintf(helper->name, sizeof(helper->name), "%s", name);
if (WARN_ON_ONCE(expect_class_max >= NF_CT_MAX_EXPECT_CLASSES))
return;
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 193ab34db795..4e6bafe41437 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -21,9 +21,6 @@
#include <net/netfilter/nf_conntrack_helper.h>
#include <linux/netfilter/nf_conntrack_irc.h>
-#define MAX_PORTS 8
-static unsigned short ports[MAX_PORTS];
-static unsigned int ports_c;
static unsigned int max_dcc_channels = 8;
static unsigned int dcc_timeout __read_mostly = 300;
/* This is slow, but it's simple. --RR */
@@ -42,8 +39,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_conntrack_irc");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-module_param_array(ports, ushort, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "port numbers of IRC servers");
module_param(max_dcc_channels, uint, 0400);
MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per "
"IRC session");
@@ -254,13 +249,13 @@ static int help(struct sk_buff *skb, unsigned int protoff,
return ret;
}
-static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly;
-static struct nf_conntrack_helper *irc_ptr[MAX_PORTS] __read_mostly;
+static struct nf_conntrack_helper irc __read_mostly;
+static struct nf_conntrack_helper *irc_ptr __read_mostly;
static struct nf_conntrack_expect_policy irc_exp_policy;
static int __init nf_conntrack_irc_init(void)
{
- int i, ret;
+ int ret;
nf_conntrack_helper_deprecated(HELPER_NAME);
@@ -282,17 +277,11 @@ static int __init nf_conntrack_irc_init(void)
if (!irc_buffer)
return -ENOMEM;
- /* If no port given, default to standard irc port */
- if (ports_c == 0)
- ports[ports_c++] = IRC_PORT;
+ nf_ct_helper_init(&irc, AF_INET, IPPROTO_TCP, HELPER_NAME,
+ &irc_exp_policy,
+ 0, help, NULL, THIS_MODULE);
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, HELPER_NAME,
- IRC_PORT, ports[i], i, &irc_exp_policy,
- 0, help, NULL, THIS_MODULE);
- }
-
- ret = nf_conntrack_helpers_register(&irc[0], ports_c, irc_ptr);
+ ret = nf_conntrack_helper_register(&irc, &irc_ptr);
if (ret) {
pr_err("failed to register helpers\n");
kfree(irc_buffer);
@@ -304,7 +293,7 @@ static int __init nf_conntrack_irc_init(void)
static void __exit nf_conntrack_irc_fini(void)
{
- nf_conntrack_helpers_unregister(irc_ptr, ports_c);
+ nf_conntrack_helper_unregister(irc_ptr);
kfree(irc_buffer);
}
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
index 89d1cf7d6512..caa2b101fa9e 100644
--- a/net/netfilter/nf_conntrack_netbios_ns.c
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -21,7 +21,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#define HELPER_NAME "netbios-ns"
-#define NMBD_PORT 137
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
@@ -54,7 +53,6 @@ static int __init nf_conntrack_netbios_ns_init(void)
exp_policy.timeout = timeout;
nf_ct_helper_init(&helper, AF_INET, IPPROTO_UDP, HELPER_NAME,
- NMBD_PORT, NMBD_PORT, NMBD_PORT,
&exp_policy, 0, netbios_ns_help, NULL, THIS_MODULE);
return nf_conntrack_helper_register(&helper, &helper_ptr);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 80fc14c87ddc..cbf32a3cb1f6 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -540,7 +540,7 @@ static int __init nf_conntrack_pptp_init(void)
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_pptp_master));
nf_ct_helper_init(&pptp, AF_INET, IPPROTO_TCP,
- "pptp", PPTP_CONTROL_PORT, PPTP_CONTROL_PORT, PPTP_CONTROL_PORT,
+ "pptp",
&pptp_exp_policy, 0, conntrack_pptp_help, NULL, THIS_MODULE);
pptp.destroy = gre_pptp_destroy_siblings;
diff --git a/net/netfilter/nf_conntrack_sane.c b/net/netfilter/nf_conntrack_sane.c
index 39085acf7a71..a0658f69d78f 100644
--- a/net/netfilter/nf_conntrack_sane.c
+++ b/net/netfilter/nf_conntrack_sane.c
@@ -34,11 +34,6 @@ MODULE_AUTHOR("Michal Schmidt <mschmidt@redhat.com>");
MODULE_DESCRIPTION("SANE connection tracking helper");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-#define MAX_PORTS 8
-static u_int16_t ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-
struct sane_request {
__be32 RPC_code;
#define SANE_NET_START 7 /* RPC code */
@@ -169,8 +164,8 @@ static int help(struct sk_buff *skb,
return ret;
}
-static struct nf_conntrack_helper sane[MAX_PORTS * 2] __read_mostly;
-static struct nf_conntrack_helper *sane_ptr[MAX_PORTS * 2] __read_mostly;
+static struct nf_conntrack_helper sane __read_mostly;
+static struct nf_conntrack_helper *sane_ptr __read_mostly;
static const struct nf_conntrack_expect_policy sane_exp_policy = {
.max_expected = 1,
@@ -179,32 +174,21 @@ static const struct nf_conntrack_expect_policy sane_exp_policy = {
static void __exit nf_conntrack_sane_fini(void)
{
- nf_conntrack_helpers_unregister(sane_ptr, ports_c * 2);
+ nf_conntrack_helper_unregister(sane_ptr);
}
static int __init nf_conntrack_sane_init(void)
{
- int i, ret = 0;
+ int ret = 0;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sane_master));
- if (ports_c == 0)
- ports[ports_c++] = SANE_PORT;
-
- /* FIXME should be configurable whether IPv4 and IPv6 connections
- are tracked or not - YK */
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP,
- HELPER_NAME, SANE_PORT, ports[i], ports[i],
- &sane_exp_policy, 0, help, NULL,
- THIS_MODULE);
- nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP,
- HELPER_NAME, SANE_PORT, ports[i], ports[i],
- &sane_exp_policy, 0, help, NULL,
- THIS_MODULE);
- }
+ nf_ct_helper_init(&sane, NFPROTO_UNSPEC, IPPROTO_TCP,
+ HELPER_NAME,
+ &sane_exp_policy, 0, help, NULL,
+ THIS_MODULE);
- ret = nf_conntrack_helpers_register(sane, ports_c * 2, sane_ptr);
+ ret = nf_conntrack_helper_register(&sane, &sane_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 5ec3a4a4bbd7..d0b85b8ad1e6 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -35,12 +35,6 @@ MODULE_DESCRIPTION("SIP connection tracking helper");
MODULE_ALIAS("ip_conntrack_sip");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-#define MAX_PORTS 8
-static unsigned short ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "port numbers of SIP servers");
-
static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
module_param(sip_timeout, uint, 0600);
MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
@@ -1764,8 +1758,8 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff,
return process_sip_msg(skb, ct, protoff, dataoff, &dptr, &datalen);
}
-static struct nf_conntrack_helper sip[MAX_PORTS * 4] __read_mostly;
-static struct nf_conntrack_helper *sip_ptr[MAX_PORTS * 4] __read_mostly;
+static struct nf_conntrack_helper sip[2] __read_mostly;
+static struct nf_conntrack_helper *sip_ptr[2] __read_mostly;
static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = {
[SIP_EXPECT_SIGNALLING] = {
@@ -1792,38 +1786,25 @@ static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1
static void __exit nf_conntrack_sip_fini(void)
{
- nf_conntrack_helpers_unregister(sip_ptr, ports_c * 4);
+ nf_conntrack_helpers_unregister(sip_ptr, 2);
}
static int __init nf_conntrack_sip_init(void)
{
- int i, ret;
+ int ret;
NF_CT_HELPER_BUILD_BUG_ON(sizeof(struct nf_ct_sip_master));
- if (ports_c == 0)
- ports[ports_c++] = SIP_PORT;
-
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
- NULL, THIS_MODULE);
- nf_ct_helper_init(&sip[4 * i + 1], AF_INET, IPPROTO_TCP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
- NULL, THIS_MODULE);
- nf_ct_helper_init(&sip[4 * i + 2], AF_INET6, IPPROTO_UDP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
- NULL, THIS_MODULE);
- nf_ct_helper_init(&sip[4 * i + 3], AF_INET6, IPPROTO_TCP,
- HELPER_NAME, SIP_PORT, ports[i], i,
- sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
- NULL, THIS_MODULE);
- }
+ nf_ct_helper_init(&sip[0], NFPROTO_UNSPEC, IPPROTO_UDP,
+ HELPER_NAME,
+ sip_exp_policy, SIP_EXPECT_MAX, sip_help_udp,
+ NULL, THIS_MODULE);
+ nf_ct_helper_init(&sip[1], NFPROTO_UNSPEC, IPPROTO_TCP,
+ HELPER_NAME,
+ sip_exp_policy, SIP_EXPECT_MAX, sip_help_tcp,
+ NULL, THIS_MODULE);
- ret = nf_conntrack_helpers_register(sip, ports_c * 4, sip_ptr);
+ ret = nf_conntrack_helpers_register(sip, 2, sip_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
diff --git a/net/netfilter/nf_conntrack_snmp.c b/net/netfilter/nf_conntrack_snmp.c
index b6fce5703fce..109986d5d55e 100644
--- a/net/netfilter/nf_conntrack_snmp.c
+++ b/net/netfilter/nf_conntrack_snmp.c
@@ -14,8 +14,6 @@
#include <net/netfilter/nf_conntrack_expect.h>
#include <linux/netfilter/nf_conntrack_snmp.h>
-#define SNMP_PORT 161
-
MODULE_AUTHOR("Jiri Olsa <jolsa@redhat.com>");
MODULE_DESCRIPTION("SNMP service broadcast connection tracking helper");
MODULE_LICENSE("GPL");
@@ -55,7 +53,7 @@ static int __init nf_conntrack_snmp_init(void)
exp_policy.timeout = timeout;
nf_ct_helper_init(&helper, AF_INET, IPPROTO_UDP,
- "snmp", SNMP_PORT, SNMP_PORT, SNMP_PORT,
+ "snmp",
&exp_policy, 0, snmp_conntrack_help, NULL,
THIS_MODULE);
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
index 4393c435aa35..a69559edf9b3 100644
--- a/net/netfilter/nf_conntrack_tftp.c
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -26,12 +26,6 @@ MODULE_LICENSE("GPL");
MODULE_ALIAS("ip_conntrack_tftp");
MODULE_ALIAS_NFCT_HELPER(HELPER_NAME);
-#define MAX_PORTS 8
-static unsigned short ports[MAX_PORTS];
-static unsigned int ports_c;
-module_param_array(ports, ushort, &ports_c, 0400);
-MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
-
nf_nat_tftp_hook_fn __rcu *nf_nat_tftp_hook __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);
@@ -95,8 +89,8 @@ static int tftp_help(struct sk_buff *skb,
return ret;
}
-static struct nf_conntrack_helper tftp[MAX_PORTS * 2] __read_mostly;
-static struct nf_conntrack_helper *tftp_ptr[MAX_PORTS * 2] __read_mostly;
+static struct nf_conntrack_helper tftp __read_mostly;
+static struct nf_conntrack_helper *tftp_ptr __read_mostly;
static const struct nf_conntrack_expect_policy tftp_exp_policy = {
.max_expected = 1,
@@ -105,30 +99,21 @@ static const struct nf_conntrack_expect_policy tftp_exp_policy = {
static void __exit nf_conntrack_tftp_fini(void)
{
- nf_conntrack_helpers_unregister(tftp_ptr, ports_c * 2);
+ nf_conntrack_helper_unregister(tftp_ptr);
}
static int __init nf_conntrack_tftp_init(void)
{
- int i, ret;
+ int ret;
NF_CT_HELPER_BUILD_BUG_ON(0);
- if (ports_c == 0)
- ports[ports_c++] = TFTP_PORT;
-
- for (i = 0; i < ports_c; i++) {
- nf_ct_helper_init(&tftp[2 * i], AF_INET, IPPROTO_UDP,
- HELPER_NAME, TFTP_PORT, ports[i], i,
- &tftp_exp_policy, 0, tftp_help, NULL,
- THIS_MODULE);
- nf_ct_helper_init(&tftp[2 * i + 1], AF_INET6, IPPROTO_UDP,
- HELPER_NAME, TFTP_PORT, ports[i], i,
- &tftp_exp_policy, 0, tftp_help, NULL,
- THIS_MODULE);
- }
+ nf_ct_helper_init(&tftp, NFPROTO_UNSPEC, IPPROTO_UDP,
+ HELPER_NAME,
+ &tftp_exp_policy, 0, tftp_help, NULL,
+ THIS_MODULE);
- ret = nf_conntrack_helpers_register(tftp, ports_c * 2, tftp_ptr);
+ ret = nf_conntrack_helper_register(&tftp, &tftp_ptr);
if (ret < 0) {
pr_err("failed to register helpers\n");
return ret;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 09/12] netfilter: conntrack: get rid of tuple in helper definitions
From: Florian Westphal @ 2026-07-02 10:50 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
Leftover from the days when the kernel did automatic assignment of helpers
based on a pre-registered / well-known-port.
This helper autoassign was removed from the kernel, so all we really
need are the l3 and l4 protocol numbers.
In the broadcast helper, the only remaining consumer of the port number is
removed. AFAICS its not needed: The expectation is populated from the
control connection reply tuple, so the src port is the original directions
destination (snmp/161 for example).
LLM complained about silent l3num (u16) -> nfproto (u8) truncation, so
add a netlink policy validation to reject large NFPROTO values upfront.
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/net/netfilter/nf_conntrack_helper.h | 9 ++++-----
net/netfilter/nf_conntrack_broadcast.c | 2 --
net/netfilter/nf_conntrack_helper.c | 22 +++++++++------------
net/netfilter/nf_conntrack_ovs.c | 6 +++---
net/netfilter/nfnetlink_cthelper.c | 21 ++++++++++----------
net/sched/act_ct.c | 4 ++--
6 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h
index c761cd8158b2..f3f0c1392e88 100644
--- a/include/net/netfilter/nf_conntrack_helper.h
+++ b/include/net/netfilter/nf_conntrack_helper.h
@@ -43,11 +43,10 @@ struct nf_conntrack_helper {
refcount_t ct_refcnt;
- /* Tuple of things we will help (compared against server response) */
- struct nf_conntrack_tuple tuple;
+ u8 nfproto; /* NFPROTO_*, can be NFPROTO_UNSPEC */
+ u8 l4proto; /* IPPROTO_UDP/TCP */
- /* Function to call when data passes; return verdict, or -1 to
- invalidate. */
+ /* Function to call when data passes; return verdict */
int __rcu (*help)(struct sk_buff *skb, unsigned int protoff,
struct nf_conn *ct,
enum ip_conntrack_info conntrackinfo);
@@ -94,7 +93,7 @@ struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
void nf_conntrack_helper_put(struct nf_conntrack_helper *helper);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
- u16 l3num, u16 protonum, const char *name,
+ u8 l3num, u16 protonum, const char *name,
u16 default_port, u16 spec_port, u32 id,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
diff --git a/net/netfilter/nf_conntrack_broadcast.c b/net/netfilter/nf_conntrack_broadcast.c
index bf78828c7549..6ff954f1bfb8 100644
--- a/net/netfilter/nf_conntrack_broadcast.c
+++ b/net/netfilter/nf_conntrack_broadcast.c
@@ -66,8 +66,6 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb,
exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
helper = rcu_dereference(help->helper);
- if (helper)
- exp->tuple.src.u.udp.port = helper->tuple.src.u.udp.port;
exp->mask.src.u3.ip = mask;
exp->mask.src.u.udp.port = htons(0xFFFF);
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 5ad5429352a7..b28986100db0 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -66,12 +66,9 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)
hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
if (strcmp(h->name, name))
continue;
-
- if (h->tuple.src.l3num != NFPROTO_UNSPEC &&
- h->tuple.src.l3num != l3num)
+ if (h->nfproto != NFPROTO_UNSPEC && h->nfproto != l3num)
continue;
-
- if (h->tuple.dst.protonum == protonum)
+ if (h->l4proto == protonum)
return h;
}
return NULL;
@@ -388,13 +385,13 @@ int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
return -EINVAL;
}
- h = helper_hash(me->name, me->tuple.dst.protonum);
+ h = helper_hash(me->name, me->l4proto);
mutex_lock(&nf_ct_helper_mutex);
hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
if (!strcmp(cur->name, me->name) &&
- (cur->tuple.src.l3num == NFPROTO_UNSPEC ||
- cur->tuple.src.l3num == me->tuple.src.l3num) &&
- cur->tuple.dst.protonum == me->tuple.dst.protonum) {
+ (cur->nfproto == NFPROTO_UNSPEC ||
+ cur->nfproto == me->nfproto) &&
+ cur->l4proto == me->l4proto) {
ret = -EBUSY;
goto out;
}
@@ -474,7 +471,7 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
- u16 l3num, u16 protonum, const char *name,
+ u8 l3num, u16 protonum, const char *name,
u16 default_port, u16 spec_port, u32 id,
const struct nf_conntrack_expect_policy *exp_pol,
u32 expect_class_max,
@@ -487,9 +484,8 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper,
{
memset(helper, 0, sizeof(*helper));
- helper->tuple.src.l3num = l3num;
- helper->tuple.dst.protonum = protonum;
- helper->tuple.src.u.all = htons(spec_port);
+ helper->nfproto = l3num;
+ helper->l4proto = protonum;
rcu_assign_pointer(helper->help, help);
helper->from_nlattr = from_nlattr;
diff --git a/net/netfilter/nf_conntrack_ovs.c b/net/netfilter/nf_conntrack_ovs.c
index 49d1511e9921..b4085af3ad1c 100644
--- a/net/netfilter/nf_conntrack_ovs.c
+++ b/net/netfilter/nf_conntrack_ovs.c
@@ -31,8 +31,8 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
if (!helper)
return NF_ACCEPT;
- if (helper->tuple.src.l3num != NFPROTO_UNSPEC &&
- helper->tuple.src.l3num != proto)
+ if (helper->nfproto != NFPROTO_UNSPEC &&
+ helper->nfproto != proto)
return NF_ACCEPT;
switch (proto) {
@@ -60,7 +60,7 @@ int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
return NF_DROP;
}
- if (helper->tuple.dst.protonum != proto)
+ if (helper->l4proto != proto)
return NF_ACCEPT;
helper_cb = rcu_dereference(helper->help);
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c
index f1460b683d7a..56655cb7fe2a 100644
--- a/net/netfilter/nfnetlink_cthelper.c
+++ b/net/netfilter/nfnetlink_cthelper.c
@@ -67,7 +67,7 @@ nfnl_userspace_cthelper(struct sk_buff *skb, unsigned int protoff,
}
static const struct nla_policy nfnl_cthelper_tuple_pol[NFCTH_TUPLE_MAX+1] = {
- [NFCTH_TUPLE_L3PROTONUM] = { .type = NLA_U16, },
+ [NFCTH_TUPLE_L3PROTONUM] = NLA_POLICY_MAX(NLA_BE16, NFPROTO_IPV6),
[NFCTH_TUPLE_L4PROTONUM] = { .type = NLA_U8, },
};
@@ -254,7 +254,8 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
helper->data_len = size;
helper->flags |= NF_CT_HELPER_F_USERSPACE;
- memcpy(&helper->tuple, tuple, sizeof(struct nf_conntrack_tuple));
+ helper->nfproto = tuple->src.l3num;
+ helper->l4proto = tuple->dst.protonum;
helper->me = THIS_MODULE;
helper->help = nfnl_userspace_cthelper;
@@ -449,8 +450,8 @@ static int nfnl_cthelper_new(struct sk_buff *skb, const struct nfnl_info *info,
if (strncmp(cur->name, helper_name, NF_CT_HELPER_NAME_LEN))
continue;
- if ((tuple.src.l3num != cur->tuple.src.l3num ||
- tuple.dst.protonum != cur->tuple.dst.protonum))
+ if ((tuple.src.l3num != cur->nfproto ||
+ tuple.dst.protonum != cur->l4proto))
continue;
if (info->nlh->nlmsg_flags & NLM_F_EXCL)
@@ -479,10 +480,10 @@ nfnl_cthelper_dump_tuple(struct sk_buff *skb,
goto nla_put_failure;
if (nla_put_be16(skb, NFCTH_TUPLE_L3PROTONUM,
- htons(helper->tuple.src.l3num)))
+ htons(helper->nfproto)))
goto nla_put_failure;
- if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->tuple.dst.protonum))
+ if (nla_put_u8(skb, NFCTH_TUPLE_L4PROTONUM, helper->l4proto))
goto nla_put_failure;
nla_nest_end(skb, nest_parms);
@@ -661,8 +662,8 @@ static int nfnl_cthelper_get(struct sk_buff *skb, const struct nfnl_info *info,
continue;
if (tuple_set &&
- (tuple.src.l3num != cur->tuple.src.l3num ||
- tuple.dst.protonum != cur->tuple.dst.protonum))
+ (tuple.src.l3num != cur->nfproto ||
+ tuple.dst.protonum != cur->l4proto))
continue;
skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -721,8 +722,8 @@ static int nfnl_cthelper_del(struct sk_buff *skb, const struct nfnl_info *info,
continue;
if (tuple_set &&
- (tuple.src.l3num != cur->tuple.src.l3num ||
- tuple.dst.protonum != cur->tuple.dst.protonum))
+ (tuple.src.l3num != cur->nfproto ||
+ tuple.dst.protonum != cur->l4proto))
continue;
found = true;
diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index be535a261fa0..4ca7964e83c8 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1527,8 +1527,8 @@ static int tcf_ct_dump_helper(struct sk_buff *skb,
return 0;
if (nla_put_string(skb, TCA_CT_HELPER_NAME, helper->name) ||
- nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper->tuple.src.l3num) ||
- nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper->tuple.dst.protonum))
+ nla_put_u8(skb, TCA_CT_HELPER_FAMILY, helper->nfproto) ||
+ nla_put_u8(skb, TCA_CT_HELPER_PROTO, helper->l4proto))
return -1;
return 0;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 08/12] netfilter: nf_conntrack_helper: do not hash by tuple
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
Long time ago helpers were auto-assigned to connections based on
port/protocol match. For this reason, nf_conntrack_helper still contains
a full tuple.
Nowadays the only relevant entries in the tuple are the l3 and l4 protocol
numbers.
Prepare for tuple removal and switch to hashing name and l4 protocol.
l3num cannot be used because helpers can also register for "unspec"
protocol.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nf_conntrack_helper.c | 67 +++++++++++++----------------
1 file changed, 31 insertions(+), 36 deletions(-)
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 500509b17663..5ad5429352a7 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -40,12 +40,16 @@ static unsigned int nf_ct_helper_count __read_mostly;
static DEFINE_MUTEX(nf_ct_nat_helpers_mutex);
static struct list_head nf_ct_nat_helpers __read_mostly;
-/* Stupid hash, but collision free for the default registrations of the
- * helpers currently in the kernel. */
-static unsigned int helper_hash(const struct nf_conntrack_tuple *tuple)
+static unsigned int helper_hash(const char *name, u8 protonum)
{
- return (((tuple->src.l3num << 8) | tuple->dst.protonum) ^
- (__force __u16)tuple->src.u.all) % nf_ct_helper_hsize;
+ static u32 seed;
+ u32 initval;
+
+ get_random_once(&seed, sizeof(seed));
+
+ initval = seed ^ protonum;
+
+ return jhash(name, strlen(name), initval) % nf_ct_helper_hsize;
}
struct nf_conntrack_helper *
@@ -54,18 +58,21 @@ __nf_conntrack_helper_find(const char *name, u16 l3num, u8 protonum)
struct nf_conntrack_helper *h;
unsigned int i;
- for (i = 0; i < nf_ct_helper_hsize; i++) {
- hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
- if (strcmp(h->name, name))
- continue;
+ if (!nf_ct_helper_hash)
+ return NULL;
- if (h->tuple.src.l3num != NFPROTO_UNSPEC &&
- h->tuple.src.l3num != l3num)
- continue;
+ i = helper_hash(name, protonum);
- if (h->tuple.dst.protonum == protonum)
- return h;
- }
+ hlist_for_each_entry_rcu(h, &nf_ct_helper_hash[i], hnode) {
+ if (strcmp(h->name, name))
+ continue;
+
+ if (h->tuple.src.l3num != NFPROTO_UNSPEC &&
+ h->tuple.src.l3num != l3num)
+ continue;
+
+ if (h->tuple.dst.protonum == protonum)
+ return h;
}
return NULL;
}
@@ -363,9 +370,8 @@ EXPORT_SYMBOL_GPL(nf_ct_helper_log);
int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
{
- struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };
- unsigned int h = helper_hash(&me->tuple);
struct nf_conntrack_helper *cur;
+ unsigned int h;
int ret = 0, i;
BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
@@ -382,29 +388,18 @@ int __nf_conntrack_helper_register(struct nf_conntrack_helper *me)
return -EINVAL;
}
+ h = helper_hash(me->name, me->tuple.dst.protonum);
mutex_lock(&nf_ct_helper_mutex);
- for (i = 0; i < nf_ct_helper_hsize; i++) {
- hlist_for_each_entry(cur, &nf_ct_helper_hash[i], hnode) {
- if (!strcmp(cur->name, me->name) &&
- (cur->tuple.src.l3num == NFPROTO_UNSPEC ||
- cur->tuple.src.l3num == me->tuple.src.l3num) &&
- cur->tuple.dst.protonum == me->tuple.dst.protonum) {
- ret = -EBUSY;
- goto out;
- }
+ hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
+ if (!strcmp(cur->name, me->name) &&
+ (cur->tuple.src.l3num == NFPROTO_UNSPEC ||
+ cur->tuple.src.l3num == me->tuple.src.l3num) &&
+ cur->tuple.dst.protonum == me->tuple.dst.protonum) {
+ ret = -EBUSY;
+ goto out;
}
}
- /* avoid unpredictable behaviour for auto_assign_helper */
- if (!(me->flags & NF_CT_HELPER_F_USERSPACE)) {
- hlist_for_each_entry(cur, &nf_ct_helper_hash[h], hnode) {
- if (nf_ct_tuple_src_mask_cmp(&cur->tuple, &me->tuple,
- &mask)) {
- ret = -EBUSY;
- goto out;
- }
- }
- }
refcount_set(&me->ct_refcnt, 1);
hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
nf_ct_helper_count++;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 07/12] netfilter: xt_dscp: add checkentry for tos match
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Feng Wu <wufengwufengwufeng@gmail.com>
The 'tos' match registered in xt_dscp.c has no .checkentry callback,
allowing userspace to insert rules with a non-boolean invert field
without any validation.
Add tos_mt_check() that rejects invert > 1 and attach it to both the
IPv4 and IPv6 'tos' match registrations.
Signed-off-by: Feng Wu <wufengwufengwufeng@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/xt_dscp.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index fb0169a8f9bb..878f27016e99 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -49,6 +49,16 @@ static int dscp_mt_check(const struct xt_mtchk_param *par)
return 0;
}
+static int tos_mt_check(const struct xt_mtchk_param *par)
+{
+ const struct xt_tos_match_info *info = par->matchinfo;
+
+ if (info->invert > 1)
+ return -EINVAL;
+
+ return 0;
+}
+
static bool tos_mt(const struct sk_buff *skb, struct xt_action_param *par)
{
const struct xt_tos_match_info *info = par->matchinfo;
@@ -82,6 +92,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
.name = "tos",
.revision = 1,
.family = NFPROTO_IPV4,
+ .checkentry = tos_mt_check,
.match = tos_mt,
.matchsize = sizeof(struct xt_tos_match_info),
.me = THIS_MODULE,
@@ -90,6 +101,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
.name = "tos",
.revision = 1,
.family = NFPROTO_IPV6,
+ .checkentry = tos_mt_check,
.match = tos_mt,
.matchsize = sizeof(struct xt_tos_match_info),
.me = THIS_MODULE,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 06/12] netfilter: xt_tcpmss: add checkentry for parameter validation
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Feng Wu <wufengwufengwufeng@gmail.com>
Add tcpmss_mt_check() that validates mss_min <= mss_max and
invert <= 1.
Signed-off-by: Feng Wu <wufengwufengwufeng@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/xt_tcpmss.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index b9da8269161d..b08b077d7f0a 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -78,10 +78,23 @@ tcpmss_mt(const struct sk_buff *skb, struct xt_action_param *par)
return false;
}
+static int tcpmss_mt_check(const struct xt_mtchk_param *par)
+{
+ const struct xt_tcpmss_match_info *info = par->matchinfo;
+
+ if (info->mss_min > info->mss_max)
+ return -EINVAL;
+ if (info->invert > 1)
+ return -EINVAL;
+
+ return 0;
+}
+
static struct xt_match tcpmss_mt_reg[] __read_mostly = {
{
.name = "tcpmss",
.family = NFPROTO_IPV4,
+ .checkentry = tcpmss_mt_check,
.match = tcpmss_mt,
.matchsize = sizeof(struct xt_tcpmss_match_info),
.proto = IPPROTO_TCP,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 05/12] netfilter: remove redundant null check before kvfree()
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Subasri S <subasris1210@gmail.com>
kvfree() internally performs NULL check on the pointer
handed to it and takes no action if it indeed is NULL.
Hence there is no need for a pre-check of the memory
pointer before handing it to kvfree().
Issue reported by ifnullfree.cocci Coccinelle semantic
patch script.
Signed-off-by: Subasri S <subasris1210@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nft_set_rbtree.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c
index 018bbb6df4ce..efc25e788a1c 100644
--- a/net/netfilter/nft_set_rbtree.c
+++ b/net/netfilter/nft_set_rbtree.c
@@ -544,8 +544,7 @@ static int nft_array_intervals_alloc(struct nft_array *array, u32 max_intervals)
if (!intervals)
return -ENOMEM;
- if (array->intervals)
- kvfree(array->intervals);
+ kvfree(array->intervals);
array->intervals = intervals;
array->max_intervals = max_intervals;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 04/12] netfilter: avoid strcpy usage
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: David Laight <david.laight.linux@gmail.com>
Replacing strcpy() with strscpy() ensures that overflow of the target
buffer cannot happen.
[ fw@strlen.de: cleanup. netlink policy rejects too large inputs,
xt_recent validates content and length before the copy ]
Signed-off-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nfnetlink_cttimeout.c | 2 +-
net/netfilter/xt_recent.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c
index 170d3db860c5..66c2016f6049 100644
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -168,7 +168,7 @@ static int cttimeout_new_timeout(struct sk_buff *skb,
if (ret < 0)
goto err_free_timeout_policy;
- strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
+ nla_strscpy(timeout->name, cda[CTA_TIMEOUT_NAME], sizeof(timeout->name));
timeout->timeout->l3num = l3num;
timeout->timeout->l4proto = l4proto;
refcount_set(&timeout->timeout->refcnt, 1);
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index f72752fa4374..d34831ce3adf 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -400,7 +400,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
t->nstamps_max_mask = nstamp_mask;
memcpy(&t->mask, &info->mask, sizeof(t->mask));
- strcpy(t->name, info->name);
+ strscpy(t->name, info->name);
INIT_LIST_HEAD(&t->lru_list);
for (i = 0; i < ip_list_hash_size; i++)
INIT_LIST_HEAD(&t->iphash[i]);
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 03/12] netfilter: replace u_int8_t and u_int16t with u8 and u16
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Carlos Grillet <carlos@carlosgrillet.me>
Use preferred kernel integer type u8 instead of the POSIX u_int8_t
variant.
No functional change.
Signed-off-by: Carlos Grillet <carlos@carlosgrillet.me>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/net/ip_vs.h | 2 +-
net/netfilter/ipvs/ip_vs_nfct.c | 2 +-
net/netfilter/nf_conntrack_amanda.c | 2 +-
net/netfilter/nf_conntrack_h323_main.c | 2 +-
net/netfilter/xt_TCPOPTSTRIP.c | 8 ++++----
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 49297fec448a..ed2e9bc1bb4e 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -2123,7 +2123,7 @@ void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp,
int outin);
int ip_vs_confirm_conntrack(struct sk_buff *skb);
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
- struct ip_vs_conn *cp, u_int8_t proto,
+ struct ip_vs_conn *cp, u8 proto,
const __be16 port, int from_rs);
void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp);
diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c
index 81974f69e5bb..347185fd0c8c 100644
--- a/net/netfilter/ipvs/ip_vs_nfct.c
+++ b/net/netfilter/ipvs/ip_vs_nfct.c
@@ -208,7 +208,7 @@ static void ip_vs_nfct_expect_callback(struct nf_conn *ct,
* Use port 0 to expect connection from any port.
*/
void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct,
- struct ip_vs_conn *cp, u_int8_t proto,
+ struct ip_vs_conn *cp, u8 proto,
const __be16 port, int from_rs)
{
struct nf_conntrack_expect *exp;
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
index ddafbdfc96dc..f10ac2c49f4b 100644
--- a/net/netfilter/nf_conntrack_amanda.c
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -89,7 +89,7 @@ static int amanda_help(struct sk_buff *skb,
struct nf_conntrack_tuple *tuple;
unsigned int dataoff, start, stop, off, i;
char pbuf[sizeof("65535")], *tmp;
- u_int16_t len;
+ u16 len;
__be16 port;
int ret = NF_ACCEPT;
nf_nat_amanda_hook_fn *nf_nat_amanda;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 24931e379985..37b6314ca772 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -671,7 +671,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
static int callforward_do_filter(struct net *net,
const union nf_inet_addr *src,
const union nf_inet_addr *dst,
- u_int8_t family)
+ u8 family)
{
int ret = 0;
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index 93f064306901..265d21697847 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -16,7 +16,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_TCPOPTSTRIP.h>
-static inline unsigned int optlen(const u_int8_t *opt, unsigned int offset)
+static inline unsigned int optlen(const u8 *opt, unsigned int offset)
{
/* Beware zero-length options: make finite progress */
if (opt[offset] <= TCPOPT_NOP || opt[offset+1] == 0)
@@ -33,8 +33,8 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
const struct xt_tcpoptstrip_target_info *info = par->targinfo;
struct tcphdr *tcph, _th;
unsigned int optl, i, j;
- u_int16_t n, o;
- u_int8_t *opt;
+ u16 n, o;
+ u8 *opt;
int tcp_hdrlen;
/* This is a fragment, no TCP header is available */
@@ -97,7 +97,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_action_param *par)
{
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
int tcphoff;
- u_int8_t nexthdr;
+ u8 nexthdr;
__be16 frag_off;
nexthdr = ipv6h->nexthdr;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 02/12] netfilter: x_tables: replace strlcat() with snprintf()
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Ian Bridges <icb@fastmail.org>
In preparation for removing the deprecated strlcat() API[1], replace the
strscpy()/strlcat() pairs in xt_proto_init() and xt_proto_fini() with
snprintf(), which builds each /proc file name in a single call.
Each name is "<prefix><suffix>", where <prefix> is the address-family
string xt_prefix[af] and <suffix> is one of the FORMAT_TABLES,
FORMAT_MATCHES or FORMAT_TARGETS literals. Prepend %s to the FORMAT
macros and switch to snprintf().
Link: https://github.com/KSPP/linux/issues/370 [1]
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/x_tables.c | 30 +++++++++++-------------------
1 file changed, 11 insertions(+), 19 deletions(-)
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 4e6708c23922..e64116bf2637 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -1920,9 +1920,9 @@ static const struct seq_operations xt_target_seq_ops = {
.show = xt_target_seq_show,
};
-#define FORMAT_TABLES "_tables_names"
-#define FORMAT_MATCHES "_tables_matches"
-#define FORMAT_TARGETS "_tables_targets"
+#define FORMAT_TABLES "%s_tables_names"
+#define FORMAT_MATCHES "%s_tables_matches"
+#define FORMAT_TARGETS "%s_tables_targets"
#endif /* CONFIG_PROC_FS */
@@ -2033,8 +2033,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
root_uid = make_kuid(net->user_ns, 0);
root_gid = make_kgid(net->user_ns, 0);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TABLES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
proc = proc_create_net_data(buf, 0440, net->proc_net, &xt_table_seq_ops,
sizeof(struct seq_net_private),
(void *)(unsigned long)af);
@@ -2043,8 +2042,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
if (uid_valid(root_uid) && gid_valid(root_gid))
proc_set_user(proc, root_uid, root_gid);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
proc = proc_create_seq_private(buf, 0440, net->proc_net,
&xt_match_seq_ops, sizeof(struct nf_mttg_trav),
(void *)(unsigned long)af);
@@ -2053,8 +2051,7 @@ int xt_proto_init(struct net *net, u_int8_t af)
if (uid_valid(root_uid) && gid_valid(root_gid))
proc_set_user(proc, root_uid, root_gid);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TARGETS, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);
proc = proc_create_seq_private(buf, 0440, net->proc_net,
&xt_target_seq_ops, sizeof(struct nf_mttg_trav),
(void *)(unsigned long)af);
@@ -2068,13 +2065,11 @@ int xt_proto_init(struct net *net, u_int8_t af)
#ifdef CONFIG_PROC_FS
out_remove_matches:
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
out_remove_tables:
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TABLES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
out:
return -1;
@@ -2087,16 +2082,13 @@ void xt_proto_fini(struct net *net, u_int8_t af)
#ifdef CONFIG_PROC_FS
char buf[XT_FUNCTION_MAXNAMELEN];
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TABLES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TABLES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_TARGETS, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_TARGETS, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
- strscpy(buf, xt_prefix[af], sizeof(buf));
- strlcat(buf, FORMAT_MATCHES, sizeof(buf));
+ snprintf(buf, sizeof(buf), FORMAT_MATCHES, xt_prefix[af]);
remove_proc_entry(buf, net->proc_net);
#endif /*CONFIG_PROC_FS*/
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 01/12] netfilter: nfnetlink_hook: Dump nat type chains
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
In-Reply-To: <20260702105003.13550-1-fw@strlen.de>
From: Phil Sutter <phil@nwl.cc>
These chains are indirectly attached to the hook since they are
not called for packets belonging to an established connection.
Introduce NF_HOOK_OP_NAT to identify the container and dump attached
entries instead of the container itself.
Dump these entries with the dispatcher's priority value since their own
priority merely defines ordering within the dispatcher's list.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/linux/netfilter.h | 7 +++++++
net/netfilter/nf_nat_core.c | 6 ------
net/netfilter/nf_nat_proto.c | 8 ++++++++
net/netfilter/nfnetlink_hook.c | 37 ++++++++++++++++++++++++++++++----
4 files changed, 48 insertions(+), 10 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index efbbfa770d66..e99afc1414cd 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -93,6 +93,7 @@ enum nf_hook_ops_type {
NF_HOOK_OP_NF_TABLES,
NF_HOOK_OP_BPF,
NF_HOOK_OP_NFT_FT,
+ NF_HOOK_OP_NAT,
};
struct nf_hook_ops {
@@ -140,6 +141,12 @@ struct nf_hook_entries {
*/
};
+struct nf_nat_lookup_hook_priv {
+ struct nf_hook_entries __rcu *entries;
+
+ struct rcu_head rcu_head;
+};
+
#ifdef CONFIG_NETFILTER
static inline struct nf_hook_ops **nf_hook_entries_get_hook_ops(const struct nf_hook_entries *e)
{
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index 63ff6b4d5d21..8ac326e1eb5b 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -39,12 +39,6 @@ static struct hlist_head *nf_nat_bysource __read_mostly;
static unsigned int nf_nat_htable_size __read_mostly;
static siphash_aligned_key_t nf_nat_hash_rnd;
-struct nf_nat_lookup_hook_priv {
- struct nf_hook_entries __rcu *entries;
-
- struct rcu_head rcu_head;
-};
-
struct nf_nat_hooks_net {
struct nf_hook_ops *nat_hook_ops;
unsigned int users;
diff --git a/net/netfilter/nf_nat_proto.c b/net/netfilter/nf_nat_proto.c
index 07f51fe75fbe..64b9bac228ea 100644
--- a/net/netfilter/nf_nat_proto.c
+++ b/net/netfilter/nf_nat_proto.c
@@ -770,6 +770,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -777,6 +778,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* Before packet filtering, change destination */
{
@@ -784,6 +786,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -791,6 +794,7 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
};
@@ -1031,6 +1035,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP6_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -1038,6 +1043,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP6_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* Before packet filtering, change destination */
{
@@ -1045,6 +1051,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_OUT,
.priority = NF_IP6_PRI_NAT_DST,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
/* After packet filtering, change source */
{
@@ -1052,6 +1059,7 @@ static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP6_PRI_NAT_SRC,
+ .hook_ops_type = NF_HOOK_OP_NAT,
},
};
diff --git a/net/netfilter/nfnetlink_hook.c b/net/netfilter/nfnetlink_hook.c
index 5623c18fcd12..95005e9a6066 100644
--- a/net/netfilter/nfnetlink_hook.c
+++ b/net/netfilter/nfnetlink_hook.c
@@ -190,7 +190,7 @@ static int nfnl_hook_put_nft_ft_info(struct sk_buff *nlskb,
static int nfnl_hook_dump_one(struct sk_buff *nlskb,
const struct nfnl_dump_hook_data *ctx,
- const struct nf_hook_ops *ops,
+ const struct nf_hook_ops *ops, int priority,
int family, unsigned int seq)
{
u16 event = nfnl_msg_type(NFNL_SUBSYS_HOOK, NFNL_MSG_HOOK_GET);
@@ -244,7 +244,7 @@ static int nfnl_hook_dump_one(struct sk_buff *nlskb,
if (ret)
goto nla_put_failure;
- ret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(ops->priority));
+ ret = nla_put_be32(nlskb, NFNLA_HOOK_PRIORITY, htonl(priority));
if (ret)
goto nla_put_failure;
@@ -337,6 +337,30 @@ nfnl_hook_entries_head(u8 pf, unsigned int hook, struct net *net, const char *de
return hook_head;
}
+static int nfnl_hook_dump_nat(struct sk_buff *nlskb,
+ const struct nfnl_dump_hook_data *ctx,
+ const struct nf_hook_ops *ops,
+ int family, unsigned int seq)
+{
+ struct nf_nat_lookup_hook_priv *priv = ops->priv;
+ struct nf_hook_entries *e = rcu_dereference(priv->entries);
+ struct nf_hook_ops **nat_ops;
+ int i, err;
+
+ if (!e)
+ return 0;
+
+ nat_ops = nf_hook_entries_get_hook_ops(e);
+
+ for (i = 0; i < e->num_hook_entries; i++) {
+ err = nfnl_hook_dump_one(nlskb, ctx, nat_ops[i],
+ ops->priority, family, seq);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
static int nfnl_hook_dump(struct sk_buff *nlskb,
struct netlink_callback *cb)
{
@@ -365,8 +389,13 @@ static int nfnl_hook_dump(struct sk_buff *nlskb,
ops = nf_hook_entries_get_hook_ops(e);
for (; i < e->num_hook_entries; i++) {
- err = nfnl_hook_dump_one(nlskb, ctx, ops[i], family,
- cb->nlh->nlmsg_seq);
+ if (ops[i]->hook_ops_type == NF_HOOK_OP_NAT)
+ err = nfnl_hook_dump_nat(nlskb, ctx, ops[i], family,
+ cb->nlh->nlmsg_seq);
+ else
+ err = nfnl_hook_dump_one(nlskb, ctx, ops[i],
+ ops[i]->priority, family,
+ cb->nlh->nlmsg_seq);
if (err)
break;
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 00/12] netfilter: updates for net-next
From: Florian Westphal @ 2026-07-02 10:49 UTC (permalink / raw)
To: netdev
Cc: Paolo Abeni, David S. Miller, Eric Dumazet, Jakub Kicinski,
netfilter-devel, pablo
Hi,
The following patchset contains Netfilter updates for *net-next*.
1) Update nfnetlink_hook to dump the individual NAT type chains
instead of the nat base chains to userspace. From Phil Sutter.
2) Replace strlcpy/strlcat() with snprintf() in x_tables, from Ian Bridges.
3) Start replacing u_int8_t and u_int16t with u8 and u16 in netfilter.
From Carlos Grillet.
4) Replace strcpy() with strscpy() in netfilter, from David Laight.
5) Remove redundant NULL check before kvfree().
6) Add parameter validation to xt_tcpmss. Ensure mss_min <= mss_max and
invert <= 1. From Feng Wu.
7) Add checkentry for xt_dscp 'tos' match. Implement tos_mt_check() to reject
invalid invert values. Also from Feng Wu.
8) Stop hashing nf_conntrack_helper by tuple. Switch to hashing by name and
L4 protocol.
9) Remove tuples from conntrack helper definitions and port usage from
broadcast helpers. Add netlink policy validation to prevent protocol
number truncation.
10) Remove obsolete netfilter conntrack module parameters.
11) Bound num_counters in ebtables: do_replace() by MAX_EBT_ENTRIES to prevent
oversized vmalloc_array() allocations. From Jiayuan Chen.
12) Make expectations created via nft_ct rules work with NAT.
Please, pull these changes from:
The following changes since commit b8ea7da314c2efcb9c2f559ed65b7a36c869d68e:
net: dsa: qca8k: fall back to ethernet-ports node name for LEDs (2026-07-02 11:48:25 +0200)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next.git tags/nf-next-26-07-02
for you to fetch changes up to d4beefc90a66672e43fdf82b43e4b3c0b1b18c5e:
netfilter: nft_ct: support expectation creation for natted flows (2026-07-02 12:17:14 +0200)
----------------------------------------------------------------
netfilter pull request nf-next-26-07-02
----------------------------------------------------------------
Carlos Grillet (1):
netfilter: replace u_int8_t and u_int16t with u8 and u16
David Laight (1):
netfilter: avoid strcpy usage
Feng Wu (2):
netfilter: xt_tcpmss: add checkentry for parameter validation
netfilter: xt_dscp: add checkentry for tos match
Florian Westphal (4):
netfilter: nf_conntrack_helper: do not hash by tuple
netfilter: conntrack: get rid of tuple in helper definitions
netfilter: conntrack: remove obsolete module parameters
netfilter: nft_ct: support expectation creation for natted flows
Ian Bridges (1):
netfilter: x_tables: replace strlcat() with snprintf()
Jiayuan Chen (1):
netfilter: ebtables: bound num_counters like nentries in do_replace()
Phil Sutter (1):
netfilter: nfnetlink_hook: Dump nat type chains
Subasri S (1):
netfilter: remove redundant null check before kvfree()
include/linux/netfilter.h | 7 ++
include/linux/netfilter/nf_conntrack_h323.h | 2 -
include/linux/netfilter/nf_conntrack_pptp.h | 2 -
include/linux/netfilter/nf_conntrack_sane.h | 2 -
include/linux/netfilter/nf_conntrack_tftp.h | 2 -
include/net/ip_vs.h | 2 +-
include/net/netfilter/nf_conntrack_helper.h | 10 ++-
net/bridge/netfilter/ebtables.c | 12 ++--
net/ipv4/netfilter/nf_nat_snmp_basic_main.c | 2 +-
net/netfilter/ipvs/ip_vs_nfct.c | 2 +-
net/netfilter/nf_conntrack_amanda.c | 6 +-
net/netfilter/nf_conntrack_broadcast.c | 2 -
net/netfilter/nf_conntrack_ftp.c | 32 +++------
net/netfilter/nf_conntrack_h323_main.c | 12 ++--
net/netfilter/nf_conntrack_helper.c | 77 +++++++++------------
net/netfilter/nf_conntrack_irc.c | 27 +++-----
net/netfilter/nf_conntrack_netbios_ns.c | 2 -
net/netfilter/nf_conntrack_ovs.c | 6 +-
net/netfilter/nf_conntrack_pptp.c | 2 +-
net/netfilter/nf_conntrack_sane.c | 34 +++------
net/netfilter/nf_conntrack_sip.c | 45 ++++--------
net/netfilter/nf_conntrack_snmp.c | 4 +-
net/netfilter/nf_conntrack_tftp.c | 33 +++------
net/netfilter/nf_nat_core.c | 6 --
net/netfilter/nf_nat_proto.c | 8 +++
net/netfilter/nfnetlink_cthelper.c | 21 +++---
net/netfilter/nfnetlink_cttimeout.c | 2 +-
net/netfilter/nfnetlink_hook.c | 37 ++++++++--
net/netfilter/nft_ct.c | 35 ++++++++++
net/netfilter/nft_set_rbtree.c | 3 +-
net/netfilter/x_tables.c | 30 +++-----
net/netfilter/xt_TCPOPTSTRIP.c | 8 +--
net/netfilter/xt_dscp.c | 12 ++++
net/netfilter/xt_recent.c | 2 +-
net/netfilter/xt_tcpmss.c | 13 ++++
net/sched/act_ct.c | 4 +-
36 files changed, 246 insertions(+), 260 deletions(-)
--
2.54.0
^ permalink raw reply
* Re: [PATCH net-next v3 05/15] net: macb: enforce reverse christmas tree (RCT) convention
From: Nicolai Buchwitz @ 2026-07-02 10:48 UTC (permalink / raw)
To: Théo Lebrun
Cc: Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Richard Cochran, Russell King,
netdev, linux-kernel, Nicolas Ferre, Claudiu Beznea,
Paolo Valerio, Vladimir Kondratiev, Gregory CLEMENT,
Benoît Monin, Tawfik Bayouk, Thomas Petazzoni,
Maxime Chevallier
In-Reply-To: <20260701-macb-context-v3-5-00268d5b1502@bootlin.com>
On 1.7.2026 17:59, Théo Lebrun wrote:
> Enforce the reverse christmas tree convention in those functions:
>
> macb_tx_error_task()
> gem_rx_refill()
> gem_rx()
> macb_rx_frame()
> macb_init_rx_ring()
> macb_rx()
> macb_rx_pending()
> macb_start_xmit()
>
> The goal is to minimise unrelated diff in future patches.
>
> In macb_tx_error_task(), we fold the assignment into the declaration
> statement.
>
> Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
> ---
> drivers/net/ethernet/cadence/macb_main.c | 61
> ++++++++++++++++----------------
> 1 file changed, 30 insertions(+), 31 deletions(-)
>
> diff --git a/drivers/net/ethernet/cadence/macb_main.c
> b/drivers/net/ethernet/cadence/macb_main.c
> index 3b75797381b6..8b52122bc134 100644
> --- a/drivers/net/ethernet/cadence/macb_main.c
> +++ b/drivers/net/ethernet/cadence/macb_main.c
> @@ -1254,20 +1254,19 @@ static dma_addr_t macb_get_addr(struct macb
> *bp, struct macb_dma_desc *desc)
>
> static void macb_tx_error_task(struct work_struct *work)
> {
> - struct macb_queue *queue = container_of(work, struct macb_queue,
> - tx_error_task);
> - bool halt_timeout = false;
> - struct macb *bp = queue->bp;
> - unsigned int q;
> - u32 packets = 0;
> - u32 bytes = 0;
> - struct macb_tx_skb *tx_skb;
> - struct macb_dma_desc *desc;
> - struct sk_buff *skb;
> - unsigned int tail;
> - unsigned long flags;
> + struct macb_queue *queue = container_of(work, struct macb_queue,
> + tx_error_task);
> + unsigned int q = queue - queue->bp->queues;
> + struct macb *bp = queue->bp;
> + struct macb_tx_skb *tx_skb;
> + struct macb_dma_desc *desc;
> + bool halt_timeout = false;
> + struct sk_buff *skb;
> + unsigned long flags;
> + unsigned int tail;
> + u32 packets = 0;
> + u32 bytes = 0;
>
> - q = queue - bp->queues;
> netdev_vdbg(bp->netdev, "macb_tx_error_task: q = %u, t = %u, h =
> %u\n",
> q, queue->tx_tail, queue->tx_head);
>
> @@ -1487,11 +1486,11 @@ static int macb_tx_complete(struct macb_queue
> *queue, int budget)
>
> static void gem_rx_refill(struct macb_queue *queue)
> {
> - unsigned int entry;
> - struct sk_buff *skb;
> - dma_addr_t paddr;
> struct macb *bp = queue->bp;
> struct macb_dma_desc *desc;
> + struct sk_buff *skb;
> + unsigned int entry;
> + dma_addr_t paddr;
>
> while (CIRC_SPACE(queue->rx_prepared_head, queue->rx_tail,
> bp->rx_ring_size) > 0) {
> @@ -1584,11 +1583,11 @@ static int gem_rx(struct macb_queue *queue,
> struct napi_struct *napi,
> int budget)
> {
> struct macb *bp = queue->bp;
> - unsigned int len;
> - unsigned int entry;
> - struct sk_buff *skb;
> - struct macb_dma_desc *desc;
> - int count = 0;
> + struct macb_dma_desc *desc;
> + struct sk_buff *skb;
> + unsigned int entry;
> + unsigned int len;
> + int count = 0;
>
> while (count < budget) {
> u32 ctrl;
> @@ -1674,12 +1673,12 @@ static int gem_rx(struct macb_queue *queue,
> struct napi_struct *napi,
> static int macb_rx_frame(struct macb_queue *queue, struct napi_struct
> *napi,
> unsigned int first_frag, unsigned int last_frag)
> {
> - unsigned int len;
> - unsigned int frag;
> + struct macb *bp = queue->bp;
> + struct macb_dma_desc *desc;
> unsigned int offset;
> struct sk_buff *skb;
> - struct macb_dma_desc *desc;
> - struct macb *bp = queue->bp;
> + unsigned int frag;
> + unsigned int len;
>
> desc = macb_rx_desc(queue, last_frag);
> len = desc->ctrl & bp->rx_frm_len_mask;
> @@ -1755,9 +1754,9 @@ static int macb_rx_frame(struct macb_queue
> *queue, struct napi_struct *napi,
>
> static inline void macb_init_rx_ring(struct macb_queue *queue)
> {
> + struct macb_dma_desc *desc = NULL;
> struct macb *bp = queue->bp;
> dma_addr_t addr;
> - struct macb_dma_desc *desc = NULL;
> int i;
>
> addr = queue->rx_buffers_dma;
> @@ -1776,9 +1775,9 @@ static int macb_rx(struct macb_queue *queue,
> struct napi_struct *napi,
> {
> struct macb *bp = queue->bp;
> bool reset_rx_queue = false;
> - int received = 0;
> - unsigned int tail;
> int first_frag = -1;
> + unsigned int tail;
> + int received = 0;
>
> for (tail = queue->rx_tail; budget > 0; tail++) {
> struct macb_dma_desc *desc = macb_rx_desc(queue, tail);
> @@ -1853,8 +1852,8 @@ static int macb_rx(struct macb_queue *queue,
> struct napi_struct *napi,
> static bool macb_rx_pending(struct macb_queue *queue)
> {
> struct macb *bp = queue->bp;
> - unsigned int entry;
> - struct macb_dma_desc *desc;
> + struct macb_dma_desc *desc;
> + unsigned int entry;
>
> entry = macb_rx_ring_wrap(bp, queue->rx_tail);
> desc = macb_rx_desc(queue, entry);
> @@ -2474,10 +2473,10 @@ static netdev_tx_t macb_start_xmit(struct
> sk_buff *skb,
> unsigned int q = skb_get_queue_mapping(skb);
> unsigned int desc_cnt, nr_frags, frag_size, f;
> struct macb_queue *queue = &bp->queues[q];
> + netdev_tx_t ret = NETDEV_TX_OK;
> unsigned int hdrlen;
> unsigned long flags;
> bool is_lso;
> - netdev_tx_t ret = NETDEV_TX_OK;
>
> if (macb_clear_csum(skb)) {
> dev_kfree_skb_any(skb);
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Thanks
Nicolai
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox