The functionality added in a46119e5 never worked: If you set
NFTA_RULE_POSITION to 0, the kernel will just complain that a rule with
this handle does not exist. This removes the broken functionality,
leaving the field deprecated.
The right way to insert a rule at the beginning of a chain is to use
InsertRule and leave Position unset.
https://github.com/google/nftables/issues/126 mentions that the nft
command allows referring to rules by index. But here is a quote from the
nft manpage:
> The add and insert commands support an optional location specifier,
> which is either a handle or the index (starting at zero) of an
> existing rule. Internally, rule locations are always identified by
> handle and the translation from index happens in userspace.
In other words, identifiying rules by index is a feature of nft and is
not part of the kernel interface.
The following keys were missing from the CtKey type:
- `NFT_CT_SRC_IP`
- `NFT_CT_DST_IP`
- `NFT_CT_SRC_IP6`
- `NFT_CT_DST_IP6`
- `NFT_CT_ID`
Since they also seem to be missing from the unix package, their actual
values were added.
This change makes it possible to delete rules after inserting them,
without needing to query the rules first. Additionally, this allows
positioning a new rule next to an existing rule.
There are two ways to refer to a rule: Either by ID or by handle. The ID
is assigned by userspace, and is only valid within a transaction, so it
can only be used before the flush. The handle is assigned by the kernel
when the transaction is committed, and can thus only be used after the
flush. We thus need to set an ID on each newly created rule, and
retrieve the handle of the rule during the flush.
I extended the message struct with a pointer to the Rule which the
message creates. This allows calling the reply handler callback which
sets the handle.
I updated tests to add a handle to generated replies for the
NFT_MSG_NEWRULE messages.
Commit 0d9bfa4d18 added code to handle "overrun", but the commit is
very misleading. NLMSG_OVERRUN is in fact not a flag, but a complete
message type, so the (re&netlink.Overrun) masking makes no sense. Even
better, NLMSG_OVERRUN is never actually used by Linux.
The actual bug which the commit was attempting to fix is that Flush was
not receiving replies which the kernel sent for messages with the echo
flag. This change reverts that commit and instead adds code in Flush to
receive the replies.
I updated tests which simulate the kernel to generate replies.
The ID allows referring to a rule before it is committed, as
demonstrated in the newly added test.
I had to update all existing tests which compared generated netlink
messages against a reference, by inserting the newly added ID attribute.
There was an existing mechanism to allocate IDs for sets, but this was
using a global counter without any synchronization to prevent data
races. I replaced this by a new mechanism which uses a connection-scoped
counter, protected by the Conn.mu Mutex. This can then also be used in
other places where IDs need to be allocated.
As an additional safeguard, it will panic instead of allocating the same
ID twice in a transaction. Most likely, your program will run out of
memory before reaching this point.
If the number of elements to be added to or removed from a set is large,
they may not all fit into one message, because the size field of a
netlink attribute is a uint16 and would overflow. To support this case,
the elements need to be split into multiple batches.
This commit adds integration tests to the nftables package to verify
that the Go code correctly programs nftables rules. The tests use
external nftables scripts to define the expected state and compare
it with the state produced by the Go code.
Change-Id: I9c8439ee462b4882b221e6244f53379b822446dc
Signed-off-by: Antonio Ojea <aojea@google.com>
Turns out we cannot make github.com/google/nftables/binaryutil
forward to encoding/binary because it’s not an API-compatible
drop-in replacement: The PutUint* methods allocate in our API,
but do not allocate in encoding/binary.
* fix: resolve deadlock in `Flush` function when handling ENOBUFS error
* Simulate deadlock issue using reduced read/write buffers to verify the fix and ensure no regressions
Note that this will fix support for single expressions on older kernels but multiple expressions on older kernels will remain unsupported as NFT_DYNSET_F_EXPR flag should not be omitted for dynsets with multiple expressions.
* Refactored obj.go to a more generic approach
* Added object support for already implemented expressions
* Added test for limit object
fixes https://github.com/google/nftables/issues/253