+++ /dev/null
-From d8e3fbedb617d8fdb48d015c523938560b1fc86c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 21 Apr 2026 16:20:47 +0300
-Subject: ALSA: usb-audio: fix null pointer dereference on pointer cs_desc
-
-From: Chengfeng Ye <cyeaa@connect.ust.hk>
-
-commit b97053df0f04747c3c1e021ecbe99db675342954 upstream.
-
-The pointer cs_desc return from snd_usb_find_clock_source could
-be null, so there is a potential null pointer dereference issue.
-Fix this by adding a null check before dereference.
-
-Signed-off-by: Chengfeng Ye <cyeaa@connect.ust.hk>
-Link: https://lore.kernel.org/r/20211024111736.11342-1-cyeaa@connect.ust.hk
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Fixes: 1dc669fed61a ("ALSA: usb-audio: UAC2: support read-only freq control")
-[ kovalev: bp to fix CVE-2021-47211; added Fixes tag; the null
- check was added into both UAC2 and UAC3 branches since the
- older kernel still has the clock source lookup split between
- snd_usb_find_clock_source() and snd_usb_find_clock_source_v3()
- (see upstream commit 9ec730052fa2) ]
-Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/clock.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/sound/usb/clock.c b/sound/usb/clock.c
-index 197a6b7d8ad6f..3d5d4f3aafce4 100644
---- a/sound/usb/clock.c
-+++ b/sound/usb/clock.c
-@@ -646,11 +646,17 @@ static int set_sample_rate_v2v3(struct snd_usb_audio *chip, int iface,
- struct uac3_clock_source_descriptor *cs_desc;
-
- cs_desc = snd_usb_find_clock_source_v3(chip->ctrl_intf, clock);
-+
-+ if (!cs_desc)
-+ return 0;
- bmControls = le32_to_cpu(cs_desc->bmControls);
- } else {
- struct uac_clock_source_descriptor *cs_desc;
-
- cs_desc = snd_usb_find_clock_source(chip->ctrl_intf, clock);
-+
-+ if (!cs_desc)
-+ return 0;
- bmControls = cs_desc->bmControls;
- }
-
---
-2.53.0
-
+++ /dev/null
-From f990e2f722bf2bd15d323544c6c87b57ebec20f3 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 19 Mar 2026 21:45:26 -0300
-Subject: ASoC: SOF: topology: reject invalid vendor array size in token parser
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
-
-[ Upstream commit 215e5fe75881a7e2425df04aeeed47a903d5cd5d ]
-
-sof_parse_token_sets() accepts array->size values that can be invalid
-for a vendor tuple array header. In particular, a zero size does not
-advance the parser state and can lead to non-progress parsing on
-malformed topology data.
-
-Validate array->size against the minimum header size and reject values
-smaller than sizeof(*array) before parsing. This preserves behavior for
-valid topologies and hardens malformed-input handling.
-
-Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
-Acked-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
-Link: https://patch.msgid.link/20260319-sof-topology-array-size-fix-v1-1-f9191b16b1b7@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/soc/sof/topology.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
-index e3aa9fa0f112f..b1682879253f6 100644
---- a/sound/soc/sof/topology.c
-+++ b/sound/soc/sof/topology.c
-@@ -941,7 +941,7 @@ static int sof_parse_token_sets(struct snd_soc_component *scomp,
- asize = le32_to_cpu(array->size);
-
- /* validate asize */
-- if (asize < 0) { /* FIXME: A zero-size array makes no sense */
-+ if (asize < sizeof(*array)) {
- dev_err(scomp->dev, "error: invalid array size 0x%x\n",
- asize);
- return -EINVAL;
---
-2.53.0
-
+++ /dev/null
-From e63fb1379f4b9300a44739964e69549bebbcdca4 Mon Sep 17 00:00:00 2001
-From: Yosry Ahmed <yosry.ahmed@linux.dev>
-Date: Tue, 10 Feb 2026 01:08:06 +0000
-Subject: KVM: nSVM: Mark all of vmcb02 dirty when restoring nested state
-
-From: Yosry Ahmed <yosry.ahmed@linux.dev>
-
-commit e63fb1379f4b9300a44739964e69549bebbcdca4 upstream.
-
-When restoring a vCPU in guest mode, any state restored before
-KVM_SET_NESTED_STATE (e.g. KVM_SET_SREGS) will mark the corresponding
-dirty bits in vmcb01, as it is the active VMCB before switching to
-vmcb02 in svm_set_nested_state().
-
-Hence, mark all fields in vmcb02 dirty in svm_set_nested_state() to
-capture any previously restored fields.
-
-Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
-CC: stable@vger.kernel.org
-Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
-Link: https://patch.msgid.link/20260210010806.3204289-1-yosry.ahmed@linux.dev
-Signed-off-by: Sean Christopherson <seanjc@google.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/kvm/svm/nested.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/arch/x86/kvm/svm/nested.c
-+++ b/arch/x86/kvm/svm/nested.c
-@@ -1236,6 +1236,12 @@ static int svm_set_nested_state(struct k
- goto out_free;
-
- /*
-+ * Any previously restored state (e.g. KVM_SET_SREGS) would mark fields
-+ * dirty in vmcb01 instead of vmcb02, so mark all of vmcb02 dirty here.
-+ */
-+ vmcb_mark_all_dirty(svm->vmcb);
-+
-+ /*
- * All checks done, we can enter guest mode. L1 control fields
- * come from the nested save state. Guest state is already
- * in the registers, the save area of the nested state instead
+++ /dev/null
-From 778d8c1b2a6ffe622ddcd3bb35b620e6e41f4da0 Mon Sep 17 00:00:00 2001
-From: Yosry Ahmed <yosry@kernel.org>
-Date: Wed, 25 Feb 2026 00:59:43 +0000
-Subject: KVM: nSVM: Sync NextRIP to cached vmcb12 after VMRUN of L2
-
-From: Yosry Ahmed <yosry@kernel.org>
-
-commit 778d8c1b2a6ffe622ddcd3bb35b620e6e41f4da0 upstream.
-
-After VMRUN in guest mode, nested_sync_control_from_vmcb02() syncs
-fields written by the CPU from vmcb02 to the cached vmcb12. This is
-because the cached vmcb12 is used as the authoritative copy of some of
-the controls, and is the payload when saving/restoring nested state.
-
-NextRIP is also written by the CPU (in some cases) after VMRUN, but is
-not sync'd to the cached vmcb12. As a result, it is corrupted after
-save/restore (replaced by the original value written by L1 on nested
-VMRUN). This could cause problems for both KVM (e.g. when injecting a
-soft IRQ) or L1 (e.g. when using NextRIP to advance RIP after emulating
-an instruction).
-
-Fix this by sync'ing NextRIP to the cache after VMRUN of L2, but only
-after completing interrupts (not in nested_sync_control_from_vmcb02()),
-as KVM may update NextRIP (e.g. when re-injecting a soft IRQ).
-
-Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
-CC: stable@vger.kernel.org
-Co-developed-by: Sean Christopherson <seanjc@google.com>
-Signed-off-by: Yosry Ahmed <yosry@kernel.org>
-Link: https://patch.msgid.link/20260225005950.3739782-2-yosry@kernel.org
-Signed-off-by: Sean Christopherson <seanjc@google.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/kvm/svm/svm.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/x86/kvm/svm/svm.c
-+++ b/arch/x86/kvm/svm/svm.c
-@@ -3677,6 +3677,16 @@ static __no_kcsan fastpath_t svm_vcpu_ru
- if (is_guest_mode(vcpu))
- return EXIT_FASTPATH_NONE;
-
-+ /*
-+ * Update the cache after completing interrupts to get an accurate
-+ * NextRIP, e.g. when re-injecting a soft interrupt.
-+ *
-+ * FIXME: Rework svm_get_nested_state() to not pull data from the
-+ * cache (except for maybe int_ctl).
-+ */
-+ if (is_guest_mode(vcpu))
-+ svm->nested.ctl.next_rip = svm->vmcb->control.next_rip;
-+
- return svm_exit_handlers_fastpath(vcpu);
- }
-
+++ /dev/null
-From 0f72edd2379b50618a7a80d37194ad2afcceda5f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 14 Apr 2026 11:01:12 +0000
-Subject: media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID
-
-From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
-
-[ Upstream commit 0e2ee70291e64a30fe36960c85294726d34a103e ]
-
-Per UVC 1.1+ specification 3.7.2, units and terminals must have a non-zero
-unique ID.
-
-```
-Each Unit and Terminal within the video function is assigned a unique
-identification number, the Unit ID (UID) or Terminal ID (TID), contained in
-the bUnitID or bTerminalID field of the descriptor. The value 0x00 is
-reserved for undefined ID,
-```
-
-If we add a new entity with id 0 or a duplicated ID, it will be marked
-as UVC_INVALID_ENTITY_ID.
-
-In a previous attempt commit 3dd075fe8ebb ("media: uvcvideo: Require
-entities to have a non-zero unique ID"), we ignored all the invalid units,
-this broke a lot of non-compatible cameras. Hopefully we are more lucky
-this time.
-
-This also prevents some syzkaller reproducers from triggering warnings due
-to a chain of entities referring to themselves. In one particular case, an
-Output Unit is connected to an Input Unit, both with the same ID of 1. But
-when looking up for the source ID of the Output Unit, that same entity is
-found instead of the input entity, which leads to such warnings.
-
-In another case, a backward chain was considered finished as the source ID
-was 0. Later on, that entity was found, but its pads were not valid.
-
-Here is a sample stack trace for one of those cases.
-
-[ 20.650953] usb 1-1: new high-speed USB device number 2 using dummy_hcd
-[ 20.830206] usb 1-1: Using ep0 maxpacket: 8
-[ 20.833501] usb 1-1: config 0 descriptor??
-[ 21.038518] usb 1-1: string descriptor 0 read error: -71
-[ 21.038893] usb 1-1: Found UVC 0.00 device <unnamed> (2833:0201)
-[ 21.039299] uvcvideo 1-1:0.0: Entity type for entity Output 1 was not initialized!
-[ 21.041583] uvcvideo 1-1:0.0: Entity type for entity Input 1 was not initialized!
-[ 21.042218] ------------[ cut here ]------------
-[ 21.042536] WARNING: CPU: 0 PID: 9 at drivers/media/mc/mc-entity.c:1147 media_create_pad_link+0x2c4/0x2e0
-[ 21.043195] Modules linked in:
-[ 21.043535] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:1 Not tainted 6.11.0-rc7-00030-g3480e43aeccf #444
-[ 21.044101] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
-[ 21.044639] Workqueue: usb_hub_wq hub_event
-[ 21.045100] RIP: 0010:media_create_pad_link+0x2c4/0x2e0
-[ 21.045508] Code: fe e8 20 01 00 00 b8 f4 ff ff ff 48 83 c4 30 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc 0f 0b eb e9 0f 0b eb 0a 0f 0b eb 06 <0f> 0b eb 02 0f 0b b8 ea ff ff ff eb d4 66 2e 0f 1f 84 00 00 00 00
-[ 21.046801] RSP: 0018:ffffc9000004b318 EFLAGS: 00010246
-[ 21.047227] RAX: ffff888004e5d458 RBX: 0000000000000000 RCX: ffffffff818fccf1
-[ 21.047719] RDX: 000000000000007b RSI: 0000000000000000 RDI: ffff888004313290
-[ 21.048241] RBP: ffff888004313290 R08: 0001ffffffffffff R09: 0000000000000000
-[ 21.048701] R10: 0000000000000013 R11: 0001888004313290 R12: 0000000000000003
-[ 21.049138] R13: ffff888004313080 R14: ffff888004313080 R15: 0000000000000000
-[ 21.049648] FS: 0000000000000000(0000) GS:ffff88803ec00000(0000) knlGS:0000000000000000
-[ 21.050271] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-[ 21.050688] CR2: 0000592cc27635b0 CR3: 000000000431c000 CR4: 0000000000750ef0
-[ 21.051136] PKRU: 55555554
-[ 21.051331] Call Trace:
-[ 21.051480] <TASK>
-[ 21.051611] ? __warn+0xc4/0x210
-[ 21.051861] ? media_create_pad_link+0x2c4/0x2e0
-[ 21.052252] ? report_bug+0x11b/0x1a0
-[ 21.052540] ? trace_hardirqs_on+0x31/0x40
-[ 21.052901] ? handle_bug+0x3d/0x70
-[ 21.053197] ? exc_invalid_op+0x1a/0x50
-[ 21.053511] ? asm_exc_invalid_op+0x1a/0x20
-[ 21.053924] ? media_create_pad_link+0x91/0x2e0
-[ 21.054364] ? media_create_pad_link+0x2c4/0x2e0
-[ 21.054834] ? media_create_pad_link+0x91/0x2e0
-[ 21.055131] ? _raw_spin_unlock+0x1e/0x40
-[ 21.055441] ? __v4l2_device_register_subdev+0x202/0x210
-[ 21.055837] uvc_mc_register_entities+0x358/0x400
-[ 21.056144] uvc_register_chains+0x1fd/0x290
-[ 21.056413] uvc_probe+0x380e/0x3dc0
-[ 21.056676] ? __lock_acquire+0x5aa/0x26e0
-[ 21.056946] ? find_held_lock+0x33/0xa0
-[ 21.057196] ? kernfs_activate+0x70/0x80
-[ 21.057533] ? usb_match_dynamic_id+0x1b/0x70
-[ 21.057811] ? find_held_lock+0x33/0xa0
-[ 21.058047] ? usb_match_dynamic_id+0x55/0x70
-[ 21.058330] ? lock_release+0x124/0x260
-[ 21.058657] ? usb_match_one_id_intf+0xa2/0x100
-[ 21.058997] usb_probe_interface+0x1ba/0x330
-[ 21.059399] really_probe+0x1ba/0x4c0
-[ 21.059662] __driver_probe_device+0xb2/0x180
-[ 21.059944] driver_probe_device+0x5a/0x100
-[ 21.060170] __device_attach_driver+0xe9/0x160
-[ 21.060427] ? __pfx___device_attach_driver+0x10/0x10
-[ 21.060872] bus_for_each_drv+0xa9/0x100
-[ 21.061312] __device_attach+0xed/0x190
-[ 21.061812] device_initial_probe+0xe/0x20
-[ 21.062229] bus_probe_device+0x4d/0xd0
-[ 21.062590] device_add+0x308/0x590
-[ 21.062912] usb_set_configuration+0x7b6/0xaf0
-[ 21.063403] usb_generic_driver_probe+0x36/0x80
-[ 21.063714] usb_probe_device+0x7b/0x130
-[ 21.063936] really_probe+0x1ba/0x4c0
-[ 21.064111] __driver_probe_device+0xb2/0x180
-[ 21.064577] driver_probe_device+0x5a/0x100
-[ 21.065019] __device_attach_driver+0xe9/0x160
-[ 21.065403] ? __pfx___device_attach_driver+0x10/0x10
-[ 21.065820] bus_for_each_drv+0xa9/0x100
-[ 21.066094] __device_attach+0xed/0x190
-[ 21.066535] device_initial_probe+0xe/0x20
-[ 21.066992] bus_probe_device+0x4d/0xd0
-[ 21.067250] device_add+0x308/0x590
-[ 21.067501] usb_new_device+0x347/0x610
-[ 21.067817] hub_event+0x156b/0x1e30
-[ 21.068060] ? process_scheduled_works+0x48b/0xaf0
-[ 21.068337] process_scheduled_works+0x5a3/0xaf0
-[ 21.068668] worker_thread+0x3cf/0x560
-[ 21.068932] ? kthread+0x109/0x1b0
-[ 21.069133] kthread+0x197/0x1b0
-[ 21.069343] ? __pfx_worker_thread+0x10/0x10
-[ 21.069598] ? __pfx_kthread+0x10/0x10
-[ 21.069908] ret_from_fork+0x32/0x40
-[ 21.070169] ? __pfx_kthread+0x10/0x10
-[ 21.070424] ret_from_fork_asm+0x1a/0x30
-[ 21.070737] </TASK>
-
-Reported-by: syzbot+0584f746fde3d52b4675@syzkaller.appspotmail.com
-Closes: https://syzkaller.appspot.com/bug?extid=0584f746fde3d52b4675
-Reported-by: syzbot+dd320d114deb3f5bb79b@syzkaller.appspotmail.com
-Closes: https://syzkaller.appspot.com/bug?extid=dd320d114deb3f5bb79b
-Reported-by: Youngjun Lee <yjjuny.lee@samsung.com>
-Fixes: a3fbc2e6bb05 ("media: mc-entity.c: use WARN_ON, validate link pads")
-Cc: stable@vger.kernel.org
-Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
-Co-developed-by: Ricardo Ribalda <ribalda@chromium.org>
-Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
-Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Reviewed-by: Hans de Goede <hansg@kernel.org>
-Signed-off-by: Hans de Goede <hansg@kernel.org>
-Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/media/usb/uvc/uvc_driver.c | 66 +++++++++++++++++++-----------
- drivers/media/usb/uvc/uvcvideo.h | 2 +
- 2 files changed, 44 insertions(+), 24 deletions(-)
-
-diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
-index c2adc6854c540..34e3f04340a23 100644
---- a/drivers/media/usb/uvc/uvc_driver.c
-+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -412,6 +412,9 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
- {
- struct uvc_entity *entity;
-
-+ if (id == UVC_INVALID_ENTITY_ID)
-+ return NULL;
-+
- list_for_each_entry(entity, &dev->entities, list) {
- if (entity->id == id)
- return entity;
-@@ -1032,14 +1035,27 @@ static int uvc_parse_streaming(struct uvc_device *dev,
- return ret;
- }
-
--static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
-- unsigned int num_pads, unsigned int extra_size)
-+static struct uvc_entity *uvc_alloc_new_entity(struct uvc_device *dev, u16 type,
-+ u16 id, unsigned int num_pads,
-+ unsigned int extra_size)
- {
- struct uvc_entity *entity;
- unsigned int num_inputs;
- unsigned int size;
- unsigned int i;
-
-+ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */
-+ if (id == 0) {
-+ dev_err(&dev->intf->dev, "Found Unit with invalid ID 0\n");
-+ id = UVC_INVALID_ENTITY_ID;
-+ }
-+
-+ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */
-+ if (uvc_entity_by_id(dev, id)) {
-+ dev_err(&dev->intf->dev, "Found multiple Units with ID %u\n", id);
-+ id = UVC_INVALID_ENTITY_ID;
-+ }
-+
- extra_size = roundup(extra_size, sizeof(*entity->pads));
- if (num_pads)
- num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1;
-@@ -1049,7 +1065,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
- + num_inputs;
- entity = kzalloc(size, GFP_KERNEL);
- if (entity == NULL)
-- return NULL;
-+ return ERR_PTR(-ENOMEM);
-
- entity->id = id;
- entity->type = type;
-@@ -1120,10 +1136,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
- break;
- }
-
-- unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
-- p + 1, 2*n);
-- if (unit == NULL)
-- return -ENOMEM;
-+ unit = uvc_alloc_new_entity(dev, UVC_VC_EXTENSION_UNIT,
-+ buffer[3], p + 1, 2 * n);
-+ if (IS_ERR(unit))
-+ return PTR_ERR(unit);
-
- memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
- unit->extension.bNumControls = buffer[20];
-@@ -1234,10 +1250,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
- return -EINVAL;
- }
-
-- term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
-- 1, n + p);
-- if (term == NULL)
-- return -ENOMEM;
-+ term = uvc_alloc_new_entity(dev, type | UVC_TERM_INPUT,
-+ buffer[3], 1, n + p);
-+ if (IS_ERR(term))
-+ return PTR_ERR(term);
-
- if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
- term->camera.bControlSize = n;
-@@ -1293,10 +1309,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
- return 0;
- }
-
-- term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
-- 1, 0);
-- if (term == NULL)
-- return -ENOMEM;
-+ term = uvc_alloc_new_entity(dev, type | UVC_TERM_OUTPUT,
-+ buffer[3], 1, 0);
-+ if (IS_ERR(term))
-+ return PTR_ERR(term);
-
- memcpy(term->baSourceID, &buffer[7], 1);
-
-@@ -1317,9 +1333,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
- return -EINVAL;
- }
-
-- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
-- if (unit == NULL)
-- return -ENOMEM;
-+ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],
-+ p + 1, 0);
-+ if (IS_ERR(unit))
-+ return PTR_ERR(unit);
-
- memcpy(unit->baSourceID, &buffer[5], p);
-
-@@ -1341,9 +1358,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
- return -EINVAL;
- }
-
-- unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
-- if (unit == NULL)
-- return -ENOMEM;
-+ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3], 2, n);
-+ if (IS_ERR(unit))
-+ return PTR_ERR(unit);
-
- memcpy(unit->baSourceID, &buffer[4], 1);
- unit->processing.wMaxMultiplier =
-@@ -1372,9 +1389,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
- return -EINVAL;
- }
-
-- unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
-- if (unit == NULL)
-- return -ENOMEM;
-+ unit = uvc_alloc_new_entity(dev, buffer[2], buffer[3],
-+ p + 1, n);
-+ if (IS_ERR(unit))
-+ return PTR_ERR(unit);
-
- memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
- unit->extension.bNumControls = buffer[20];
-diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
-index a83995276170b..46ec07ef1ef5a 100644
---- a/drivers/media/usb/uvc/uvcvideo.h
-+++ b/drivers/media/usb/uvc/uvcvideo.h
-@@ -170,6 +170,8 @@
- 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
-
-
-+#define UVC_INVALID_ENTITY_ID 0xffff
-+
- /* ------------------------------------------------------------------------
- * Driver specific constants.
- */
---
-2.53.0
-
+++ /dev/null
-From dd8f8e5b1d5789d2f2b8ddd71cd77241a9cb831c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 14 Apr 2026 11:01:13 +0000
-Subject: media: uvcvideo: Use heuristic to find stream entity
-
-From: Ricardo Ribalda <ribalda@chromium.org>
-
-[ Upstream commit 758dbc756aad429da11c569c0d067f7fd032bcf7 ]
-
-Some devices, like the Grandstream GUV3100 webcam, have an invalid UVC
-descriptor where multiple entities share the same ID, this is invalid
-and makes it impossible to make a proper entity tree without heuristics.
-
-We have recently introduced a change in the way that we handle invalid
-entities that has caused a regression on broken devices.
-
-Implement a new heuristic to handle these devices properly.
-
-Reported-by: Angel4005 <ooara1337@gmail.com>
-Closes: https://lore.kernel.org/linux-media/CAOzBiVuS7ygUjjhCbyWg-KiNx+HFTYnqH5+GJhd6cYsNLT=DaA@mail.gmail.com/
-Fixes: 0e2ee70291e6 ("media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID")
-Cc: stable@vger.kernel.org
-Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
-Reviewed-by: Hans de Goede <hansg@kernel.org>
-Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
-Tested-by: Ron Economos <re@w6rz.net>
-Tested-by: Pavel Machek (CIP) <pavel@nabladev.com>
-Tested-by: Brett A C Sheffield <bacs@librecast.net>
-Tested-by: Mark Brown <broonie@kernel.org>
-Tested-by: Barry K. Nathan <barryn@pobox.com>
-Tested-by: Peter Schneider <pschneider1968@googlemail.com>
-Tested-by: Francesco Dolcini <francesco.dolcini@toradex.com>
-Tested-by: Shuah Khan <skhan@linuxfoundation.org>
-Tested-by: Jon Hunter <jonathanh@nvidia.com>
-Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
-Tested-by: Miguel Ojeda <ojeda@kernel.org>
-Tested-by: Vijayendra Suman <vijayendra.suman@oracle.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/media/usb/uvc/uvc_driver.c | 15 ++++++++++++++-
- 1 file changed, 14 insertions(+), 1 deletion(-)
-
-diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
-index 34e3f04340a23..20a18caf77176 100644
---- a/drivers/media/usb/uvc/uvc_driver.c
-+++ b/drivers/media/usb/uvc/uvc_driver.c
-@@ -442,13 +442,26 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
-
- static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
- {
-- struct uvc_streaming *stream;
-+ struct uvc_streaming *stream, *last_stream;
-+ unsigned int count = 0;
-
- list_for_each_entry(stream, &dev->streams, list) {
-+ count += 1;
-+ last_stream = stream;
- if (stream->header.bTerminalLink == id)
- return stream;
- }
-
-+ /*
-+ * If the streaming entity is referenced by an invalid ID, notify the
-+ * user and use heuristics to guess the correct entity.
-+ */
-+ if (count == 1 && id == UVC_INVALID_ENTITY_ID) {
-+ dev_warn(&dev->intf->dev,
-+ "UVC non compliance: Invalid USB header. The streaming entity has an invalid ID, guessing the correct one.");
-+ return last_stream;
-+ }
-+
- return NULL;
- }
-
---
-2.53.0
-
+++ /dev/null
-From stable+bounces-237688-greg=kroah.com@vger.kernel.org Tue Apr 14 02:30:17 2026
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 13 Apr 2026 20:29:48 -0400
-Subject: rxrpc: Fix key quota calculation for multitoken keys
-To: stable@vger.kernel.org
-Cc: David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Jeffrey Altman <jaltman@auristor.com>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
-Message-ID: <20260414002948.3802454-1-sashal@kernel.org>
-
-From: David Howells <dhowells@redhat.com>
-
-[ Upstream commit bdbfead6d38979475df0c2f4bad2b19394fe9bdc ]
-
-In the rxrpc key preparsing, every token extracted sets the proposed quota
-value, but for multitoken keys, this will overwrite the previous proposed
-quota, losing it.
-
-Fix this by adding to the proposed quota instead.
-
-Fixes: 8a7a3eb4ddbe ("KEYS: RxRPC: Use key preparsing")
-Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
-Signed-off-by: David Howells <dhowells@redhat.com>
-cc: Marc Dionne <marc.dionne@auristor.com>
-cc: Jeffrey Altman <jaltman@auristor.com>
-cc: Simon Horman <horms@kernel.org>
-cc: linux-afs@lists.infradead.org
-cc: stable@kernel.org
-Link: https://patch.msgid.link/20260408121252.2249051-2-dhowells@redhat.com
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-[ dropped hunk for rxrpc_preparse_xdr_yfs_rxgk() ]
-Signed-off-by: Sasha Levin <sashal@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- net/rxrpc/key.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
---- a/net/rxrpc/key.c
-+++ b/net/rxrpc/key.c
-@@ -108,7 +108,7 @@ static int rxrpc_preparse_xdr_rxkad(stru
- return -EKEYREJECTED;
-
- plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
-- prep->quotalen = datalen + plen;
-+ prep->quotalen += datalen + plen;
-
- plen -= sizeof(*token);
- token = kzalloc(sizeof(*token), GFP_KERNEL);
-@@ -718,6 +718,7 @@ static int rxrpc_preparse(struct key_pre
- memcpy(&kver, prep->data, sizeof(kver));
- prep->data += sizeof(kver);
- prep->datalen -= sizeof(kver);
-+ prep->quotalen = 0;
-
- _debug("KEY I/F VERSION: %u", kver);
-
-@@ -755,7 +756,7 @@ static int rxrpc_preparse(struct key_pre
- goto error;
-
- plen = sizeof(*token->kad) + v1->ticket_length;
-- prep->quotalen = plen + sizeof(*token);
-+ prep->quotalen += plen + sizeof(*token);
-
- ret = -ENOMEM;
- token = kzalloc(sizeof(*token), GFP_KERNEL);
alsa-asihpi-avoid-write-overflow-check-warning.patch
-asoc-sof-topology-reject-invalid-vendor-array-size-i.patch
can-mcp251x-add-error-handling-for-power-enable-in-o.patch
btrfs-tracepoints-get-correct-superblock-from-dentry.patch
alsa-hda-realtek-add-mute-led-quirk-for-hp-pavilion-.patch
tracing-probe-reject-non-closed-empty-immediate-stri.patch
e1000-check-return-value-of-e1000_read_eeprom.patch
xsk-tighten-umem-headroom-validation-to-account-for-.patch
-xfrm-wait-for-rcu-readers-during-policy-netns-exit.patch
xfrm_user-fix-info-leak-in-build_mapping.patch
netfilter-nfnetlink_log-initialize-nfgenmsg-in-nlmsg.patch
netfilter-xt_multiport-validate-range-encoding-in-ch.patch
rxrpc-proc-size-address-buffers-for-pispc-output.patch
revert-wifi-cfg80211-stop-nan-and-p2p-in-cfg80211_le.patch
media-uvcvideo-allow-extra-entities.patch
-media-uvcvideo-mark-invalid-entities-with-id-uvc_inv.patch
-media-uvcvideo-use-heuristic-to-find-stream-entity.patch
checkpatch-add-support-for-assisted-by-tag.patch
kvm-x86-use-scratch-field-in-mmio-fragment-to-hold-small-write-values.patch
mm-kasan-fix-double-free-for-kasan-pxds.patch
drm-amd-display-fix-memory-leak.patch
thermal-int340x_thermal-handle-data_vault-when-the-v.patch
blk-cgroup-reinit-blkg_iostat_set-after-clearing-in-.patch
-alsa-usb-audio-fix-null-pointer-dereference-on-point.patch
scsi-ufs-core-improve-scsi-abort-handling.patch
ib-mad-don-t-call-to-function-that-might-sleep-while.patch
powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch
mailbox-prevent-out-of-bounds-access-in-of_mbox_index_xlate.patch
rxrpc-fix-reference-count-leak-in-rxrpc_server_keyring.patch
-rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch
xfrm-clear-trailing-padding-in-build_polexpire.patch
ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch
ocfs2-validate-inline-data-i_size-during-inode-read.patch
mmc-block-use-single-block-write-in-retry.patch
tpm-tpm_tis-add-error-logging-for-data-transfer.patch
userfaultfd-allow-registration-of-ranges-below-mmap_min_addr.patch
-kvm-nsvm-mark-all-of-vmcb02-dirty-when-restoring-nested-state.patch
-kvm-nsvm-sync-nextrip-to-cached-vmcb12-after-vmrun-of-l2.patch
kvm-nsvm-sync-interrupt-shadow-to-cached-vmcb12-after-vmrun-of-l2.patch
kvm-nsvm-ensure-avic-is-inhibited-when-restoring-a-vcpu-to-guest-mode.patch
kvm-nsvm-clear-gif-on-nested-vmexit-invalid.patch
+++ /dev/null
-From a827b545eb118d6c950519f79aeaa66b34aa97c8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 2 Apr 2026 13:31:04 +0200
-Subject: xfrm: Wait for RCU readers during policy netns exit
-
-From: Steffen Klassert <steffen.klassert@secunet.com>
-
-[ Upstream commit 069daad4f2ae9c5c108131995529d5f02392c446 ]
-
-xfrm_policy_fini() frees the policy_bydst hash tables after flushing the
-policy work items and deleting all policies, but it does not wait for
-concurrent RCU readers to leave their read-side critical sections first.
-
-The policy_bydst tables are published via rcu_assign_pointer() and are
-looked up through rcu_dereference_check(), so netns teardown must also
-wait for an RCU grace period before freeing the table memory.
-
-Fix this by adding synchronize_rcu() before freeing the policy hash tables.
-
-Fixes: e1e551bc5630 ("xfrm: policy: prepare policy_bydst hash for rcu lookups")
-Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-Reviewed-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/xfrm/xfrm_policy.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
-index c4ebfaa0b2ed0..56956abd38180 100644
---- a/net/xfrm/xfrm_policy.c
-+++ b/net/xfrm/xfrm_policy.c
-@@ -4166,6 +4166,8 @@ static void xfrm_policy_fini(struct net *net)
- #endif
- xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false);
-
-+ synchronize_rcu();
-+
- WARN_ON(!list_empty(&net->xfrm.policy_all));
-
- for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
---
-2.53.0
-
+++ /dev/null
-From 33ea23496035b1fdbd2c75f2cd5cc6a77cacf97f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 21 Feb 2026 02:33:45 +1030
-Subject: ALSA: usb-audio: Improve Focusrite sample rate filtering
-
-From: Geoffrey D. Bennett <g@b4.vu>
-
-[ Upstream commit 24d2d3c5f94007a5a0554065ab7349bb69e28bcb ]
-
-Replace the bLength == 10 max_rate check in
-focusrite_valid_sample_rate() with filtering that also examines the
-bmControls VAL_ALT_SETTINGS bit.
-
-When VAL_ALT_SETTINGS is readable, the device uses strict
-per-altsetting rate filtering (only the highest rate pair for that
-altsetting is valid). When it is not readable, all rates up to
-max_rate are valid.
-
-For devices without the bLength == 10 Format Type descriptor extension
-but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen
-in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
-convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
-
-This produces correct rate tables for all tested Focusrite devices
-(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using
-only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed
-for Focusrite in the next commit.
-
-Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/format.c | 86 +++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 74 insertions(+), 12 deletions(-)
-
-diff --git a/sound/usb/format.c b/sound/usb/format.c
-index f33d25a4e4cc7..682adbdf7ee79 100644
---- a/sound/usb/format.c
-+++ b/sound/usb/format.c
-@@ -304,9 +304,37 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
- }
-
- /*
-- * Many Focusrite devices supports a limited set of sampling rates per
-- * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
-- * descriptor which has a non-standard bLength = 10.
-+ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and
-+ * 176400/192000. Return true if rate is in the pair for max_rate.
-+ */
-+static bool focusrite_rate_pair(unsigned int rate,
-+ unsigned int max_rate)
-+{
-+ switch (max_rate) {
-+ case 48000: return rate == 44100 || rate == 48000;
-+ case 96000: return rate == 88200 || rate == 96000;
-+ case 192000: return rate == 176400 || rate == 192000;
-+ default: return true;
-+ }
-+}
-+
-+/*
-+ * Focusrite devices report all supported rates in a single clock
-+ * source but only a subset is valid per altsetting.
-+ *
-+ * Detection uses two descriptor features:
-+ *
-+ * 1. Format Type descriptor bLength == 10: non-standard extension
-+ * with max sample rate in bytes 6..9.
-+ *
-+ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device
-+ * only supports the highest rate pair for that altsetting, and when
-+ * clear, all rates up to max_rate are valid.
-+ *
-+ * For devices without the bLength == 10 extension but with
-+ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in
-+ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
-+ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
- */
- static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
- struct audioformat *fp,
-@@ -314,8 +342,10 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
- {
- struct usb_interface *iface;
- struct usb_host_interface *alts;
-+ struct uac2_as_header_descriptor *as;
- unsigned char *fmt;
- unsigned int max_rate;
-+ bool val_alt;
-
- iface = usb_ifnum_to_if(chip->dev, fp->iface);
- if (!iface)
-@@ -327,26 +357,58 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
- if (!fmt)
- return true;
-
-+ as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
-+ NULL, UAC_AS_GENERAL);
-+ if (!as)
-+ return true;
-+
-+ val_alt = uac_v2v3_control_is_readable(as->bmControls,
-+ UAC2_AS_VAL_ALT_SETTINGS);
-+
- if (fmt[0] == 10) { /* bLength */
- max_rate = combine_quad(&fmt[6]);
-
-- /* Validate max rate */
-- if (max_rate != 48000 &&
-- max_rate != 96000 &&
-- max_rate != 192000 &&
-- max_rate != 384000) {
--
-+ if (val_alt)
-+ return focusrite_rate_pair(rate, max_rate);
-+
-+ /* No val_alt: rates fall through from higher */
-+ switch (max_rate) {
-+ case 192000:
-+ if (rate == 176400 || rate == 192000)
-+ return true;
-+ fallthrough;
-+ case 96000:
-+ if (rate == 88200 || rate == 96000)
-+ return true;
-+ fallthrough;
-+ case 48000:
-+ return (rate == 44100 || rate == 48000);
-+ default:
- usb_audio_info(chip,
- "%u:%d : unexpected max rate: %u\n",
- fp->iface, fp->altsetting, max_rate);
--
- return true;
- }
-+ }
-
-- return rate <= max_rate;
-+ if (!val_alt)
-+ return true;
-+
-+ /* Multi-altsetting device with val_alt but no max_rate
-+ * in the format descriptor. Use Focusrite convention:
-+ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
-+ */
-+ if (iface->num_altsetting <= 2)
-+ return true;
-+
-+ switch (fp->altsetting) {
-+ case 1: max_rate = 48000; break;
-+ case 2: max_rate = 96000; break;
-+ case 3: max_rate = 192000; break;
-+ default: return true;
- }
-
-- return true;
-+ return focusrite_rate_pair(rate, max_rate);
- }
-
- /*
---
-2.53.0
-
+++ /dev/null
-From 9247a4d23e700a19a1168245c0b138c87a0cbfca Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 21 Feb 2026 02:34:48 +1030
-Subject: ALSA: usb-audio: Remove VALIDATE_RATES quirk for Focusrite devices
-
-From: Geoffrey D. Bennett <g@b4.vu>
-
-[ Upstream commit a8cc55bf81a45772cad44c83ea7bb0e98431094a ]
-
-Remove QUIRK_FLAG_VALIDATE_RATES for Focusrite. With the previous
-commit, focusrite_valid_sample_rate() produces correct rate tables
-without USB probing.
-
-QUIRK_FLAG_VALIDATE_RATES sends SET_CUR requests for each rate (~25ms
-each) and leaves the device at 192kHz. This is a problem because that
-rate: 1) disables the internal mixer, so outputs are silent until an
-application opens the PCM and sets a lower rate, and 2) the Air and
-Safe modes get disabled.
-
-Fixes: 5963e5262180 ("ALSA: usb-audio: Enable rate validation for Scarlett devices")
-Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Link: https://patch.msgid.link/09b9c012024c998c4ca14bd876ef0dce0d0b6101.1771594828.git.g@b4.vu
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/quirks.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index acfad87636277..e1c6a38303dfd 100644
---- a/sound/usb/quirks.c
-+++ b/sound/usb/quirks.c
-@@ -1982,7 +1982,7 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
- VENDOR_FLG(0x07fd, /* MOTU */
- QUIRK_FLAG_VALIDATE_RATES),
- VENDOR_FLG(0x1235, /* Focusrite Novation */
-- QUIRK_FLAG_VALIDATE_RATES),
-+ 0),
- VENDOR_FLG(0x1511, /* AURALiC */
- QUIRK_FLAG_DSD_RAW),
- VENDOR_FLG(0x152a, /* Thesycon devices */
---
-2.53.0
-
+++ /dev/null
-From 4f8916e8b21927a009d69184ca5cd1b9bf54157e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 19 Mar 2026 21:45:26 -0300
-Subject: ASoC: SOF: topology: reject invalid vendor array size in token parser
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
-
-[ Upstream commit 215e5fe75881a7e2425df04aeeed47a903d5cd5d ]
-
-sof_parse_token_sets() accepts array->size values that can be invalid
-for a vendor tuple array header. In particular, a zero size does not
-advance the parser state and can lead to non-progress parsing on
-malformed topology data.
-
-Validate array->size against the minimum header size and reject values
-smaller than sizeof(*array) before parsing. This preserves behavior for
-valid topologies and hardens malformed-input handling.
-
-Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
-Acked-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
-Link: https://patch.msgid.link/20260319-sof-topology-array-size-fix-v1-1-f9191b16b1b7@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/soc/sof/topology.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
-index 1bb2dcf37ffe9..16feb5d268022 100644
---- a/sound/soc/sof/topology.c
-+++ b/sound/soc/sof/topology.c
-@@ -941,7 +941,7 @@ static int sof_parse_token_sets(struct snd_soc_component *scomp,
- asize = le32_to_cpu(array->size);
-
- /* validate asize */
-- if (asize < 0) { /* FIXME: A zero-size array makes no sense */
-+ if (asize < sizeof(*array)) {
- dev_err(scomp->dev, "error: invalid array size 0x%x\n",
- asize);
- return -EINVAL;
---
-2.53.0
-
+++ /dev/null
-From 778d8c1b2a6ffe622ddcd3bb35b620e6e41f4da0 Mon Sep 17 00:00:00 2001
-From: Yosry Ahmed <yosry@kernel.org>
-Date: Wed, 25 Feb 2026 00:59:43 +0000
-Subject: KVM: nSVM: Sync NextRIP to cached vmcb12 after VMRUN of L2
-
-From: Yosry Ahmed <yosry@kernel.org>
-
-commit 778d8c1b2a6ffe622ddcd3bb35b620e6e41f4da0 upstream.
-
-After VMRUN in guest mode, nested_sync_control_from_vmcb02() syncs
-fields written by the CPU from vmcb02 to the cached vmcb12. This is
-because the cached vmcb12 is used as the authoritative copy of some of
-the controls, and is the payload when saving/restoring nested state.
-
-NextRIP is also written by the CPU (in some cases) after VMRUN, but is
-not sync'd to the cached vmcb12. As a result, it is corrupted after
-save/restore (replaced by the original value written by L1 on nested
-VMRUN). This could cause problems for both KVM (e.g. when injecting a
-soft IRQ) or L1 (e.g. when using NextRIP to advance RIP after emulating
-an instruction).
-
-Fix this by sync'ing NextRIP to the cache after VMRUN of L2, but only
-after completing interrupts (not in nested_sync_control_from_vmcb02()),
-as KVM may update NextRIP (e.g. when re-injecting a soft IRQ).
-
-Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
-CC: stable@vger.kernel.org
-Co-developed-by: Sean Christopherson <seanjc@google.com>
-Signed-off-by: Yosry Ahmed <yosry@kernel.org>
-Link: https://patch.msgid.link/20260225005950.3739782-2-yosry@kernel.org
-Signed-off-by: Sean Christopherson <seanjc@google.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/x86/kvm/svm/svm.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
---- a/arch/x86/kvm/svm/svm.c
-+++ b/arch/x86/kvm/svm/svm.c
-@@ -3952,6 +3952,16 @@ static __no_kcsan fastpath_t svm_vcpu_ru
- if (is_guest_mode(vcpu))
- return EXIT_FASTPATH_NONE;
-
-+ /*
-+ * Update the cache after completing interrupts to get an accurate
-+ * NextRIP, e.g. when re-injecting a soft interrupt.
-+ *
-+ * FIXME: Rework svm_get_nested_state() to not pull data from the
-+ * cache (except for maybe int_ctl).
-+ */
-+ if (is_guest_mode(vcpu))
-+ svm->nested.ctl.next_rip = svm->vmcb->control.next_rip;
-+
- return svm_exit_handlers_fastpath(vcpu);
- }
-
+++ /dev/null
-From f307f70bbbf56368343e011e2c3a141d8548ef50 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 11 Oct 2021 17:15:12 +0200
-Subject: netfilter: arp_tables: allow use of arpt_do_table as hookfn
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit e8d225b6002673366abc2e40e30c991bdc8d62ca ]
-
-This is possible now that the xt_table structure is passed in via *priv.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter_arp/arp_tables.h | 5 ++---
- net/ipv4/netfilter/arp_tables.c | 7 ++++---
- net/ipv4/netfilter/arptable_filter.c | 10 +---------
- 3 files changed, 7 insertions(+), 15 deletions(-)
-
-diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
-index 4f9a4b3c58926..a40aaf645fa47 100644
---- a/include/linux/netfilter_arp/arp_tables.h
-+++ b/include/linux/netfilter_arp/arp_tables.h
-@@ -54,9 +54,8 @@ int arpt_register_table(struct net *net, const struct xt_table *table,
- const struct nf_hook_ops *ops);
- void arpt_unregister_table(struct net *net, const char *name);
- void arpt_unregister_table_pre_exit(struct net *net, const char *name);
--extern unsigned int arpt_do_table(struct sk_buff *skb,
-- const struct nf_hook_state *state,
-- struct xt_table *table);
-+extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb,
-+ const struct nf_hook_state *state);
-
- #ifdef CONFIG_NETFILTER_XTABLES_COMPAT
- #include <net/compat.h>
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 92bc90ee76748..564054123772a 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -191,10 +191,11 @@ struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry)
- return (void *)entry + entry->next_offset;
- }
-
--unsigned int arpt_do_table(struct sk_buff *skb,
-- const struct nf_hook_state *state,
-- struct xt_table *table)
-+unsigned int arpt_do_table(void *priv,
-+ struct sk_buff *skb,
-+ const struct nf_hook_state *state)
- {
-+ const struct xt_table *table = priv;
- unsigned int hook = state->hook;
- static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
- unsigned int verdict = NF_DROP;
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 771eec4629352..359d00d74095b 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -26,14 +26,6 @@ static const struct xt_table packet_filter = {
- .priority = NF_IP_PRI_FILTER,
- };
-
--/* The work comes in here from netfilter.c */
--static unsigned int
--arptable_filter_hook(void *priv, struct sk_buff *skb,
-- const struct nf_hook_state *state)
--{
-- return arpt_do_table(skb, state, priv);
--}
--
- static struct nf_hook_ops *arpfilter_ops __read_mostly;
-
- static int arptable_filter_table_init(struct net *net)
-@@ -72,7 +64,7 @@ static int __init arptable_filter_init(void)
- if (ret < 0)
- return ret;
-
-- arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arptable_filter_hook);
-+ arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arpt_do_table);
- if (IS_ERR(arpfilter_ops)) {
- xt_unregister_template(&packet_filter);
- return PTR_ERR(arpfilter_ops);
---
-2.53.0
-
+++ /dev/null
-From 1f1b596c154d38f81561118087a37754d66453be Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Jan 2024 16:42:48 +0100
-Subject: netfilter: arptables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 4654467dc7e111e84f43ed1b70322873ae77e7be ]
-
-Allows to build kernel that supports the arptables mangle target
-via nftables' compat infra but without the arptables get/setsockopt
-interface or the old arptables filter interpreter.
-
-IOW, setting IP_NF_ARPFILTER=n will break arptables-legacy, but
-arptables-nft will continue to work as long as nftables compat
-support is enabled.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Reviewed-by: Phil Sutter <phil@nwl.cc>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 28 +++++++++++++---------------
- 1 file changed, 13 insertions(+), 15 deletions(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 63cb953bd0196..5c2cdcb19dba3 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -331,36 +331,34 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate "ARP tables support"
-- select NETFILTER_XTABLES
-- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_ADVANCED
-- help
-- arptables is a general, extensible packet identification framework.
-- The ARP packet filtering and mangling (manipulation)subsystems
-- use this: say Y or M here if you want to use either of those.
--
-- To compile it as a module, choose M here. If unsure, say N.
-+ tristate
-
--if IP_NF_ARPTABLES
-+config NFT_COMPAT_ARP
-+ tristate
-+ depends on NF_TABLES_ARP && NFT_COMPAT
-+ default m if NFT_COMPAT=m
-+ default y if NFT_COMPAT=y
-
- config IP_NF_ARPFILTER
-- tristate "ARP packet filtering"
-+ tristate "arptables-legacy packet filtering support"
-+ select IP_NF_ARPTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-- local output. On a bridge, you can also specify filtering rules
-- for forwarded ARP packets. See the man page for arptables(8).
-+ local output. This is only needed for arptables-legacy(8).
-+ Neither arptables-nft nor nftables need this to work.
-
- To compile it as a module, choose M here. If unsure, say N.
-
- config IP_NF_ARP_MANGLE
- tristate "ARP payload mangling"
-+ depends on IP_NF_ARPTABLES || NFT_COMPAT_ARP
- help
- Allows altering the ARP packet payload: source and destination
- hardware and network addresses.
-
--endif # IP_NF_ARPTABLES
-+ This option is needed by both arptables-legacy and arptables-nft.
-+ It is not used by nftables.
-
- endmenu
-
---
-2.53.0
-
+++ /dev/null
-From dd443750c3981759c31944f3d8beb0ada5df4f0b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Mar 2024 21:15:52 -0700
-Subject: netfilter: arptables: Select NETFILTER_FAMILY_ARP when building
- arp_tables.c
-
-From: Kuniyuki Iwashima <kuniyu@amazon.com>
-
-[ Upstream commit 15fba562f7a9f04322b8bfc8f392e04bb93d81be ]
-
-syzkaller started to report a warning below [0] after consuming the
-commit 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only
-builds").
-
-The change accidentally removed the dependency on NETFILTER_FAMILY_ARP
-from IP_NF_ARPTABLES.
-
-If NF_TABLES_ARP is not enabled on Kconfig, NETFILTER_FAMILY_ARP will
-be removed and some code necessary for arptables will not be compiled.
-
- $ grep -E "(NETFILTER_FAMILY_ARP|IP_NF_ARPTABLES|NF_TABLES_ARP)" .config
- CONFIG_NETFILTER_FAMILY_ARP=y
- # CONFIG_NF_TABLES_ARP is not set
- CONFIG_IP_NF_ARPTABLES=y
-
- $ make olddefconfig
-
- $ grep -E "(NETFILTER_FAMILY_ARP|IP_NF_ARPTABLES|NF_TABLES_ARP)" .config
- # CONFIG_NF_TABLES_ARP is not set
- CONFIG_IP_NF_ARPTABLES=y
-
-So, when nf_register_net_hooks() is called for arptables, it will
-trigger the splat below.
-
-Now IP_NF_ARPTABLES is only enabled by IP_NF_ARPFILTER, so let's
-restore the dependency on NETFILTER_FAMILY_ARP in IP_NF_ARPFILTER.
-
-[0]:
-WARNING: CPU: 0 PID: 242 at net/netfilter/core.c:316 nf_hook_entry_head+0x1e1/0x2c0 net/netfilter/core.c:316
-Modules linked in:
-CPU: 0 PID: 242 Comm: syz-executor.0 Not tainted 6.8.0-12821-g537c2e91d354 #10
-Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
-RIP: 0010:nf_hook_entry_head+0x1e1/0x2c0 net/netfilter/core.c:316
-Code: 83 fd 04 0f 87 bc 00 00 00 e8 5b 84 83 fd 4d 8d ac ec a8 0b 00 00 e8 4e 84 83 fd 4c 89 e8 5b 5d 41 5c 41 5d c3 e8 3f 84 83 fd <0f> 0b e8 38 84 83 fd 45 31 ed 5b 5d 4c 89 e8 41 5c 41 5d c3 e8 26
-RSP: 0018:ffffc90000b8f6e8 EFLAGS: 00010293
-RAX: 0000000000000000 RBX: 0000000000000003 RCX: ffffffff83c42164
-RDX: ffff888106851180 RSI: ffffffff83c42321 RDI: 0000000000000005
-RBP: 0000000000000000 R08: 0000000000000005 R09: 000000000000000a
-R10: 0000000000000003 R11: ffff8881055c2f00 R12: ffff888112b78000
-R13: 0000000000000000 R14: ffff8881055c2f00 R15: ffff8881055c2f00
-FS: 00007f377bd78800(0000) GS:ffff88811b000000(0000) knlGS:0000000000000000
-CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-CR2: 0000000000496068 CR3: 000000011298b003 CR4: 0000000000770ef0
-PKRU: 55555554
-Call Trace:
- <TASK>
- __nf_register_net_hook+0xcd/0x7a0 net/netfilter/core.c:428
- nf_register_net_hook+0x116/0x170 net/netfilter/core.c:578
- nf_register_net_hooks+0x5d/0xc0 net/netfilter/core.c:594
- arpt_register_table+0x250/0x420 net/ipv4/netfilter/arp_tables.c:1553
- arptable_filter_table_init+0x41/0x60 net/ipv4/netfilter/arptable_filter.c:39
- xt_find_table_lock+0x2e9/0x4b0 net/netfilter/x_tables.c:1260
- xt_request_find_table_lock+0x2b/0xe0 net/netfilter/x_tables.c:1285
- get_info+0x169/0x5c0 net/ipv4/netfilter/arp_tables.c:808
- do_arpt_get_ctl+0x3f9/0x830 net/ipv4/netfilter/arp_tables.c:1444
- nf_getsockopt+0x76/0xd0 net/netfilter/nf_sockopt.c:116
- ip_getsockopt+0x17d/0x1c0 net/ipv4/ip_sockglue.c:1777
- tcp_getsockopt+0x99/0x100 net/ipv4/tcp.c:4373
- do_sock_getsockopt+0x279/0x360 net/socket.c:2373
- __sys_getsockopt+0x115/0x1e0 net/socket.c:2402
- __do_sys_getsockopt net/socket.c:2412 [inline]
- __se_sys_getsockopt net/socket.c:2409 [inline]
- __x64_sys_getsockopt+0xbd/0x150 net/socket.c:2409
- do_syscall_x64 arch/x86/entry/common.c:52 [inline]
- do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
- entry_SYSCALL_64_after_hwframe+0x46/0x4e
-RIP: 0033:0x7f377beca6fe
-Code: 1f 44 00 00 48 8b 15 01 97 0a 00 f7 d8 64 89 02 b8 ff ff ff ff eb b8 0f 1f 44 00 00 f3 0f 1e fa 49 89 ca b8 37 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 0a c3 66 0f 1f 84 00 00 00 00 00 48 8b 15 c9
-RSP: 002b:00000000005df728 EFLAGS: 00000246 ORIG_RAX: 0000000000000037
-RAX: ffffffffffffffda RBX: 00000000004966e0 RCX: 00007f377beca6fe
-RDX: 0000000000000060 RSI: 0000000000000000 RDI: 0000000000000003
-RBP: 000000000042938a R08: 00000000005df73c R09: 00000000005df800
-R10: 00000000004966e8 R11: 0000000000000246 R12: 0000000000000003
-R13: 0000000000496068 R14: 0000000000000003 R15: 00000000004bc9d8
- </TASK>
-
-Fixes: 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only builds")
-Reported-by: syzkaller <syzkaller@googlegroups.com>
-Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 18f60e675c438..e752a07a871fe 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -351,6 +351,7 @@ config NFT_COMPAT_ARP
- config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
-+ select NETFILTER_FAMILY_ARP
- depends on NETFILTER_XTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
---
-2.53.0
-
+++ /dev/null
-From 76719a23d5c96d4690773efa9826f16243e7fcf5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 7 May 2026 11:19:22 +0200
-Subject: netfilter: bridge: eb_tables: close module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 27414ff1b287ea9a2a11675149ec28e05539f3cc ]
-
-sashiko reports for unrelated patch:
- Does the core ebtables initialization in ebtables.c suffer from a similar race?
- Once nf_register_sockopt() completes, the sockopts are exposed globally.
-
-sockopt has to be registered last, just like in ip/ip6/arptables.
-
-Fixes: 5b53951cfc85 ("netfilter: ebtables: use net_generic infra")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtables.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index 5390b25cdb45e..9374a3207a276 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -2582,19 +2582,20 @@ static int __init ebtables_init(void)
- {
- int ret;
-
-- ret = xt_register_target(&ebt_standard_target);
-+ ret = register_pernet_subsys(&ebt_net_ops);
- if (ret < 0)
- return ret;
-- ret = nf_register_sockopt(&ebt_sockopts);
-+
-+ ret = xt_register_target(&ebt_standard_target);
- if (ret < 0) {
-- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
-- ret = register_pernet_subsys(&ebt_net_ops);
-+ ret = nf_register_sockopt(&ebt_sockopts);
- if (ret < 0) {
-- nf_unregister_sockopt(&ebt_sockopts);
- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 4b30a7c2d72444a5dd148c1d12a20ff29aab15bd Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 24 Jan 2024 10:21:12 +0100
-Subject: netfilter: ebtables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 7ad269787b6615ca56bb161063331991fce51abf ]
-
-Same patch as previous one, but for ebtables.
-
-To build a kernel that only supports ebtables-nft, the builtin tables
-need to be disabled, i.e.:
-
-CONFIG_BRIDGE_EBT_BROUTE=n
-CONFIG_BRIDGE_EBT_T_FILTER=n
-CONFIG_BRIDGE_EBT_T_NAT=n
-
-The ebtables specific extensions can then be used nftables'
-NFT_COMPAT interface.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 7 +++++++
- net/bridge/netfilter/Makefile | 2 +-
- 2 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 7f304a19ac1bf..104c0125e32e8 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -39,6 +39,10 @@ config NF_CONNTRACK_BRIDGE
-
- To compile it as a module, choose M here. If unsure, say N.
-
-+# old sockopt interface and eval loop
-+config BRIDGE_NF_EBTABLES_LEGACY
-+ tristate
-+
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
- depends on BRIDGE && NETFILTER && NETFILTER_XTABLES
-@@ -55,6 +59,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -65,6 +70,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -74,6 +80,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
-index 1c9ce49ab6513..b9a1303da9771 100644
---- a/net/bridge/netfilter/Makefile
-+++ b/net/bridge/netfilter/Makefile
-@@ -9,7 +9,7 @@ obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o
- # connection tracking
- obj-$(CONFIG_NF_CONNTRACK_BRIDGE) += nf_conntrack_bridge.o
-
--obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
-+obj-$(CONFIG_BRIDGE_NF_EBTABLES_LEGACY) += ebtables.o
-
- # tables
- obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o
---
-2.53.0
-
+++ /dev/null
-From a7e863cc557ce860b44115390ed12d114f47ea0c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:19 +0200
-Subject: netfilter: ebtables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 92c603fa07bc0d6a17345de3ad7954730b8de44b ]
-
-sashiko reported for a related patch:
- In modules like iptable_raw.c, [..], if register_pernet_subsys() fails,
- the rollback might call kfree(rawtable_ops) before [..]
- During this window, could a concurrent userspace process find the globally
- visible template, trigger table_init(), [..]
-
-The table init functions must always register the template last.
-
-Otherwise, set/getsockopt can instantiate a table in a namespace
-while the required pernet ops (contain the destructor) isn't available.
-This change is also required in x_tables, handled in followup change.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 12 +++++-------
- net/bridge/netfilter/ebtable_filter.c | 12 +++++-------
- net/bridge/netfilter/ebtable_nat.c | 10 ++++------
- 3 files changed, 14 insertions(+), 20 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index c5d6fb937394c..d54afb88761e6 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -112,18 +112,16 @@ static struct pernet_operations broute_net_ops = {
-
- static int __init ebtable_broute_init(void)
- {
-- int ret = ebt_register_template(&broute_table, broute_table_init);
-+ int ret = register_pernet_subsys(&broute_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&broute_net_ops);
-- if (ret) {
-- ebt_unregister_template(&broute_table);
-- return ret;
-- }
-+ ret = ebt_register_template(&broute_table, broute_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&broute_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_broute_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index ee3d6d5a03a35..28f6a1f33898a 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -100,18 +100,16 @@ static struct pernet_operations frame_filter_net_ops = {
-
- static int __init ebtable_filter_init(void)
- {
-- int ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ int ret = register_pernet_subsys(&frame_filter_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_filter_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_filter);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_filter_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_filter_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index c98840b68fc52..a9450d6e49565 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -99,16 +99,14 @@ static struct pernet_operations frame_nat_net_ops = {
-
- static int __init ebtable_nat_init(void)
- {
-- int ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ int ret = register_pernet_subsys(&frame_nat_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_nat_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_nat);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_nat_net_ops);
-
- return ret;
- }
---
-2.53.0
-
+++ /dev/null
-From ef22989140ba8137a7d5f9add8a21de6ca6eabfb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:18 +0200
-Subject: netfilter: ebtables: move to two-stage removal scheme
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b7f0544d86d439cb946515d2ef6a0a75e8626710 ]
-
-Like previous patches for x_tables, follow same pattern in ebtables.
-We can't reuse xt helpers: ebt_table struct layout is incompatible.
-
-table->ops assignment is now done while still holding the ebt mutex
-to make sure we never expose partially-filled table struct.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 2 +-
- net/bridge/netfilter/ebtable_filter.c | 2 +-
- net/bridge/netfilter/ebtable_nat.c | 2 +-
- net/bridge/netfilter/ebtables.c | 60 +++++++++++++++++----------
- 4 files changed, 40 insertions(+), 26 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index 3d4ea774d7e8f..c5d6fb937394c 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -128,8 +128,8 @@ static int __init ebtable_broute_init(void)
-
- static void __exit ebtable_broute_fini(void)
- {
-- unregister_pernet_subsys(&broute_net_ops);
- ebt_unregister_template(&broute_table);
-+ unregister_pernet_subsys(&broute_net_ops);
- }
-
- module_init(ebtable_broute_init);
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index 257d63b5dec16..ee3d6d5a03a35 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -116,8 +116,8 @@ static int __init ebtable_filter_init(void)
-
- static void __exit ebtable_filter_fini(void)
- {
-- unregister_pernet_subsys(&frame_filter_net_ops);
- ebt_unregister_template(&frame_filter);
-+ unregister_pernet_subsys(&frame_filter_net_ops);
- }
-
- module_init(ebtable_filter_init);
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 39179c2cf87d2..c98840b68fc52 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -115,8 +115,8 @@ static int __init ebtable_nat_init(void)
-
- static void __exit ebtable_nat_fini(void)
- {
-- unregister_pernet_subsys(&frame_nat_net_ops);
- ebt_unregister_template(&frame_nat);
-+ unregister_pernet_subsys(&frame_nat_net_ops);
- }
-
- module_init(ebtable_nat_init);
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index c74efcc2b4996..5390b25cdb45e 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -42,6 +42,7 @@
-
- struct ebt_pernet {
- struct list_head tables;
-+ struct list_head dead_tables;
- };
-
- struct ebt_template {
-@@ -1162,11 +1163,6 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
-
- static void __ebt_unregister_table(struct net *net, struct ebt_table *table)
- {
-- mutex_lock(&ebt_mutex);
-- list_del(&table->list);
-- mutex_unlock(&ebt_mutex);
-- audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
- EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
- ebt_cleanup_entry, net, NULL);
- if (table->private->nentries)
-@@ -1267,13 +1263,15 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
- for (i = 0; i < num_ops; i++)
- ops[i].priv = table;
-
-- list_add(&table->list, &ebt_net->tables);
-- mutex_unlock(&ebt_mutex);
--
- table->ops = ops;
- ret = nf_register_net_hooks(net, ops, num_ops);
-- if (ret)
-+ if (ret) {
-+ synchronize_rcu();
- __ebt_unregister_table(net, table);
-+ } else {
-+ list_add(&table->list, &ebt_net->tables);
-+ }
-+ mutex_unlock(&ebt_mutex);
-
- audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
- AUDIT_XT_OP_REGISTER, GFP_KERNEL);
-@@ -1339,7 +1337,7 @@ void ebt_unregister_template(const struct ebt_table *t)
- }
- EXPORT_SYMBOL(ebt_unregister_template);
-
--static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-+void ebt_unregister_table_pre_exit(struct net *net, const char *name)
- {
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
- struct ebt_table *t;
-@@ -1348,30 +1346,36 @@ static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-
- list_for_each_entry(t, &ebt_net->tables, list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &ebt_net->dead_tables);
- mutex_unlock(&ebt_mutex);
-- return t;
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
- }
- }
-
- mutex_unlock(&ebt_mutex);
-- return NULL;
--}
--
--void ebt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct ebt_table *table = __ebt_find_table(net, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
- }
- EXPORT_SYMBOL(ebt_unregister_table_pre_exit);
-
- void ebt_unregister_table(struct net *net, const char *name)
- {
-- struct ebt_table *table = __ebt_find_table(net, name);
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+ struct ebt_table *t;
-
-- if (table)
-- __ebt_unregister_table(net, table);
-+ mutex_lock(&ebt_mutex);
-+
-+ list_for_each_entry(t, &ebt_net->dead_tables, list) {
-+ if (strcmp(t->name, name) == 0) {
-+ list_del(&t->list);
-+ audit_log_nfcfg(t->name, AF_BRIDGE, t->private->nentries,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ __ebt_unregister_table(net, t);
-+ mutex_unlock(&ebt_mutex);
-+ return;
-+ }
-+ }
-+
-+ mutex_unlock(&ebt_mutex);
- }
-
- /* userspace just supplied us with counters */
-@@ -2555,11 +2559,21 @@ static int __net_init ebt_pernet_init(struct net *net)
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-
- INIT_LIST_HEAD(&ebt_net->tables);
-+ INIT_LIST_HEAD(&ebt_net->dead_tables);
- return 0;
- }
-
-+static void __net_exit ebt_pernet_exit(struct net *net)
-+{
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+
-+ WARN_ON_ONCE(!list_empty(&ebt_net->tables));
-+ WARN_ON_ONCE(!list_empty(&ebt_net->dead_tables));
-+}
-+
- static struct pernet_operations ebt_net_ops = {
- .init = ebt_pernet_init,
-+ .exit = ebt_pernet_exit,
- .id = &ebt_pernet_id,
- .size = sizeof(struct ebt_pernet),
- };
---
-2.53.0
-
+++ /dev/null
-From f36d8452557e5a33aa0f8d50e331733865ad14c1 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Jun 2025 17:44:23 +0200
-Subject: netfilter: Exclude LEGACY TABLES on PREEMPT_RT.
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-[ Upstream commit 9fce66583f06c212e95e4b76dd61d8432ffa56b6 ]
-
-The seqcount xt_recseq is used to synchronize the replacement of
-xt_table::private in xt_replace_table() against all readers such as
-ipt_do_table()
-
-To ensure that there is only one writer, the writing side disables
-bottom halves. The sequence counter can be acquired recursively. Only the
-first invocation modifies the sequence counter (signaling that a writer
-is in progress) while the following (recursive) writer does not modify
-the counter.
-The lack of a proper locking mechanism for the sequence counter can lead
-to live lock on PREEMPT_RT if the high prior reader preempts the
-writer. Additionally if the per-CPU lock on PREEMPT_RT is removed from
-local_bh_disable() then there is no synchronisation for the per-CPU
-sequence counter.
-
-The affected code is "just" the legacy netfilter code which is replaced
-by "netfilter tables". That code can be disabled without sacrificing
-functionality because everything is provided by the newer
-implementation. This will only requires the usage of the "-nft" tools
-instead of the "-legacy" ones.
-The long term plan is to remove the legacy code so lets accelerate the
-progress.
-
-Relax dependencies on iptables legacy, replace select with depends on,
-this should cause no harm to existing kernel configs and users can still
-toggle IP{6}_NF_IPTABLES_LEGACY in any case.
-Make EBTABLES_LEGACY, IPTABLES_LEGACY and ARPTABLES depend on
-NETFILTER_XTABLES_LEGACY. Hide xt_recseq and its users,
-xt_register_table() and xt_percpu_counter_alloc() behind
-NETFILTER_XTABLES_LEGACY. Let NETFILTER_XTABLES_LEGACY depend on
-!PREEMPT_RT.
-
-This will break selftest expecing the legacy options enabled and will be
-addressed in a following patch.
-
-Co-developed-by: Florian Westphal <fw@strlen.de>
-Co-developed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 10 +++++-----
- net/ipv4/netfilter/Kconfig | 24 ++++++++++++------------
- net/ipv6/netfilter/Kconfig | 19 +++++++++----------
- net/netfilter/Kconfig | 10 ++++++++++
- net/netfilter/x_tables.c | 16 +++++++++++-----
- 5 files changed, 47 insertions(+), 32 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index f16bbbbb94817..60f28e4fb5c0a 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -42,8 +42,8 @@ config NF_CONNTRACK_BRIDGE
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
- tristate "Legacy EBTABLES support"
-- depends on BRIDGE && NETFILTER_XTABLES
-- default n
-+ depends on BRIDGE && NETFILTER_XTABLES_LEGACY
-+ default n
- help
- Legacy ebtables packet/frame classifier.
- This is not needed if you are using ebtables over nftables
-@@ -65,7 +65,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -76,7 +76,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -86,7 +86,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 2e540786f9512..4cfe4b12bda7c 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -13,8 +13,8 @@ config NF_DEFRAG_IPV4
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
- tristate "Legacy IP tables support"
-- default n
-- select NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- iptables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -190,8 +190,8 @@ config IP_NF_MATCH_TTL
- # `filter', generic and specific targets
- config IP_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -228,10 +228,10 @@ config IP_NF_TARGET_SYNPROXY
- config IP_NF_NAT
- tristate "iptables NAT support"
- depends on NF_CONNTRACK
-+ depends on IP_NF_IPTABLES_LEGACY
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -271,8 +271,8 @@ endif # IP_NF_NAT
- # mangle + specific targets
- config IP_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -321,7 +321,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -335,7 +335,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -347,8 +347,8 @@ endif # IP_NF_IPTABLES
- # ARP tables
- config IP_NF_ARPTABLES
- tristate "Legacy ARPTABLES support"
-- depends on NETFILTER_XTABLES
-- default n
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default n
- help
- arptables is a legacy packet classifier.
- This is not needed if you are using arptables over nftables
-@@ -364,7 +364,7 @@ config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index 670d23f926e62..052f1f53c4dfe 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -9,9 +9,8 @@ menu "IPv6: Netfilter Configuration"
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
- tristate "Legacy IP6 tables support"
-- depends on INET && IPV6
-- select NETFILTER_XTABLES
-- default n
-+ depends on INET && IPV6 && NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- ip6tables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -204,8 +203,8 @@ config IP6_NF_TARGET_HL
-
- config IP6_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- tristate
- help
- Packet filtering defines a table `filter', which has a series of
-@@ -241,8 +240,8 @@ config IP6_NF_TARGET_SYNPROXY
-
- config IP6_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -252,7 +251,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -266,7 +265,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -277,8 +276,8 @@ config IP6_NF_NAT
- tristate "ip6tables NAT support"
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
-+ depends on IP6_NF_IPTABLES_LEGACY
- select NF_NAT
-- select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index fdfda4b6bff67..085ea824c503d 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -756,6 +756,16 @@ config NETFILTER_XTABLES_COMPAT
-
- If unsure, say N.
-
-+config NETFILTER_XTABLES_LEGACY
-+ bool "Netfilter legacy tables support"
-+ depends on !PREEMPT_RT
-+ help
-+ Say Y here if you still require support for legacy tables. This is
-+ required by the legacy tools (iptables-legacy) and is not needed if
-+ you use iptables over nftables (iptables-nft).
-+ Legacy support is not limited to IP, it also includes EBTABLES and
-+ ARPTABLES.
-+
- comment "Xtables combined modules"
-
- config NETFILTER_XT_MARK
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 9c0ec0bbb5699..30af321d6c964 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1339,12 +1339,13 @@ void xt_compat_unlock(u_int8_t af)
- EXPORT_SYMBOL_GPL(xt_compat_unlock);
- #endif
-
--DEFINE_PER_CPU(seqcount_t, xt_recseq);
--EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
--
- struct static_key xt_tee_enabled __read_mostly;
- EXPORT_SYMBOL_GPL(xt_tee_enabled);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
-+DEFINE_PER_CPU(seqcount_t, xt_recseq);
-+EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
-+
- static int xt_jumpstack_alloc(struct xt_table_info *i)
- {
- unsigned int size;
-@@ -1536,6 +1537,7 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+#endif
-
- #ifdef CONFIG_PROC_FS
- static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
-@@ -1919,6 +1921,7 @@ void xt_proto_fini(struct net *net, u_int8_t af)
- }
- EXPORT_SYMBOL_GPL(xt_proto_fini);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
- /**
- * xt_percpu_counter_alloc - allocate x_tables rule counter
- *
-@@ -1973,6 +1976,7 @@ void xt_percpu_counter_free(struct xt_counters *counters)
- free_percpu((void __percpu *)pcnt);
- }
- EXPORT_SYMBOL_GPL(xt_percpu_counter_free);
-+#endif
-
- static int __net_init xt_net_init(struct net *net)
- {
-@@ -2005,8 +2009,10 @@ static int __init xt_init(void)
- unsigned int i;
- int rv;
-
-- for_each_possible_cpu(i) {
-- seqcount_init(&per_cpu(xt_recseq, i));
-+ if (IS_ENABLED(CONFIG_NETFILTER_XTABLES_LEGACY)) {
-+ for_each_possible_cpu(i) {
-+ seqcount_init(&per_cpu(xt_recseq, i));
-+ }
- }
-
- xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL);
---
-2.53.0
-
+++ /dev/null
-From 5efc00fb9fb380446b8c97f514aa19916dcee2b2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Sep 2024 02:58:54 -0700
-Subject: netfilter: Make legacy configs user selectable
-
-From: Breno Leitao <leitao@debian.org>
-
-[ Upstream commit 6c959fd5e17387201dba3619b2e6af213939a0a7 ]
-
-This option makes legacy Netfilter Kconfig user selectable, giving users
-the option to configure iptables without enabling any other config.
-
-Make the following KConfig entries user selectable:
- * BRIDGE_NF_EBTABLES_LEGACY
- * IP_NF_ARPTABLES
- * IP_NF_IPTABLES_LEGACY
- * IP6_NF_IPTABLES_LEGACY
-
-Signed-off-by: Breno Leitao <leitao@debian.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 8 +++++++-
- net/ipv4/netfilter/Kconfig | 16 ++++++++++++++--
- net/ipv6/netfilter/Kconfig | 9 ++++++++-
- 3 files changed, 29 insertions(+), 4 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 104c0125e32e8..f16bbbbb94817 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -41,7 +41,13 @@ config NF_CONNTRACK_BRIDGE
-
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
-- tristate
-+ tristate "Legacy EBTABLES support"
-+ depends on BRIDGE && NETFILTER_XTABLES
-+ default n
-+ help
-+ Legacy ebtables packet/frame classifier.
-+ This is not needed if you are using ebtables over nftables
-+ (iptables-nft).
-
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index e752a07a871fe..2e540786f9512 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -12,7 +12,13 @@ config NF_DEFRAG_IPV4
-
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP tables support"
-+ default n
-+ select NETFILTER_XTABLES
-+ help
-+ iptables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
-@@ -340,7 +346,13 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate
-+ tristate "Legacy ARPTABLES support"
-+ depends on NETFILTER_XTABLES
-+ default n
-+ help
-+ arptables is a legacy packet classifier.
-+ This is not needed if you are using arptables over nftables
-+ (iptables-nft).
-
- config NFT_COMPAT_ARP
- tristate
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index bc51a77fb6c07..670d23f926e62 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -8,7 +8,14 @@ menu "IPv6: Netfilter Configuration"
-
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP6 tables support"
-+ depends on INET && IPV6
-+ select NETFILTER_XTABLES
-+ default n
-+ help
-+ ip6tables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
---
-2.53.0
-
+++ /dev/null
-From ae03afb432750e922150888d09a18044ba580ea6 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:15 +0200
-Subject: netfilter: x_tables: add and use xt_unregister_table_pre_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 527d6931473b75d90e38942aae6537d1a527f1fd ]
-
-Remove the copypasted variants of _pre_exit and add one single
-function in the xtables core. ebtables is not compatible with
-x_tables and therefore unchanged.
-
-This is a preparation patch to reduce noise in the followup
-bug fixes.
-
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 1 +
- include/linux/netfilter_arp/arp_tables.h | 1 -
- include/linux/netfilter_ipv4/ip_tables.h | 1 -
- include/linux/netfilter_ipv6/ip6_tables.h | 1 -
- net/ipv4/netfilter/arp_tables.c | 9 -------
- net/ipv4/netfilter/arptable_filter.c | 2 +-
- net/ipv4/netfilter/ip_tables.c | 9 -------
- net/ipv4/netfilter/iptable_filter.c | 2 +-
- net/ipv4/netfilter/iptable_mangle.c | 2 +-
- net/ipv4/netfilter/iptable_nat.c | 1 +
- net/ipv4/netfilter/iptable_raw.c | 2 +-
- net/ipv4/netfilter/iptable_security.c | 2 +-
- net/ipv6/netfilter/ip6_tables.c | 9 -------
- net/ipv6/netfilter/ip6table_filter.c | 2 +-
- net/ipv6/netfilter/ip6table_mangle.c | 2 +-
- net/ipv6/netfilter/ip6table_nat.c | 1 +
- net/ipv6/netfilter/ip6table_raw.c | 2 +-
- net/ipv6/netfilter/ip6table_security.c | 2 +-
- net/netfilter/x_tables.c | 29 +++++++++++++++++++++++
- 19 files changed, 41 insertions(+), 39 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index 5897f3dbaf7c3..df2022fe440b0 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -310,6 +310,7 @@ struct xt_table *xt_register_table(struct net *net,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
- void *xt_unregister_table(struct xt_table *table);
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
-index a40aaf645fa47..05631a25e6229 100644
---- a/include/linux/netfilter_arp/arp_tables.h
-+++ b/include/linux/netfilter_arp/arp_tables.h
-@@ -53,7 +53,6 @@ int arpt_register_table(struct net *net, const struct xt_table *table,
- const struct arpt_replace *repl,
- const struct nf_hook_ops *ops);
- void arpt_unregister_table(struct net *net, const char *name);
--void arpt_unregister_table_pre_exit(struct net *net, const char *name);
- extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-
-diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
-index 8d09bfe850dc3..68f0153531e64 100644
---- a/include/linux/netfilter_ipv4/ip_tables.h
-+++ b/include/linux/netfilter_ipv4/ip_tables.h
-@@ -26,7 +26,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- const struct ipt_replace *repl,
- const struct nf_hook_ops *ops);
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name);
- void ipt_unregister_table_exit(struct net *net, const char *name);
-
- /* Standard entry. */
-diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
-index 79e73fd7d965c..45302640c1ca9 100644
---- a/include/linux/netfilter_ipv6/ip6_tables.h
-+++ b/include/linux/netfilter_ipv6/ip6_tables.h
-@@ -27,7 +27,6 @@ extern void *ip6t_alloc_initial_table(const struct xt_table *);
- int ip6t_register_table(struct net *net, const struct xt_table *table,
- const struct ip6t_replace *repl,
- const struct nf_hook_ops *ops);
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name);
- void ip6t_unregister_table_exit(struct net *net, const char *name);
- extern unsigned int ip6t_do_table(struct sk_buff *skb,
- const struct nf_hook_state *state,
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 564054123772a..9b905c6562313 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1581,15 +1581,6 @@ int arpt_register_table(struct net *net,
- return ret;
- }
-
--void arpt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--EXPORT_SYMBOL(arpt_unregister_table_pre_exit);
--
- void arpt_unregister_table(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 359d00d74095b..382345567a600 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -43,7 +43,7 @@ static int arptable_filter_table_init(struct net *net)
-
- static void __net_exit arptable_filter_net_pre_exit(struct net *net)
- {
-- arpt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_ARP, "filter");
- }
-
- static void __net_exit arptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index aee7cd584c926..a2a267e1b2573 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1790,14 +1790,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-@@ -1952,7 +1944,6 @@ static void __exit ip_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ipt_register_table);
--EXPORT_SYMBOL(ipt_unregister_table_pre_exit);
- EXPORT_SYMBOL(ipt_unregister_table_exit);
- EXPORT_SYMBOL(ipt_do_table);
- module_init(ip_tables_init);
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index 9155c5b5318d7..9dbebfa057ee8 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -68,7 +68,7 @@ static int __net_init iptable_filter_net_init(struct net *net)
-
- static void __net_exit iptable_filter_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "filter");
- }
-
- static void __net_exit iptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index f2997709c08b1..b7322b0051a6b 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -95,7 +95,7 @@ static int iptable_mangle_table_init(struct net *net)
-
- static void __net_exit iptable_mangle_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "mangle");
- }
-
- static void __net_exit iptable_mangle_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index 226000a740860..e5e30d4e37eb0 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -136,6 +136,7 @@ static int iptable_nat_table_init(struct net *net)
- static void __net_exit iptable_nat_net_pre_exit(struct net *net)
- {
- ipt_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
- }
-
- static void __net_exit iptable_nat_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index 4749ecc9a416d..77dabf8ff4388 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -61,7 +61,7 @@ static int iptable_raw_table_init(struct net *net)
-
- static void __net_exit iptable_raw_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "raw");
- }
-
- static void __net_exit iptable_raw_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 3e85be8cc9803..89f8f93b36f64 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -57,7 +57,7 @@ static int iptable_security_table_init(struct net *net)
-
- static void __net_exit iptable_security_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "security");
- }
-
- static void __net_exit iptable_security_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index afd22ea9f555b..4fbb6111ed56e 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1797,14 +1797,6 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-@@ -1960,7 +1952,6 @@ static void __exit ip6_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ip6t_register_table);
--EXPORT_SYMBOL(ip6t_unregister_table_pre_exit);
- EXPORT_SYMBOL(ip6t_unregister_table_exit);
- EXPORT_SYMBOL(ip6t_do_table);
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index 477982fcc04ae..76b5cb69a54a0 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -68,7 +68,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
-
- static void __net_exit ip6table_filter_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "filter");
- }
-
- static void __net_exit ip6table_filter_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index bf062c01041ec..387c53da77fd6 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -88,7 +88,7 @@ static int ip6table_mangle_table_init(struct net *net)
-
- static void __net_exit ip6table_mangle_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "mangle");
- }
-
- static void __net_exit ip6table_mangle_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index 229a81cf1a729..18d5b39936466 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -138,6 +138,7 @@ static int ip6table_nat_table_init(struct net *net)
- static void __net_exit ip6table_nat_net_pre_exit(struct net *net)
- {
- ip6t_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
- }
-
- static void __net_exit ip6table_nat_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index 6214c0b97f123..a13a3c6298b01 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -60,7 +60,7 @@ static int ip6table_raw_table_init(struct net *net)
-
- static void __net_exit ip6table_raw_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "raw");
- }
-
- static void __net_exit ip6table_raw_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index 36b62f848897a..56057c01ff803 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -56,7 +56,7 @@ static int ip6table_security_table_init(struct net *net)
-
- static void __net_exit ip6table_security_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "security");
- }
-
- static void __net_exit ip6table_security_net_exit(struct net *net)
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 30af321d6c964..85155c64d0443 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1537,6 +1537,35 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+
-+/**
-+ * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
-+ * @net: network namespace
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Unregisters the specified netfilter table from the given network namespace
-+ * and also unregisters the hooks from netfilter core: no new packets will be
-+ * processed.
-+ */
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *t;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(t, &xt_net->tables[af], list) {
-+ if (strcmp(t->name, name) == 0) {
-+ mutex_unlock(&xt[af].mutex);
-+
-+ if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
-+ }
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+}
-+EXPORT_SYMBOL(xt_unregister_table_pre_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
---
-2.53.0
-
+++ /dev/null
-From 287a51bf65c0fd8401bdacbb6faa6f63237e1d42 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:17 +0200
-Subject: netfilter: x_tables: add and use xtables_unregister_table_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b4597d5fd7d2f8cebfffd40dffb5e003cc78964c ]
-
-Previous change added xtables_unregister_table_pre_exit to detach the
-table from the packetpath and to unlink it from the active table list.
-In case of rmmod, userspace that is doing set/getsockopt for this table
-will not be able to re-instantiate the table:
- 1. The larval table has been removed already
- 2. existing instantiated table is no longer on the xt pernet table list.
-
-This adds the second stage helper:
-
-unlink the table from the dying list, free the hook ops (if any) and do
-the audit notification. It replaces xt_unregister_table().
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Reported-by: Tristan Madani <tristan@talencesecurity.com>
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Closes: https://lore.kernel.org/netfilter-devel/20260429175613.1459342-1-tristmd@gmail.com/
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 2 +-
- net/ipv4/netfilter/arp_tables.c | 9 ++--
- net/ipv4/netfilter/ip_tables.c | 9 ++--
- net/ipv4/netfilter/iptable_nat.c | 5 +-
- net/ipv6/netfilter/ip6_tables.c | 9 ++--
- net/ipv6/netfilter/ip6table_nat.c | 5 +-
- net/netfilter/x_tables.c | 81 +++++++++++++++++++++++-------
- 7 files changed, 83 insertions(+), 37 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index df2022fe440b0..706f08839050a 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -309,8 +309,8 @@ struct xt_table *xt_register_table(struct net *net,
- const struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
--void *xt_unregister_table(struct xt_table *table);
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 9b905c6562313..f9dd18244f251 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1501,13 +1501,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
-
- static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
-+ void *loc_cpu_entry;
- struct arpt_entry *iter;
-
-- private = xt_unregister_table(table);
--
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
- xt_entry_foreach(iter, loc_cpu_entry, private->size)
-@@ -1515,6 +1513,7 @@ static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int arpt_register_table(struct net *net,
-@@ -1583,7 +1582,7 @@ int arpt_register_table(struct net *net,
-
- void arpt_unregister_table(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_ARP, name);
-
- if (table)
- __arpt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index a2a267e1b2573..1829bf3774062 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1705,12 +1705,10 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ipt_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1719,6 +1717,7 @@ static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ipt_register_table(struct net *net, const struct xt_table *table,
-@@ -1792,7 +1791,7 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
-
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV4, name);
-
- if (table)
- __ipt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index e5e30d4e37eb0..d5153736f1d8c 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -126,8 +126,11 @@ static int iptable_nat_table_init(struct net *net)
- }
-
- ret = ipt_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
-+ synchronize_rcu();
- ipt_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 4fbb6111ed56e..2b4c3fa5a8d08 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1715,12 +1715,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ip6t_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1729,6 +1727,7 @@ static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ip6t_register_table(struct net *net, const struct xt_table *table,
-@@ -1799,7 +1798,7 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
-
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV6, name);
-
- if (table)
- __ip6t_unregister_table(net, table);
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index 18d5b39936466..4ba85748bf6d3 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -128,8 +128,11 @@ static int ip6table_nat_table_init(struct net *net)
- }
-
- ret = ip6t_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
-+ synchronize_rcu();
- ip6t_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 85155c64d0443..7c87e1a478d68 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -55,6 +55,9 @@ static struct list_head xt_templates[NFPROTO_NUMPROTO];
-
- struct xt_pernet {
- struct list_head tables[NFPROTO_NUMPROTO];
-+
-+ /* stash area used during netns exit */
-+ struct list_head dead_tables[NFPROTO_NUMPROTO];
- };
-
- struct compat_delta {
-@@ -1521,23 +1524,6 @@ struct xt_table *xt_register_table(struct net *net,
- }
- EXPORT_SYMBOL_GPL(xt_register_table);
-
--void *xt_unregister_table(struct xt_table *table)
--{
-- struct xt_table_info *private;
--
-- mutex_lock(&xt[table->af].mutex);
-- private = table->private;
-- list_del(&table->list);
-- mutex_unlock(&xt[table->af].mutex);
-- audit_log_nfcfg(table->name, table->af, private->number,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-- kfree(table->ops);
-- kfree(table);
--
-- return private;
--}
--EXPORT_SYMBOL_GPL(xt_unregister_table);
--
- /**
- * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
- * @net: network namespace
-@@ -1547,6 +1533,14 @@ EXPORT_SYMBOL_GPL(xt_unregister_table);
- * Unregisters the specified netfilter table from the given network namespace
- * and also unregisters the hooks from netfilter core: no new packets will be
- * processed.
-+ *
-+ * This must be called prior to xt_unregister_table_exit() from the pernet
-+ * .pre_exit callback. After this call, the table is no longer visible to
-+ * the get/setsockopt path. In case of rmmod, module exit path must have
-+ * called xt_unregister_template() prior to unregistering pernet ops to
-+ * prevent re-instantiation of the table.
-+ *
-+ * See also: xt_unregister_table_exit()
- */
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- {
-@@ -1556,6 +1550,7 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_lock(&xt[af].mutex);
- list_for_each_entry(t, &xt_net->tables[af], list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &xt_net->dead_tables[af]);
- mutex_unlock(&xt[af].mutex);
-
- if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-@@ -1566,6 +1561,50 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_unlock(&xt[af].mutex);
- }
- EXPORT_SYMBOL(xt_unregister_table_pre_exit);
-+
-+/**
-+ * xt_unregister_table_exit - remove a table during namespace teardown
-+ * @net: the network namespace from which to unregister the table
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Completes the unregister process for a table. This must be called from
-+ * the pernet ops .exit callback. This is the second stage after
-+ * xt_unregister_table_pre_exit().
-+ *
-+ * pair with xt_unregister_table_pre_exit() during namespace shutdown.
-+ *
-+ * Return: the unregistered table or NULL if the table was never
-+ * instantiated. The caller needs to kfree() the table after it
-+ * has removed the family specific matches/targets.
-+ */
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *table;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(table, &xt_net->dead_tables[af], list) {
-+ struct nf_hook_ops *ops = NULL;
-+
-+ if (strcmp(table->name, name) != 0)
-+ continue;
-+
-+ list_del(&table->list);
-+
-+ audit_log_nfcfg(table->name, table->af, table->private->number,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ swap(table->ops, ops);
-+ mutex_unlock(&xt[af].mutex);
-+
-+ kfree(ops);
-+ return table;
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL_GPL(xt_unregister_table_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
-@@ -2012,8 +2051,10 @@ static int __net_init xt_net_init(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- INIT_LIST_HEAD(&xt_net->tables[i]);
-+ INIT_LIST_HEAD(&xt_net->dead_tables[i]);
-+ }
- return 0;
- }
-
-@@ -2022,8 +2063,10 @@ static void __net_exit xt_net_exit(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- WARN_ON_ONCE(!list_empty(&xt_net->tables[i]));
-+ WARN_ON_ONCE(!list_empty(&xt_net->dead_tables[i]));
-+ }
- }
-
- static struct pernet_operations xt_net_ops = {
---
-2.53.0
-
+++ /dev/null
-From 3ee29420e4e1f869606efb8da60dabf7285792a2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 24 Jan 2024 10:21:11 +0100
-Subject: netfilter: xtables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit a9525c7f6219cee9284c0031c5930e8d41384677 ]
-
-Add hidden IP(6)_NF_IPTABLES_LEGACY symbol.
-
-When any of the "old" builtin tables are enabled the "old" iptables
-interface will be supported.
-
-To disable the old set/getsockopt interface the existing options
-for the builtin tables need to be turned off:
-
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_FILTER is not set
-CONFIG_IP_NF_NAT is not set
-CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_SECURITY is not set
-
-Same for CONFIG_IP6_NF_ variants.
-
-This allows to build a kernel that only supports ip(6)tables-nft
-(iptables-over-nftables api).
-
-In the future the _LEGACY symbol will become visible and the select
-statements will be turned into 'depends on', but for now be on safe side
-so "make oldconfig" won't break things.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 15 ++++++++++++---
- net/ipv4/netfilter/Makefile | 2 +-
- net/ipv6/netfilter/Kconfig | 20 ++++++++++++++------
- net/ipv6/netfilter/Makefile | 2 +-
- net/netfilter/Kconfig | 12 ++++++------
- 5 files changed, 34 insertions(+), 17 deletions(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 5c2cdcb19dba3..7c2b8a652016d 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -10,6 +10,10 @@ config NF_DEFRAG_IPV4
- tristate
- default n
-
-+# old sockopt interface and eval loop
-+config IP_NF_IPTABLES_LEGACY
-+ tristate
-+
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
- help
-@@ -160,7 +164,7 @@ config IP_NF_MATCH_ECN
- config IP_NF_MATCH_RPFILTER
- tristate '"rpfilter" reverse path filter match support'
- depends on NETFILTER_ADVANCED
-- depends on IP_NF_MANGLE || IP_NF_RAW
-+ depends on IP_NF_MANGLE || IP_NF_RAW || NFT_COMPAT
- help
- This option allows you to match packets whose replies would
- go out via the interface the packet came in.
-@@ -181,6 +185,7 @@ config IP_NF_MATCH_TTL
- config IP_NF_FILTER
- tristate "Packet filtering"
- default m if NETFILTER_ADVANCED=n
-+ select IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -190,7 +195,7 @@ config IP_NF_FILTER
-
- config IP_NF_TARGET_REJECT
- tristate "REJECT target support"
-- depends on IP_NF_FILTER
-+ depends on IP_NF_FILTER || NFT_COMPAT
- select NF_REJECT_IPV4
- default m if NETFILTER_ADVANCED=n
- help
-@@ -220,6 +225,7 @@ config IP_NF_NAT
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -260,6 +266,7 @@ endif # IP_NF_NAT
- config IP_NF_MANGLE
- tristate "Packet mangling"
- default m if NETFILTER_ADVANCED=n
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -283,7 +290,7 @@ config IP_NF_TARGET_CLUSTERIP
-
- config IP_NF_TARGET_ECN
- tristate "ECN target support"
-- depends on IP_NF_MANGLE
-+ depends on IP_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `ECN' target, which can be used in the iptables mangle
-@@ -308,6 +315,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -321,6 +329,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
-index f38fb1368ddb2..d3150ea5b8e57 100644
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -28,7 +28,7 @@ obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
- obj-$(CONFIG_NF_FLOW_TABLE_IPV4) += nf_flow_table_ipv4.o
-
- # generic IP tables
--obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
-+obj-$(CONFIG_IP_NF_IPTABLES_LEGACY) += ip_tables.o
-
- # the three instances of ip_tables
- obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index f22233e44ee97..bc51a77fb6c07 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -6,6 +6,10 @@
- menu "IPv6: Netfilter Configuration"
- depends on INET && IPV6 && NETFILTER
-
-+# old sockopt interface and eval loop
-+config IP6_NF_IPTABLES_LEGACY
-+ tristate
-+
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
- help
-@@ -155,7 +159,7 @@ config IP6_NF_MATCH_MH
- config IP6_NF_MATCH_RPFILTER
- tristate '"rpfilter" reverse path filter match support'
- depends on NETFILTER_ADVANCED
-- depends on IP6_NF_MANGLE || IP6_NF_RAW
-+ depends on IP6_NF_MANGLE || IP6_NF_RAW || NFT_COMPAT
- help
- This option allows you to match packets whose replies would
- go out via the interface the packet came in.
-@@ -194,6 +198,8 @@ config IP6_NF_TARGET_HL
- config IP6_NF_FILTER
- tristate "Packet filtering"
- default m if NETFILTER_ADVANCED=n
-+ select IP6_NF_IPTABLES_LEGACY
-+ tristate
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -203,7 +209,7 @@ config IP6_NF_FILTER
-
- config IP6_NF_TARGET_REJECT
- tristate "REJECT target support"
-- depends on IP6_NF_FILTER
-+ depends on IP6_NF_FILTER || NFT_COMPAT
- select NF_REJECT_IPV6
- default m if NETFILTER_ADVANCED=n
- help
-@@ -229,6 +235,7 @@ config IP6_NF_TARGET_SYNPROXY
- config IP6_NF_MANGLE
- tristate "Packet mangling"
- default m if NETFILTER_ADVANCED=n
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -238,6 +245,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -251,6 +259,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -262,6 +271,7 @@ config IP6_NF_NAT
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
- select NF_NAT
-+ select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-@@ -270,25 +280,23 @@ config IP6_NF_NAT
-
- To compile it as a module, choose M here. If unsure, say N.
-
--if IP6_NF_NAT
--
- config IP6_NF_TARGET_MASQUERADE
- tristate "MASQUERADE target support"
- select NETFILTER_XT_TARGET_MASQUERADE
-+ depends on IP6_NF_NAT
- help
- This is a backwards-compat option for the user's convenience
- (e.g. when running oldconfig). It selects NETFILTER_XT_TARGET_MASQUERADE.
-
- config IP6_NF_TARGET_NPT
- tristate "NPT (Network Prefix translation) target support"
-+ depends on IP6_NF_NAT || NFT_COMPAT
- help
- This option adds the `SNPT' and `DNPT' target, which perform
- stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
-
- To compile it as a module, choose M here. If unsure, say N.
-
--endif # IP6_NF_NAT
--
- endif # IP6_NF_IPTABLES
- endmenu
-
-diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
-index b85383606df71..7d0a913529891 100644
---- a/net/ipv6/netfilter/Makefile
-+++ b/net/ipv6/netfilter/Makefile
-@@ -4,7 +4,7 @@
- #
-
- # Link order matters here.
--obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
-+obj-$(CONFIG_IP6_NF_IPTABLES_LEGACY) += ip6_tables.o
- obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
- obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
- obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index f02ebe4609650..fdfda4b6bff67 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -812,7 +812,7 @@ config NETFILTER_XT_TARGET_AUDIT
-
- config NETFILTER_XT_TARGET_CHECKSUM
- tristate "CHECKSUM target support"
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `CHECKSUM' target, which can be used in the iptables mangle
-@@ -863,7 +863,7 @@ config NETFILTER_XT_TARGET_CONNSECMARK
- config NETFILTER_XT_TARGET_CT
- tristate '"CT" target support'
- depends on NF_CONNTRACK
-- depends on IP_NF_RAW || IP6_NF_RAW
-+ depends on IP_NF_RAW || IP6_NF_RAW || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This options adds a `CT' target, which allows to specify initial
-@@ -874,7 +874,7 @@ config NETFILTER_XT_TARGET_CT
-
- config NETFILTER_XT_TARGET_DSCP
- tristate '"DSCP" and "TOS" target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `DSCP' target, which allows you to manipulate
-@@ -890,7 +890,7 @@ config NETFILTER_XT_TARGET_DSCP
-
- config NETFILTER_XT_TARGET_HL
- tristate '"HL" hoplimit target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds the "HL" (for IPv6) and "TTL" (for IPv4)
-@@ -1074,7 +1074,7 @@ config NETFILTER_XT_TARGET_TPROXY
- depends on NETFILTER_ADVANCED
- depends on IPV6 || IPV6=n
- depends on IP6_NF_IPTABLES || IP6_NF_IPTABLES=n
-- depends on IP_NF_MANGLE
-+ depends on IP_NF_MANGLE || NFT_COMPAT
- select NF_DEFRAG_IPV4
- select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES != n
- select NF_TPROXY_IPV4
-@@ -1141,7 +1141,7 @@ config NETFILTER_XT_TARGET_TCPMSS
-
- config NETFILTER_XT_TARGET_TCPOPTSTRIP
- tristate '"TCPOPTSTRIP" target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a "TCPOPTSTRIP" target, which allows you to strip
---
-2.53.0
-
+++ /dev/null
-From 68db07bb9db862eff5c2e6e80b9cfbb8422819dd Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 6 Feb 2024 14:55:53 +0100
-Subject: netfilter: xtables: fix up kconfig dependencies
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 749d4ef0868c5d8a98e07073791b2198178c93b4 ]
-
-Randy Dunlap reports arptables build failure:
-arp_tables.c:(.text+0x20): undefined reference to `xt_find_table'
-
-... because recent change removed a 'select' on the xtables core.
-Add a "depends" clause on arptables to resolve this.
-
-Kernel test robot reports another build breakage:
-iptable_nat.c:(.text+0x8): undefined reference to `ipt_unregister_table_exit'
-
-... because of a typo, the nat table selected ip6tables.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Randy Dunlap <rdunlap@infradead.org>
-Closes: https://lore.kernel.org/netfilter-devel/d0dfbaef-046a-4c42-9daa-53636664bf6d@infradead.org/
-Fixes: a9525c7f6219 ("netfilter: xtables: allow xtables-nft only builds")
-Fixes: 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only builds")
-Acked-by: Randy Dunlap <rdunlap@infradead.org>
-Tested-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 7c2b8a652016d..18f60e675c438 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -225,7 +225,7 @@ config IP_NF_NAT
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP6_NF_IPTABLES_LEGACY
-+ select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -351,6 +351,7 @@ config NFT_COMPAT_ARP
- config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
-+ depends on NETFILTER_XTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
---
-2.53.0
-
alsa-asihpi-avoid-write-overflow-check-warning.patch
-asoc-sof-topology-reject-invalid-vendor-array-size-i.patch
can-mcp251x-add-error-handling-for-power-enable-in-o.patch
btrfs-tracepoints-get-correct-superblock-from-dentry.patch
alsa-hda-realtek-add-mute-led-quirk-for-hp-pavilion-.patch
tracing-probe-reject-non-closed-empty-immediate-stri.patch
e1000-check-return-value-of-e1000_read_eeprom.patch
xsk-tighten-umem-headroom-validation-to-account-for-.patch
-xfrm-wait-for-rcu-readers-during-policy-netns-exit.patch
xfrm_user-fix-info-leak-in-build_mapping.patch
netfilter-nfnetlink_log-initialize-nfgenmsg-in-nlmsg.patch
netfilter-xt_multiport-validate-range-encoding-in-ch.patch
mips-always-record-segbits-in-cpu_data.vmbits.patch
mips-mm-suppress-tlb-uniquification-on-ehinv-hardwar.patch
mips-mm-rewrite-tlb-uniquification-for-the-hidden-bi.patch
-alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch
alsa-usb-audio-update-for-native-dsd-support-quirks.patch
-alsa-usb-audio-remove-validate_rates-quirk-for-focus.patch
batman-adv-hold-claim-backbone-gateways-by-reference.patch
nfc-llcp-add-missing-return-after-llcp_closed-checks.patch
can-raw-fix-ro-uniq-use-after-free-in-raw_rcv.patch
rtc-ntxec-fix-of-node-reference-imbalance.patch
userfaultfd-allow-registration-of-ranges-below-mmap_min_addr.patch
kvm-nsvm-mark-all-of-vmcb02-dirty-when-restoring-nested-state.patch
-kvm-nsvm-sync-nextrip-to-cached-vmcb12-after-vmrun-of-l2.patch
kvm-nsvm-sync-interrupt-shadow-to-cached-vmcb12-after-vmrun-of-l2.patch
kvm-svm-inject-ud-for-invlpga-if-efer.svme-0.patch
kvm-svm-explicitly-mark-vmcb01-dirty-after-modifying-vmcb-intercepts.patch
kunit-config-kunit_debugfs-should-depend-on-debug_fs.patch
arm-integrator-fix-early-initialization.patch
netfilter-x_tables-unregister-the-templates-first.patch
-netfilter-arp_tables-allow-use-of-arpt_do_table-as-h.patch
-netfilter-arptables-allow-xtables-nft-only-builds.patch
-netfilter-xtables-allow-xtables-nft-only-builds.patch
-netfilter-ebtables-allow-xtables-nft-only-builds.patch
-netfilter-xtables-fix-up-kconfig-dependencies.patch
-netfilter-arptables-select-netfilter_family_arp-when.patch
-netfilter-make-legacy-configs-user-selectable.patch
-netfilter-exclude-legacy-tables-on-preempt_rt.patch
-netfilter-x_tables-add-and-use-xt_unregister_table_p.patch
-netfilter-x_tables-add-and-use-xtables_unregister_ta.patch
-netfilter-ebtables-move-to-two-stage-removal-scheme.patch
-netfilter-ebtables-close-dangling-table-module-init-.patch
-netfilter-bridge-eb_tables-close-module-init-race.patch
tcp-fix-imbalanced-icsk_accept_queue-count.patch
ice-fix-locking-in-ice_dcb_rebuild.patch
phy-marvell-mvebu-a3700-utmi-fix-incorrect-usb2_phy_.patch
+++ /dev/null
-From 826fc42aff385f6259f9aa52e996dafe873e0abc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 2 Apr 2026 13:31:04 +0200
-Subject: xfrm: Wait for RCU readers during policy netns exit
-
-From: Steffen Klassert <steffen.klassert@secunet.com>
-
-[ Upstream commit 069daad4f2ae9c5c108131995529d5f02392c446 ]
-
-xfrm_policy_fini() frees the policy_bydst hash tables after flushing the
-policy work items and deleting all policies, but it does not wait for
-concurrent RCU readers to leave their read-side critical sections first.
-
-The policy_bydst tables are published via rcu_assign_pointer() and are
-looked up through rcu_dereference_check(), so netns teardown must also
-wait for an RCU grace period before freeing the table memory.
-
-Fix this by adding synchronize_rcu() before freeing the policy hash tables.
-
-Fixes: e1e551bc5630 ("xfrm: policy: prepare policy_bydst hash for rcu lookups")
-Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-Reviewed-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/xfrm/xfrm_policy.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
-index 851029a5383a2..29b3db09e19cf 100644
---- a/net/xfrm/xfrm_policy.c
-+++ b/net/xfrm/xfrm_policy.c
-@@ -4125,6 +4125,8 @@ static void xfrm_policy_fini(struct net *net)
- #endif
- xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false);
-
-+ synchronize_rcu();
-+
- WARN_ON(!list_empty(&net->xfrm.policy_all));
-
- for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
---
-2.53.0
-
+++ /dev/null
-From fc64cb98f74170b3f76a0b78faab0ef2ac69ab11 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sat, 21 Feb 2026 02:33:45 +1030
-Subject: ALSA: usb-audio: Improve Focusrite sample rate filtering
-
-From: Geoffrey D. Bennett <g@b4.vu>
-
-[ Upstream commit 24d2d3c5f94007a5a0554065ab7349bb69e28bcb ]
-
-Replace the bLength == 10 max_rate check in
-focusrite_valid_sample_rate() with filtering that also examines the
-bmControls VAL_ALT_SETTINGS bit.
-
-When VAL_ALT_SETTINGS is readable, the device uses strict
-per-altsetting rate filtering (only the highest rate pair for that
-altsetting is valid). When it is not readable, all rates up to
-max_rate are valid.
-
-For devices without the bLength == 10 Format Type descriptor extension
-but with VAL_ALT_SETTINGS readable and multiple altsettings (only seen
-in Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
-convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
-
-This produces correct rate tables for all tested Focusrite devices
-(all Scarlett 2nd, 3rd, and 4th Gen, Clarett+, and Vocaster) using
-only USB descriptors, allowing QUIRK_FLAG_VALIDATE_RATES to be removed
-for Focusrite in the next commit.
-
-Signed-off-by: Geoffrey D. Bennett <g@b4.vu>
-Signed-off-by: Takashi Iwai <tiwai@suse.de>
-Link: https://patch.msgid.link/7e18c1f393a6ecb6fc75dd867a2c4dbe135e3e22.1771594828.git.g@b4.vu
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/usb/format.c | 86 +++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 74 insertions(+), 12 deletions(-)
-
-diff --git a/sound/usb/format.c b/sound/usb/format.c
-index f33d25a4e4cc7..682adbdf7ee79 100644
---- a/sound/usb/format.c
-+++ b/sound/usb/format.c
-@@ -304,9 +304,37 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp,
- }
-
- /*
-- * Many Focusrite devices supports a limited set of sampling rates per
-- * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
-- * descriptor which has a non-standard bLength = 10.
-+ * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and
-+ * 176400/192000. Return true if rate is in the pair for max_rate.
-+ */
-+static bool focusrite_rate_pair(unsigned int rate,
-+ unsigned int max_rate)
-+{
-+ switch (max_rate) {
-+ case 48000: return rate == 44100 || rate == 48000;
-+ case 96000: return rate == 88200 || rate == 96000;
-+ case 192000: return rate == 176400 || rate == 192000;
-+ default: return true;
-+ }
-+}
-+
-+/*
-+ * Focusrite devices report all supported rates in a single clock
-+ * source but only a subset is valid per altsetting.
-+ *
-+ * Detection uses two descriptor features:
-+ *
-+ * 1. Format Type descriptor bLength == 10: non-standard extension
-+ * with max sample rate in bytes 6..9.
-+ *
-+ * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device
-+ * only supports the highest rate pair for that altsetting, and when
-+ * clear, all rates up to max_rate are valid.
-+ *
-+ * For devices without the bLength == 10 extension but with
-+ * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in
-+ * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite
-+ * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
- */
- static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
- struct audioformat *fp,
-@@ -314,8 +342,10 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
- {
- struct usb_interface *iface;
- struct usb_host_interface *alts;
-+ struct uac2_as_header_descriptor *as;
- unsigned char *fmt;
- unsigned int max_rate;
-+ bool val_alt;
-
- iface = usb_ifnum_to_if(chip->dev, fp->iface);
- if (!iface)
-@@ -327,26 +357,58 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
- if (!fmt)
- return true;
-
-+ as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
-+ NULL, UAC_AS_GENERAL);
-+ if (!as)
-+ return true;
-+
-+ val_alt = uac_v2v3_control_is_readable(as->bmControls,
-+ UAC2_AS_VAL_ALT_SETTINGS);
-+
- if (fmt[0] == 10) { /* bLength */
- max_rate = combine_quad(&fmt[6]);
-
-- /* Validate max rate */
-- if (max_rate != 48000 &&
-- max_rate != 96000 &&
-- max_rate != 192000 &&
-- max_rate != 384000) {
--
-+ if (val_alt)
-+ return focusrite_rate_pair(rate, max_rate);
-+
-+ /* No val_alt: rates fall through from higher */
-+ switch (max_rate) {
-+ case 192000:
-+ if (rate == 176400 || rate == 192000)
-+ return true;
-+ fallthrough;
-+ case 96000:
-+ if (rate == 88200 || rate == 96000)
-+ return true;
-+ fallthrough;
-+ case 48000:
-+ return (rate == 44100 || rate == 48000);
-+ default:
- usb_audio_info(chip,
- "%u:%d : unexpected max rate: %u\n",
- fp->iface, fp->altsetting, max_rate);
--
- return true;
- }
-+ }
-
-- return rate <= max_rate;
-+ if (!val_alt)
-+ return true;
-+
-+ /* Multi-altsetting device with val_alt but no max_rate
-+ * in the format descriptor. Use Focusrite convention:
-+ * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz.
-+ */
-+ if (iface->num_altsetting <= 2)
-+ return true;
-+
-+ switch (fp->altsetting) {
-+ case 1: max_rate = 48000; break;
-+ case 2: max_rate = 96000; break;
-+ case 3: max_rate = 192000; break;
-+ default: return true;
- }
-
-- return true;
-+ return focusrite_rate_pair(rate, max_rate);
- }
-
- /*
---
-2.53.0
-
+++ /dev/null
-From 2604ef8eef5f29edb873a2b178923e253b7aa20e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 19 Mar 2026 21:45:26 -0300
-Subject: ASoC: SOF: topology: reject invalid vendor array size in token parser
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
-
-[ Upstream commit 215e5fe75881a7e2425df04aeeed47a903d5cd5d ]
-
-sof_parse_token_sets() accepts array->size values that can be invalid
-for a vendor tuple array header. In particular, a zero size does not
-advance the parser state and can lead to non-progress parsing on
-malformed topology data.
-
-Validate array->size against the minimum header size and reject values
-smaller than sizeof(*array) before parsing. This preserves behavior for
-valid topologies and hardens malformed-input handling.
-
-Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
-Acked-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
-Link: https://patch.msgid.link/20260319-sof-topology-array-size-fix-v1-1-f9191b16b1b7@gmail.com
-Signed-off-by: Mark Brown <broonie@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- sound/soc/sof/topology.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
-index 374c8b1d69584..d803111e36385 100644
---- a/sound/soc/sof/topology.c
-+++ b/sound/soc/sof/topology.c
-@@ -678,7 +678,7 @@ static int sof_parse_token_sets(struct snd_soc_component *scomp,
- asize = le32_to_cpu(array->size);
-
- /* validate asize */
-- if (asize < 0) { /* FIXME: A zero-size array makes no sense */
-+ if (asize < sizeof(*array)) {
- dev_err(scomp->dev, "error: invalid array size 0x%x\n",
- asize);
- return -EINVAL;
---
-2.53.0
-
+++ /dev/null
-From 5445ac1e1d917b8e8c4bca0c138dbf70539618f4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Jan 2024 16:42:48 +0100
-Subject: netfilter: arptables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 4654467dc7e111e84f43ed1b70322873ae77e7be ]
-
-Allows to build kernel that supports the arptables mangle target
-via nftables' compat infra but without the arptables get/setsockopt
-interface or the old arptables filter interpreter.
-
-IOW, setting IP_NF_ARPFILTER=n will break arptables-legacy, but
-arptables-nft will continue to work as long as nftables compat
-support is enabled.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Reviewed-by: Phil Sutter <phil@nwl.cc>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 28 +++++++++++++---------------
- 1 file changed, 13 insertions(+), 15 deletions(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index aab384126f61f..483778f379d44 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -323,36 +323,34 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate "ARP tables support"
-- select NETFILTER_XTABLES
-- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_ADVANCED
-- help
-- arptables is a general, extensible packet identification framework.
-- The ARP packet filtering and mangling (manipulation)subsystems
-- use this: say Y or M here if you want to use either of those.
--
-- To compile it as a module, choose M here. If unsure, say N.
-+ tristate
-
--if IP_NF_ARPTABLES
-+config NFT_COMPAT_ARP
-+ tristate
-+ depends on NF_TABLES_ARP && NFT_COMPAT
-+ default m if NFT_COMPAT=m
-+ default y if NFT_COMPAT=y
-
- config IP_NF_ARPFILTER
-- tristate "ARP packet filtering"
-+ tristate "arptables-legacy packet filtering support"
-+ select IP_NF_ARPTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-- local output. On a bridge, you can also specify filtering rules
-- for forwarded ARP packets. See the man page for arptables(8).
-+ local output. This is only needed for arptables-legacy(8).
-+ Neither arptables-nft nor nftables need this to work.
-
- To compile it as a module, choose M here. If unsure, say N.
-
- config IP_NF_ARP_MANGLE
- tristate "ARP payload mangling"
-+ depends on IP_NF_ARPTABLES || NFT_COMPAT_ARP
- help
- Allows altering the ARP packet payload: source and destination
- hardware and network addresses.
-
--endif # IP_NF_ARPTABLES
-+ This option is needed by both arptables-legacy and arptables-nft.
-+ It is not used by nftables.
-
- endmenu
-
---
-2.53.0
-
+++ /dev/null
-From e2b622c702013ca0d80dfd33ec3283eec78d8b63 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Mar 2024 21:15:52 -0700
-Subject: netfilter: arptables: Select NETFILTER_FAMILY_ARP when building
- arp_tables.c
-
-From: Kuniyuki Iwashima <kuniyu@amazon.com>
-
-[ Upstream commit 15fba562f7a9f04322b8bfc8f392e04bb93d81be ]
-
-syzkaller started to report a warning below [0] after consuming the
-commit 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only
-builds").
-
-The change accidentally removed the dependency on NETFILTER_FAMILY_ARP
-from IP_NF_ARPTABLES.
-
-If NF_TABLES_ARP is not enabled on Kconfig, NETFILTER_FAMILY_ARP will
-be removed and some code necessary for arptables will not be compiled.
-
- $ grep -E "(NETFILTER_FAMILY_ARP|IP_NF_ARPTABLES|NF_TABLES_ARP)" .config
- CONFIG_NETFILTER_FAMILY_ARP=y
- # CONFIG_NF_TABLES_ARP is not set
- CONFIG_IP_NF_ARPTABLES=y
-
- $ make olddefconfig
-
- $ grep -E "(NETFILTER_FAMILY_ARP|IP_NF_ARPTABLES|NF_TABLES_ARP)" .config
- # CONFIG_NF_TABLES_ARP is not set
- CONFIG_IP_NF_ARPTABLES=y
-
-So, when nf_register_net_hooks() is called for arptables, it will
-trigger the splat below.
-
-Now IP_NF_ARPTABLES is only enabled by IP_NF_ARPFILTER, so let's
-restore the dependency on NETFILTER_FAMILY_ARP in IP_NF_ARPFILTER.
-
-[0]:
-WARNING: CPU: 0 PID: 242 at net/netfilter/core.c:316 nf_hook_entry_head+0x1e1/0x2c0 net/netfilter/core.c:316
-Modules linked in:
-CPU: 0 PID: 242 Comm: syz-executor.0 Not tainted 6.8.0-12821-g537c2e91d354 #10
-Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
-RIP: 0010:nf_hook_entry_head+0x1e1/0x2c0 net/netfilter/core.c:316
-Code: 83 fd 04 0f 87 bc 00 00 00 e8 5b 84 83 fd 4d 8d ac ec a8 0b 00 00 e8 4e 84 83 fd 4c 89 e8 5b 5d 41 5c 41 5d c3 e8 3f 84 83 fd <0f> 0b e8 38 84 83 fd 45 31 ed 5b 5d 4c 89 e8 41 5c 41 5d c3 e8 26
-RSP: 0018:ffffc90000b8f6e8 EFLAGS: 00010293
-RAX: 0000000000000000 RBX: 0000000000000003 RCX: ffffffff83c42164
-RDX: ffff888106851180 RSI: ffffffff83c42321 RDI: 0000000000000005
-RBP: 0000000000000000 R08: 0000000000000005 R09: 000000000000000a
-R10: 0000000000000003 R11: ffff8881055c2f00 R12: ffff888112b78000
-R13: 0000000000000000 R14: ffff8881055c2f00 R15: ffff8881055c2f00
-FS: 00007f377bd78800(0000) GS:ffff88811b000000(0000) knlGS:0000000000000000
-CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-CR2: 0000000000496068 CR3: 000000011298b003 CR4: 0000000000770ef0
-PKRU: 55555554
-Call Trace:
- <TASK>
- __nf_register_net_hook+0xcd/0x7a0 net/netfilter/core.c:428
- nf_register_net_hook+0x116/0x170 net/netfilter/core.c:578
- nf_register_net_hooks+0x5d/0xc0 net/netfilter/core.c:594
- arpt_register_table+0x250/0x420 net/ipv4/netfilter/arp_tables.c:1553
- arptable_filter_table_init+0x41/0x60 net/ipv4/netfilter/arptable_filter.c:39
- xt_find_table_lock+0x2e9/0x4b0 net/netfilter/x_tables.c:1260
- xt_request_find_table_lock+0x2b/0xe0 net/netfilter/x_tables.c:1285
- get_info+0x169/0x5c0 net/ipv4/netfilter/arp_tables.c:808
- do_arpt_get_ctl+0x3f9/0x830 net/ipv4/netfilter/arp_tables.c:1444
- nf_getsockopt+0x76/0xd0 net/netfilter/nf_sockopt.c:116
- ip_getsockopt+0x17d/0x1c0 net/ipv4/ip_sockglue.c:1777
- tcp_getsockopt+0x99/0x100 net/ipv4/tcp.c:4373
- do_sock_getsockopt+0x279/0x360 net/socket.c:2373
- __sys_getsockopt+0x115/0x1e0 net/socket.c:2402
- __do_sys_getsockopt net/socket.c:2412 [inline]
- __se_sys_getsockopt net/socket.c:2409 [inline]
- __x64_sys_getsockopt+0xbd/0x150 net/socket.c:2409
- do_syscall_x64 arch/x86/entry/common.c:52 [inline]
- do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
- entry_SYSCALL_64_after_hwframe+0x46/0x4e
-RIP: 0033:0x7f377beca6fe
-Code: 1f 44 00 00 48 8b 15 01 97 0a 00 f7 d8 64 89 02 b8 ff ff ff ff eb b8 0f 1f 44 00 00 f3 0f 1e fa 49 89 ca b8 37 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 0a c3 66 0f 1f 84 00 00 00 00 00 48 8b 15 c9
-RSP: 002b:00000000005df728 EFLAGS: 00000246 ORIG_RAX: 0000000000000037
-RAX: ffffffffffffffda RBX: 00000000004966e0 RCX: 00007f377beca6fe
-RDX: 0000000000000060 RSI: 0000000000000000 RDI: 0000000000000003
-RBP: 000000000042938a R08: 00000000005df73c R09: 00000000005df800
-R10: 00000000004966e8 R11: 0000000000000246 R12: 0000000000000003
-R13: 0000000000496068 R14: 0000000000000003 R15: 00000000004bc9d8
- </TASK>
-
-Fixes: 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only builds")
-Reported-by: syzkaller <syzkaller@googlegroups.com>
-Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 0f60a740d117d..6146ef5fc728f 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -343,6 +343,7 @@ config NFT_COMPAT_ARP
- config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
-+ select NETFILTER_FAMILY_ARP
- depends on NETFILTER_XTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
---
-2.53.0
-
+++ /dev/null
-From d19344d6078be196205ad30274c76ac47c05283f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 7 May 2026 11:19:22 +0200
-Subject: netfilter: bridge: eb_tables: close module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 27414ff1b287ea9a2a11675149ec28e05539f3cc ]
-
-sashiko reports for unrelated patch:
- Does the core ebtables initialization in ebtables.c suffer from a similar race?
- Once nf_register_sockopt() completes, the sockopts are exposed globally.
-
-sockopt has to be registered last, just like in ip/ip6/arptables.
-
-Fixes: 5b53951cfc85 ("netfilter: ebtables: use net_generic infra")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtables.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index ec286e54229b7..ca426e49ea1a1 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -2583,19 +2583,20 @@ static int __init ebtables_init(void)
- {
- int ret;
-
-- ret = xt_register_target(&ebt_standard_target);
-+ ret = register_pernet_subsys(&ebt_net_ops);
- if (ret < 0)
- return ret;
-- ret = nf_register_sockopt(&ebt_sockopts);
-+
-+ ret = xt_register_target(&ebt_standard_target);
- if (ret < 0) {
-- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
-- ret = register_pernet_subsys(&ebt_net_ops);
-+ ret = nf_register_sockopt(&ebt_sockopts);
- if (ret < 0) {
-- nf_unregister_sockopt(&ebt_sockopts);
- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 31b08e7485e3b49baf686a56324396a6debd1582 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 24 Jan 2024 10:21:12 +0100
-Subject: netfilter: ebtables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 7ad269787b6615ca56bb161063331991fce51abf ]
-
-Same patch as previous one, but for ebtables.
-
-To build a kernel that only supports ebtables-nft, the builtin tables
-need to be disabled, i.e.:
-
-CONFIG_BRIDGE_EBT_BROUTE=n
-CONFIG_BRIDGE_EBT_T_FILTER=n
-CONFIG_BRIDGE_EBT_T_NAT=n
-
-The ebtables specific extensions can then be used nftables'
-NFT_COMPAT interface.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 7 +++++++
- net/bridge/netfilter/Makefile | 2 +-
- 2 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 7f304a19ac1bf..104c0125e32e8 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -39,6 +39,10 @@ config NF_CONNTRACK_BRIDGE
-
- To compile it as a module, choose M here. If unsure, say N.
-
-+# old sockopt interface and eval loop
-+config BRIDGE_NF_EBTABLES_LEGACY
-+ tristate
-+
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
- depends on BRIDGE && NETFILTER && NETFILTER_XTABLES
-@@ -55,6 +59,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -65,6 +70,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -74,6 +80,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
-index 1c9ce49ab6513..b9a1303da9771 100644
---- a/net/bridge/netfilter/Makefile
-+++ b/net/bridge/netfilter/Makefile
-@@ -9,7 +9,7 @@ obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o
- # connection tracking
- obj-$(CONFIG_NF_CONNTRACK_BRIDGE) += nf_conntrack_bridge.o
-
--obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
-+obj-$(CONFIG_BRIDGE_NF_EBTABLES_LEGACY) += ebtables.o
-
- # tables
- obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o
---
-2.53.0
-
+++ /dev/null
-From 4cabc0abf23050af4a2eb00a4347489cc6ea2c3f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:19 +0200
-Subject: netfilter: ebtables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 92c603fa07bc0d6a17345de3ad7954730b8de44b ]
-
-sashiko reported for a related patch:
- In modules like iptable_raw.c, [..], if register_pernet_subsys() fails,
- the rollback might call kfree(rawtable_ops) before [..]
- During this window, could a concurrent userspace process find the globally
- visible template, trigger table_init(), [..]
-
-The table init functions must always register the template last.
-
-Otherwise, set/getsockopt can instantiate a table in a namespace
-while the required pernet ops (contain the destructor) isn't available.
-This change is also required in x_tables, handled in followup change.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 12 +++++-------
- net/bridge/netfilter/ebtable_filter.c | 12 +++++-------
- net/bridge/netfilter/ebtable_nat.c | 10 ++++------
- 3 files changed, 14 insertions(+), 20 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index 33d8640d21ac1..43c808e525e87 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -112,18 +112,16 @@ static struct pernet_operations broute_net_ops = {
-
- static int __init ebtable_broute_init(void)
- {
-- int ret = ebt_register_template(&broute_table, broute_table_init);
-+ int ret = register_pernet_subsys(&broute_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&broute_net_ops);
-- if (ret) {
-- ebt_unregister_template(&broute_table);
-- return ret;
-- }
-+ ret = ebt_register_template(&broute_table, broute_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&broute_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_broute_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index fdb988c24916a..f76d45dfe9b46 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -93,18 +93,16 @@ static struct pernet_operations frame_filter_net_ops = {
-
- static int __init ebtable_filter_init(void)
- {
-- int ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ int ret = register_pernet_subsys(&frame_filter_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_filter_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_filter);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_filter_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_filter_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 8b981b2041b5d..af0732e2f889d 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -93,16 +93,14 @@ static struct pernet_operations frame_nat_net_ops = {
-
- static int __init ebtable_nat_init(void)
- {
-- int ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ int ret = register_pernet_subsys(&frame_nat_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_nat_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_nat);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_nat_net_ops);
-
- return ret;
- }
---
-2.53.0
-
+++ /dev/null
-From 332bde2e4549c55bae7b469a718babdc55c54e13 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:18 +0200
-Subject: netfilter: ebtables: move to two-stage removal scheme
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b7f0544d86d439cb946515d2ef6a0a75e8626710 ]
-
-Like previous patches for x_tables, follow same pattern in ebtables.
-We can't reuse xt helpers: ebt_table struct layout is incompatible.
-
-table->ops assignment is now done while still holding the ebt mutex
-to make sure we never expose partially-filled table struct.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 2 +-
- net/bridge/netfilter/ebtable_filter.c | 2 +-
- net/bridge/netfilter/ebtable_nat.c | 2 +-
- net/bridge/netfilter/ebtables.c | 60 +++++++++++++++++----------
- 4 files changed, 40 insertions(+), 26 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index 8f19253024b0a..33d8640d21ac1 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -128,8 +128,8 @@ static int __init ebtable_broute_init(void)
-
- static void __exit ebtable_broute_fini(void)
- {
-- unregister_pernet_subsys(&broute_net_ops);
- ebt_unregister_template(&broute_table);
-+ unregister_pernet_subsys(&broute_net_ops);
- }
-
- module_init(ebtable_broute_init);
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index 278f324e67524..fdb988c24916a 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -109,8 +109,8 @@ static int __init ebtable_filter_init(void)
-
- static void __exit ebtable_filter_fini(void)
- {
-- unregister_pernet_subsys(&frame_filter_net_ops);
- ebt_unregister_template(&frame_filter);
-+ unregister_pernet_subsys(&frame_filter_net_ops);
- }
-
- module_init(ebtable_filter_init);
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 9066f7f376d57..8b981b2041b5d 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -109,8 +109,8 @@ static int __init ebtable_nat_init(void)
-
- static void __exit ebtable_nat_fini(void)
- {
-- unregister_pernet_subsys(&frame_nat_net_ops);
- ebt_unregister_template(&frame_nat);
-+ unregister_pernet_subsys(&frame_nat_net_ops);
- }
-
- module_init(ebtable_nat_init);
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index f99e348c8f37f..ec286e54229b7 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -42,6 +42,7 @@
-
- struct ebt_pernet {
- struct list_head tables;
-+ struct list_head dead_tables;
- };
-
- struct ebt_template {
-@@ -1162,11 +1163,6 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
-
- static void __ebt_unregister_table(struct net *net, struct ebt_table *table)
- {
-- mutex_lock(&ebt_mutex);
-- list_del(&table->list);
-- mutex_unlock(&ebt_mutex);
-- audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
- EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
- ebt_cleanup_entry, net, NULL);
- if (table->private->nentries)
-@@ -1267,13 +1263,15 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
- for (i = 0; i < num_ops; i++)
- ops[i].priv = table;
-
-- list_add(&table->list, &ebt_net->tables);
-- mutex_unlock(&ebt_mutex);
--
- table->ops = ops;
- ret = nf_register_net_hooks(net, ops, num_ops);
-- if (ret)
-+ if (ret) {
-+ synchronize_rcu();
- __ebt_unregister_table(net, table);
-+ } else {
-+ list_add(&table->list, &ebt_net->tables);
-+ }
-+ mutex_unlock(&ebt_mutex);
-
- audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
- AUDIT_XT_OP_REGISTER, GFP_KERNEL);
-@@ -1339,7 +1337,7 @@ void ebt_unregister_template(const struct ebt_table *t)
- }
- EXPORT_SYMBOL(ebt_unregister_template);
-
--static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-+void ebt_unregister_table_pre_exit(struct net *net, const char *name)
- {
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
- struct ebt_table *t;
-@@ -1348,30 +1346,36 @@ static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-
- list_for_each_entry(t, &ebt_net->tables, list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &ebt_net->dead_tables);
- mutex_unlock(&ebt_mutex);
-- return t;
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
- }
- }
-
- mutex_unlock(&ebt_mutex);
-- return NULL;
--}
--
--void ebt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct ebt_table *table = __ebt_find_table(net, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
- }
- EXPORT_SYMBOL(ebt_unregister_table_pre_exit);
-
- void ebt_unregister_table(struct net *net, const char *name)
- {
-- struct ebt_table *table = __ebt_find_table(net, name);
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+ struct ebt_table *t;
-
-- if (table)
-- __ebt_unregister_table(net, table);
-+ mutex_lock(&ebt_mutex);
-+
-+ list_for_each_entry(t, &ebt_net->dead_tables, list) {
-+ if (strcmp(t->name, name) == 0) {
-+ list_del(&t->list);
-+ audit_log_nfcfg(t->name, AF_BRIDGE, t->private->nentries,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ __ebt_unregister_table(net, t);
-+ mutex_unlock(&ebt_mutex);
-+ return;
-+ }
-+ }
-+
-+ mutex_unlock(&ebt_mutex);
- }
-
- /* userspace just supplied us with counters */
-@@ -2556,11 +2560,21 @@ static int __net_init ebt_pernet_init(struct net *net)
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-
- INIT_LIST_HEAD(&ebt_net->tables);
-+ INIT_LIST_HEAD(&ebt_net->dead_tables);
- return 0;
- }
-
-+static void __net_exit ebt_pernet_exit(struct net *net)
-+{
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+
-+ WARN_ON_ONCE(!list_empty(&ebt_net->tables));
-+ WARN_ON_ONCE(!list_empty(&ebt_net->dead_tables));
-+}
-+
- static struct pernet_operations ebt_net_ops = {
- .init = ebt_pernet_init,
-+ .exit = ebt_pernet_exit,
- .id = &ebt_pernet_id,
- .size = sizeof(struct ebt_pernet),
- };
---
-2.53.0
-
+++ /dev/null
-From 4fd8ba08d22ba9f7b09e67331fa5c68365b38589 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Jun 2025 17:44:23 +0200
-Subject: netfilter: Exclude LEGACY TABLES on PREEMPT_RT.
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-[ Upstream commit 9fce66583f06c212e95e4b76dd61d8432ffa56b6 ]
-
-The seqcount xt_recseq is used to synchronize the replacement of
-xt_table::private in xt_replace_table() against all readers such as
-ipt_do_table()
-
-To ensure that there is only one writer, the writing side disables
-bottom halves. The sequence counter can be acquired recursively. Only the
-first invocation modifies the sequence counter (signaling that a writer
-is in progress) while the following (recursive) writer does not modify
-the counter.
-The lack of a proper locking mechanism for the sequence counter can lead
-to live lock on PREEMPT_RT if the high prior reader preempts the
-writer. Additionally if the per-CPU lock on PREEMPT_RT is removed from
-local_bh_disable() then there is no synchronisation for the per-CPU
-sequence counter.
-
-The affected code is "just" the legacy netfilter code which is replaced
-by "netfilter tables". That code can be disabled without sacrificing
-functionality because everything is provided by the newer
-implementation. This will only requires the usage of the "-nft" tools
-instead of the "-legacy" ones.
-The long term plan is to remove the legacy code so lets accelerate the
-progress.
-
-Relax dependencies on iptables legacy, replace select with depends on,
-this should cause no harm to existing kernel configs and users can still
-toggle IP{6}_NF_IPTABLES_LEGACY in any case.
-Make EBTABLES_LEGACY, IPTABLES_LEGACY and ARPTABLES depend on
-NETFILTER_XTABLES_LEGACY. Hide xt_recseq and its users,
-xt_register_table() and xt_percpu_counter_alloc() behind
-NETFILTER_XTABLES_LEGACY. Let NETFILTER_XTABLES_LEGACY depend on
-!PREEMPT_RT.
-
-This will break selftest expecing the legacy options enabled and will be
-addressed in a following patch.
-
-Co-developed-by: Florian Westphal <fw@strlen.de>
-Co-developed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 10 +++++-----
- net/ipv4/netfilter/Kconfig | 24 ++++++++++++------------
- net/ipv6/netfilter/Kconfig | 19 +++++++++----------
- net/netfilter/Kconfig | 10 ++++++++++
- net/netfilter/x_tables.c | 16 +++++++++++-----
- 5 files changed, 47 insertions(+), 32 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index f16bbbbb94817..60f28e4fb5c0a 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -42,8 +42,8 @@ config NF_CONNTRACK_BRIDGE
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
- tristate "Legacy EBTABLES support"
-- depends on BRIDGE && NETFILTER_XTABLES
-- default n
-+ depends on BRIDGE && NETFILTER_XTABLES_LEGACY
-+ default n
- help
- Legacy ebtables packet/frame classifier.
- This is not needed if you are using ebtables over nftables
-@@ -65,7 +65,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -76,7 +76,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -86,7 +86,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 1d0a89a67acf5..ffb1f193a8bd5 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -13,8 +13,8 @@ config NF_DEFRAG_IPV4
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
- tristate "Legacy IP tables support"
-- default n
-- select NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- iptables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -182,8 +182,8 @@ config IP_NF_MATCH_TTL
- # `filter', generic and specific targets
- config IP_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -220,10 +220,10 @@ config IP_NF_TARGET_SYNPROXY
- config IP_NF_NAT
- tristate "iptables NAT support"
- depends on NF_CONNTRACK
-+ depends on IP_NF_IPTABLES_LEGACY
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -263,8 +263,8 @@ endif # IP_NF_NAT
- # mangle + specific targets
- config IP_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -313,7 +313,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -327,7 +327,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -339,8 +339,8 @@ endif # IP_NF_IPTABLES
- # ARP tables
- config IP_NF_ARPTABLES
- tristate "Legacy ARPTABLES support"
-- depends on NETFILTER_XTABLES
-- default n
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default n
- help
- arptables is a legacy packet classifier.
- This is not needed if you are using arptables over nftables
-@@ -356,7 +356,7 @@ config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index e087a8e97ba78..276860f65baae 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -9,9 +9,8 @@ menu "IPv6: Netfilter Configuration"
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
- tristate "Legacy IP6 tables support"
-- depends on INET && IPV6
-- select NETFILTER_XTABLES
-- default n
-+ depends on INET && IPV6 && NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- ip6tables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -196,8 +195,8 @@ config IP6_NF_TARGET_HL
-
- config IP6_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- tristate
- help
- Packet filtering defines a table `filter', which has a series of
-@@ -233,8 +232,8 @@ config IP6_NF_TARGET_SYNPROXY
-
- config IP6_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -244,7 +243,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -258,7 +257,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -269,8 +268,8 @@ config IP6_NF_NAT
- tristate "ip6tables NAT support"
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
-+ depends on IP6_NF_IPTABLES_LEGACY
- select NF_NAT
-- select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index 344c287aa3f41..4937f32bcd6e7 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -760,6 +760,16 @@ config NETFILTER_XTABLES_COMPAT
-
- If unsure, say N.
-
-+config NETFILTER_XTABLES_LEGACY
-+ bool "Netfilter legacy tables support"
-+ depends on !PREEMPT_RT
-+ help
-+ Say Y here if you still require support for legacy tables. This is
-+ required by the legacy tools (iptables-legacy) and is not needed if
-+ you use iptables over nftables (iptables-nft).
-+ Legacy support is not limited to IP, it also includes EBTABLES and
-+ ARPTABLES.
-+
- comment "Xtables combined modules"
-
- config NETFILTER_XT_MARK
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 650cb725ba271..be786cd704508 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1339,12 +1339,13 @@ void xt_compat_unlock(u_int8_t af)
- EXPORT_SYMBOL_GPL(xt_compat_unlock);
- #endif
-
--DEFINE_PER_CPU(seqcount_t, xt_recseq);
--EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
--
- struct static_key xt_tee_enabled __read_mostly;
- EXPORT_SYMBOL_GPL(xt_tee_enabled);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
-+DEFINE_PER_CPU(seqcount_t, xt_recseq);
-+EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
-+
- static int xt_jumpstack_alloc(struct xt_table_info *i)
- {
- unsigned int size;
-@@ -1536,6 +1537,7 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+#endif
-
- #ifdef CONFIG_PROC_FS
- static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
-@@ -1919,6 +1921,7 @@ void xt_proto_fini(struct net *net, u_int8_t af)
- }
- EXPORT_SYMBOL_GPL(xt_proto_fini);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
- /**
- * xt_percpu_counter_alloc - allocate x_tables rule counter
- *
-@@ -1973,6 +1976,7 @@ void xt_percpu_counter_free(struct xt_counters *counters)
- free_percpu((void __percpu *)pcnt);
- }
- EXPORT_SYMBOL_GPL(xt_percpu_counter_free);
-+#endif
-
- static int __net_init xt_net_init(struct net *net)
- {
-@@ -2005,8 +2009,10 @@ static int __init xt_init(void)
- unsigned int i;
- int rv;
-
-- for_each_possible_cpu(i) {
-- seqcount_init(&per_cpu(xt_recseq, i));
-+ if (IS_ENABLED(CONFIG_NETFILTER_XTABLES_LEGACY)) {
-+ for_each_possible_cpu(i) {
-+ seqcount_init(&per_cpu(xt_recseq, i));
-+ }
- }
-
- xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL);
---
-2.53.0
-
+++ /dev/null
-From b2399c7be634fdaa657a6398be0b0c86b1bdde0c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Sep 2024 02:58:54 -0700
-Subject: netfilter: Make legacy configs user selectable
-
-From: Breno Leitao <leitao@debian.org>
-
-[ Upstream commit 6c959fd5e17387201dba3619b2e6af213939a0a7 ]
-
-This option makes legacy Netfilter Kconfig user selectable, giving users
-the option to configure iptables without enabling any other config.
-
-Make the following KConfig entries user selectable:
- * BRIDGE_NF_EBTABLES_LEGACY
- * IP_NF_ARPTABLES
- * IP_NF_IPTABLES_LEGACY
- * IP6_NF_IPTABLES_LEGACY
-
-Signed-off-by: Breno Leitao <leitao@debian.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 8 +++++++-
- net/ipv4/netfilter/Kconfig | 16 ++++++++++++++--
- net/ipv6/netfilter/Kconfig | 9 ++++++++-
- 3 files changed, 29 insertions(+), 4 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 104c0125e32e8..f16bbbbb94817 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -41,7 +41,13 @@ config NF_CONNTRACK_BRIDGE
-
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
-- tristate
-+ tristate "Legacy EBTABLES support"
-+ depends on BRIDGE && NETFILTER_XTABLES
-+ default n
-+ help
-+ Legacy ebtables packet/frame classifier.
-+ This is not needed if you are using ebtables over nftables
-+ (iptables-nft).
-
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 6146ef5fc728f..1d0a89a67acf5 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -12,7 +12,13 @@ config NF_DEFRAG_IPV4
-
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP tables support"
-+ default n
-+ select NETFILTER_XTABLES
-+ help
-+ iptables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
-@@ -332,7 +338,13 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate
-+ tristate "Legacy ARPTABLES support"
-+ depends on NETFILTER_XTABLES
-+ default n
-+ help
-+ arptables is a legacy packet classifier.
-+ This is not needed if you are using arptables over nftables
-+ (iptables-nft).
-
- config NFT_COMPAT_ARP
- tristate
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index f3c8e2d918e13..e087a8e97ba78 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -8,7 +8,14 @@ menu "IPv6: Netfilter Configuration"
-
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP6 tables support"
-+ depends on INET && IPV6
-+ select NETFILTER_XTABLES
-+ default n
-+ help
-+ ip6tables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
---
-2.53.0
-
+++ /dev/null
-From 52fa5ccd0b1247175261438baa604793b079444f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:15 +0200
-Subject: netfilter: x_tables: add and use xt_unregister_table_pre_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 527d6931473b75d90e38942aae6537d1a527f1fd ]
-
-Remove the copypasted variants of _pre_exit and add one single
-function in the xtables core. ebtables is not compatible with
-x_tables and therefore unchanged.
-
-This is a preparation patch to reduce noise in the followup
-bug fixes.
-
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 1 +
- include/linux/netfilter_arp/arp_tables.h | 1 -
- include/linux/netfilter_ipv4/ip_tables.h | 1 -
- include/linux/netfilter_ipv6/ip6_tables.h | 1 -
- net/ipv4/netfilter/arp_tables.c | 9 -------
- net/ipv4/netfilter/arptable_filter.c | 2 +-
- net/ipv4/netfilter/ip_tables.c | 9 -------
- net/ipv4/netfilter/iptable_filter.c | 2 +-
- net/ipv4/netfilter/iptable_mangle.c | 2 +-
- net/ipv4/netfilter/iptable_nat.c | 1 +
- net/ipv4/netfilter/iptable_raw.c | 2 +-
- net/ipv4/netfilter/iptable_security.c | 2 +-
- net/ipv6/netfilter/ip6_tables.c | 9 -------
- net/ipv6/netfilter/ip6table_filter.c | 2 +-
- net/ipv6/netfilter/ip6table_mangle.c | 2 +-
- net/ipv6/netfilter/ip6table_nat.c | 1 +
- net/ipv6/netfilter/ip6table_raw.c | 2 +-
- net/ipv6/netfilter/ip6table_security.c | 2 +-
- net/netfilter/x_tables.c | 29 +++++++++++++++++++++++
- 19 files changed, 41 insertions(+), 39 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index 5897f3dbaf7c3..df2022fe440b0 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -310,6 +310,7 @@ struct xt_table *xt_register_table(struct net *net,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
- void *xt_unregister_table(struct xt_table *table);
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
-index a40aaf645fa47..05631a25e6229 100644
---- a/include/linux/netfilter_arp/arp_tables.h
-+++ b/include/linux/netfilter_arp/arp_tables.h
-@@ -53,7 +53,6 @@ int arpt_register_table(struct net *net, const struct xt_table *table,
- const struct arpt_replace *repl,
- const struct nf_hook_ops *ops);
- void arpt_unregister_table(struct net *net, const char *name);
--void arpt_unregister_table_pre_exit(struct net *net, const char *name);
- extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-
-diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
-index 132b0e4a6d4df..13593391d6058 100644
---- a/include/linux/netfilter_ipv4/ip_tables.h
-+++ b/include/linux/netfilter_ipv4/ip_tables.h
-@@ -26,7 +26,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- const struct ipt_replace *repl,
- const struct nf_hook_ops *ops);
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name);
- void ipt_unregister_table_exit(struct net *net, const char *name);
-
- /* Standard entry. */
-diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
-index 8b8885a73c764..c6d5b927830dd 100644
---- a/include/linux/netfilter_ipv6/ip6_tables.h
-+++ b/include/linux/netfilter_ipv6/ip6_tables.h
-@@ -27,7 +27,6 @@ extern void *ip6t_alloc_initial_table(const struct xt_table *);
- int ip6t_register_table(struct net *net, const struct xt_table *table,
- const struct ip6t_replace *repl,
- const struct nf_hook_ops *ops);
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name);
- void ip6t_unregister_table_exit(struct net *net, const char *name);
- extern unsigned int ip6t_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 564054123772a..9b905c6562313 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1581,15 +1581,6 @@ int arpt_register_table(struct net *net,
- return ret;
- }
-
--void arpt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--EXPORT_SYMBOL(arpt_unregister_table_pre_exit);
--
- void arpt_unregister_table(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 359d00d74095b..382345567a600 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -43,7 +43,7 @@ static int arptable_filter_table_init(struct net *net)
-
- static void __net_exit arptable_filter_net_pre_exit(struct net *net)
- {
-- arpt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_ARP, "filter");
- }
-
- static void __net_exit arptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index a6208efcfccfc..7c6b21f8174a3 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1791,14 +1791,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-@@ -1953,7 +1945,6 @@ static void __exit ip_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ipt_register_table);
--EXPORT_SYMBOL(ipt_unregister_table_pre_exit);
- EXPORT_SYMBOL(ipt_unregister_table_exit);
- EXPORT_SYMBOL(ipt_do_table);
- module_init(ip_tables_init);
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index c03c1a4ea7cab..fb85745793ba5 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -61,7 +61,7 @@ static int __net_init iptable_filter_net_init(struct net *net)
-
- static void __net_exit iptable_filter_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "filter");
- }
-
- static void __net_exit iptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index 6a51e61b35562..6259bcf178bba 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -95,7 +95,7 @@ static int iptable_mangle_table_init(struct net *net)
-
- static void __net_exit iptable_mangle_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "mangle");
- }
-
- static void __net_exit iptable_mangle_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index 12ca666d6e2c1..ca6964b957ead 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -129,6 +129,7 @@ static int iptable_nat_table_init(struct net *net)
- static void __net_exit iptable_nat_net_pre_exit(struct net *net)
- {
- ipt_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
- }
-
- static void __net_exit iptable_nat_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index 33330e13ea18d..c7b91b2042dc6 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -53,7 +53,7 @@ static int iptable_raw_table_init(struct net *net)
-
- static void __net_exit iptable_raw_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "raw");
- }
-
- static void __net_exit iptable_raw_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 2b89adc1e5751..81175c20ccbe8 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -50,7 +50,7 @@ static int iptable_security_table_init(struct net *net)
-
- static void __net_exit iptable_security_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "security");
- }
-
- static void __net_exit iptable_security_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index b844e519da1b4..1324413fb29c3 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1797,14 +1797,6 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-@@ -1960,7 +1952,6 @@ static void __exit ip6_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ip6t_register_table);
--EXPORT_SYMBOL(ip6t_unregister_table_pre_exit);
- EXPORT_SYMBOL(ip6t_unregister_table_exit);
- EXPORT_SYMBOL(ip6t_do_table);
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index 16a38d56b2e54..982900920e730 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -60,7 +60,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
-
- static void __net_exit ip6table_filter_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "filter");
- }
-
- static void __net_exit ip6table_filter_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index 39f0716667131..475361aa81310 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -88,7 +88,7 @@ static int ip6table_mangle_table_init(struct net *net)
-
- static void __net_exit ip6table_mangle_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "mangle");
- }
-
- static void __net_exit ip6table_mangle_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index 52d597b16b658..bef2d309369bc 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -131,6 +131,7 @@ static int ip6table_nat_table_init(struct net *net)
- static void __net_exit ip6table_nat_net_pre_exit(struct net *net)
- {
- ip6t_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
- }
-
- static void __net_exit ip6table_nat_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index 01def8aa7a2e8..a99879f173b4a 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -52,7 +52,7 @@ static int ip6table_raw_table_init(struct net *net)
-
- static void __net_exit ip6table_raw_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "raw");
- }
-
- static void __net_exit ip6table_raw_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index 66018b169b010..c44834d93fc79 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -49,7 +49,7 @@ static int ip6table_security_table_init(struct net *net)
-
- static void __net_exit ip6table_security_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "security");
- }
-
- static void __net_exit ip6table_security_net_exit(struct net *net)
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index be786cd704508..6a4bca66a0ae6 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1537,6 +1537,35 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+
-+/**
-+ * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
-+ * @net: network namespace
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Unregisters the specified netfilter table from the given network namespace
-+ * and also unregisters the hooks from netfilter core: no new packets will be
-+ * processed.
-+ */
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *t;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(t, &xt_net->tables[af], list) {
-+ if (strcmp(t->name, name) == 0) {
-+ mutex_unlock(&xt[af].mutex);
-+
-+ if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
-+ }
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+}
-+EXPORT_SYMBOL(xt_unregister_table_pre_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
---
-2.53.0
-
+++ /dev/null
-From 850ceb93c8b61020afb1780cf3ae25b0b52193d4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:17 +0200
-Subject: netfilter: x_tables: add and use xtables_unregister_table_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b4597d5fd7d2f8cebfffd40dffb5e003cc78964c ]
-
-Previous change added xtables_unregister_table_pre_exit to detach the
-table from the packetpath and to unlink it from the active table list.
-In case of rmmod, userspace that is doing set/getsockopt for this table
-will not be able to re-instantiate the table:
- 1. The larval table has been removed already
- 2. existing instantiated table is no longer on the xt pernet table list.
-
-This adds the second stage helper:
-
-unlink the table from the dying list, free the hook ops (if any) and do
-the audit notification. It replaces xt_unregister_table().
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Reported-by: Tristan Madani <tristan@talencesecurity.com>
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Closes: https://lore.kernel.org/netfilter-devel/20260429175613.1459342-1-tristmd@gmail.com/
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 2 +-
- net/ipv4/netfilter/arp_tables.c | 9 ++--
- net/ipv4/netfilter/ip_tables.c | 9 ++--
- net/ipv4/netfilter/iptable_nat.c | 5 +-
- net/ipv6/netfilter/ip6_tables.c | 9 ++--
- net/ipv6/netfilter/ip6table_nat.c | 5 +-
- net/netfilter/x_tables.c | 81 +++++++++++++++++++++++-------
- 7 files changed, 83 insertions(+), 37 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index df2022fe440b0..706f08839050a 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -309,8 +309,8 @@ struct xt_table *xt_register_table(struct net *net,
- const struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
--void *xt_unregister_table(struct xt_table *table);
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 9b905c6562313..f9dd18244f251 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1501,13 +1501,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
-
- static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
-+ void *loc_cpu_entry;
- struct arpt_entry *iter;
-
-- private = xt_unregister_table(table);
--
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
- xt_entry_foreach(iter, loc_cpu_entry, private->size)
-@@ -1515,6 +1513,7 @@ static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int arpt_register_table(struct net *net,
-@@ -1583,7 +1582,7 @@ int arpt_register_table(struct net *net,
-
- void arpt_unregister_table(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_ARP, name);
-
- if (table)
- __arpt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index 7c6b21f8174a3..0ff9b7c9dc59c 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1706,12 +1706,10 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ipt_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1720,6 +1718,7 @@ static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ipt_register_table(struct net *net, const struct xt_table *table,
-@@ -1793,7 +1792,7 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
-
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV4, name);
-
- if (table)
- __ipt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index ca6964b957ead..87d934b12bcb6 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -119,8 +119,11 @@ static int iptable_nat_table_init(struct net *net)
- }
-
- ret = ipt_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
-+ synchronize_rcu();
- ipt_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 1324413fb29c3..baa1c094faf48 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1715,12 +1715,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ip6t_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1729,6 +1727,7 @@ static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ip6t_register_table(struct net *net, const struct xt_table *table,
-@@ -1799,7 +1798,7 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
-
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV6, name);
-
- if (table)
- __ip6t_unregister_table(net, table);
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index bef2d309369bc..cf260d8ebdb70 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -121,8 +121,11 @@ static int ip6table_nat_table_init(struct net *net)
- }
-
- ret = ip6t_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
-+ synchronize_rcu();
- ip6t_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 6a4bca66a0ae6..cba2b8d2f9069 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -55,6 +55,9 @@ static struct list_head xt_templates[NFPROTO_NUMPROTO];
-
- struct xt_pernet {
- struct list_head tables[NFPROTO_NUMPROTO];
-+
-+ /* stash area used during netns exit */
-+ struct list_head dead_tables[NFPROTO_NUMPROTO];
- };
-
- struct compat_delta {
-@@ -1521,23 +1524,6 @@ struct xt_table *xt_register_table(struct net *net,
- }
- EXPORT_SYMBOL_GPL(xt_register_table);
-
--void *xt_unregister_table(struct xt_table *table)
--{
-- struct xt_table_info *private;
--
-- mutex_lock(&xt[table->af].mutex);
-- private = table->private;
-- list_del(&table->list);
-- mutex_unlock(&xt[table->af].mutex);
-- audit_log_nfcfg(table->name, table->af, private->number,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-- kfree(table->ops);
-- kfree(table);
--
-- return private;
--}
--EXPORT_SYMBOL_GPL(xt_unregister_table);
--
- /**
- * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
- * @net: network namespace
-@@ -1547,6 +1533,14 @@ EXPORT_SYMBOL_GPL(xt_unregister_table);
- * Unregisters the specified netfilter table from the given network namespace
- * and also unregisters the hooks from netfilter core: no new packets will be
- * processed.
-+ *
-+ * This must be called prior to xt_unregister_table_exit() from the pernet
-+ * .pre_exit callback. After this call, the table is no longer visible to
-+ * the get/setsockopt path. In case of rmmod, module exit path must have
-+ * called xt_unregister_template() prior to unregistering pernet ops to
-+ * prevent re-instantiation of the table.
-+ *
-+ * See also: xt_unregister_table_exit()
- */
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- {
-@@ -1556,6 +1550,7 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_lock(&xt[af].mutex);
- list_for_each_entry(t, &xt_net->tables[af], list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &xt_net->dead_tables[af]);
- mutex_unlock(&xt[af].mutex);
-
- if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-@@ -1566,6 +1561,50 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_unlock(&xt[af].mutex);
- }
- EXPORT_SYMBOL(xt_unregister_table_pre_exit);
-+
-+/**
-+ * xt_unregister_table_exit - remove a table during namespace teardown
-+ * @net: the network namespace from which to unregister the table
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Completes the unregister process for a table. This must be called from
-+ * the pernet ops .exit callback. This is the second stage after
-+ * xt_unregister_table_pre_exit().
-+ *
-+ * pair with xt_unregister_table_pre_exit() during namespace shutdown.
-+ *
-+ * Return: the unregistered table or NULL if the table was never
-+ * instantiated. The caller needs to kfree() the table after it
-+ * has removed the family specific matches/targets.
-+ */
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *table;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(table, &xt_net->dead_tables[af], list) {
-+ struct nf_hook_ops *ops = NULL;
-+
-+ if (strcmp(table->name, name) != 0)
-+ continue;
-+
-+ list_del(&table->list);
-+
-+ audit_log_nfcfg(table->name, table->af, table->private->number,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ swap(table->ops, ops);
-+ mutex_unlock(&xt[af].mutex);
-+
-+ kfree(ops);
-+ return table;
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL_GPL(xt_unregister_table_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
-@@ -2012,8 +2051,10 @@ static int __net_init xt_net_init(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- INIT_LIST_HEAD(&xt_net->tables[i]);
-+ INIT_LIST_HEAD(&xt_net->dead_tables[i]);
-+ }
- return 0;
- }
-
-@@ -2022,8 +2063,10 @@ static void __net_exit xt_net_exit(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- WARN_ON_ONCE(!list_empty(&xt_net->tables[i]));
-+ WARN_ON_ONCE(!list_empty(&xt_net->dead_tables[i]));
-+ }
- }
-
- static struct pernet_operations xt_net_ops = {
---
-2.53.0
-
+++ /dev/null
-From 4f5d0768119e450f16a20a8836c38e4fd6369d98 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:20 +0200
-Subject: netfilter: x_tables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 16bc4b6686b2c112c10e67d6b493adc3607256d3 ]
-
-Similar to the previous ebtables patch:
-template add exposes the table to userspace, we must do this last to
-rnsure the pernet ops are set up (contain the destructors).
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/arptable_filter.c | 23 ++++++++++++-----------
- net/ipv4/netfilter/iptable_filter.c | 23 ++++++++++++-----------
- net/ipv4/netfilter/iptable_mangle.c | 25 +++++++++++++------------
- net/ipv4/netfilter/iptable_raw.c | 22 +++++++++++-----------
- net/ipv4/netfilter/iptable_security.c | 23 ++++++++++++-----------
- net/ipv6/netfilter/ip6table_filter.c | 22 +++++++++++-----------
- net/ipv6/netfilter/ip6table_mangle.c | 23 ++++++++++++-----------
- net/ipv6/netfilter/ip6table_raw.c | 20 ++++++++++----------
- net/ipv6/netfilter/ip6table_security.c | 23 ++++++++++++-----------
- 9 files changed, 105 insertions(+), 99 deletions(-)
-
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 382345567a600..370b635e3523b 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -58,25 +58,26 @@ static struct pernet_operations arptable_filter_net_ops = {
-
- static int __init arptable_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- arptable_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arpt_do_table);
-- if (IS_ERR(arpfilter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(arpfilter_ops))
- return PTR_ERR(arpfilter_ops);
-- }
-
- ret = register_pernet_subsys(&arptable_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter,
-+ arptable_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(arpfilter_ops);
-- return ret;
-+ unregister_pernet_subsys(&arptable_filter_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(arpfilter_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index fb85745793ba5..409e96c72164b 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -77,26 +77,27 @@ static struct pernet_operations iptable_filter_net_ops = {
-
- static int __init iptable_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- iptable_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- filter_ops = xt_hook_ops_alloc(&packet_filter, ipt_do_table);
-- if (IS_ERR(filter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(filter_ops))
- return PTR_ERR(filter_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter,
-+ iptable_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(filter_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_filter_net_ops);
-+ goto err_free;
- }
-
- return 0;
-+err_free:
-+ kfree(filter_ops);
-+ return ret;
- }
-
- static void __exit iptable_filter_fini(void)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index 6259bcf178bba..b8618bdf5fdc4 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -110,25 +110,26 @@ static struct pernet_operations iptable_mangle_net_ops = {
-
- static int __init iptable_mangle_init(void)
- {
-- int ret = xt_register_template(&packet_mangler,
-- iptable_mangle_table_init);
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- mangle_ops = xt_hook_ops_alloc(&packet_mangler, iptable_mangle_hook);
-- if (IS_ERR(mangle_ops)) {
-- xt_unregister_template(&packet_mangler);
-- ret = PTR_ERR(mangle_ops);
-- return ret;
-- }
-+ if (IS_ERR(mangle_ops))
-+ return PTR_ERR(mangle_ops);
-
- ret = register_pernet_subsys(&iptable_mangle_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_mangler,
-+ iptable_mangle_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_mangler);
-- kfree(mangle_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_mangle_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(mangle_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index c7b91b2042dc6..94ad7fad3a1f3 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -77,24 +77,24 @@ static int __init iptable_raw_init(void)
- pr_info("Enabling raw table before defrag\n");
- }
-
-- ret = xt_register_template(table,
-- iptable_raw_table_init);
-- if (ret < 0)
-- return ret;
--
- rawtable_ops = xt_hook_ops_alloc(table, ipt_do_table);
-- if (IS_ERR(rawtable_ops)) {
-- xt_unregister_template(table);
-+ if (IS_ERR(rawtable_ops))
- return PTR_ERR(rawtable_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_raw_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(table,
-+ iptable_raw_table_init);
- if (ret < 0) {
-- xt_unregister_template(table);
-- kfree(rawtable_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_raw_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(rawtable_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 81175c20ccbe8..491894511c544 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -65,25 +65,26 @@ static struct pernet_operations iptable_security_net_ops = {
-
- static int __init iptable_security_init(void)
- {
-- int ret = xt_register_template(&security_table,
-- iptable_security_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- sectbl_ops = xt_hook_ops_alloc(&security_table, ipt_do_table);
-- if (IS_ERR(sectbl_ops)) {
-- xt_unregister_template(&security_table);
-+ if (IS_ERR(sectbl_ops))
- return PTR_ERR(sectbl_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_security_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&security_table,
-+ iptable_security_table_init);
- if (ret < 0) {
-- xt_unregister_template(&security_table);
-- kfree(sectbl_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_security_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(sectbl_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index 982900920e730..f444071346859 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -76,25 +76,25 @@ static struct pernet_operations ip6table_filter_net_ops = {
-
- static int __init ip6table_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- ip6table_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- filter_ops = xt_hook_ops_alloc(&packet_filter, ip6t_do_table);
-- if (IS_ERR(filter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(filter_ops))
- return PTR_ERR(filter_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter, ip6table_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(filter_ops);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_filter_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(filter_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index 475361aa81310..dbc64e4428403 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -103,25 +103,26 @@ static struct pernet_operations ip6table_mangle_net_ops = {
-
- static int __init ip6table_mangle_init(void)
- {
-- int ret = xt_register_template(&packet_mangler,
-- ip6table_mangle_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- mangle_ops = xt_hook_ops_alloc(&packet_mangler, ip6table_mangle_hook);
-- if (IS_ERR(mangle_ops)) {
-- xt_unregister_template(&packet_mangler);
-+ if (IS_ERR(mangle_ops))
- return PTR_ERR(mangle_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_mangle_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_mangler,
-+ ip6table_mangle_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_mangler);
-- kfree(mangle_ops);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_mangle_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(mangle_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index a99879f173b4a..1eadf553c746e 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -75,24 +75,24 @@ static int __init ip6table_raw_init(void)
- pr_info("Enabling raw table before defrag\n");
- }
-
-- ret = xt_register_template(table, ip6table_raw_table_init);
-- if (ret < 0)
-- return ret;
--
- /* Register hooks */
- rawtable_ops = xt_hook_ops_alloc(table, ip6t_do_table);
-- if (IS_ERR(rawtable_ops)) {
-- xt_unregister_template(table);
-+ if (IS_ERR(rawtable_ops))
- return PTR_ERR(rawtable_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_raw_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(table, ip6table_raw_table_init);
- if (ret < 0) {
-- kfree(rawtable_ops);
-- xt_unregister_template(table);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_raw_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(rawtable_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index c44834d93fc79..4bd5d97b8ab65 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -64,25 +64,26 @@ static struct pernet_operations ip6table_security_net_ops = {
-
- static int __init ip6table_security_init(void)
- {
-- int ret = xt_register_template(&security_table,
-- ip6table_security_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- sectbl_ops = xt_hook_ops_alloc(&security_table, ip6t_do_table);
-- if (IS_ERR(sectbl_ops)) {
-- xt_unregister_template(&security_table);
-+ if (IS_ERR(sectbl_ops))
- return PTR_ERR(sectbl_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_security_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&security_table,
-+ ip6table_security_table_init);
- if (ret < 0) {
-- kfree(sectbl_ops);
-- xt_unregister_template(&security_table);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_security_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(sectbl_ops);
- return ret;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 1618cdd6bf14d5034f5987795aab22ed27c42637 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 24 Jan 2024 10:21:11 +0100
-Subject: netfilter: xtables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit a9525c7f6219cee9284c0031c5930e8d41384677 ]
-
-Add hidden IP(6)_NF_IPTABLES_LEGACY symbol.
-
-When any of the "old" builtin tables are enabled the "old" iptables
-interface will be supported.
-
-To disable the old set/getsockopt interface the existing options
-for the builtin tables need to be turned off:
-
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_FILTER is not set
-CONFIG_IP_NF_NAT is not set
-CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_SECURITY is not set
-
-Same for CONFIG_IP6_NF_ variants.
-
-This allows to build a kernel that only supports ip(6)tables-nft
-(iptables-over-nftables api).
-
-In the future the _LEGACY symbol will become visible and the select
-statements will be turned into 'depends on', but for now be on safe side
-so "make oldconfig" won't break things.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 15 ++++++++++++---
- net/ipv4/netfilter/Makefile | 2 +-
- net/ipv6/netfilter/Kconfig | 20 ++++++++++++++------
- net/ipv6/netfilter/Makefile | 2 +-
- net/netfilter/Kconfig | 12 ++++++------
- 5 files changed, 34 insertions(+), 17 deletions(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 483778f379d44..5ee86c7ae4dcb 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -10,6 +10,10 @@ config NF_DEFRAG_IPV4
- tristate
- default n
-
-+# old sockopt interface and eval loop
-+config IP_NF_IPTABLES_LEGACY
-+ tristate
-+
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
- help
-@@ -152,7 +156,7 @@ config IP_NF_MATCH_ECN
- config IP_NF_MATCH_RPFILTER
- tristate '"rpfilter" reverse path filter match support'
- depends on NETFILTER_ADVANCED
-- depends on IP_NF_MANGLE || IP_NF_RAW
-+ depends on IP_NF_MANGLE || IP_NF_RAW || NFT_COMPAT
- help
- This option allows you to match packets whose replies would
- go out via the interface the packet came in.
-@@ -173,6 +177,7 @@ config IP_NF_MATCH_TTL
- config IP_NF_FILTER
- tristate "Packet filtering"
- default m if NETFILTER_ADVANCED=n
-+ select IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -182,7 +187,7 @@ config IP_NF_FILTER
-
- config IP_NF_TARGET_REJECT
- tristate "REJECT target support"
-- depends on IP_NF_FILTER
-+ depends on IP_NF_FILTER || NFT_COMPAT
- select NF_REJECT_IPV4
- default m if NETFILTER_ADVANCED=n
- help
-@@ -212,6 +217,7 @@ config IP_NF_NAT
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -252,6 +258,7 @@ endif # IP_NF_NAT
- config IP_NF_MANGLE
- tristate "Packet mangling"
- default m if NETFILTER_ADVANCED=n
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -275,7 +282,7 @@ config IP_NF_TARGET_CLUSTERIP
-
- config IP_NF_TARGET_ECN
- tristate "ECN target support"
-- depends on IP_NF_MANGLE
-+ depends on IP_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `ECN' target, which can be used in the iptables mangle
-@@ -300,6 +307,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -313,6 +321,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
-index 93bad11842517..2e606a13ee5ff 100644
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -25,7 +25,7 @@ obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o
- obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
-
- # generic IP tables
--obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
-+obj-$(CONFIG_IP_NF_IPTABLES_LEGACY) += ip_tables.o
-
- # the three instances of ip_tables
- obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index 0ba62f4868f97..f3c8e2d918e13 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -6,6 +6,10 @@
- menu "IPv6: Netfilter Configuration"
- depends on INET && IPV6 && NETFILTER
-
-+# old sockopt interface and eval loop
-+config IP6_NF_IPTABLES_LEGACY
-+ tristate
-+
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
- help
-@@ -147,7 +151,7 @@ config IP6_NF_MATCH_MH
- config IP6_NF_MATCH_RPFILTER
- tristate '"rpfilter" reverse path filter match support'
- depends on NETFILTER_ADVANCED
-- depends on IP6_NF_MANGLE || IP6_NF_RAW
-+ depends on IP6_NF_MANGLE || IP6_NF_RAW || NFT_COMPAT
- help
- This option allows you to match packets whose replies would
- go out via the interface the packet came in.
-@@ -186,6 +190,8 @@ config IP6_NF_TARGET_HL
- config IP6_NF_FILTER
- tristate "Packet filtering"
- default m if NETFILTER_ADVANCED=n
-+ select IP6_NF_IPTABLES_LEGACY
-+ tristate
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -195,7 +201,7 @@ config IP6_NF_FILTER
-
- config IP6_NF_TARGET_REJECT
- tristate "REJECT target support"
-- depends on IP6_NF_FILTER
-+ depends on IP6_NF_FILTER || NFT_COMPAT
- select NF_REJECT_IPV6
- default m if NETFILTER_ADVANCED=n
- help
-@@ -221,6 +227,7 @@ config IP6_NF_TARGET_SYNPROXY
- config IP6_NF_MANGLE
- tristate "Packet mangling"
- default m if NETFILTER_ADVANCED=n
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -230,6 +237,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -243,6 +251,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -254,6 +263,7 @@ config IP6_NF_NAT
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
- select NF_NAT
-+ select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-@@ -262,25 +272,23 @@ config IP6_NF_NAT
-
- To compile it as a module, choose M here. If unsure, say N.
-
--if IP6_NF_NAT
--
- config IP6_NF_TARGET_MASQUERADE
- tristate "MASQUERADE target support"
- select NETFILTER_XT_TARGET_MASQUERADE
-+ depends on IP6_NF_NAT
- help
- This is a backwards-compat option for the user's convenience
- (e.g. when running oldconfig). It selects NETFILTER_XT_TARGET_MASQUERADE.
-
- config IP6_NF_TARGET_NPT
- tristate "NPT (Network Prefix translation) target support"
-+ depends on IP6_NF_NAT || NFT_COMPAT
- help
- This option adds the `SNPT' and `DNPT' target, which perform
- stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
-
- To compile it as a module, choose M here. If unsure, say N.
-
--endif # IP6_NF_NAT
--
- endif # IP6_NF_IPTABLES
- endmenu
-
-diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
-index b8d6dc9aeeb6f..66ce6fa5b2f52 100644
---- a/net/ipv6/netfilter/Makefile
-+++ b/net/ipv6/netfilter/Makefile
-@@ -4,7 +4,7 @@
- #
-
- # Link order matters here.
--obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
-+obj-$(CONFIG_IP6_NF_IPTABLES_LEGACY) += ip6_tables.o
- obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
- obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
- obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index 4b8d04640ff32..344c287aa3f41 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -816,7 +816,7 @@ config NETFILTER_XT_TARGET_AUDIT
-
- config NETFILTER_XT_TARGET_CHECKSUM
- tristate "CHECKSUM target support"
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `CHECKSUM' target, which can be used in the iptables mangle
-@@ -867,7 +867,7 @@ config NETFILTER_XT_TARGET_CONNSECMARK
- config NETFILTER_XT_TARGET_CT
- tristate '"CT" target support'
- depends on NF_CONNTRACK
-- depends on IP_NF_RAW || IP6_NF_RAW
-+ depends on IP_NF_RAW || IP6_NF_RAW || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This options adds a `CT' target, which allows to specify initial
-@@ -878,7 +878,7 @@ config NETFILTER_XT_TARGET_CT
-
- config NETFILTER_XT_TARGET_DSCP
- tristate '"DSCP" and "TOS" target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `DSCP' target, which allows you to manipulate
-@@ -894,7 +894,7 @@ config NETFILTER_XT_TARGET_DSCP
-
- config NETFILTER_XT_TARGET_HL
- tristate '"HL" hoplimit target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds the "HL" (for IPv6) and "TTL" (for IPv4)
-@@ -1078,7 +1078,7 @@ config NETFILTER_XT_TARGET_TPROXY
- depends on NETFILTER_ADVANCED
- depends on IPV6 || IPV6=n
- depends on IP6_NF_IPTABLES || IP6_NF_IPTABLES=n
-- depends on IP_NF_MANGLE
-+ depends on IP_NF_MANGLE || NFT_COMPAT
- select NF_DEFRAG_IPV4
- select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES != n
- select NF_TPROXY_IPV4
-@@ -1145,7 +1145,7 @@ config NETFILTER_XT_TARGET_TCPMSS
-
- config NETFILTER_XT_TARGET_TCPOPTSTRIP
- tristate '"TCPOPTSTRIP" target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a "TCPOPTSTRIP" target, which allows you to strip
---
-2.53.0
-
+++ /dev/null
-From 3419026d7dccb97b25c126794f3efbf78b9f6d18 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 6 Feb 2024 14:55:53 +0100
-Subject: netfilter: xtables: fix up kconfig dependencies
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 749d4ef0868c5d8a98e07073791b2198178c93b4 ]
-
-Randy Dunlap reports arptables build failure:
-arp_tables.c:(.text+0x20): undefined reference to `xt_find_table'
-
-... because recent change removed a 'select' on the xtables core.
-Add a "depends" clause on arptables to resolve this.
-
-Kernel test robot reports another build breakage:
-iptable_nat.c:(.text+0x8): undefined reference to `ipt_unregister_table_exit'
-
-... because of a typo, the nat table selected ip6tables.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Randy Dunlap <rdunlap@infradead.org>
-Closes: https://lore.kernel.org/netfilter-devel/d0dfbaef-046a-4c42-9daa-53636664bf6d@infradead.org/
-Fixes: a9525c7f6219 ("netfilter: xtables: allow xtables-nft only builds")
-Fixes: 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only builds")
-Acked-by: Randy Dunlap <rdunlap@infradead.org>
-Tested-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 5ee86c7ae4dcb..0f60a740d117d 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -217,7 +217,7 @@ config IP_NF_NAT
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP6_NF_IPTABLES_LEGACY
-+ select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -343,6 +343,7 @@ config NFT_COMPAT_ARP
- config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
-+ depends on NETFILTER_XTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
---
-2.53.0
-
media-rkvdec-reduce-stack-usage-in-rkvdec_init_v4l2_.patch
alsa-asihpi-avoid-write-overflow-check-warning.patch
asoc-amd-yc-add-dmi-quirk-for-thin-a15-b7vf.patch
-asoc-sof-topology-reject-invalid-vendor-array-size-i.patch
can-mcp251x-add-error-handling-for-power-enable-in-o.patch
btrfs-tracepoints-get-correct-superblock-from-dentry.patch
alsa-hda-realtek-add-mute-led-quirk-for-hp-pavilion-.patch
ixgbevf-add-missing-negotiate_features-op-to-hyper-v.patch
e1000-check-return-value-of-e1000_read_eeprom.patch
xsk-tighten-umem-headroom-validation-to-account-for-.patch
-xfrm-wait-for-rcu-readers-during-policy-netns-exit.patch
xfrm_user-fix-info-leak-in-build_mapping.patch
selftests-net-bridge_vlan_mcast-wait-for-h1-before-q.patch
netfilter-nfnetlink_log-initialize-nfgenmsg-in-nlmsg.patch
perf-x86-intel-uncore-skip-discovery-table-for-offli.patch
revert-drm-fix-use-after-free-on-framebuffers-and-pr.patch
netfilter-conntrack-add-missing-netlink-policy-valid.patch
-alsa-usb-audio-improve-focusrite-sample-rate-filteri.patch
drm-i915-psr-do-not-use-pipe_src-as-borders-for-su-a.patch
nfc-llcp-add-missing-return-after-llcp_closed-checks.patch
can-raw-fix-ro-uniq-use-after-free-in-raw_rcv.patch
pinctrl-qcom-fix-wakeirq-map-by-removing-disconnecte.patch
arm-integrator-fix-early-initialization.patch
netfilter-x_tables-unregister-the-templates-first.patch
-netfilter-arptables-allow-xtables-nft-only-builds.patch
-netfilter-xtables-allow-xtables-nft-only-builds.patch
-netfilter-ebtables-allow-xtables-nft-only-builds.patch
-netfilter-xtables-fix-up-kconfig-dependencies.patch
-netfilter-arptables-select-netfilter_family_arp-when.patch
-netfilter-make-legacy-configs-user-selectable.patch
-netfilter-exclude-legacy-tables-on-preempt_rt.patch
-netfilter-x_tables-add-and-use-xt_unregister_table_p.patch
-netfilter-x_tables-add-and-use-xtables_unregister_ta.patch
-netfilter-ebtables-move-to-two-stage-removal-scheme.patch
-netfilter-ebtables-close-dangling-table-module-init-.patch
-netfilter-x_tables-close-dangling-table-module-init-.patch
-netfilter-bridge-eb_tables-close-module-init-race.patch
tcp-fix-imbalanced-icsk_accept_queue-count.patch
ice-fix-locking-in-ice_dcb_rebuild.patch
net-lan966x-avoid-unregistering-netdev-on-register-f.patch
+++ /dev/null
-From e62b6de563ec799c4b8321961dd7628c12bc529d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 2 Apr 2026 13:31:04 +0200
-Subject: xfrm: Wait for RCU readers during policy netns exit
-
-From: Steffen Klassert <steffen.klassert@secunet.com>
-
-[ Upstream commit 069daad4f2ae9c5c108131995529d5f02392c446 ]
-
-xfrm_policy_fini() frees the policy_bydst hash tables after flushing the
-policy work items and deleting all policies, but it does not wait for
-concurrent RCU readers to leave their read-side critical sections first.
-
-The policy_bydst tables are published via rcu_assign_pointer() and are
-looked up through rcu_dereference_check(), so netns teardown must also
-wait for an RCU grace period before freeing the table memory.
-
-Fix this by adding synchronize_rcu() before freeing the policy hash tables.
-
-Fixes: e1e551bc5630 ("xfrm: policy: prepare policy_bydst hash for rcu lookups")
-Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-Reviewed-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/xfrm/xfrm_policy.c | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
-index cd534803a0e42..7b9151f4eccfd 100644
---- a/net/xfrm/xfrm_policy.c
-+++ b/net/xfrm/xfrm_policy.c
-@@ -4129,6 +4129,8 @@ static void xfrm_policy_fini(struct net *net)
- #endif
- xfrm_policy_flush(net, XFRM_POLICY_TYPE_MAIN, false);
-
-+ synchronize_rcu();
-+
- WARN_ON(!list_empty(&net->xfrm.policy_all));
-
- for (dir = 0; dir < XFRM_POLICY_MAX; dir++) {
---
-2.53.0
-
+++ /dev/null
-From 0f0858de8fc62dd00bbf0a9a2edb6ed1b8f350fa Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 7 May 2026 11:19:22 +0200
-Subject: netfilter: bridge: eb_tables: close module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 27414ff1b287ea9a2a11675149ec28e05539f3cc ]
-
-sashiko reports for unrelated patch:
- Does the core ebtables initialization in ebtables.c suffer from a similar race?
- Once nf_register_sockopt() completes, the sockopts are exposed globally.
-
-sockopt has to be registered last, just like in ip/ip6/arptables.
-
-Fixes: 5b53951cfc85 ("netfilter: ebtables: use net_generic infra")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtables.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index 6240bb2b5b5b7..d480a91f081d3 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -2583,19 +2583,20 @@ static int __init ebtables_init(void)
- {
- int ret;
-
-- ret = xt_register_target(&ebt_standard_target);
-+ ret = register_pernet_subsys(&ebt_net_ops);
- if (ret < 0)
- return ret;
-- ret = nf_register_sockopt(&ebt_sockopts);
-+
-+ ret = xt_register_target(&ebt_standard_target);
- if (ret < 0) {
-- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
-- ret = register_pernet_subsys(&ebt_net_ops);
-+ ret = nf_register_sockopt(&ebt_sockopts);
- if (ret < 0) {
-- nf_unregister_sockopt(&ebt_sockopts);
- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 4fecde4351a36da95d8d5db39d90cc979ea18278 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:19 +0200
-Subject: netfilter: ebtables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 92c603fa07bc0d6a17345de3ad7954730b8de44b ]
-
-sashiko reported for a related patch:
- In modules like iptable_raw.c, [..], if register_pernet_subsys() fails,
- the rollback might call kfree(rawtable_ops) before [..]
- During this window, could a concurrent userspace process find the globally
- visible template, trigger table_init(), [..]
-
-The table init functions must always register the template last.
-
-Otherwise, set/getsockopt can instantiate a table in a namespace
-while the required pernet ops (contain the destructor) isn't available.
-This change is also required in x_tables, handled in followup change.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 12 +++++-------
- net/bridge/netfilter/ebtable_filter.c | 12 +++++-------
- net/bridge/netfilter/ebtable_nat.c | 10 ++++------
- 3 files changed, 14 insertions(+), 20 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index e6f9e343b41f1..f05c79f215ea0 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -112,18 +112,16 @@ static struct pernet_operations broute_net_ops = {
-
- static int __init ebtable_broute_init(void)
- {
-- int ret = ebt_register_template(&broute_table, broute_table_init);
-+ int ret = register_pernet_subsys(&broute_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&broute_net_ops);
-- if (ret) {
-- ebt_unregister_template(&broute_table);
-- return ret;
-- }
-+ ret = ebt_register_template(&broute_table, broute_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&broute_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_broute_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index 02b6501c15a5e..0fc03b07e62ae 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -93,18 +93,16 @@ static struct pernet_operations frame_filter_net_ops = {
-
- static int __init ebtable_filter_init(void)
- {
-- int ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ int ret = register_pernet_subsys(&frame_filter_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_filter_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_filter);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_filter_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_filter_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 9985a82555c41..8a10375d89099 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -93,16 +93,14 @@ static struct pernet_operations frame_nat_net_ops = {
-
- static int __init ebtable_nat_init(void)
- {
-- int ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ int ret = register_pernet_subsys(&frame_nat_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_nat_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_nat);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_nat_net_ops);
-
- return ret;
- }
---
-2.53.0
-
+++ /dev/null
-From 7957ef5e91f977c4d26639c0342b921e5d1ba667 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:18 +0200
-Subject: netfilter: ebtables: move to two-stage removal scheme
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b7f0544d86d439cb946515d2ef6a0a75e8626710 ]
-
-Like previous patches for x_tables, follow same pattern in ebtables.
-We can't reuse xt helpers: ebt_table struct layout is incompatible.
-
-table->ops assignment is now done while still holding the ebt mutex
-to make sure we never expose partially-filled table struct.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 2 +-
- net/bridge/netfilter/ebtable_filter.c | 2 +-
- net/bridge/netfilter/ebtable_nat.c | 2 +-
- net/bridge/netfilter/ebtables.c | 60 +++++++++++++++++----------
- 4 files changed, 40 insertions(+), 26 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index 7413602195525..e6f9e343b41f1 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -128,8 +128,8 @@ static int __init ebtable_broute_init(void)
-
- static void __exit ebtable_broute_fini(void)
- {
-- unregister_pernet_subsys(&broute_net_ops);
- ebt_unregister_template(&broute_table);
-+ unregister_pernet_subsys(&broute_net_ops);
- }
-
- module_init(ebtable_broute_init);
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index dacd81b12e626..02b6501c15a5e 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -109,8 +109,8 @@ static int __init ebtable_filter_init(void)
-
- static void __exit ebtable_filter_fini(void)
- {
-- unregister_pernet_subsys(&frame_filter_net_ops);
- ebt_unregister_template(&frame_filter);
-+ unregister_pernet_subsys(&frame_filter_net_ops);
- }
-
- module_init(ebtable_filter_init);
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 0f2a8c6118d42..9985a82555c41 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -109,8 +109,8 @@ static int __init ebtable_nat_init(void)
-
- static void __exit ebtable_nat_fini(void)
- {
-- unregister_pernet_subsys(&frame_nat_net_ops);
- ebt_unregister_template(&frame_nat);
-+ unregister_pernet_subsys(&frame_nat_net_ops);
- }
-
- module_init(ebtable_nat_init);
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index a461c59ad2859..6240bb2b5b5b7 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -42,6 +42,7 @@
-
- struct ebt_pernet {
- struct list_head tables;
-+ struct list_head dead_tables;
- };
-
- struct ebt_template {
-@@ -1162,11 +1163,6 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
-
- static void __ebt_unregister_table(struct net *net, struct ebt_table *table)
- {
-- mutex_lock(&ebt_mutex);
-- list_del(&table->list);
-- mutex_unlock(&ebt_mutex);
-- audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
- EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
- ebt_cleanup_entry, net, NULL);
- if (table->private->nentries)
-@@ -1267,13 +1263,15 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
- for (i = 0; i < num_ops; i++)
- ops[i].priv = table;
-
-- list_add(&table->list, &ebt_net->tables);
-- mutex_unlock(&ebt_mutex);
--
- table->ops = ops;
- ret = nf_register_net_hooks(net, ops, num_ops);
-- if (ret)
-+ if (ret) {
-+ synchronize_rcu();
- __ebt_unregister_table(net, table);
-+ } else {
-+ list_add(&table->list, &ebt_net->tables);
-+ }
-+ mutex_unlock(&ebt_mutex);
-
- audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
- AUDIT_XT_OP_REGISTER, GFP_KERNEL);
-@@ -1339,7 +1337,7 @@ void ebt_unregister_template(const struct ebt_table *t)
- }
- EXPORT_SYMBOL(ebt_unregister_template);
-
--static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-+void ebt_unregister_table_pre_exit(struct net *net, const char *name)
- {
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
- struct ebt_table *t;
-@@ -1348,30 +1346,36 @@ static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-
- list_for_each_entry(t, &ebt_net->tables, list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &ebt_net->dead_tables);
- mutex_unlock(&ebt_mutex);
-- return t;
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
- }
- }
-
- mutex_unlock(&ebt_mutex);
-- return NULL;
--}
--
--void ebt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct ebt_table *table = __ebt_find_table(net, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
- }
- EXPORT_SYMBOL(ebt_unregister_table_pre_exit);
-
- void ebt_unregister_table(struct net *net, const char *name)
- {
-- struct ebt_table *table = __ebt_find_table(net, name);
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+ struct ebt_table *t;
-
-- if (table)
-- __ebt_unregister_table(net, table);
-+ mutex_lock(&ebt_mutex);
-+
-+ list_for_each_entry(t, &ebt_net->dead_tables, list) {
-+ if (strcmp(t->name, name) == 0) {
-+ list_del(&t->list);
-+ audit_log_nfcfg(t->name, AF_BRIDGE, t->private->nentries,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ __ebt_unregister_table(net, t);
-+ mutex_unlock(&ebt_mutex);
-+ return;
-+ }
-+ }
-+
-+ mutex_unlock(&ebt_mutex);
- }
-
- /* userspace just supplied us with counters */
-@@ -2556,11 +2560,21 @@ static int __net_init ebt_pernet_init(struct net *net)
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-
- INIT_LIST_HEAD(&ebt_net->tables);
-+ INIT_LIST_HEAD(&ebt_net->dead_tables);
- return 0;
- }
-
-+static void __net_exit ebt_pernet_exit(struct net *net)
-+{
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+
-+ WARN_ON_ONCE(!list_empty(&ebt_net->tables));
-+ WARN_ON_ONCE(!list_empty(&ebt_net->dead_tables));
-+}
-+
- static struct pernet_operations ebt_net_ops = {
- .init = ebt_pernet_init,
-+ .exit = ebt_pernet_exit,
- .id = &ebt_pernet_id,
- .size = sizeof(struct ebt_pernet),
- };
---
-2.53.0
-
+++ /dev/null
-From a824fb74dd93049c912c324a788fbb27121fb501 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Jun 2025 17:44:23 +0200
-Subject: netfilter: Exclude LEGACY TABLES on PREEMPT_RT.
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-[ Upstream commit 9fce66583f06c212e95e4b76dd61d8432ffa56b6 ]
-
-The seqcount xt_recseq is used to synchronize the replacement of
-xt_table::private in xt_replace_table() against all readers such as
-ipt_do_table()
-
-To ensure that there is only one writer, the writing side disables
-bottom halves. The sequence counter can be acquired recursively. Only the
-first invocation modifies the sequence counter (signaling that a writer
-is in progress) while the following (recursive) writer does not modify
-the counter.
-The lack of a proper locking mechanism for the sequence counter can lead
-to live lock on PREEMPT_RT if the high prior reader preempts the
-writer. Additionally if the per-CPU lock on PREEMPT_RT is removed from
-local_bh_disable() then there is no synchronisation for the per-CPU
-sequence counter.
-
-The affected code is "just" the legacy netfilter code which is replaced
-by "netfilter tables". That code can be disabled without sacrificing
-functionality because everything is provided by the newer
-implementation. This will only requires the usage of the "-nft" tools
-instead of the "-legacy" ones.
-The long term plan is to remove the legacy code so lets accelerate the
-progress.
-
-Relax dependencies on iptables legacy, replace select with depends on,
-this should cause no harm to existing kernel configs and users can still
-toggle IP{6}_NF_IPTABLES_LEGACY in any case.
-Make EBTABLES_LEGACY, IPTABLES_LEGACY and ARPTABLES depend on
-NETFILTER_XTABLES_LEGACY. Hide xt_recseq and its users,
-xt_register_table() and xt_percpu_counter_alloc() behind
-NETFILTER_XTABLES_LEGACY. Let NETFILTER_XTABLES_LEGACY depend on
-!PREEMPT_RT.
-
-This will break selftest expecing the legacy options enabled and will be
-addressed in a following patch.
-
-Co-developed-by: Florian Westphal <fw@strlen.de>
-Co-developed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 10 +++++-----
- net/ipv4/netfilter/Kconfig | 24 ++++++++++++------------
- net/ipv6/netfilter/Kconfig | 19 +++++++++----------
- net/netfilter/Kconfig | 10 ++++++++++
- net/netfilter/x_tables.c | 16 +++++++++++-----
- 5 files changed, 47 insertions(+), 32 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index f16bbbbb94817..60f28e4fb5c0a 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -42,8 +42,8 @@ config NF_CONNTRACK_BRIDGE
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
- tristate "Legacy EBTABLES support"
-- depends on BRIDGE && NETFILTER_XTABLES
-- default n
-+ depends on BRIDGE && NETFILTER_XTABLES_LEGACY
-+ default n
- help
- Legacy ebtables packet/frame classifier.
- This is not needed if you are using ebtables over nftables
-@@ -65,7 +65,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -76,7 +76,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -86,7 +86,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index ef8009281da5c..2c438b140e88f 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -13,8 +13,8 @@ config NF_DEFRAG_IPV4
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
- tristate "Legacy IP tables support"
-- default n
-- select NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- iptables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -182,8 +182,8 @@ config IP_NF_MATCH_TTL
- # `filter', generic and specific targets
- config IP_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -220,10 +220,10 @@ config IP_NF_TARGET_SYNPROXY
- config IP_NF_NAT
- tristate "iptables NAT support"
- depends on NF_CONNTRACK
-+ depends on IP_NF_IPTABLES_LEGACY
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -263,8 +263,8 @@ endif # IP_NF_NAT
- # mangle + specific targets
- config IP_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -299,7 +299,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -313,7 +313,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -325,8 +325,8 @@ endif # IP_NF_IPTABLES
- # ARP tables
- config IP_NF_ARPTABLES
- tristate "Legacy ARPTABLES support"
-- depends on NETFILTER_XTABLES
-- default n
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default n
- help
- arptables is a legacy packet classifier.
- This is not needed if you are using arptables over nftables
-@@ -342,7 +342,7 @@ config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index e087a8e97ba78..276860f65baae 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -9,9 +9,8 @@ menu "IPv6: Netfilter Configuration"
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
- tristate "Legacy IP6 tables support"
-- depends on INET && IPV6
-- select NETFILTER_XTABLES
-- default n
-+ depends on INET && IPV6 && NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- ip6tables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -196,8 +195,8 @@ config IP6_NF_TARGET_HL
-
- config IP6_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- tristate
- help
- Packet filtering defines a table `filter', which has a series of
-@@ -233,8 +232,8 @@ config IP6_NF_TARGET_SYNPROXY
-
- config IP6_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -244,7 +243,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -258,7 +257,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -269,8 +268,8 @@ config IP6_NF_NAT
- tristate "ip6tables NAT support"
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
-+ depends on IP6_NF_IPTABLES_LEGACY
- select NF_NAT
-- select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index df2dc21304efb..0d1d997abe191 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -762,6 +762,16 @@ config NETFILTER_XTABLES_COMPAT
-
- If unsure, say N.
-
-+config NETFILTER_XTABLES_LEGACY
-+ bool "Netfilter legacy tables support"
-+ depends on !PREEMPT_RT
-+ help
-+ Say Y here if you still require support for legacy tables. This is
-+ required by the legacy tools (iptables-legacy) and is not needed if
-+ you use iptables over nftables (iptables-nft).
-+ Legacy support is not limited to IP, it also includes EBTABLES and
-+ ARPTABLES.
-+
- comment "Xtables combined modules"
-
- config NETFILTER_XT_MARK
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index efe7b7d71e7f7..1ca4fa9d249b8 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1340,12 +1340,13 @@ void xt_compat_unlock(u_int8_t af)
- EXPORT_SYMBOL_GPL(xt_compat_unlock);
- #endif
-
--DEFINE_PER_CPU(seqcount_t, xt_recseq);
--EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
--
- struct static_key xt_tee_enabled __read_mostly;
- EXPORT_SYMBOL_GPL(xt_tee_enabled);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
-+DEFINE_PER_CPU(seqcount_t, xt_recseq);
-+EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
-+
- static int xt_jumpstack_alloc(struct xt_table_info *i)
- {
- unsigned int size;
-@@ -1537,6 +1538,7 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+#endif
-
- #ifdef CONFIG_PROC_FS
- static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
-@@ -1920,6 +1922,7 @@ void xt_proto_fini(struct net *net, u_int8_t af)
- }
- EXPORT_SYMBOL_GPL(xt_proto_fini);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
- /**
- * xt_percpu_counter_alloc - allocate x_tables rule counter
- *
-@@ -1974,6 +1977,7 @@ void xt_percpu_counter_free(struct xt_counters *counters)
- free_percpu((void __percpu *)pcnt);
- }
- EXPORT_SYMBOL_GPL(xt_percpu_counter_free);
-+#endif
-
- static int __net_init xt_net_init(struct net *net)
- {
-@@ -2006,8 +2010,10 @@ static int __init xt_init(void)
- unsigned int i;
- int rv;
-
-- for_each_possible_cpu(i) {
-- seqcount_init(&per_cpu(xt_recseq, i));
-+ if (IS_ENABLED(CONFIG_NETFILTER_XTABLES_LEGACY)) {
-+ for_each_possible_cpu(i) {
-+ seqcount_init(&per_cpu(xt_recseq, i));
-+ }
- }
-
- xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL);
---
-2.53.0
-
+++ /dev/null
-From 8d07f48651e8c171d698b0ce36915aaa96085d27 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Sep 2024 02:58:54 -0700
-Subject: netfilter: Make legacy configs user selectable
-
-From: Breno Leitao <leitao@debian.org>
-
-[ Upstream commit 6c959fd5e17387201dba3619b2e6af213939a0a7 ]
-
-This option makes legacy Netfilter Kconfig user selectable, giving users
-the option to configure iptables without enabling any other config.
-
-Make the following KConfig entries user selectable:
- * BRIDGE_NF_EBTABLES_LEGACY
- * IP_NF_ARPTABLES
- * IP_NF_IPTABLES_LEGACY
- * IP6_NF_IPTABLES_LEGACY
-
-Signed-off-by: Breno Leitao <leitao@debian.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 8 +++++++-
- net/ipv4/netfilter/Kconfig | 16 ++++++++++++++--
- net/ipv6/netfilter/Kconfig | 9 ++++++++-
- 3 files changed, 29 insertions(+), 4 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 104c0125e32e8..f16bbbbb94817 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -41,7 +41,13 @@ config NF_CONNTRACK_BRIDGE
-
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
-- tristate
-+ tristate "Legacy EBTABLES support"
-+ depends on BRIDGE && NETFILTER_XTABLES
-+ default n
-+ help
-+ Legacy ebtables packet/frame classifier.
-+ This is not needed if you are using ebtables over nftables
-+ (iptables-nft).
-
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 1b991b889506a..ef8009281da5c 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -12,7 +12,13 @@ config NF_DEFRAG_IPV4
-
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP tables support"
-+ default n
-+ select NETFILTER_XTABLES
-+ help
-+ iptables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
-@@ -318,7 +324,13 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate
-+ tristate "Legacy ARPTABLES support"
-+ depends on NETFILTER_XTABLES
-+ default n
-+ help
-+ arptables is a legacy packet classifier.
-+ This is not needed if you are using arptables over nftables
-+ (iptables-nft).
-
- config NFT_COMPAT_ARP
- tristate
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index f3c8e2d918e13..e087a8e97ba78 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -8,7 +8,14 @@ menu "IPv6: Netfilter Configuration"
-
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP6 tables support"
-+ depends on INET && IPV6
-+ select NETFILTER_XTABLES
-+ default n
-+ help
-+ ip6tables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
---
-2.53.0
-
+++ /dev/null
-From e0da8f8aafbbc0d4f4829171a14bb9607bce7aef Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:15 +0200
-Subject: netfilter: x_tables: add and use xt_unregister_table_pre_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 527d6931473b75d90e38942aae6537d1a527f1fd ]
-
-Remove the copypasted variants of _pre_exit and add one single
-function in the xtables core. ebtables is not compatible with
-x_tables and therefore unchanged.
-
-This is a preparation patch to reduce noise in the followup
-bug fixes.
-
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 1 +
- include/linux/netfilter_arp/arp_tables.h | 1 -
- include/linux/netfilter_ipv4/ip_tables.h | 1 -
- include/linux/netfilter_ipv6/ip6_tables.h | 1 -
- net/ipv4/netfilter/arp_tables.c | 9 -------
- net/ipv4/netfilter/arptable_filter.c | 2 +-
- net/ipv4/netfilter/ip_tables.c | 9 -------
- net/ipv4/netfilter/iptable_filter.c | 2 +-
- net/ipv4/netfilter/iptable_mangle.c | 2 +-
- net/ipv4/netfilter/iptable_nat.c | 1 +
- net/ipv4/netfilter/iptable_raw.c | 2 +-
- net/ipv4/netfilter/iptable_security.c | 2 +-
- net/ipv6/netfilter/ip6_tables.c | 9 -------
- net/ipv6/netfilter/ip6table_filter.c | 2 +-
- net/ipv6/netfilter/ip6table_mangle.c | 2 +-
- net/ipv6/netfilter/ip6table_nat.c | 1 +
- net/ipv6/netfilter/ip6table_raw.c | 2 +-
- net/ipv6/netfilter/ip6table_security.c | 2 +-
- net/netfilter/x_tables.c | 29 +++++++++++++++++++++++
- 19 files changed, 41 insertions(+), 39 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index 5897f3dbaf7c3..df2022fe440b0 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -310,6 +310,7 @@ struct xt_table *xt_register_table(struct net *net,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
- void *xt_unregister_table(struct xt_table *table);
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
-index a40aaf645fa47..05631a25e6229 100644
---- a/include/linux/netfilter_arp/arp_tables.h
-+++ b/include/linux/netfilter_arp/arp_tables.h
-@@ -53,7 +53,6 @@ int arpt_register_table(struct net *net, const struct xt_table *table,
- const struct arpt_replace *repl,
- const struct nf_hook_ops *ops);
- void arpt_unregister_table(struct net *net, const char *name);
--void arpt_unregister_table_pre_exit(struct net *net, const char *name);
- extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-
-diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
-index 132b0e4a6d4df..13593391d6058 100644
---- a/include/linux/netfilter_ipv4/ip_tables.h
-+++ b/include/linux/netfilter_ipv4/ip_tables.h
-@@ -26,7 +26,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- const struct ipt_replace *repl,
- const struct nf_hook_ops *ops);
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name);
- void ipt_unregister_table_exit(struct net *net, const char *name);
-
- /* Standard entry. */
-diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
-index 8b8885a73c764..c6d5b927830dd 100644
---- a/include/linux/netfilter_ipv6/ip6_tables.h
-+++ b/include/linux/netfilter_ipv6/ip6_tables.h
-@@ -27,7 +27,6 @@ extern void *ip6t_alloc_initial_table(const struct xt_table *);
- int ip6t_register_table(struct net *net, const struct xt_table *table,
- const struct ip6t_replace *repl,
- const struct nf_hook_ops *ops);
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name);
- void ip6t_unregister_table_exit(struct net *net, const char *name);
- extern unsigned int ip6t_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 97ead883e4a13..d19fce8589809 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1581,15 +1581,6 @@ int arpt_register_table(struct net *net,
- return ret;
- }
-
--void arpt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--EXPORT_SYMBOL(arpt_unregister_table_pre_exit);
--
- void arpt_unregister_table(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 359d00d74095b..382345567a600 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -43,7 +43,7 @@ static int arptable_filter_table_init(struct net *net)
-
- static void __net_exit arptable_filter_net_pre_exit(struct net *net)
- {
-- arpt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_ARP, "filter");
- }
-
- static void __net_exit arptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index 3d101613f27fa..49b7989c24e08 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1789,14 +1789,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-@@ -1887,7 +1879,6 @@ static void __exit ip_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ipt_register_table);
--EXPORT_SYMBOL(ipt_unregister_table_pre_exit);
- EXPORT_SYMBOL(ipt_unregister_table_exit);
- EXPORT_SYMBOL(ipt_do_table);
- module_init(ip_tables_init);
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index 595bfb492b1c1..0dea754a91209 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -61,7 +61,7 @@ static int __net_init iptable_filter_net_init(struct net *net)
-
- static void __net_exit iptable_filter_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "filter");
- }
-
- static void __net_exit iptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index db90db7057cc4..4d3b124923080 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -96,7 +96,7 @@ static int iptable_mangle_table_init(struct net *net)
-
- static void __net_exit iptable_mangle_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "mangle");
- }
-
- static void __net_exit iptable_mangle_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index a5db7c67d61be..d6c5824943f8e 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -129,6 +129,7 @@ static int iptable_nat_table_init(struct net *net)
- static void __net_exit iptable_nat_net_pre_exit(struct net *net)
- {
- ipt_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
- }
-
- static void __net_exit iptable_nat_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index b46a790917306..6f7afec7954bd 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -53,7 +53,7 @@ static int iptable_raw_table_init(struct net *net)
-
- static void __net_exit iptable_raw_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "raw");
- }
-
- static void __net_exit iptable_raw_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 2b89adc1e5751..81175c20ccbe8 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -50,7 +50,7 @@ static int iptable_security_table_init(struct net *net)
-
- static void __net_exit iptable_security_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "security");
- }
-
- static void __net_exit iptable_security_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 7d5602950ae72..6b431b3f90ddb 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1795,14 +1795,6 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-@@ -1894,7 +1886,6 @@ static void __exit ip6_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ip6t_register_table);
--EXPORT_SYMBOL(ip6t_unregister_table_pre_exit);
- EXPORT_SYMBOL(ip6t_unregister_table_exit);
- EXPORT_SYMBOL(ip6t_do_table);
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index 9dcd4501fe800..cf561919bde84 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -60,7 +60,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
-
- static void __net_exit ip6table_filter_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "filter");
- }
-
- static void __net_exit ip6table_filter_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index ce2cbce9e3ed3..1a758f2bc5379 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -89,7 +89,7 @@ static int ip6table_mangle_table_init(struct net *net)
-
- static void __net_exit ip6table_mangle_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "mangle");
- }
-
- static void __net_exit ip6table_mangle_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index e119d4f090cc8..4ce45f3d11109 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -131,6 +131,7 @@ static int ip6table_nat_table_init(struct net *net)
- static void __net_exit ip6table_nat_net_pre_exit(struct net *net)
- {
- ip6t_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
- }
-
- static void __net_exit ip6table_nat_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index 8af0f8bd036dc..923455921c1dd 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -52,7 +52,7 @@ static int ip6table_raw_table_init(struct net *net)
-
- static void __net_exit ip6table_raw_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "raw");
- }
-
- static void __net_exit ip6table_raw_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index 66018b169b010..c44834d93fc79 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -49,7 +49,7 @@ static int ip6table_security_table_init(struct net *net)
-
- static void __net_exit ip6table_security_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "security");
- }
-
- static void __net_exit ip6table_security_net_exit(struct net *net)
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 1ca4fa9d249b8..2d93f189a79b9 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1538,6 +1538,35 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+
-+/**
-+ * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
-+ * @net: network namespace
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Unregisters the specified netfilter table from the given network namespace
-+ * and also unregisters the hooks from netfilter core: no new packets will be
-+ * processed.
-+ */
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *t;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(t, &xt_net->tables[af], list) {
-+ if (strcmp(t->name, name) == 0) {
-+ mutex_unlock(&xt[af].mutex);
-+
-+ if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
-+ }
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+}
-+EXPORT_SYMBOL(xt_unregister_table_pre_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
---
-2.53.0
-
+++ /dev/null
-From f47da49deed52dbdd3d10f928793fb2be6c4f9cb Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:17 +0200
-Subject: netfilter: x_tables: add and use xtables_unregister_table_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b4597d5fd7d2f8cebfffd40dffb5e003cc78964c ]
-
-Previous change added xtables_unregister_table_pre_exit to detach the
-table from the packetpath and to unlink it from the active table list.
-In case of rmmod, userspace that is doing set/getsockopt for this table
-will not be able to re-instantiate the table:
- 1. The larval table has been removed already
- 2. existing instantiated table is no longer on the xt pernet table list.
-
-This adds the second stage helper:
-
-unlink the table from the dying list, free the hook ops (if any) and do
-the audit notification. It replaces xt_unregister_table().
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Reported-by: Tristan Madani <tristan@talencesecurity.com>
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Closes: https://lore.kernel.org/netfilter-devel/20260429175613.1459342-1-tristmd@gmail.com/
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 2 +-
- net/ipv4/netfilter/arp_tables.c | 9 ++--
- net/ipv4/netfilter/ip_tables.c | 9 ++--
- net/ipv4/netfilter/iptable_nat.c | 5 +-
- net/ipv6/netfilter/ip6_tables.c | 9 ++--
- net/ipv6/netfilter/ip6table_nat.c | 5 +-
- net/netfilter/x_tables.c | 81 +++++++++++++++++++++++-------
- 7 files changed, 83 insertions(+), 37 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index df2022fe440b0..706f08839050a 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -309,8 +309,8 @@ struct xt_table *xt_register_table(struct net *net,
- const struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
--void *xt_unregister_table(struct xt_table *table);
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index d19fce8589809..f3dadbc416a3a 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1501,13 +1501,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
-
- static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
-+ void *loc_cpu_entry;
- struct arpt_entry *iter;
-
-- private = xt_unregister_table(table);
--
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
- xt_entry_foreach(iter, loc_cpu_entry, private->size)
-@@ -1515,6 +1513,7 @@ static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int arpt_register_table(struct net *net,
-@@ -1583,7 +1582,7 @@ int arpt_register_table(struct net *net,
-
- void arpt_unregister_table(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_ARP, name);
-
- if (table)
- __arpt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index 49b7989c24e08..84b1f49ddbc5c 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1704,12 +1704,10 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ipt_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1718,6 +1716,7 @@ static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ipt_register_table(struct net *net, const struct xt_table *table,
-@@ -1791,7 +1790,7 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
-
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV4, name);
-
- if (table)
- __ipt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index d6c5824943f8e..4dae3da4586b8 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -119,8 +119,11 @@ static int iptable_nat_table_init(struct net *net)
- }
-
- ret = ipt_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
-+ synchronize_rcu();
- ipt_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 6b431b3f90ddb..1eac22dbb957c 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1713,12 +1713,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ip6t_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1727,6 +1725,7 @@ static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ip6t_register_table(struct net *net, const struct xt_table *table,
-@@ -1797,7 +1796,7 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
-
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV6, name);
-
- if (table)
- __ip6t_unregister_table(net, table);
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index 4ce45f3d11109..8088ebaf9b352 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -121,8 +121,11 @@ static int ip6table_nat_table_init(struct net *net)
- }
-
- ret = ip6t_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
-+ synchronize_rcu();
- ip6t_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 2d93f189a79b9..76fd0999db4a8 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -55,6 +55,9 @@ static struct list_head xt_templates[NFPROTO_NUMPROTO];
-
- struct xt_pernet {
- struct list_head tables[NFPROTO_NUMPROTO];
-+
-+ /* stash area used during netns exit */
-+ struct list_head dead_tables[NFPROTO_NUMPROTO];
- };
-
- struct compat_delta {
-@@ -1522,23 +1525,6 @@ struct xt_table *xt_register_table(struct net *net,
- }
- EXPORT_SYMBOL_GPL(xt_register_table);
-
--void *xt_unregister_table(struct xt_table *table)
--{
-- struct xt_table_info *private;
--
-- mutex_lock(&xt[table->af].mutex);
-- private = table->private;
-- list_del(&table->list);
-- mutex_unlock(&xt[table->af].mutex);
-- audit_log_nfcfg(table->name, table->af, private->number,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-- kfree(table->ops);
-- kfree(table);
--
-- return private;
--}
--EXPORT_SYMBOL_GPL(xt_unregister_table);
--
- /**
- * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
- * @net: network namespace
-@@ -1548,6 +1534,14 @@ EXPORT_SYMBOL_GPL(xt_unregister_table);
- * Unregisters the specified netfilter table from the given network namespace
- * and also unregisters the hooks from netfilter core: no new packets will be
- * processed.
-+ *
-+ * This must be called prior to xt_unregister_table_exit() from the pernet
-+ * .pre_exit callback. After this call, the table is no longer visible to
-+ * the get/setsockopt path. In case of rmmod, module exit path must have
-+ * called xt_unregister_template() prior to unregistering pernet ops to
-+ * prevent re-instantiation of the table.
-+ *
-+ * See also: xt_unregister_table_exit()
- */
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- {
-@@ -1557,6 +1551,7 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_lock(&xt[af].mutex);
- list_for_each_entry(t, &xt_net->tables[af], list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &xt_net->dead_tables[af]);
- mutex_unlock(&xt[af].mutex);
-
- if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-@@ -1567,6 +1562,50 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_unlock(&xt[af].mutex);
- }
- EXPORT_SYMBOL(xt_unregister_table_pre_exit);
-+
-+/**
-+ * xt_unregister_table_exit - remove a table during namespace teardown
-+ * @net: the network namespace from which to unregister the table
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Completes the unregister process for a table. This must be called from
-+ * the pernet ops .exit callback. This is the second stage after
-+ * xt_unregister_table_pre_exit().
-+ *
-+ * pair with xt_unregister_table_pre_exit() during namespace shutdown.
-+ *
-+ * Return: the unregistered table or NULL if the table was never
-+ * instantiated. The caller needs to kfree() the table after it
-+ * has removed the family specific matches/targets.
-+ */
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *table;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(table, &xt_net->dead_tables[af], list) {
-+ struct nf_hook_ops *ops = NULL;
-+
-+ if (strcmp(table->name, name) != 0)
-+ continue;
-+
-+ list_del(&table->list);
-+
-+ audit_log_nfcfg(table->name, table->af, table->private->number,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ swap(table->ops, ops);
-+ mutex_unlock(&xt[af].mutex);
-+
-+ kfree(ops);
-+ return table;
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL_GPL(xt_unregister_table_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
-@@ -2013,8 +2052,10 @@ static int __net_init xt_net_init(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- INIT_LIST_HEAD(&xt_net->tables[i]);
-+ INIT_LIST_HEAD(&xt_net->dead_tables[i]);
-+ }
- return 0;
- }
-
-@@ -2023,8 +2064,10 @@ static void __net_exit xt_net_exit(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- WARN_ON_ONCE(!list_empty(&xt_net->tables[i]));
-+ WARN_ON_ONCE(!list_empty(&xt_net->dead_tables[i]));
-+ }
- }
-
- static struct pernet_operations xt_net_ops = {
---
-2.53.0
-
+++ /dev/null
-From 56e2255297c4fab7ff8d74a2a60ff039f83ad9c4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:20 +0200
-Subject: netfilter: x_tables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 16bc4b6686b2c112c10e67d6b493adc3607256d3 ]
-
-Similar to the previous ebtables patch:
-template add exposes the table to userspace, we must do this last to
-rnsure the pernet ops are set up (contain the destructors).
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/arptable_filter.c | 23 ++++++++++++-----------
- net/ipv4/netfilter/iptable_filter.c | 23 ++++++++++++-----------
- net/ipv4/netfilter/iptable_mangle.c | 25 +++++++++++++------------
- net/ipv4/netfilter/iptable_raw.c | 22 +++++++++++-----------
- net/ipv4/netfilter/iptable_security.c | 23 ++++++++++++-----------
- net/ipv6/netfilter/ip6table_filter.c | 22 +++++++++++-----------
- net/ipv6/netfilter/ip6table_mangle.c | 23 ++++++++++++-----------
- net/ipv6/netfilter/ip6table_raw.c | 20 ++++++++++----------
- net/ipv6/netfilter/ip6table_security.c | 23 ++++++++++++-----------
- 9 files changed, 105 insertions(+), 99 deletions(-)
-
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 382345567a600..370b635e3523b 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -58,25 +58,26 @@ static struct pernet_operations arptable_filter_net_ops = {
-
- static int __init arptable_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- arptable_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arpt_do_table);
-- if (IS_ERR(arpfilter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(arpfilter_ops))
- return PTR_ERR(arpfilter_ops);
-- }
-
- ret = register_pernet_subsys(&arptable_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter,
-+ arptable_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(arpfilter_ops);
-- return ret;
-+ unregister_pernet_subsys(&arptable_filter_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(arpfilter_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index 0dea754a91209..672d7da1071d3 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -77,26 +77,27 @@ static struct pernet_operations iptable_filter_net_ops = {
-
- static int __init iptable_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- iptable_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- filter_ops = xt_hook_ops_alloc(&packet_filter, ipt_do_table);
-- if (IS_ERR(filter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(filter_ops))
- return PTR_ERR(filter_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter,
-+ iptable_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(filter_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_filter_net_ops);
-+ goto err_free;
- }
-
- return 0;
-+err_free:
-+ kfree(filter_ops);
-+ return ret;
- }
-
- static void __exit iptable_filter_fini(void)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index 4d3b124923080..13d25d9a4610e 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -111,25 +111,26 @@ static struct pernet_operations iptable_mangle_net_ops = {
-
- static int __init iptable_mangle_init(void)
- {
-- int ret = xt_register_template(&packet_mangler,
-- iptable_mangle_table_init);
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- mangle_ops = xt_hook_ops_alloc(&packet_mangler, iptable_mangle_hook);
-- if (IS_ERR(mangle_ops)) {
-- xt_unregister_template(&packet_mangler);
-- ret = PTR_ERR(mangle_ops);
-- return ret;
-- }
-+ if (IS_ERR(mangle_ops))
-+ return PTR_ERR(mangle_ops);
-
- ret = register_pernet_subsys(&iptable_mangle_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_mangler,
-+ iptable_mangle_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_mangler);
-- kfree(mangle_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_mangle_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(mangle_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index 6f7afec7954bd..2745c22f4034d 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -77,24 +77,24 @@ static int __init iptable_raw_init(void)
- pr_info("Enabling raw table before defrag\n");
- }
-
-- ret = xt_register_template(table,
-- iptable_raw_table_init);
-- if (ret < 0)
-- return ret;
--
- rawtable_ops = xt_hook_ops_alloc(table, ipt_do_table);
-- if (IS_ERR(rawtable_ops)) {
-- xt_unregister_template(table);
-+ if (IS_ERR(rawtable_ops))
- return PTR_ERR(rawtable_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_raw_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(table,
-+ iptable_raw_table_init);
- if (ret < 0) {
-- xt_unregister_template(table);
-- kfree(rawtable_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_raw_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(rawtable_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 81175c20ccbe8..491894511c544 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -65,25 +65,26 @@ static struct pernet_operations iptable_security_net_ops = {
-
- static int __init iptable_security_init(void)
- {
-- int ret = xt_register_template(&security_table,
-- iptable_security_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- sectbl_ops = xt_hook_ops_alloc(&security_table, ipt_do_table);
-- if (IS_ERR(sectbl_ops)) {
-- xt_unregister_template(&security_table);
-+ if (IS_ERR(sectbl_ops))
- return PTR_ERR(sectbl_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_security_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&security_table,
-+ iptable_security_table_init);
- if (ret < 0) {
-- xt_unregister_template(&security_table);
-- kfree(sectbl_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_security_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(sectbl_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index cf561919bde84..b074fc4776764 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -76,25 +76,25 @@ static struct pernet_operations ip6table_filter_net_ops = {
-
- static int __init ip6table_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- ip6table_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- filter_ops = xt_hook_ops_alloc(&packet_filter, ip6t_do_table);
-- if (IS_ERR(filter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(filter_ops))
- return PTR_ERR(filter_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter, ip6table_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(filter_ops);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_filter_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(filter_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index 1a758f2bc5379..e6ee036a9b2c5 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -104,25 +104,26 @@ static struct pernet_operations ip6table_mangle_net_ops = {
-
- static int __init ip6table_mangle_init(void)
- {
-- int ret = xt_register_template(&packet_mangler,
-- ip6table_mangle_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- mangle_ops = xt_hook_ops_alloc(&packet_mangler, ip6table_mangle_hook);
-- if (IS_ERR(mangle_ops)) {
-- xt_unregister_template(&packet_mangler);
-+ if (IS_ERR(mangle_ops))
- return PTR_ERR(mangle_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_mangle_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_mangler,
-+ ip6table_mangle_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_mangler);
-- kfree(mangle_ops);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_mangle_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(mangle_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index 923455921c1dd..3b161ee875bcc 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -75,24 +75,24 @@ static int __init ip6table_raw_init(void)
- pr_info("Enabling raw table before defrag\n");
- }
-
-- ret = xt_register_template(table, ip6table_raw_table_init);
-- if (ret < 0)
-- return ret;
--
- /* Register hooks */
- rawtable_ops = xt_hook_ops_alloc(table, ip6t_do_table);
-- if (IS_ERR(rawtable_ops)) {
-- xt_unregister_template(table);
-+ if (IS_ERR(rawtable_ops))
- return PTR_ERR(rawtable_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_raw_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(table, ip6table_raw_table_init);
- if (ret < 0) {
-- kfree(rawtable_ops);
-- xt_unregister_template(table);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_raw_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(rawtable_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index c44834d93fc79..4bd5d97b8ab65 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -64,25 +64,26 @@ static struct pernet_operations ip6table_security_net_ops = {
-
- static int __init ip6table_security_init(void)
- {
-- int ret = xt_register_template(&security_table,
-- ip6table_security_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- sectbl_ops = xt_hook_ops_alloc(&security_table, ip6t_do_table);
-- if (IS_ERR(sectbl_ops)) {
-- xt_unregister_template(&security_table);
-+ if (IS_ERR(sectbl_ops))
- return PTR_ERR(sectbl_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_security_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&security_table,
-+ ip6table_security_table_init);
- if (ret < 0) {
-- kfree(sectbl_ops);
-- xt_unregister_template(&security_table);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_security_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(sectbl_ops);
- return ret;
- }
-
---
-2.53.0
-
alsa-hda-cs35l41-put-acpi-device-on-missing-physical.patch
btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch
netfilter-x_tables-unregister-the-templates-first.patch
-netfilter-make-legacy-configs-user-selectable.patch
-netfilter-exclude-legacy-tables-on-preempt_rt.patch
-netfilter-x_tables-add-and-use-xt_unregister_table_p.patch
-netfilter-x_tables-add-and-use-xtables_unregister_ta.patch
-netfilter-ebtables-move-to-two-stage-removal-scheme.patch
-netfilter-ebtables-close-dangling-table-module-init-.patch
-netfilter-x_tables-close-dangling-table-module-init-.patch
-netfilter-bridge-eb_tables-close-module-init-race.patch
kprobes-skip-non-symbol-addresses-in-kprobe_add_ksym.patch
test_kprobes-clear-kprobes-between-test-runs.patch
tcp-fix-imbalanced-icsk_accept_queue-count.patch
+++ /dev/null
-From 209d7fc49e05dc6bc6fa94dffaa381a99e7f5e78 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Jan 2024 16:42:48 +0100
-Subject: netfilter: arptables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 4654467dc7e111e84f43ed1b70322873ae77e7be ]
-
-Allows to build kernel that supports the arptables mangle target
-via nftables' compat infra but without the arptables get/setsockopt
-interface or the old arptables filter interpreter.
-
-IOW, setting IP_NF_ARPFILTER=n will break arptables-legacy, but
-arptables-nft will continue to work as long as nftables compat
-support is enabled.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Reviewed-by: Phil Sutter <phil@nwl.cc>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 28 +++++++++++++---------------
- 1 file changed, 13 insertions(+), 15 deletions(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index f71a7e9a7de6d..070475392236f 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -309,36 +309,34 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate "ARP tables support"
-- select NETFILTER_XTABLES
-- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_ADVANCED
-- help
-- arptables is a general, extensible packet identification framework.
-- The ARP packet filtering and mangling (manipulation)subsystems
-- use this: say Y or M here if you want to use either of those.
--
-- To compile it as a module, choose M here. If unsure, say N.
-+ tristate
-
--if IP_NF_ARPTABLES
-+config NFT_COMPAT_ARP
-+ tristate
-+ depends on NF_TABLES_ARP && NFT_COMPAT
-+ default m if NFT_COMPAT=m
-+ default y if NFT_COMPAT=y
-
- config IP_NF_ARPFILTER
-- tristate "ARP packet filtering"
-+ tristate "arptables-legacy packet filtering support"
-+ select IP_NF_ARPTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-- local output. On a bridge, you can also specify filtering rules
-- for forwarded ARP packets. See the man page for arptables(8).
-+ local output. This is only needed for arptables-legacy(8).
-+ Neither arptables-nft nor nftables need this to work.
-
- To compile it as a module, choose M here. If unsure, say N.
-
- config IP_NF_ARP_MANGLE
- tristate "ARP payload mangling"
-+ depends on IP_NF_ARPTABLES || NFT_COMPAT_ARP
- help
- Allows altering the ARP packet payload: source and destination
- hardware and network addresses.
-
--endif # IP_NF_ARPTABLES
-+ This option is needed by both arptables-legacy and arptables-nft.
-+ It is not used by nftables.
-
- endmenu
-
---
-2.53.0
-
+++ /dev/null
-From 9cd2a62d96f43ca483d588ac324dad0e31a152c5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Mar 2024 21:15:52 -0700
-Subject: netfilter: arptables: Select NETFILTER_FAMILY_ARP when building
- arp_tables.c
-
-From: Kuniyuki Iwashima <kuniyu@amazon.com>
-
-[ Upstream commit 15fba562f7a9f04322b8bfc8f392e04bb93d81be ]
-
-syzkaller started to report a warning below [0] after consuming the
-commit 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only
-builds").
-
-The change accidentally removed the dependency on NETFILTER_FAMILY_ARP
-from IP_NF_ARPTABLES.
-
-If NF_TABLES_ARP is not enabled on Kconfig, NETFILTER_FAMILY_ARP will
-be removed and some code necessary for arptables will not be compiled.
-
- $ grep -E "(NETFILTER_FAMILY_ARP|IP_NF_ARPTABLES|NF_TABLES_ARP)" .config
- CONFIG_NETFILTER_FAMILY_ARP=y
- # CONFIG_NF_TABLES_ARP is not set
- CONFIG_IP_NF_ARPTABLES=y
-
- $ make olddefconfig
-
- $ grep -E "(NETFILTER_FAMILY_ARP|IP_NF_ARPTABLES|NF_TABLES_ARP)" .config
- # CONFIG_NF_TABLES_ARP is not set
- CONFIG_IP_NF_ARPTABLES=y
-
-So, when nf_register_net_hooks() is called for arptables, it will
-trigger the splat below.
-
-Now IP_NF_ARPTABLES is only enabled by IP_NF_ARPFILTER, so let's
-restore the dependency on NETFILTER_FAMILY_ARP in IP_NF_ARPFILTER.
-
-[0]:
-WARNING: CPU: 0 PID: 242 at net/netfilter/core.c:316 nf_hook_entry_head+0x1e1/0x2c0 net/netfilter/core.c:316
-Modules linked in:
-CPU: 0 PID: 242 Comm: syz-executor.0 Not tainted 6.8.0-12821-g537c2e91d354 #10
-Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
-RIP: 0010:nf_hook_entry_head+0x1e1/0x2c0 net/netfilter/core.c:316
-Code: 83 fd 04 0f 87 bc 00 00 00 e8 5b 84 83 fd 4d 8d ac ec a8 0b 00 00 e8 4e 84 83 fd 4c 89 e8 5b 5d 41 5c 41 5d c3 e8 3f 84 83 fd <0f> 0b e8 38 84 83 fd 45 31 ed 5b 5d 4c 89 e8 41 5c 41 5d c3 e8 26
-RSP: 0018:ffffc90000b8f6e8 EFLAGS: 00010293
-RAX: 0000000000000000 RBX: 0000000000000003 RCX: ffffffff83c42164
-RDX: ffff888106851180 RSI: ffffffff83c42321 RDI: 0000000000000005
-RBP: 0000000000000000 R08: 0000000000000005 R09: 000000000000000a
-R10: 0000000000000003 R11: ffff8881055c2f00 R12: ffff888112b78000
-R13: 0000000000000000 R14: ffff8881055c2f00 R15: ffff8881055c2f00
-FS: 00007f377bd78800(0000) GS:ffff88811b000000(0000) knlGS:0000000000000000
-CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
-CR2: 0000000000496068 CR3: 000000011298b003 CR4: 0000000000770ef0
-PKRU: 55555554
-Call Trace:
- <TASK>
- __nf_register_net_hook+0xcd/0x7a0 net/netfilter/core.c:428
- nf_register_net_hook+0x116/0x170 net/netfilter/core.c:578
- nf_register_net_hooks+0x5d/0xc0 net/netfilter/core.c:594
- arpt_register_table+0x250/0x420 net/ipv4/netfilter/arp_tables.c:1553
- arptable_filter_table_init+0x41/0x60 net/ipv4/netfilter/arptable_filter.c:39
- xt_find_table_lock+0x2e9/0x4b0 net/netfilter/x_tables.c:1260
- xt_request_find_table_lock+0x2b/0xe0 net/netfilter/x_tables.c:1285
- get_info+0x169/0x5c0 net/ipv4/netfilter/arp_tables.c:808
- do_arpt_get_ctl+0x3f9/0x830 net/ipv4/netfilter/arp_tables.c:1444
- nf_getsockopt+0x76/0xd0 net/netfilter/nf_sockopt.c:116
- ip_getsockopt+0x17d/0x1c0 net/ipv4/ip_sockglue.c:1777
- tcp_getsockopt+0x99/0x100 net/ipv4/tcp.c:4373
- do_sock_getsockopt+0x279/0x360 net/socket.c:2373
- __sys_getsockopt+0x115/0x1e0 net/socket.c:2402
- __do_sys_getsockopt net/socket.c:2412 [inline]
- __se_sys_getsockopt net/socket.c:2409 [inline]
- __x64_sys_getsockopt+0xbd/0x150 net/socket.c:2409
- do_syscall_x64 arch/x86/entry/common.c:52 [inline]
- do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
- entry_SYSCALL_64_after_hwframe+0x46/0x4e
-RIP: 0033:0x7f377beca6fe
-Code: 1f 44 00 00 48 8b 15 01 97 0a 00 f7 d8 64 89 02 b8 ff ff ff ff eb b8 0f 1f 44 00 00 f3 0f 1e fa 49 89 ca b8 37 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 0a c3 66 0f 1f 84 00 00 00 00 00 48 8b 15 c9
-RSP: 002b:00000000005df728 EFLAGS: 00000246 ORIG_RAX: 0000000000000037
-RAX: ffffffffffffffda RBX: 00000000004966e0 RCX: 00007f377beca6fe
-RDX: 0000000000000060 RSI: 0000000000000000 RDI: 0000000000000003
-RBP: 000000000042938a R08: 00000000005df73c R09: 00000000005df800
-R10: 00000000004966e8 R11: 0000000000000246 R12: 0000000000000003
-R13: 0000000000496068 R14: 0000000000000003 R15: 00000000004bc9d8
- </TASK>
-
-Fixes: 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only builds")
-Reported-by: syzkaller <syzkaller@googlegroups.com>
-Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
-Reviewed-by: Simon Horman <horms@kernel.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 8f6e950163a79..1b991b889506a 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -329,6 +329,7 @@ config NFT_COMPAT_ARP
- config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
-+ select NETFILTER_FAMILY_ARP
- depends on NETFILTER_XTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
---
-2.53.0
-
+++ /dev/null
-From 66369db872908fe432e1d407449372db0834fd98 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 7 May 2026 11:19:22 +0200
-Subject: netfilter: bridge: eb_tables: close module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 27414ff1b287ea9a2a11675149ec28e05539f3cc ]
-
-sashiko reports for unrelated patch:
- Does the core ebtables initialization in ebtables.c suffer from a similar race?
- Once nf_register_sockopt() completes, the sockopts are exposed globally.
-
-sockopt has to be registered last, just like in ip/ip6/arptables.
-
-Fixes: 5b53951cfc85 ("netfilter: ebtables: use net_generic infra")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtables.c | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index ec286e54229b7..ca426e49ea1a1 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -2583,19 +2583,20 @@ static int __init ebtables_init(void)
- {
- int ret;
-
-- ret = xt_register_target(&ebt_standard_target);
-+ ret = register_pernet_subsys(&ebt_net_ops);
- if (ret < 0)
- return ret;
-- ret = nf_register_sockopt(&ebt_sockopts);
-+
-+ ret = xt_register_target(&ebt_standard_target);
- if (ret < 0) {
-- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
-- ret = register_pernet_subsys(&ebt_net_ops);
-+ ret = nf_register_sockopt(&ebt_sockopts);
- if (ret < 0) {
-- nf_unregister_sockopt(&ebt_sockopts);
- xt_unregister_target(&ebt_standard_target);
-+ unregister_pernet_subsys(&ebt_net_ops);
- return ret;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 812f90f09db00caf502621c1b511708e54f7326b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 24 Jan 2024 10:21:12 +0100
-Subject: netfilter: ebtables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 7ad269787b6615ca56bb161063331991fce51abf ]
-
-Same patch as previous one, but for ebtables.
-
-To build a kernel that only supports ebtables-nft, the builtin tables
-need to be disabled, i.e.:
-
-CONFIG_BRIDGE_EBT_BROUTE=n
-CONFIG_BRIDGE_EBT_T_FILTER=n
-CONFIG_BRIDGE_EBT_T_NAT=n
-
-The ebtables specific extensions can then be used nftables'
-NFT_COMPAT interface.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 7 +++++++
- net/bridge/netfilter/Makefile | 2 +-
- 2 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 7f304a19ac1bf..104c0125e32e8 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -39,6 +39,10 @@ config NF_CONNTRACK_BRIDGE
-
- To compile it as a module, choose M here. If unsure, say N.
-
-+# old sockopt interface and eval loop
-+config BRIDGE_NF_EBTABLES_LEGACY
-+ tristate
-+
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
- depends on BRIDGE && NETFILTER && NETFILTER_XTABLES
-@@ -55,6 +59,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -65,6 +70,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -74,6 +80,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-+ select BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
-index 1c9ce49ab6513..b9a1303da9771 100644
---- a/net/bridge/netfilter/Makefile
-+++ b/net/bridge/netfilter/Makefile
-@@ -9,7 +9,7 @@ obj-$(CONFIG_NFT_BRIDGE_REJECT) += nft_reject_bridge.o
- # connection tracking
- obj-$(CONFIG_NF_CONNTRACK_BRIDGE) += nf_conntrack_bridge.o
-
--obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
-+obj-$(CONFIG_BRIDGE_NF_EBTABLES_LEGACY) += ebtables.o
-
- # tables
- obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o
---
-2.53.0
-
+++ /dev/null
-From 1f8996773559b470b18aa8d370e630503e096a72 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:19 +0200
-Subject: netfilter: ebtables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 92c603fa07bc0d6a17345de3ad7954730b8de44b ]
-
-sashiko reported for a related patch:
- In modules like iptable_raw.c, [..], if register_pernet_subsys() fails,
- the rollback might call kfree(rawtable_ops) before [..]
- During this window, could a concurrent userspace process find the globally
- visible template, trigger table_init(), [..]
-
-The table init functions must always register the template last.
-
-Otherwise, set/getsockopt can instantiate a table in a namespace
-while the required pernet ops (contain the destructor) isn't available.
-This change is also required in x_tables, handled in followup change.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 12 +++++-------
- net/bridge/netfilter/ebtable_filter.c | 12 +++++-------
- net/bridge/netfilter/ebtable_nat.c | 10 ++++------
- 3 files changed, 14 insertions(+), 20 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index 33d8640d21ac1..43c808e525e87 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -112,18 +112,16 @@ static struct pernet_operations broute_net_ops = {
-
- static int __init ebtable_broute_init(void)
- {
-- int ret = ebt_register_template(&broute_table, broute_table_init);
-+ int ret = register_pernet_subsys(&broute_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&broute_net_ops);
-- if (ret) {
-- ebt_unregister_template(&broute_table);
-- return ret;
-- }
-+ ret = ebt_register_template(&broute_table, broute_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&broute_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_broute_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index fdb988c24916a..f76d45dfe9b46 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -93,18 +93,16 @@ static struct pernet_operations frame_filter_net_ops = {
-
- static int __init ebtable_filter_init(void)
- {
-- int ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ int ret = register_pernet_subsys(&frame_filter_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_filter_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_filter);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_filter, frame_filter_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_filter_net_ops);
-
-- return 0;
-+ return ret;
- }
-
- static void __exit ebtable_filter_fini(void)
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 8b981b2041b5d..af0732e2f889d 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -93,16 +93,14 @@ static struct pernet_operations frame_nat_net_ops = {
-
- static int __init ebtable_nat_init(void)
- {
-- int ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ int ret = register_pernet_subsys(&frame_nat_net_ops);
-
- if (ret)
- return ret;
-
-- ret = register_pernet_subsys(&frame_nat_net_ops);
-- if (ret) {
-- ebt_unregister_template(&frame_nat);
-- return ret;
-- }
-+ ret = ebt_register_template(&frame_nat, frame_nat_table_init);
-+ if (ret)
-+ unregister_pernet_subsys(&frame_nat_net_ops);
-
- return ret;
- }
---
-2.53.0
-
+++ /dev/null
-From 8537307f1432dc229dd72bbba23abf7139c20bbf Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:18 +0200
-Subject: netfilter: ebtables: move to two-stage removal scheme
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b7f0544d86d439cb946515d2ef6a0a75e8626710 ]
-
-Like previous patches for x_tables, follow same pattern in ebtables.
-We can't reuse xt helpers: ebt_table struct layout is incompatible.
-
-table->ops assignment is now done while still holding the ebt mutex
-to make sure we never expose partially-filled table struct.
-
-Fixes: 87663c39f898 ("netfilter: ebtables: do not hook tables by default")
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/ebtable_broute.c | 2 +-
- net/bridge/netfilter/ebtable_filter.c | 2 +-
- net/bridge/netfilter/ebtable_nat.c | 2 +-
- net/bridge/netfilter/ebtables.c | 60 +++++++++++++++++----------
- 4 files changed, 40 insertions(+), 26 deletions(-)
-
-diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
-index 8f19253024b0a..33d8640d21ac1 100644
---- a/net/bridge/netfilter/ebtable_broute.c
-+++ b/net/bridge/netfilter/ebtable_broute.c
-@@ -128,8 +128,8 @@ static int __init ebtable_broute_init(void)
-
- static void __exit ebtable_broute_fini(void)
- {
-- unregister_pernet_subsys(&broute_net_ops);
- ebt_unregister_template(&broute_table);
-+ unregister_pernet_subsys(&broute_net_ops);
- }
-
- module_init(ebtable_broute_init);
-diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
-index 278f324e67524..fdb988c24916a 100644
---- a/net/bridge/netfilter/ebtable_filter.c
-+++ b/net/bridge/netfilter/ebtable_filter.c
-@@ -109,8 +109,8 @@ static int __init ebtable_filter_init(void)
-
- static void __exit ebtable_filter_fini(void)
- {
-- unregister_pernet_subsys(&frame_filter_net_ops);
- ebt_unregister_template(&frame_filter);
-+ unregister_pernet_subsys(&frame_filter_net_ops);
- }
-
- module_init(ebtable_filter_init);
-diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
-index 9066f7f376d57..8b981b2041b5d 100644
---- a/net/bridge/netfilter/ebtable_nat.c
-+++ b/net/bridge/netfilter/ebtable_nat.c
-@@ -109,8 +109,8 @@ static int __init ebtable_nat_init(void)
-
- static void __exit ebtable_nat_fini(void)
- {
-- unregister_pernet_subsys(&frame_nat_net_ops);
- ebt_unregister_template(&frame_nat);
-+ unregister_pernet_subsys(&frame_nat_net_ops);
- }
-
- module_init(ebtable_nat_init);
-diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
-index f99e348c8f37f..ec286e54229b7 100644
---- a/net/bridge/netfilter/ebtables.c
-+++ b/net/bridge/netfilter/ebtables.c
-@@ -42,6 +42,7 @@
-
- struct ebt_pernet {
- struct list_head tables;
-+ struct list_head dead_tables;
- };
-
- struct ebt_template {
-@@ -1162,11 +1163,6 @@ static int do_replace(struct net *net, sockptr_t arg, unsigned int len)
-
- static void __ebt_unregister_table(struct net *net, struct ebt_table *table)
- {
-- mutex_lock(&ebt_mutex);
-- list_del(&table->list);
-- mutex_unlock(&ebt_mutex);
-- audit_log_nfcfg(table->name, AF_BRIDGE, table->private->nentries,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
- EBT_ENTRY_ITERATE(table->private->entries, table->private->entries_size,
- ebt_cleanup_entry, net, NULL);
- if (table->private->nentries)
-@@ -1267,13 +1263,15 @@ int ebt_register_table(struct net *net, const struct ebt_table *input_table,
- for (i = 0; i < num_ops; i++)
- ops[i].priv = table;
-
-- list_add(&table->list, &ebt_net->tables);
-- mutex_unlock(&ebt_mutex);
--
- table->ops = ops;
- ret = nf_register_net_hooks(net, ops, num_ops);
-- if (ret)
-+ if (ret) {
-+ synchronize_rcu();
- __ebt_unregister_table(net, table);
-+ } else {
-+ list_add(&table->list, &ebt_net->tables);
-+ }
-+ mutex_unlock(&ebt_mutex);
-
- audit_log_nfcfg(repl->name, AF_BRIDGE, repl->nentries,
- AUDIT_XT_OP_REGISTER, GFP_KERNEL);
-@@ -1339,7 +1337,7 @@ void ebt_unregister_template(const struct ebt_table *t)
- }
- EXPORT_SYMBOL(ebt_unregister_template);
-
--static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-+void ebt_unregister_table_pre_exit(struct net *net, const char *name)
- {
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
- struct ebt_table *t;
-@@ -1348,30 +1346,36 @@ static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
-
- list_for_each_entry(t, &ebt_net->tables, list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &ebt_net->dead_tables);
- mutex_unlock(&ebt_mutex);
-- return t;
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
- }
- }
-
- mutex_unlock(&ebt_mutex);
-- return NULL;
--}
--
--void ebt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct ebt_table *table = __ebt_find_table(net, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
- }
- EXPORT_SYMBOL(ebt_unregister_table_pre_exit);
-
- void ebt_unregister_table(struct net *net, const char *name)
- {
-- struct ebt_table *table = __ebt_find_table(net, name);
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+ struct ebt_table *t;
-
-- if (table)
-- __ebt_unregister_table(net, table);
-+ mutex_lock(&ebt_mutex);
-+
-+ list_for_each_entry(t, &ebt_net->dead_tables, list) {
-+ if (strcmp(t->name, name) == 0) {
-+ list_del(&t->list);
-+ audit_log_nfcfg(t->name, AF_BRIDGE, t->private->nentries,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ __ebt_unregister_table(net, t);
-+ mutex_unlock(&ebt_mutex);
-+ return;
-+ }
-+ }
-+
-+ mutex_unlock(&ebt_mutex);
- }
-
- /* userspace just supplied us with counters */
-@@ -2556,11 +2560,21 @@ static int __net_init ebt_pernet_init(struct net *net)
- struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-
- INIT_LIST_HEAD(&ebt_net->tables);
-+ INIT_LIST_HEAD(&ebt_net->dead_tables);
- return 0;
- }
-
-+static void __net_exit ebt_pernet_exit(struct net *net)
-+{
-+ struct ebt_pernet *ebt_net = net_generic(net, ebt_pernet_id);
-+
-+ WARN_ON_ONCE(!list_empty(&ebt_net->tables));
-+ WARN_ON_ONCE(!list_empty(&ebt_net->dead_tables));
-+}
-+
- static struct pernet_operations ebt_net_ops = {
- .init = ebt_pernet_init,
-+ .exit = ebt_pernet_exit,
- .id = &ebt_pernet_id,
- .size = sizeof(struct ebt_pernet),
- };
---
-2.53.0
-
+++ /dev/null
-From 2bf5b7722bf6803b23acd83a7421e9eba760e47a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Jun 2025 17:44:23 +0200
-Subject: netfilter: Exclude LEGACY TABLES on PREEMPT_RT.
-
-From: Pablo Neira Ayuso <pablo@netfilter.org>
-
-[ Upstream commit 9fce66583f06c212e95e4b76dd61d8432ffa56b6 ]
-
-The seqcount xt_recseq is used to synchronize the replacement of
-xt_table::private in xt_replace_table() against all readers such as
-ipt_do_table()
-
-To ensure that there is only one writer, the writing side disables
-bottom halves. The sequence counter can be acquired recursively. Only the
-first invocation modifies the sequence counter (signaling that a writer
-is in progress) while the following (recursive) writer does not modify
-the counter.
-The lack of a proper locking mechanism for the sequence counter can lead
-to live lock on PREEMPT_RT if the high prior reader preempts the
-writer. Additionally if the per-CPU lock on PREEMPT_RT is removed from
-local_bh_disable() then there is no synchronisation for the per-CPU
-sequence counter.
-
-The affected code is "just" the legacy netfilter code which is replaced
-by "netfilter tables". That code can be disabled without sacrificing
-functionality because everything is provided by the newer
-implementation. This will only requires the usage of the "-nft" tools
-instead of the "-legacy" ones.
-The long term plan is to remove the legacy code so lets accelerate the
-progress.
-
-Relax dependencies on iptables legacy, replace select with depends on,
-this should cause no harm to existing kernel configs and users can still
-toggle IP{6}_NF_IPTABLES_LEGACY in any case.
-Make EBTABLES_LEGACY, IPTABLES_LEGACY and ARPTABLES depend on
-NETFILTER_XTABLES_LEGACY. Hide xt_recseq and its users,
-xt_register_table() and xt_percpu_counter_alloc() behind
-NETFILTER_XTABLES_LEGACY. Let NETFILTER_XTABLES_LEGACY depend on
-!PREEMPT_RT.
-
-This will break selftest expecing the legacy options enabled and will be
-addressed in a following patch.
-
-Co-developed-by: Florian Westphal <fw@strlen.de>
-Co-developed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 10 +++++-----
- net/ipv4/netfilter/Kconfig | 24 ++++++++++++------------
- net/ipv6/netfilter/Kconfig | 19 +++++++++----------
- net/netfilter/Kconfig | 10 ++++++++++
- net/netfilter/x_tables.c | 16 +++++++++++-----
- 5 files changed, 47 insertions(+), 32 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index f16bbbbb94817..60f28e4fb5c0a 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -42,8 +42,8 @@ config NF_CONNTRACK_BRIDGE
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
- tristate "Legacy EBTABLES support"
-- depends on BRIDGE && NETFILTER_XTABLES
-- default n
-+ depends on BRIDGE && NETFILTER_XTABLES_LEGACY
-+ default n
- help
- Legacy ebtables packet/frame classifier.
- This is not needed if you are using ebtables over nftables
-@@ -65,7 +65,7 @@ if BRIDGE_NF_EBTABLES
- #
- config BRIDGE_EBT_BROUTE
- tristate "ebt: broute table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables broute table is used to define rules that decide between
- bridging and routing frames, giving Linux the functionality of a
-@@ -76,7 +76,7 @@ config BRIDGE_EBT_BROUTE
-
- config BRIDGE_EBT_T_FILTER
- tristate "ebt: filter table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables filter table is used to define frame filtering rules at
- local input, forwarding and local output. See the man page for
-@@ -86,7 +86,7 @@ config BRIDGE_EBT_T_FILTER
-
- config BRIDGE_EBT_T_NAT
- tristate "ebt: nat table support"
-- select BRIDGE_NF_EBTABLES_LEGACY
-+ depends on BRIDGE_NF_EBTABLES_LEGACY
- help
- The ebtables nat table is used to define rules that alter the MAC
- source address (MAC SNAT) or the MAC destination address (MAC DNAT).
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index ef8009281da5c..2c438b140e88f 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -13,8 +13,8 @@ config NF_DEFRAG_IPV4
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
- tristate "Legacy IP tables support"
-- default n
-- select NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- iptables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -182,8 +182,8 @@ config IP_NF_MATCH_TTL
- # `filter', generic and specific targets
- config IP_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -220,10 +220,10 @@ config IP_NF_TARGET_SYNPROXY
- config IP_NF_NAT
- tristate "iptables NAT support"
- depends on NF_CONNTRACK
-+ depends on IP_NF_IPTABLES_LEGACY
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -263,8 +263,8 @@ endif # IP_NF_NAT
- # mangle + specific targets
- config IP_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -299,7 +299,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -313,7 +313,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP_NF_IPTABLES_LEGACY
-+ depends on IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -325,8 +325,8 @@ endif # IP_NF_IPTABLES
- # ARP tables
- config IP_NF_ARPTABLES
- tristate "Legacy ARPTABLES support"
-- depends on NETFILTER_XTABLES
-- default n
-+ depends on NETFILTER_XTABLES_LEGACY
-+ default n
- help
- arptables is a legacy packet classifier.
- This is not needed if you are using arptables over nftables
-@@ -342,7 +342,7 @@ config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
- select NETFILTER_FAMILY_ARP
-- depends on NETFILTER_XTABLES
-+ depends on NETFILTER_XTABLES_LEGACY
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index e087a8e97ba78..276860f65baae 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -9,9 +9,8 @@ menu "IPv6: Netfilter Configuration"
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
- tristate "Legacy IP6 tables support"
-- depends on INET && IPV6
-- select NETFILTER_XTABLES
-- default n
-+ depends on INET && IPV6 && NETFILTER_XTABLES_LEGACY
-+ default m if NETFILTER_XTABLES_LEGACY
- help
- ip6tables is a legacy packet classifier.
- This is not needed if you are using iptables over nftables
-@@ -196,8 +195,8 @@ config IP6_NF_TARGET_HL
-
- config IP6_NF_FILTER
- tristate "Packet filtering"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- tristate
- help
- Packet filtering defines a table `filter', which has a series of
-@@ -233,8 +232,8 @@ config IP6_NF_TARGET_SYNPROXY
-
- config IP6_NF_MANGLE
- tristate "Packet mangling"
-- default m if NETFILTER_ADVANCED=n
-- select IP6_NF_IPTABLES_LEGACY
-+ default m if NETFILTER_ADVANCED=n || IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -244,7 +243,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -258,7 +257,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-- select IP6_NF_IPTABLES_LEGACY
-+ depends on IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -269,8 +268,8 @@ config IP6_NF_NAT
- tristate "ip6tables NAT support"
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
-+ depends on IP6_NF_IPTABLES_LEGACY
- select NF_NAT
-- select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index df2dc21304efb..0d1d997abe191 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -762,6 +762,16 @@ config NETFILTER_XTABLES_COMPAT
-
- If unsure, say N.
-
-+config NETFILTER_XTABLES_LEGACY
-+ bool "Netfilter legacy tables support"
-+ depends on !PREEMPT_RT
-+ help
-+ Say Y here if you still require support for legacy tables. This is
-+ required by the legacy tools (iptables-legacy) and is not needed if
-+ you use iptables over nftables (iptables-nft).
-+ Legacy support is not limited to IP, it also includes EBTABLES and
-+ ARPTABLES.
-+
- comment "Xtables combined modules"
-
- config NETFILTER_XT_MARK
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index c1ab85fb8c46d..98384bb17bbe3 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1339,12 +1339,13 @@ void xt_compat_unlock(u_int8_t af)
- EXPORT_SYMBOL_GPL(xt_compat_unlock);
- #endif
-
--DEFINE_PER_CPU(seqcount_t, xt_recseq);
--EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
--
- struct static_key xt_tee_enabled __read_mostly;
- EXPORT_SYMBOL_GPL(xt_tee_enabled);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
-+DEFINE_PER_CPU(seqcount_t, xt_recseq);
-+EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
-+
- static int xt_jumpstack_alloc(struct xt_table_info *i)
- {
- unsigned int size;
-@@ -1536,6 +1537,7 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+#endif
-
- #ifdef CONFIG_PROC_FS
- static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
-@@ -1919,6 +1921,7 @@ void xt_proto_fini(struct net *net, u_int8_t af)
- }
- EXPORT_SYMBOL_GPL(xt_proto_fini);
-
-+#ifdef CONFIG_NETFILTER_XTABLES_LEGACY
- /**
- * xt_percpu_counter_alloc - allocate x_tables rule counter
- *
-@@ -1973,6 +1976,7 @@ void xt_percpu_counter_free(struct xt_counters *counters)
- free_percpu((void __percpu *)pcnt);
- }
- EXPORT_SYMBOL_GPL(xt_percpu_counter_free);
-+#endif
-
- static int __net_init xt_net_init(struct net *net)
- {
-@@ -2005,8 +2009,10 @@ static int __init xt_init(void)
- unsigned int i;
- int rv;
-
-- for_each_possible_cpu(i) {
-- seqcount_init(&per_cpu(xt_recseq, i));
-+ if (IS_ENABLED(CONFIG_NETFILTER_XTABLES_LEGACY)) {
-+ for_each_possible_cpu(i) {
-+ seqcount_init(&per_cpu(xt_recseq, i));
-+ }
- }
-
- xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL);
---
-2.53.0
-
+++ /dev/null
-From b8effb0ad3a9f6fff1b2b97e499104c7b3cbcd34 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 30 Sep 2024 02:58:54 -0700
-Subject: netfilter: Make legacy configs user selectable
-
-From: Breno Leitao <leitao@debian.org>
-
-[ Upstream commit 6c959fd5e17387201dba3619b2e6af213939a0a7 ]
-
-This option makes legacy Netfilter Kconfig user selectable, giving users
-the option to configure iptables without enabling any other config.
-
-Make the following KConfig entries user selectable:
- * BRIDGE_NF_EBTABLES_LEGACY
- * IP_NF_ARPTABLES
- * IP_NF_IPTABLES_LEGACY
- * IP6_NF_IPTABLES_LEGACY
-
-Signed-off-by: Breno Leitao <leitao@debian.org>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/bridge/netfilter/Kconfig | 8 +++++++-
- net/ipv4/netfilter/Kconfig | 16 ++++++++++++++--
- net/ipv6/netfilter/Kconfig | 9 ++++++++-
- 3 files changed, 29 insertions(+), 4 deletions(-)
-
-diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
-index 104c0125e32e8..f16bbbbb94817 100644
---- a/net/bridge/netfilter/Kconfig
-+++ b/net/bridge/netfilter/Kconfig
-@@ -41,7 +41,13 @@ config NF_CONNTRACK_BRIDGE
-
- # old sockopt interface and eval loop
- config BRIDGE_NF_EBTABLES_LEGACY
-- tristate
-+ tristate "Legacy EBTABLES support"
-+ depends on BRIDGE && NETFILTER_XTABLES
-+ default n
-+ help
-+ Legacy ebtables packet/frame classifier.
-+ This is not needed if you are using ebtables over nftables
-+ (iptables-nft).
-
- menuconfig BRIDGE_NF_EBTABLES
- tristate "Ethernet Bridge tables (ebtables) support"
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 1b991b889506a..ef8009281da5c 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -12,7 +12,13 @@ config NF_DEFRAG_IPV4
-
- # old sockopt interface and eval loop
- config IP_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP tables support"
-+ default n
-+ select NETFILTER_XTABLES
-+ help
-+ iptables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
-@@ -318,7 +324,13 @@ endif # IP_NF_IPTABLES
-
- # ARP tables
- config IP_NF_ARPTABLES
-- tristate
-+ tristate "Legacy ARPTABLES support"
-+ depends on NETFILTER_XTABLES
-+ default n
-+ help
-+ arptables is a legacy packet classifier.
-+ This is not needed if you are using arptables over nftables
-+ (iptables-nft).
-
- config NFT_COMPAT_ARP
- tristate
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index f3c8e2d918e13..e087a8e97ba78 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -8,7 +8,14 @@ menu "IPv6: Netfilter Configuration"
-
- # old sockopt interface and eval loop
- config IP6_NF_IPTABLES_LEGACY
-- tristate
-+ tristate "Legacy IP6 tables support"
-+ depends on INET && IPV6
-+ select NETFILTER_XTABLES
-+ default n
-+ help
-+ ip6tables is a legacy packet classifier.
-+ This is not needed if you are using iptables over nftables
-+ (iptables-nft).
-
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
---
-2.53.0
-
+++ /dev/null
-From 76190268d1575a7cf36ebb0f39ebec01c83d384f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:15 +0200
-Subject: netfilter: x_tables: add and use xt_unregister_table_pre_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 527d6931473b75d90e38942aae6537d1a527f1fd ]
-
-Remove the copypasted variants of _pre_exit and add one single
-function in the xtables core. ebtables is not compatible with
-x_tables and therefore unchanged.
-
-This is a preparation patch to reduce noise in the followup
-bug fixes.
-
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 1 +
- include/linux/netfilter_arp/arp_tables.h | 1 -
- include/linux/netfilter_ipv4/ip_tables.h | 1 -
- include/linux/netfilter_ipv6/ip6_tables.h | 1 -
- net/ipv4/netfilter/arp_tables.c | 9 -------
- net/ipv4/netfilter/arptable_filter.c | 2 +-
- net/ipv4/netfilter/ip_tables.c | 9 -------
- net/ipv4/netfilter/iptable_filter.c | 2 +-
- net/ipv4/netfilter/iptable_mangle.c | 2 +-
- net/ipv4/netfilter/iptable_nat.c | 1 +
- net/ipv4/netfilter/iptable_raw.c | 2 +-
- net/ipv4/netfilter/iptable_security.c | 2 +-
- net/ipv6/netfilter/ip6_tables.c | 9 -------
- net/ipv6/netfilter/ip6table_filter.c | 2 +-
- net/ipv6/netfilter/ip6table_mangle.c | 2 +-
- net/ipv6/netfilter/ip6table_nat.c | 1 +
- net/ipv6/netfilter/ip6table_raw.c | 2 +-
- net/ipv6/netfilter/ip6table_security.c | 2 +-
- net/netfilter/x_tables.c | 29 +++++++++++++++++++++++
- 19 files changed, 41 insertions(+), 39 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index 5897f3dbaf7c3..df2022fe440b0 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -310,6 +310,7 @@ struct xt_table *xt_register_table(struct net *net,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
- void *xt_unregister_table(struct xt_table *table);
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
-index a40aaf645fa47..05631a25e6229 100644
---- a/include/linux/netfilter_arp/arp_tables.h
-+++ b/include/linux/netfilter_arp/arp_tables.h
-@@ -53,7 +53,6 @@ int arpt_register_table(struct net *net, const struct xt_table *table,
- const struct arpt_replace *repl,
- const struct nf_hook_ops *ops);
- void arpt_unregister_table(struct net *net, const char *name);
--void arpt_unregister_table_pre_exit(struct net *net, const char *name);
- extern unsigned int arpt_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-
-diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
-index 132b0e4a6d4df..13593391d6058 100644
---- a/include/linux/netfilter_ipv4/ip_tables.h
-+++ b/include/linux/netfilter_ipv4/ip_tables.h
-@@ -26,7 +26,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- const struct ipt_replace *repl,
- const struct nf_hook_ops *ops);
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name);
- void ipt_unregister_table_exit(struct net *net, const char *name);
-
- /* Standard entry. */
-diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
-index 8b8885a73c764..c6d5b927830dd 100644
---- a/include/linux/netfilter_ipv6/ip6_tables.h
-+++ b/include/linux/netfilter_ipv6/ip6_tables.h
-@@ -27,7 +27,6 @@ extern void *ip6t_alloc_initial_table(const struct xt_table *);
- int ip6t_register_table(struct net *net, const struct xt_table *table,
- const struct ip6t_replace *repl,
- const struct nf_hook_ops *ops);
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name);
- void ip6t_unregister_table_exit(struct net *net, const char *name);
- extern unsigned int ip6t_do_table(void *priv, struct sk_buff *skb,
- const struct nf_hook_state *state);
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 564054123772a..9b905c6562313 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1581,15 +1581,6 @@ int arpt_register_table(struct net *net,
- return ret;
- }
-
--void arpt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--EXPORT_SYMBOL(arpt_unregister_table_pre_exit);
--
- void arpt_unregister_table(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 359d00d74095b..382345567a600 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -43,7 +43,7 @@ static int arptable_filter_table_init(struct net *net)
-
- static void __net_exit arptable_filter_net_pre_exit(struct net *net)
- {
-- arpt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_ARP, "filter");
- }
-
- static void __net_exit arptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index fe89a056eb06c..8240b3b0e0260 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1789,14 +1789,6 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ipt_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-@@ -1887,7 +1879,6 @@ static void __exit ip_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ipt_register_table);
--EXPORT_SYMBOL(ipt_unregister_table_pre_exit);
- EXPORT_SYMBOL(ipt_unregister_table_exit);
- EXPORT_SYMBOL(ipt_do_table);
- module_init(ip_tables_init);
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index c03c1a4ea7cab..fb85745793ba5 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -61,7 +61,7 @@ static int __net_init iptable_filter_net_init(struct net *net)
-
- static void __net_exit iptable_filter_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "filter");
- }
-
- static void __net_exit iptable_filter_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index 6a51e61b35562..6259bcf178bba 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -95,7 +95,7 @@ static int iptable_mangle_table_init(struct net *net)
-
- static void __net_exit iptable_mangle_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "mangle");
- }
-
- static void __net_exit iptable_mangle_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index 12ca666d6e2c1..ca6964b957ead 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -129,6 +129,7 @@ static int iptable_nat_table_init(struct net *net)
- static void __net_exit iptable_nat_net_pre_exit(struct net *net)
- {
- ipt_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
- }
-
- static void __net_exit iptable_nat_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index 33330e13ea18d..c7b91b2042dc6 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -53,7 +53,7 @@ static int iptable_raw_table_init(struct net *net)
-
- static void __net_exit iptable_raw_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "raw");
- }
-
- static void __net_exit iptable_raw_net_exit(struct net *net)
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 2b89adc1e5751..81175c20ccbe8 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -50,7 +50,7 @@ static int iptable_security_table_init(struct net *net)
-
- static void __net_exit iptable_security_net_pre_exit(struct net *net)
- {
-- ipt_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "security");
- }
-
- static void __net_exit iptable_security_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index 131f7bb2110d3..c956c2bd73d59 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1795,14 +1795,6 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
- return ret;
- }
-
--void ip6t_unregister_table_pre_exit(struct net *net, const char *name)
--{
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
--
-- if (table)
-- nf_unregister_net_hooks(net, table->ops, hweight32(table->valid_hooks));
--}
--
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-@@ -1894,7 +1886,6 @@ static void __exit ip6_tables_fini(void)
- }
-
- EXPORT_SYMBOL(ip6t_register_table);
--EXPORT_SYMBOL(ip6t_unregister_table_pre_exit);
- EXPORT_SYMBOL(ip6t_unregister_table_exit);
- EXPORT_SYMBOL(ip6t_do_table);
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index 16a38d56b2e54..982900920e730 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -60,7 +60,7 @@ static int __net_init ip6table_filter_net_init(struct net *net)
-
- static void __net_exit ip6table_filter_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "filter");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "filter");
- }
-
- static void __net_exit ip6table_filter_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index 39f0716667131..475361aa81310 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -88,7 +88,7 @@ static int ip6table_mangle_table_init(struct net *net)
-
- static void __net_exit ip6table_mangle_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "mangle");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "mangle");
- }
-
- static void __net_exit ip6table_mangle_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index 52d597b16b658..bef2d309369bc 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -131,6 +131,7 @@ static int ip6table_nat_table_init(struct net *net)
- static void __net_exit ip6table_nat_net_pre_exit(struct net *net)
- {
- ip6t_nat_unregister_lookups(net);
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
- }
-
- static void __net_exit ip6table_nat_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index 01def8aa7a2e8..a99879f173b4a 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -52,7 +52,7 @@ static int ip6table_raw_table_init(struct net *net)
-
- static void __net_exit ip6table_raw_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "raw");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "raw");
- }
-
- static void __net_exit ip6table_raw_net_exit(struct net *net)
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index 66018b169b010..c44834d93fc79 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -49,7 +49,7 @@ static int ip6table_security_table_init(struct net *net)
-
- static void __net_exit ip6table_security_net_pre_exit(struct net *net)
- {
-- ip6t_unregister_table_pre_exit(net, "security");
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "security");
- }
-
- static void __net_exit ip6table_security_net_exit(struct net *net)
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 98384bb17bbe3..670483735d225 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -1537,6 +1537,35 @@ void *xt_unregister_table(struct xt_table *table)
- return private;
- }
- EXPORT_SYMBOL_GPL(xt_unregister_table);
-+
-+/**
-+ * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
-+ * @net: network namespace
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Unregisters the specified netfilter table from the given network namespace
-+ * and also unregisters the hooks from netfilter core: no new packets will be
-+ * processed.
-+ */
-+void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *t;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(t, &xt_net->tables[af], list) {
-+ if (strcmp(t->name, name) == 0) {
-+ mutex_unlock(&xt[af].mutex);
-+
-+ if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-+ nf_unregister_net_hooks(net, t->ops, hweight32(t->valid_hooks));
-+ return;
-+ }
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+}
-+EXPORT_SYMBOL(xt_unregister_table_pre_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
---
-2.53.0
-
+++ /dev/null
-From 47c134bacc6253723f9853513c1cf61bd6d0060a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:17 +0200
-Subject: netfilter: x_tables: add and use xtables_unregister_table_exit
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit b4597d5fd7d2f8cebfffd40dffb5e003cc78964c ]
-
-Previous change added xtables_unregister_table_pre_exit to detach the
-table from the packetpath and to unlink it from the active table list.
-In case of rmmod, userspace that is doing set/getsockopt for this table
-will not be able to re-instantiate the table:
- 1. The larval table has been removed already
- 2. existing instantiated table is no longer on the xt pernet table list.
-
-This adds the second stage helper:
-
-unlink the table from the dying list, free the hook ops (if any) and do
-the audit notification. It replaces xt_unregister_table().
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Reported-by: Tristan Madani <tristan@talencesecurity.com>
-Reviewed-by: Tristan Madani <tristan@talencesecurity.com>
-Closes: https://lore.kernel.org/netfilter-devel/20260429175613.1459342-1-tristmd@gmail.com/
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- include/linux/netfilter/x_tables.h | 2 +-
- net/ipv4/netfilter/arp_tables.c | 9 ++--
- net/ipv4/netfilter/ip_tables.c | 9 ++--
- net/ipv4/netfilter/iptable_nat.c | 5 +-
- net/ipv6/netfilter/ip6_tables.c | 9 ++--
- net/ipv6/netfilter/ip6table_nat.c | 5 +-
- net/netfilter/x_tables.c | 81 +++++++++++++++++++++++-------
- 7 files changed, 83 insertions(+), 37 deletions(-)
-
-diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
-index df2022fe440b0..706f08839050a 100644
---- a/include/linux/netfilter/x_tables.h
-+++ b/include/linux/netfilter/x_tables.h
-@@ -309,8 +309,8 @@ struct xt_table *xt_register_table(struct net *net,
- const struct xt_table *table,
- struct xt_table_info *bootstrap,
- struct xt_table_info *newinfo);
--void *xt_unregister_table(struct xt_table *table);
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name);
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name);
-
- struct xt_table_info *xt_replace_table(struct xt_table *table,
- unsigned int num_counters,
-diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
-index 9b905c6562313..f9dd18244f251 100644
---- a/net/ipv4/netfilter/arp_tables.c
-+++ b/net/ipv4/netfilter/arp_tables.c
-@@ -1501,13 +1501,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
-
- static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
-+ void *loc_cpu_entry;
- struct arpt_entry *iter;
-
-- private = xt_unregister_table(table);
--
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
- xt_entry_foreach(iter, loc_cpu_entry, private->size)
-@@ -1515,6 +1513,7 @@ static void __arpt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int arpt_register_table(struct net *net,
-@@ -1583,7 +1582,7 @@ int arpt_register_table(struct net *net,
-
- void arpt_unregister_table(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_ARP, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_ARP, name);
-
- if (table)
- __arpt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
-index 8240b3b0e0260..02730b6ab8203 100644
---- a/net/ipv4/netfilter/ip_tables.c
-+++ b/net/ipv4/netfilter/ip_tables.c
-@@ -1704,12 +1704,10 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ipt_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1718,6 +1716,7 @@ static void __ipt_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ipt_register_table(struct net *net, const struct xt_table *table,
-@@ -1791,7 +1790,7 @@ int ipt_register_table(struct net *net, const struct xt_table *table,
-
- void ipt_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV4, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV4, name);
-
- if (table)
- __ipt_unregister_table(net, table);
-diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
-index ca6964b957ead..87d934b12bcb6 100644
---- a/net/ipv4/netfilter/iptable_nat.c
-+++ b/net/ipv4/netfilter/iptable_nat.c
-@@ -119,8 +119,11 @@ static int iptable_nat_table_init(struct net *net)
- }
-
- ret = ipt_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV4, "nat");
-+ synchronize_rcu();
- ipt_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
-index c956c2bd73d59..2cbf346940d29 100644
---- a/net/ipv6/netfilter/ip6_tables.c
-+++ b/net/ipv6/netfilter/ip6_tables.c
-@@ -1713,12 +1713,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
-
- static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- {
-- struct xt_table_info *private;
-- void *loc_cpu_entry;
-+ struct xt_table_info *private = table->private;
- struct module *table_owner = table->me;
- struct ip6t_entry *iter;
--
-- private = xt_unregister_table(table);
-+ void *loc_cpu_entry;
-
- /* Decrease module usage counts and free resources */
- loc_cpu_entry = private->entries;
-@@ -1727,6 +1725,7 @@ static void __ip6t_unregister_table(struct net *net, struct xt_table *table)
- if (private->number > private->initial_entries)
- module_put(table_owner);
- xt_free_table_info(private);
-+ kfree(table);
- }
-
- int ip6t_register_table(struct net *net, const struct xt_table *table,
-@@ -1797,7 +1796,7 @@ int ip6t_register_table(struct net *net, const struct xt_table *table,
-
- void ip6t_unregister_table_exit(struct net *net, const char *name)
- {
-- struct xt_table *table = xt_find_table(net, NFPROTO_IPV6, name);
-+ struct xt_table *table = xt_unregister_table_exit(net, NFPROTO_IPV6, name);
-
- if (table)
- __ip6t_unregister_table(net, table);
-diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
-index bef2d309369bc..cf260d8ebdb70 100644
---- a/net/ipv6/netfilter/ip6table_nat.c
-+++ b/net/ipv6/netfilter/ip6table_nat.c
-@@ -121,8 +121,11 @@ static int ip6table_nat_table_init(struct net *net)
- }
-
- ret = ip6t_nat_register_lookups(net);
-- if (ret < 0)
-+ if (ret < 0) {
-+ xt_unregister_table_pre_exit(net, NFPROTO_IPV6, "nat");
-+ synchronize_rcu();
- ip6t_unregister_table_exit(net, "nat");
-+ }
-
- kfree(repl);
- return ret;
-diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
-index 670483735d225..593eb3ebef128 100644
---- a/net/netfilter/x_tables.c
-+++ b/net/netfilter/x_tables.c
-@@ -55,6 +55,9 @@ static struct list_head xt_templates[NFPROTO_NUMPROTO];
-
- struct xt_pernet {
- struct list_head tables[NFPROTO_NUMPROTO];
-+
-+ /* stash area used during netns exit */
-+ struct list_head dead_tables[NFPROTO_NUMPROTO];
- };
-
- struct compat_delta {
-@@ -1521,23 +1524,6 @@ struct xt_table *xt_register_table(struct net *net,
- }
- EXPORT_SYMBOL_GPL(xt_register_table);
-
--void *xt_unregister_table(struct xt_table *table)
--{
-- struct xt_table_info *private;
--
-- mutex_lock(&xt[table->af].mutex);
-- private = table->private;
-- list_del(&table->list);
-- mutex_unlock(&xt[table->af].mutex);
-- audit_log_nfcfg(table->name, table->af, private->number,
-- AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-- kfree(table->ops);
-- kfree(table);
--
-- return private;
--}
--EXPORT_SYMBOL_GPL(xt_unregister_table);
--
- /**
- * xt_unregister_table_pre_exit - pre-shutdown unregister of a table
- * @net: network namespace
-@@ -1547,6 +1533,14 @@ EXPORT_SYMBOL_GPL(xt_unregister_table);
- * Unregisters the specified netfilter table from the given network namespace
- * and also unregisters the hooks from netfilter core: no new packets will be
- * processed.
-+ *
-+ * This must be called prior to xt_unregister_table_exit() from the pernet
-+ * .pre_exit callback. After this call, the table is no longer visible to
-+ * the get/setsockopt path. In case of rmmod, module exit path must have
-+ * called xt_unregister_template() prior to unregistering pernet ops to
-+ * prevent re-instantiation of the table.
-+ *
-+ * See also: xt_unregister_table_exit()
- */
- void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- {
-@@ -1556,6 +1550,7 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_lock(&xt[af].mutex);
- list_for_each_entry(t, &xt_net->tables[af], list) {
- if (strcmp(t->name, name) == 0) {
-+ list_move(&t->list, &xt_net->dead_tables[af]);
- mutex_unlock(&xt[af].mutex);
-
- if (t->ops) /* nat table registers with nat core, t->ops is NULL. */
-@@ -1566,6 +1561,50 @@ void xt_unregister_table_pre_exit(struct net *net, u8 af, const char *name)
- mutex_unlock(&xt[af].mutex);
- }
- EXPORT_SYMBOL(xt_unregister_table_pre_exit);
-+
-+/**
-+ * xt_unregister_table_exit - remove a table during namespace teardown
-+ * @net: the network namespace from which to unregister the table
-+ * @af: address family (e.g., NFPROTO_IPV4, NFPROTO_IPV6)
-+ * @name: name of the table to unregister
-+ *
-+ * Completes the unregister process for a table. This must be called from
-+ * the pernet ops .exit callback. This is the second stage after
-+ * xt_unregister_table_pre_exit().
-+ *
-+ * pair with xt_unregister_table_pre_exit() during namespace shutdown.
-+ *
-+ * Return: the unregistered table or NULL if the table was never
-+ * instantiated. The caller needs to kfree() the table after it
-+ * has removed the family specific matches/targets.
-+ */
-+struct xt_table *xt_unregister_table_exit(struct net *net, u8 af, const char *name)
-+{
-+ struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
-+ struct xt_table *table;
-+
-+ mutex_lock(&xt[af].mutex);
-+ list_for_each_entry(table, &xt_net->dead_tables[af], list) {
-+ struct nf_hook_ops *ops = NULL;
-+
-+ if (strcmp(table->name, name) != 0)
-+ continue;
-+
-+ list_del(&table->list);
-+
-+ audit_log_nfcfg(table->name, table->af, table->private->number,
-+ AUDIT_XT_OP_UNREGISTER, GFP_KERNEL);
-+ swap(table->ops, ops);
-+ mutex_unlock(&xt[af].mutex);
-+
-+ kfree(ops);
-+ return table;
-+ }
-+ mutex_unlock(&xt[af].mutex);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL_GPL(xt_unregister_table_exit);
- #endif
-
- #ifdef CONFIG_PROC_FS
-@@ -2012,8 +2051,10 @@ static int __net_init xt_net_init(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- INIT_LIST_HEAD(&xt_net->tables[i]);
-+ INIT_LIST_HEAD(&xt_net->dead_tables[i]);
-+ }
- return 0;
- }
-
-@@ -2022,8 +2063,10 @@ static void __net_exit xt_net_exit(struct net *net)
- struct xt_pernet *xt_net = net_generic(net, xt_pernet_id);
- int i;
-
-- for (i = 0; i < NFPROTO_NUMPROTO; i++)
-+ for (i = 0; i < NFPROTO_NUMPROTO; i++) {
- WARN_ON_ONCE(!list_empty(&xt_net->tables[i]));
-+ WARN_ON_ONCE(!list_empty(&xt_net->dead_tables[i]));
-+ }
- }
-
- static struct pernet_operations xt_net_ops = {
---
-2.53.0
-
+++ /dev/null
-From 13a37f515950e43f29e085dea0ca998b8925b9d1 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 6 May 2026 12:07:20 +0200
-Subject: netfilter: x_tables: close dangling table module init race
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 16bc4b6686b2c112c10e67d6b493adc3607256d3 ]
-
-Similar to the previous ebtables patch:
-template add exposes the table to userspace, we must do this last to
-rnsure the pernet ops are set up (contain the destructors).
-
-Fixes: fdacd57c79b7 ("netfilter: x_tables: never register tables by default")
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/arptable_filter.c | 23 ++++++++++++-----------
- net/ipv4/netfilter/iptable_filter.c | 23 ++++++++++++-----------
- net/ipv4/netfilter/iptable_mangle.c | 25 +++++++++++++------------
- net/ipv4/netfilter/iptable_raw.c | 22 +++++++++++-----------
- net/ipv4/netfilter/iptable_security.c | 23 ++++++++++++-----------
- net/ipv6/netfilter/ip6table_filter.c | 22 +++++++++++-----------
- net/ipv6/netfilter/ip6table_mangle.c | 23 ++++++++++++-----------
- net/ipv6/netfilter/ip6table_raw.c | 20 ++++++++++----------
- net/ipv6/netfilter/ip6table_security.c | 23 ++++++++++++-----------
- 9 files changed, 105 insertions(+), 99 deletions(-)
-
-diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
-index 382345567a600..370b635e3523b 100644
---- a/net/ipv4/netfilter/arptable_filter.c
-+++ b/net/ipv4/netfilter/arptable_filter.c
-@@ -58,25 +58,26 @@ static struct pernet_operations arptable_filter_net_ops = {
-
- static int __init arptable_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- arptable_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- arpfilter_ops = xt_hook_ops_alloc(&packet_filter, arpt_do_table);
-- if (IS_ERR(arpfilter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(arpfilter_ops))
- return PTR_ERR(arpfilter_ops);
-- }
-
- ret = register_pernet_subsys(&arptable_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter,
-+ arptable_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(arpfilter_ops);
-- return ret;
-+ unregister_pernet_subsys(&arptable_filter_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(arpfilter_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
-index fb85745793ba5..409e96c72164b 100644
---- a/net/ipv4/netfilter/iptable_filter.c
-+++ b/net/ipv4/netfilter/iptable_filter.c
-@@ -77,26 +77,27 @@ static struct pernet_operations iptable_filter_net_ops = {
-
- static int __init iptable_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- iptable_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- filter_ops = xt_hook_ops_alloc(&packet_filter, ipt_do_table);
-- if (IS_ERR(filter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(filter_ops))
- return PTR_ERR(filter_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter,
-+ iptable_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(filter_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_filter_net_ops);
-+ goto err_free;
- }
-
- return 0;
-+err_free:
-+ kfree(filter_ops);
-+ return ret;
- }
-
- static void __exit iptable_filter_fini(void)
-diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
-index 6259bcf178bba..b8618bdf5fdc4 100644
---- a/net/ipv4/netfilter/iptable_mangle.c
-+++ b/net/ipv4/netfilter/iptable_mangle.c
-@@ -110,25 +110,26 @@ static struct pernet_operations iptable_mangle_net_ops = {
-
- static int __init iptable_mangle_init(void)
- {
-- int ret = xt_register_template(&packet_mangler,
-- iptable_mangle_table_init);
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- mangle_ops = xt_hook_ops_alloc(&packet_mangler, iptable_mangle_hook);
-- if (IS_ERR(mangle_ops)) {
-- xt_unregister_template(&packet_mangler);
-- ret = PTR_ERR(mangle_ops);
-- return ret;
-- }
-+ if (IS_ERR(mangle_ops))
-+ return PTR_ERR(mangle_ops);
-
- ret = register_pernet_subsys(&iptable_mangle_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_mangler,
-+ iptable_mangle_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_mangler);
-- kfree(mangle_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_mangle_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(mangle_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
-index c7b91b2042dc6..94ad7fad3a1f3 100644
---- a/net/ipv4/netfilter/iptable_raw.c
-+++ b/net/ipv4/netfilter/iptable_raw.c
-@@ -77,24 +77,24 @@ static int __init iptable_raw_init(void)
- pr_info("Enabling raw table before defrag\n");
- }
-
-- ret = xt_register_template(table,
-- iptable_raw_table_init);
-- if (ret < 0)
-- return ret;
--
- rawtable_ops = xt_hook_ops_alloc(table, ipt_do_table);
-- if (IS_ERR(rawtable_ops)) {
-- xt_unregister_template(table);
-+ if (IS_ERR(rawtable_ops))
- return PTR_ERR(rawtable_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_raw_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(table,
-+ iptable_raw_table_init);
- if (ret < 0) {
-- xt_unregister_template(table);
-- kfree(rawtable_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_raw_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(rawtable_ops);
- return ret;
- }
-
-diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
-index 81175c20ccbe8..491894511c544 100644
---- a/net/ipv4/netfilter/iptable_security.c
-+++ b/net/ipv4/netfilter/iptable_security.c
-@@ -65,25 +65,26 @@ static struct pernet_operations iptable_security_net_ops = {
-
- static int __init iptable_security_init(void)
- {
-- int ret = xt_register_template(&security_table,
-- iptable_security_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- sectbl_ops = xt_hook_ops_alloc(&security_table, ipt_do_table);
-- if (IS_ERR(sectbl_ops)) {
-- xt_unregister_template(&security_table);
-+ if (IS_ERR(sectbl_ops))
- return PTR_ERR(sectbl_ops);
-- }
-
- ret = register_pernet_subsys(&iptable_security_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&security_table,
-+ iptable_security_table_init);
- if (ret < 0) {
-- xt_unregister_template(&security_table);
-- kfree(sectbl_ops);
-- return ret;
-+ unregister_pernet_subsys(&iptable_security_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(sectbl_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
-index 982900920e730..f444071346859 100644
---- a/net/ipv6/netfilter/ip6table_filter.c
-+++ b/net/ipv6/netfilter/ip6table_filter.c
-@@ -76,25 +76,25 @@ static struct pernet_operations ip6table_filter_net_ops = {
-
- static int __init ip6table_filter_init(void)
- {
-- int ret = xt_register_template(&packet_filter,
-- ip6table_filter_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- filter_ops = xt_hook_ops_alloc(&packet_filter, ip6t_do_table);
-- if (IS_ERR(filter_ops)) {
-- xt_unregister_template(&packet_filter);
-+ if (IS_ERR(filter_ops))
- return PTR_ERR(filter_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_filter_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_filter, ip6table_filter_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_filter);
-- kfree(filter_ops);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_filter_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(filter_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
-index 475361aa81310..dbc64e4428403 100644
---- a/net/ipv6/netfilter/ip6table_mangle.c
-+++ b/net/ipv6/netfilter/ip6table_mangle.c
-@@ -103,25 +103,26 @@ static struct pernet_operations ip6table_mangle_net_ops = {
-
- static int __init ip6table_mangle_init(void)
- {
-- int ret = xt_register_template(&packet_mangler,
-- ip6table_mangle_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- mangle_ops = xt_hook_ops_alloc(&packet_mangler, ip6table_mangle_hook);
-- if (IS_ERR(mangle_ops)) {
-- xt_unregister_template(&packet_mangler);
-+ if (IS_ERR(mangle_ops))
- return PTR_ERR(mangle_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_mangle_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&packet_mangler,
-+ ip6table_mangle_table_init);
- if (ret < 0) {
-- xt_unregister_template(&packet_mangler);
-- kfree(mangle_ops);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_mangle_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(mangle_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
-index a99879f173b4a..1eadf553c746e 100644
---- a/net/ipv6/netfilter/ip6table_raw.c
-+++ b/net/ipv6/netfilter/ip6table_raw.c
-@@ -75,24 +75,24 @@ static int __init ip6table_raw_init(void)
- pr_info("Enabling raw table before defrag\n");
- }
-
-- ret = xt_register_template(table, ip6table_raw_table_init);
-- if (ret < 0)
-- return ret;
--
- /* Register hooks */
- rawtable_ops = xt_hook_ops_alloc(table, ip6t_do_table);
-- if (IS_ERR(rawtable_ops)) {
-- xt_unregister_template(table);
-+ if (IS_ERR(rawtable_ops))
- return PTR_ERR(rawtable_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_raw_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(table, ip6table_raw_table_init);
- if (ret < 0) {
-- kfree(rawtable_ops);
-- xt_unregister_template(table);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_raw_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(rawtable_ops);
- return ret;
- }
-
-diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
-index c44834d93fc79..4bd5d97b8ab65 100644
---- a/net/ipv6/netfilter/ip6table_security.c
-+++ b/net/ipv6/netfilter/ip6table_security.c
-@@ -64,25 +64,26 @@ static struct pernet_operations ip6table_security_net_ops = {
-
- static int __init ip6table_security_init(void)
- {
-- int ret = xt_register_template(&security_table,
-- ip6table_security_table_init);
--
-- if (ret < 0)
-- return ret;
-+ int ret;
-
- sectbl_ops = xt_hook_ops_alloc(&security_table, ip6t_do_table);
-- if (IS_ERR(sectbl_ops)) {
-- xt_unregister_template(&security_table);
-+ if (IS_ERR(sectbl_ops))
- return PTR_ERR(sectbl_ops);
-- }
-
- ret = register_pernet_subsys(&ip6table_security_net_ops);
-+ if (ret < 0)
-+ goto err_free;
-+
-+ ret = xt_register_template(&security_table,
-+ ip6table_security_table_init);
- if (ret < 0) {
-- kfree(sectbl_ops);
-- xt_unregister_template(&security_table);
-- return ret;
-+ unregister_pernet_subsys(&ip6table_security_net_ops);
-+ goto err_free;
- }
-
-+ return 0;
-+err_free:
-+ kfree(sectbl_ops);
- return ret;
- }
-
---
-2.53.0
-
+++ /dev/null
-From 67aec5a1e1f22a9082cf7f661a3163bae38a147b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 24 Jan 2024 10:21:11 +0100
-Subject: netfilter: xtables: allow xtables-nft only builds
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit a9525c7f6219cee9284c0031c5930e8d41384677 ]
-
-Add hidden IP(6)_NF_IPTABLES_LEGACY symbol.
-
-When any of the "old" builtin tables are enabled the "old" iptables
-interface will be supported.
-
-To disable the old set/getsockopt interface the existing options
-for the builtin tables need to be turned off:
-
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_FILTER is not set
-CONFIG_IP_NF_NAT is not set
-CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_RAW is not set
-CONFIG_IP_NF_SECURITY is not set
-
-Same for CONFIG_IP6_NF_ variants.
-
-This allows to build a kernel that only supports ip(6)tables-nft
-(iptables-over-nftables api).
-
-In the future the _LEGACY symbol will become visible and the select
-statements will be turned into 'depends on', but for now be on safe side
-so "make oldconfig" won't break things.
-
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 15 ++++++++++++---
- net/ipv4/netfilter/Makefile | 2 +-
- net/ipv6/netfilter/Kconfig | 20 ++++++++++++++------
- net/ipv6/netfilter/Makefile | 2 +-
- net/netfilter/Kconfig | 12 ++++++------
- 5 files changed, 34 insertions(+), 17 deletions(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 070475392236f..7835230872818 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -10,6 +10,10 @@ config NF_DEFRAG_IPV4
- tristate
- default n
-
-+# old sockopt interface and eval loop
-+config IP_NF_IPTABLES_LEGACY
-+ tristate
-+
- config NF_SOCKET_IPV4
- tristate "IPv4 socket lookup support"
- help
-@@ -152,7 +156,7 @@ config IP_NF_MATCH_ECN
- config IP_NF_MATCH_RPFILTER
- tristate '"rpfilter" reverse path filter match support'
- depends on NETFILTER_ADVANCED
-- depends on IP_NF_MANGLE || IP_NF_RAW
-+ depends on IP_NF_MANGLE || IP_NF_RAW || NFT_COMPAT
- help
- This option allows you to match packets whose replies would
- go out via the interface the packet came in.
-@@ -173,6 +177,7 @@ config IP_NF_MATCH_TTL
- config IP_NF_FILTER
- tristate "Packet filtering"
- default m if NETFILTER_ADVANCED=n
-+ select IP_NF_IPTABLES_LEGACY
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -182,7 +187,7 @@ config IP_NF_FILTER
-
- config IP_NF_TARGET_REJECT
- tristate "REJECT target support"
-- depends on IP_NF_FILTER
-+ depends on IP_NF_FILTER || NFT_COMPAT
- select NF_REJECT_IPV4
- default m if NETFILTER_ADVANCED=n
- help
-@@ -212,6 +217,7 @@ config IP_NF_NAT
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -252,6 +258,7 @@ endif # IP_NF_NAT
- config IP_NF_MANGLE
- tristate "Packet mangling"
- default m if NETFILTER_ADVANCED=n
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -261,7 +268,7 @@ config IP_NF_MANGLE
-
- config IP_NF_TARGET_ECN
- tristate "ECN target support"
-- depends on IP_NF_MANGLE
-+ depends on IP_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `ECN' target, which can be used in the iptables mangle
-@@ -286,6 +293,7 @@ config IP_NF_TARGET_TTL
- # raw + specific targets
- config IP_NF_RAW
- tristate 'raw table support (required for NOTRACK/TRACE)'
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to iptables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -299,6 +307,7 @@ config IP_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-+ select IP_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
-index 5a26f9de1ab92..85502d4dfbb4d 100644
---- a/net/ipv4/netfilter/Makefile
-+++ b/net/ipv4/netfilter/Makefile
-@@ -25,7 +25,7 @@ obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o
- obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
-
- # generic IP tables
--obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
-+obj-$(CONFIG_IP_NF_IPTABLES_LEGACY) += ip_tables.o
-
- # the three instances of ip_tables
- obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
-diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
-index 0ba62f4868f97..f3c8e2d918e13 100644
---- a/net/ipv6/netfilter/Kconfig
-+++ b/net/ipv6/netfilter/Kconfig
-@@ -6,6 +6,10 @@
- menu "IPv6: Netfilter Configuration"
- depends on INET && IPV6 && NETFILTER
-
-+# old sockopt interface and eval loop
-+config IP6_NF_IPTABLES_LEGACY
-+ tristate
-+
- config NF_SOCKET_IPV6
- tristate "IPv6 socket lookup support"
- help
-@@ -147,7 +151,7 @@ config IP6_NF_MATCH_MH
- config IP6_NF_MATCH_RPFILTER
- tristate '"rpfilter" reverse path filter match support'
- depends on NETFILTER_ADVANCED
-- depends on IP6_NF_MANGLE || IP6_NF_RAW
-+ depends on IP6_NF_MANGLE || IP6_NF_RAW || NFT_COMPAT
- help
- This option allows you to match packets whose replies would
- go out via the interface the packet came in.
-@@ -186,6 +190,8 @@ config IP6_NF_TARGET_HL
- config IP6_NF_FILTER
- tristate "Packet filtering"
- default m if NETFILTER_ADVANCED=n
-+ select IP6_NF_IPTABLES_LEGACY
-+ tristate
- help
- Packet filtering defines a table `filter', which has a series of
- rules for simple packet filtering at local input, forwarding and
-@@ -195,7 +201,7 @@ config IP6_NF_FILTER
-
- config IP6_NF_TARGET_REJECT
- tristate "REJECT target support"
-- depends on IP6_NF_FILTER
-+ depends on IP6_NF_FILTER || NFT_COMPAT
- select NF_REJECT_IPV6
- default m if NETFILTER_ADVANCED=n
- help
-@@ -221,6 +227,7 @@ config IP6_NF_TARGET_SYNPROXY
- config IP6_NF_MANGLE
- tristate "Packet mangling"
- default m if NETFILTER_ADVANCED=n
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `mangle' table to iptables: see the man page for
- iptables(8). This table is used for various packet alterations
-@@ -230,6 +237,7 @@ config IP6_NF_MANGLE
-
- config IP6_NF_RAW
- tristate 'raw table support (required for TRACE)'
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `raw' table to ip6tables. This table is the very
- first in the netfilter framework and hooks in at the PREROUTING
-@@ -243,6 +251,7 @@ config IP6_NF_SECURITY
- tristate "Security table"
- depends on SECURITY
- depends on NETFILTER_ADVANCED
-+ select IP6_NF_IPTABLES_LEGACY
- help
- This option adds a `security' table to iptables, for use
- with Mandatory Access Control (MAC) policy.
-@@ -254,6 +263,7 @@ config IP6_NF_NAT
- depends on NF_CONNTRACK
- depends on NETFILTER_ADVANCED
- select NF_NAT
-+ select IP6_NF_IPTABLES_LEGACY
- select NETFILTER_XT_NAT
- help
- This enables the `nat' table in ip6tables. This allows masquerading,
-@@ -262,25 +272,23 @@ config IP6_NF_NAT
-
- To compile it as a module, choose M here. If unsure, say N.
-
--if IP6_NF_NAT
--
- config IP6_NF_TARGET_MASQUERADE
- tristate "MASQUERADE target support"
- select NETFILTER_XT_TARGET_MASQUERADE
-+ depends on IP6_NF_NAT
- help
- This is a backwards-compat option for the user's convenience
- (e.g. when running oldconfig). It selects NETFILTER_XT_TARGET_MASQUERADE.
-
- config IP6_NF_TARGET_NPT
- tristate "NPT (Network Prefix translation) target support"
-+ depends on IP6_NF_NAT || NFT_COMPAT
- help
- This option adds the `SNPT' and `DNPT' target, which perform
- stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
-
- To compile it as a module, choose M here. If unsure, say N.
-
--endif # IP6_NF_NAT
--
- endif # IP6_NF_IPTABLES
- endmenu
-
-diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
-index b8d6dc9aeeb6f..66ce6fa5b2f52 100644
---- a/net/ipv6/netfilter/Makefile
-+++ b/net/ipv6/netfilter/Makefile
-@@ -4,7 +4,7 @@
- #
-
- # Link order matters here.
--obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
-+obj-$(CONFIG_IP6_NF_IPTABLES_LEGACY) += ip6_tables.o
- obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
- obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
- obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
-diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
-index 441d1f1341100..df2dc21304efb 100644
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -818,7 +818,7 @@ config NETFILTER_XT_TARGET_AUDIT
-
- config NETFILTER_XT_TARGET_CHECKSUM
- tristate "CHECKSUM target support"
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `CHECKSUM' target, which can be used in the iptables mangle
-@@ -869,7 +869,7 @@ config NETFILTER_XT_TARGET_CONNSECMARK
- config NETFILTER_XT_TARGET_CT
- tristate '"CT" target support'
- depends on NF_CONNTRACK
-- depends on IP_NF_RAW || IP6_NF_RAW
-+ depends on IP_NF_RAW || IP6_NF_RAW || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This options adds a `CT' target, which allows to specify initial
-@@ -880,7 +880,7 @@ config NETFILTER_XT_TARGET_CT
-
- config NETFILTER_XT_TARGET_DSCP
- tristate '"DSCP" and "TOS" target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a `DSCP' target, which allows you to manipulate
-@@ -896,7 +896,7 @@ config NETFILTER_XT_TARGET_DSCP
-
- config NETFILTER_XT_TARGET_HL
- tristate '"HL" hoplimit target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds the "HL" (for IPv6) and "TTL" (for IPv4)
-@@ -1080,7 +1080,7 @@ config NETFILTER_XT_TARGET_TPROXY
- depends on NETFILTER_ADVANCED
- depends on IPV6 || IPV6=n
- depends on IP6_NF_IPTABLES || IP6_NF_IPTABLES=n
-- depends on IP_NF_MANGLE
-+ depends on IP_NF_MANGLE || NFT_COMPAT
- select NF_DEFRAG_IPV4
- select NF_DEFRAG_IPV6 if IP6_NF_IPTABLES != n
- select NF_TPROXY_IPV4
-@@ -1147,7 +1147,7 @@ config NETFILTER_XT_TARGET_TCPMSS
-
- config NETFILTER_XT_TARGET_TCPOPTSTRIP
- tristate '"TCPOPTSTRIP" target support'
-- depends on IP_NF_MANGLE || IP6_NF_MANGLE
-+ depends on IP_NF_MANGLE || IP6_NF_MANGLE || NFT_COMPAT
- depends on NETFILTER_ADVANCED
- help
- This option adds a "TCPOPTSTRIP" target, which allows you to strip
---
-2.53.0
-
+++ /dev/null
-From 152783ad008bcb793a21b8fc2186ae17cd702d56 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 6 Feb 2024 14:55:53 +0100
-Subject: netfilter: xtables: fix up kconfig dependencies
-
-From: Florian Westphal <fw@strlen.de>
-
-[ Upstream commit 749d4ef0868c5d8a98e07073791b2198178c93b4 ]
-
-Randy Dunlap reports arptables build failure:
-arp_tables.c:(.text+0x20): undefined reference to `xt_find_table'
-
-... because recent change removed a 'select' on the xtables core.
-Add a "depends" clause on arptables to resolve this.
-
-Kernel test robot reports another build breakage:
-iptable_nat.c:(.text+0x8): undefined reference to `ipt_unregister_table_exit'
-
-... because of a typo, the nat table selected ip6tables.
-
-Reported-by: kernel test robot <lkp@intel.com>
-Reported-by: Randy Dunlap <rdunlap@infradead.org>
-Closes: https://lore.kernel.org/netfilter-devel/d0dfbaef-046a-4c42-9daa-53636664bf6d@infradead.org/
-Fixes: a9525c7f6219 ("netfilter: xtables: allow xtables-nft only builds")
-Fixes: 4654467dc7e1 ("netfilter: arptables: allow xtables-nft only builds")
-Acked-by: Randy Dunlap <rdunlap@infradead.org>
-Tested-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
-Signed-off-by: Florian Westphal <fw@strlen.de>
-Stable-dep-of: b4597d5fd7d2 ("netfilter: x_tables: add and use xtables_unregister_table_exit")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- net/ipv4/netfilter/Kconfig | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
-index 7835230872818..8f6e950163a79 100644
---- a/net/ipv4/netfilter/Kconfig
-+++ b/net/ipv4/netfilter/Kconfig
-@@ -217,7 +217,7 @@ config IP_NF_NAT
- default m if NETFILTER_ADVANCED=n
- select NF_NAT
- select NETFILTER_XT_NAT
-- select IP6_NF_IPTABLES_LEGACY
-+ select IP_NF_IPTABLES_LEGACY
- help
- This enables the `nat' table in iptables. This allows masquerading,
- port forwarding and other forms of full Network Address Port
-@@ -329,6 +329,7 @@ config NFT_COMPAT_ARP
- config IP_NF_ARPFILTER
- tristate "arptables-legacy packet filtering support"
- select IP_NF_ARPTABLES
-+ depends on NETFILTER_XTABLES
- help
- ARP packet filtering defines a table `filter', which has a series of
- rules for simple ARP packet filtering at local input and
---
-2.53.0
-
alsa-hda-cs35l56-put-acpi-device-after-setting-compa.patch
btrfs-tracepoints-fix-sleep-while-in-atomic-context-.patch
netfilter-x_tables-unregister-the-templates-first.patch
-netfilter-arptables-allow-xtables-nft-only-builds.patch
-netfilter-xtables-allow-xtables-nft-only-builds.patch
-netfilter-ebtables-allow-xtables-nft-only-builds.patch
-netfilter-xtables-fix-up-kconfig-dependencies.patch
-netfilter-arptables-select-netfilter_family_arp-when.patch
-netfilter-make-legacy-configs-user-selectable.patch
-netfilter-exclude-legacy-tables-on-preempt_rt.patch
-netfilter-x_tables-add-and-use-xt_unregister_table_p.patch
-netfilter-x_tables-add-and-use-xtables_unregister_ta.patch
-netfilter-ebtables-move-to-two-stage-removal-scheme.patch
-netfilter-ebtables-close-dangling-table-module-init-.patch
-netfilter-x_tables-close-dangling-table-module-init-.patch
-netfilter-bridge-eb_tables-close-module-init-race.patch
kprobes-skip-non-symbol-addresses-in-kprobe_add_ksym.patch
test_kprobes-clear-kprobes-between-test-runs.patch
tcp-fix-imbalanced-icsk_accept_queue-count.patch
5.4 0a58d2ae572adaec8d046f8d35b40c2c32ac7468
5.4 0a5e9306b812fe3517548fab92b3d3d6ce7576e5
314ba9d9255ff1f624228e2acf71db22c60acec0
+6.1 069daad4f2ae9c5c108131995529d5f02392c446
+5.15 069daad4f2ae9c5c108131995529d5f02392c446
+5.10 069daad4f2ae9c5c108131995529d5f02392c446
+5.10 215e5fe75881a7e2425df04aeeed47a903d5cd5d
+5.15 215e5fe75881a7e2425df04aeeed47a903d5cd5d
+6.1 215e5fe75881a7e2425df04aeeed47a903d5cd5d
+6.1 24d2d3c5f94007a5a0554065ab7349bb69e28bcb
+5.15 24d2d3c5f94007a5a0554065ab7349bb69e28bcb
+5.15 a8cc55bf81a45772cad44c83ea7bb0e98431094a
+5.10 758dbc756aad429da11c569c0d067f7fd032bcf7
+5.10 0e2ee70291e64a30fe36960c85294726d34a103e
+5.10 b97053df0f04747c3c1e021ecbe99db675342954
+5.10 778d8c1b2a6ffe622ddcd3bb35b620e6e41f4da0
+5.15 778d8c1b2a6ffe622ddcd3bb35b620e6e41f4da0
+5.10 bdbfead6d38979475df0c2f4bad2b19394fe9bdc
+5.10 e63fb1379f4b9300a44739964e69549bebbcdca4
+6.12 6c959fd5e17387201dba3619b2e6af213939a0a7
+6.12 9fce66583f06c212e95e4b76dd61d8432ffa56b6
+6.12 527d6931473b75d90e38942aae6537d1a527f1fd
+6.12 b4597d5fd7d2f8cebfffd40dffb5e003cc78964c
+6.12 b7f0544d86d439cb946515d2ef6a0a75e8626710
+6.12 92c603fa07bc0d6a17345de3ad7954730b8de44b
+6.12 16bc4b6686b2c112c10e67d6b493adc3607256d3
+6.12 27414ff1b287ea9a2a11675149ec28e05539f3cc
+6.6 4654467dc7e111e84f43ed1b70322873ae77e7be
+6.6 a9525c7f6219cee9284c0031c5930e8d41384677
+6.6 7ad269787b6615ca56bb161063331991fce51abf
+6.6 749d4ef0868c5d8a98e07073791b2198178c93b4
+6.6 15fba562f7a9f04322b8bfc8f392e04bb93d81be
+6.6 6c959fd5e17387201dba3619b2e6af213939a0a7
+6.6 9fce66583f06c212e95e4b76dd61d8432ffa56b6
+6.6 527d6931473b75d90e38942aae6537d1a527f1fd
+6.6 b4597d5fd7d2f8cebfffd40dffb5e003cc78964c
+6.6 b7f0544d86d439cb946515d2ef6a0a75e8626710
+6.6 92c603fa07bc0d6a17345de3ad7954730b8de44b
+6.6 16bc4b6686b2c112c10e67d6b493adc3607256d3
+6.6 27414ff1b287ea9a2a11675149ec28e05539f3cc
+6.1 4654467dc7e111e84f43ed1b70322873ae77e7be
+6.1 a9525c7f6219cee9284c0031c5930e8d41384677
+6.1 7ad269787b6615ca56bb161063331991fce51abf
+6.1 749d4ef0868c5d8a98e07073791b2198178c93b4
+6.1 15fba562f7a9f04322b8bfc8f392e04bb93d81be
+6.1 6c959fd5e17387201dba3619b2e6af213939a0a7
+6.1 9fce66583f06c212e95e4b76dd61d8432ffa56b6
+6.1 527d6931473b75d90e38942aae6537d1a527f1fd
+6.1 b4597d5fd7d2f8cebfffd40dffb5e003cc78964c
+6.1 b7f0544d86d439cb946515d2ef6a0a75e8626710
+6.1 92c603fa07bc0d6a17345de3ad7954730b8de44b
+6.1 16bc4b6686b2c112c10e67d6b493adc3607256d3
+6.1 27414ff1b287ea9a2a11675149ec28e05539f3cc
+5.15 e8d225b6002673366abc2e40e30c991bdc8d62ca
+5.15 4654467dc7e111e84f43ed1b70322873ae77e7be
+5.15 a9525c7f6219cee9284c0031c5930e8d41384677
+5.15 7ad269787b6615ca56bb161063331991fce51abf
+5.15 749d4ef0868c5d8a98e07073791b2198178c93b4
+5.15 15fba562f7a9f04322b8bfc8f392e04bb93d81be
+5.15 6c959fd5e17387201dba3619b2e6af213939a0a7
+5.15 9fce66583f06c212e95e4b76dd61d8432ffa56b6
+5.15 527d6931473b75d90e38942aae6537d1a527f1fd
+5.15 b4597d5fd7d2f8cebfffd40dffb5e003cc78964c
+5.15 b7f0544d86d439cb946515d2ef6a0a75e8626710
+5.15 92c603fa07bc0d6a17345de3ad7954730b8de44b
+5.15 27414ff1b287ea9a2a11675149ec28e05539f3cc