Open JeroenvIS opened 1 year ago
The ffi_prep_cif_var
probably originates somewhere within ctypes. Exact error unclear, not sure how to proceed in debugging. Added some print statements in #6b22a36 and tried to use more strict ctype casts on arguments, but that doesn't help.
Output with extra print statements from #6b22a36:
(venv) root@sflow:/home/jeroen/code/pynetfilter_conntrack# ./expect.py
__setattr__: orig_l3proto, 2, 2, (15, 8)
_setAttr: name orig_l3proto, attrid 15, value 2, handle <pynetfilter_conntrack.func.LP_nf_conntrack object at 0x7f6663d97d40>
Traceback (most recent call last):
File "/home/jeroen/code/pynetfilter_conntrack/./expect.py", line 97, in <module>
main()
File "/home/jeroen/code/pynetfilter_conntrack/./expect.py", line 92, in main
create_conntrack()
File "/home/jeroen/code/pynetfilter_conntrack/./expect.py", line 31, in create_conntrack
master.orig_l3proto = AF_INET
File "/home/jeroen/code/pynetfilter_conntrack/pynetfilter_conntrack/conntrack_entry.py", line 95, in __setattr__
self._setAttr(name, value)
File "/home/jeroen/code/pynetfilter_conntrack/pynetfilter_conntrack/conntrack_entry.py", line 82, in _setAttr
setter(self._handle, attrid, value)
RuntimeError: ffi_prep_cif_var failed
The issue occurs when setting the address family. If that is skipped by commenting out https://github.com/JeroenvIS/pynetfilter_conntrack/blob/6b22a36959f78d9b49b6a5b738f0257db23ecb68/expect.py#L31 , setting the IP addresses succeeds and the RuntimeError happens when we try to set the L4 protocol:
(venv) root@sflow:/home/jeroen/code/pynetfilter_conntrack# ./expect.py
__setattr__: orig_ipv4_src, 172.16.127.201, 172.16.127.201, (0, 32)
_setAttr: name orig_ipv4_src, attrid 0, value 3380547756, handle <pynetfilter_conntrack.func.LP_nf_conntrack object at 0x7f0837673d40>
__setattr__: orig_ipv4_dst, 204.152.191.36, 204.152.191.36, (1, 32)
_setAttr: name orig_ipv4_dst, attrid 1, value 616536268, handle <pynetfilter_conntrack.func.LP_nf_conntrack object at 0x7f0837673d40>
__setattr__: orig_l4proto, 6, 6, (17, 8)
_setAttr: name orig_l4proto, attrid 17, value 6, handle <pynetfilter_conntrack.func.LP_nf_conntrack object at 0x7f0837673d40>
Traceback (most recent call last):
File "/home/jeroen/code/pynetfilter_conntrack/./expect.py", line 97, in <module>
main()
File "/home/jeroen/code/pynetfilter_conntrack/./expect.py", line 92, in main
create_conntrack()
File "/home/jeroen/code/pynetfilter_conntrack/./expect.py", line 34, in create_conntrack
master.orig_l4proto = IPPROTO_TCP
File "/home/jeroen/code/pynetfilter_conntrack/pynetfilter_conntrack/conntrack_entry.py", line 95, in __setattr__
self._setAttr(name, value)
File "/home/jeroen/code/pynetfilter_conntrack/pynetfilter_conntrack/conntrack_entry.py", line 82, in _setAttr
setter(self._handle, attrid, value)
RuntimeError: ffi_prep_cif_var failed
That tells us:
Perhaps this change in libffi-3.4.2 (https://github.com/libffi/libffi/releases/tag/v3.4.2) is relevant:
Reject float and small integer argument in ffi_prep_cif_var(). Callers must promote these types themselves.
I did a bit of digging around to see what is going on, and found this page: https://netfilter.org/projects/libnetfilter_conntrack/doxygen/html/group__ct.html
From what I can see, there is a function: nfct_set_attr_u8 (struct nf_conntrack *ct, const enum nf_conntrack_attr type, uint8_t value)
Checking the python code, it looks like the setter only has two arguments (instead of the three I've found here).
As discussed offline with @ylebre : setting IP protocol and L4 protocol succeeds when using nfct_set_attr_u32
for 8-bit attributes. Then the 16-bit items fail, and there the same fix helps.
With the two simple changes in #a6022a5, all the _setAttr calls resulting from creating the "master" conntrack entry succeed,
Now the expect.py fails at the last step of creating the Expect entry, but that's a different issue.
The expect.py example code gives a RunTimeError in conntrack_entry.py:
Environment: