Skip to content

[AI] Unified IPv4/IPv6 libxt_NAT.so support (Ubuntu 24.04+)#360

Open
vpnable wants to merge 1 commit into
ldx:masterfrom
vpnable:master
Open

[AI] Unified IPv4/IPv6 libxt_NAT.so support (Ubuntu 24.04+)#360
vpnable wants to merge 1 commit into
ldx:masterfrom
vpnable:master

Conversation

@vpnable

@vpnable vpnable commented Jun 21, 2026

Copy link
Copy Markdown

Note: the code is AI-generated and is maybe not so nice

On Ubuntu 24.04+, creating a NAT target for both IPv4 and IPv6 raises an error:
import iptc; iptc.iptc.Rule6().create_target('SNAT'); iptc.iptc.Rule().create_target('SNAT')
or vice-verse:
import iptc; iptc.iptc.Rule().create_target('SNAT'); iptc.iptc.Rule6().create_target('SNAT')

Traceback (most recent call last):
  File "site-packages/iptc/ip4tc.py", line 1013, in create_target
    target = Target(selt, name=name, revision=revision, goto=goto)
  File "site-packages/iptc/ip4tc.py", line 737, in _init_
    raise XTablesError("can't find target %s" % (name))
iptc.errors.XTablesError: can't find target SNAT

It's because iptables used to have separate shared libraries for IPv4 and IPv6 (e.g., libipt_SNAT.so and libip6t_SNAT.so). On Ubuntu 24.04+, an unified shared library is used via symlinks to libxt_NAT.so for both protocols (provided by the iptables package)

When python-iptables attempts to load an extension for one protocol and then subsequently the other, dlopen returns the cached library handle without re-running the C constructor -> the structures for the second protocol are never generated, resulting in an XTablesError.

This patch works by:

  1. Resolving .so symlinks to reliably locate the real C init fn.
  2. Temporarily unlinking existing targets from the global xtables pending lists to execute the constructor a second time without triggering a fatal "target already registered" C crash.
  3. Adding a manual pure-Python ctypes list search as a fallback to bypass internal negative caching in xtables_find_target.

It works well, but there might be a cleaner way to handle this (?)

Historically, iptables used separate shared libraries for IPv4 and IPv6 (e.g., libipt_SNAT.so and libip6t_SNAT.so).
On Ubuntu 24.04+, an unified shared library is used via symlinks to libxt_NAT.so for both protocols.

When python-iptables attempts to load an extension for one protocol and then subsequently the other, dlopen returns the cached library handle without re-running the C constructor -> the structures for the second protocol are never generated, resulting in an XTablesError.

> import iptc; iptc.iptc.Rule6().create_target('SNAT'); iptc.iptc.Rule().create_target('SNAT')
Traceback (most recent call last):
  File "site-packages/iptc/ip4tc.py", line 1013, in create_target
    target = Target(selt, name=name, revision=revision, goto=goto)
  File "site-packages/iptc/ip4tc.py", line 737, in _init_
    raise XTablesError("can't find target %s" % (name))
iptc.errors.XTablesError: can't find target SNAT

This patch works by:
1. Resolving .so symlinks to reliably locate the real C init fn.
2. Temporarily unlinking existing targets from the global xtables pending lists to execute the constructor a second time without triggering a fatal "target already registered" C crash.
3. Adding a manual pure-Python ctypes list search as a fallback to bypass internal negative caching in xtables_find_target.
@vpnable vpnable changed the title [AI] Unified IPv4+IPv6 libxt_NAT.so support (Ubuntu 24.04+) [AI] Unified IPv4/IPv6 libxt_NAT.so support (Ubuntu 24.04+) Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant