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.
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 SNATIt'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:
It works well, but there might be a cleaner way to handle this (?)