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
`Conn.AddTable` use netlink.Create which will not emit an error
if the table we want to create already existed,
just like the `nft add table ...` command works.
The caller should use netlink.Excl to
get an EEXIST error for that already existed,
So I add another method `Conn.CreateTable`
which works just like `nft create table ...` command.
Related: #245
Signed-off-by: black-desk <me@black-desk.cn>
Related: #242
After 7879d7ecf6, it seems that
any multi-message operation performed without CAP_SYS_ADMIN will
leads to forever block inside nftables.Conn.Flush.
For example:
```go
package main
import "github.com/google/nftables"
func main() {
conn, err := nftables.New()
if err != nil {
panic(err)
}
t := conn.AddTable(&nftables.Table{})
err = conn.AddSet(&nftables.Set{Table: t}, []nftables.SetElement{})
if err != nil {
panic(err)
}
conn.AddSet(&nftables.Set{Table: t}, []nftables.SetElement{})
if err != nil {
panic(err)
}
err = conn.Flush()
if err != nil {
panic(err)
}
return
}
```
That's because that although we send multiple messages on netlink
socket, kernel will only sends one permission error message as reply.
Signed-off-by: black-desk <me@black-desk.cn>