Merge 54b203b3ed
into 5e242ec578
This commit is contained in:
commit
aae6a4edc8
17
counter.go
17
counter.go
|
@ -16,11 +16,12 @@ package nftables
|
|||
|
||||
import (
|
||||
"github.com/google/nftables/binaryutil"
|
||||
"github.com/google/nftables/expr"
|
||||
"github.com/mdlayher/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// CounterObj implements Obj.
|
||||
// Deprecated: Use ObjAttr instead
|
||||
type CounterObj struct {
|
||||
Table *Table
|
||||
Name string // e.g. “fwded”
|
||||
|
@ -41,6 +42,20 @@ func (c *CounterObj) unmarshal(ad *netlink.AttributeDecoder) error {
|
|||
return ad.Err()
|
||||
}
|
||||
|
||||
func (c *CounterObj) data() expr.Any {
|
||||
return &expr.Counter{
|
||||
Bytes: c.Bytes,
|
||||
Packets: c.Packets,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CounterObj) name() string {
|
||||
return c.Name
|
||||
}
|
||||
func (c *CounterObj) objType() ObjType {
|
||||
return ObjTypeCounter
|
||||
}
|
||||
|
||||
func (c *CounterObj) table() *Table {
|
||||
return c.Table
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ type Bitwise struct {
|
|||
Xor []byte
|
||||
}
|
||||
|
||||
func (e *Bitwise) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Bitwise) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
mask, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_DATA_VALUE, Data: e.Mask},
|
||||
})
|
||||
|
@ -54,6 +54,9 @@ func (e *Bitwise) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("bitwise\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestBitwise(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
nbw := Bitwise{}
|
||||
data, err := tt.bw.marshal(0 /* don't care in this test */)
|
||||
data, err := tt.bw.marshal(0 /* don't care in this test */, false)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal error: %+v", err)
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ type Byteorder struct {
|
|||
Size uint32
|
||||
}
|
||||
|
||||
func (e *Byteorder) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Byteorder) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_BYTEORDER_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)},
|
||||
{Type: unix.NFTA_BYTEORDER_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)},
|
||||
|
@ -48,6 +48,9 @@ func (e *Byteorder) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("byteorder\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -36,7 +36,7 @@ type Connlimit struct {
|
|||
Flags uint32
|
||||
}
|
||||
|
||||
func (e *Connlimit) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Connlimit) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: NFTA_CONNLIMIT_COUNT, Data: binaryutil.BigEndian.PutUint32(e.Count)},
|
||||
{Type: NFTA_CONNLIMIT_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)},
|
||||
|
@ -44,6 +44,9 @@ func (e *Connlimit) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("connlimit\x00")},
|
||||
|
|
|
@ -27,7 +27,7 @@ type Counter struct {
|
|||
Packets uint64
|
||||
}
|
||||
|
||||
func (e *Counter) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Counter) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_COUNTER_BYTES, Data: binaryutil.BigEndian.PutUint64(e.Bytes)},
|
||||
{Type: unix.NFTA_COUNTER_PACKETS, Data: binaryutil.BigEndian.PutUint64(e.Packets)},
|
||||
|
@ -35,6 +35,9 @@ func (e *Counter) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("counter\x00")},
|
||||
|
|
|
@ -63,8 +63,8 @@ type Ct struct {
|
|||
Key CtKey
|
||||
}
|
||||
|
||||
func (e *Ct) marshal(fam byte) ([]byte, error) {
|
||||
regData := []byte{}
|
||||
func (e *Ct) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
var regData []byte
|
||||
exprData, err := netlink.MarshalAttributes(
|
||||
[]netlink.Attribute{
|
||||
{Type: unix.NFTA_CT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
||||
|
@ -90,6 +90,9 @@ func (e *Ct) marshal(fam byte) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
exprData = append(exprData, regData...)
|
||||
if dataOnly {
|
||||
return exprData, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("ct\x00")},
|
||||
|
|
|
@ -28,7 +28,7 @@ type Dup struct {
|
|||
IsRegDevSet bool
|
||||
}
|
||||
|
||||
func (e *Dup) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Dup) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_DUP_SREG_ADDR, Data: binaryutil.BigEndian.PutUint32(e.RegAddr)},
|
||||
}
|
||||
|
@ -38,10 +38,12 @@ func (e *Dup) marshal(fam byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
data, err := netlink.MarshalAttributes(attrs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("dup\x00")},
|
||||
|
|
|
@ -43,7 +43,7 @@ type Dynset struct {
|
|||
Exprs []Any
|
||||
}
|
||||
|
||||
func (e *Dynset) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Dynset) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// See: https://git.netfilter.org/libnftnl/tree/src/expr/dynset.c
|
||||
var opAttrs []netlink.Attribute
|
||||
opAttrs = append(opAttrs, netlink.Attribute{Type: unix.NFTA_DYNSET_SREG_KEY, Data: binaryutil.BigEndian.PutUint32(e.SrcRegKey)})
|
||||
|
@ -95,6 +95,9 @@ func (e *Dynset) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return opData, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("dynset\x00")},
|
||||
|
@ -125,7 +128,7 @@ func (e *Dynset) unmarshal(fam byte, data []byte) error {
|
|||
case unix.NFTA_DYNSET_FLAGS:
|
||||
e.Invert = (ad.Uint32() & unix.NFT_DYNSET_F_INV) != 0
|
||||
case unix.NFTA_DYNSET_EXPR:
|
||||
exprs, err := parseexprfunc.ParseExprBytesFunc(fam, ad, ad.Bytes())
|
||||
exprs, err := parseexprfunc.ParseExprBytesFunc(fam, ad)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
105
expr/expr.go
105
expr/expr.go
|
@ -25,8 +25,8 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
parseexprfunc.ParseExprBytesFunc = func(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]interface{}, error) {
|
||||
exprs, err := exprsFromBytes(fam, ad, b)
|
||||
parseexprfunc.ParseExprBytesFunc = func(fam byte, ad *netlink.AttributeDecoder, args ...string) ([]interface{}, error) {
|
||||
exprs, err := exprsFromBytes(fam, ad, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func init() {
|
|||
}
|
||||
return result, nil
|
||||
}
|
||||
parseexprfunc.ParseExprMsgFunc = func(fam byte, b []byte) ([]interface{}, error) {
|
||||
parseexprfunc.ParseExprMsgFunc = func(fam byte, b []byte, args ...string) ([]interface{}, error) {
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -44,7 +44,7 @@ func init() {
|
|||
ad.ByteOrder = binary.BigEndian
|
||||
var exprs []interface{}
|
||||
for ad.Next() {
|
||||
e, err := parseexprfunc.ParseExprBytesFunc(fam, ad, b)
|
||||
e, err := parseexprfunc.ParseExprBytesFunc(fam, ad, args...)
|
||||
if err != nil {
|
||||
return e, err
|
||||
}
|
||||
|
@ -56,7 +56,11 @@ func init() {
|
|||
|
||||
// Marshal serializes the specified expression into a byte slice.
|
||||
func Marshal(fam byte, e Any) ([]byte, error) {
|
||||
return e.marshal(fam)
|
||||
return e.marshal(fam, false)
|
||||
}
|
||||
|
||||
func MarshalExprData(fam byte, e Any) ([]byte, error) {
|
||||
return e.marshal(fam, true)
|
||||
}
|
||||
|
||||
// Unmarshal fills an expression from the specified byte slice.
|
||||
|
@ -66,8 +70,20 @@ func Unmarshal(fam byte, data []byte, e Any) error {
|
|||
|
||||
// exprsFromBytes parses nested raw expressions bytes
|
||||
// to construct nftables expressions
|
||||
func exprsFromBytes(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]Any, error) {
|
||||
func exprsFromBytes(fam byte, ad *netlink.AttributeDecoder, args ...string) ([]Any, error) {
|
||||
var exprs []Any
|
||||
if len(args) > 0 {
|
||||
e := exprFromName(args[0])
|
||||
ad.Do(func(b []byte) error {
|
||||
if err := Unmarshal(fam, b, e); err != nil {
|
||||
return err
|
||||
}
|
||||
exprs = append(exprs, e)
|
||||
return nil
|
||||
})
|
||||
return exprs, ad.Err()
|
||||
}
|
||||
|
||||
ad.Do(func(b []byte) error {
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
|
@ -84,6 +100,36 @@ func exprsFromBytes(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]Any, er
|
|||
exprs = append(exprs, e)
|
||||
}
|
||||
case unix.NFTA_EXPR_DATA:
|
||||
e := exprFromName(name)
|
||||
if e == nil {
|
||||
// TODO: introduce an opaque expression type so that users know
|
||||
// something is here.
|
||||
continue // unsupported expression type
|
||||
}
|
||||
ad.Do(func(b []byte) error {
|
||||
if err := Unmarshal(fam, b, e); err != nil {
|
||||
return err
|
||||
}
|
||||
// Verdict expressions are a special-case of immediate expressions, so
|
||||
// if the expression is an immediate writing nothing into the verdict
|
||||
// register (invalid), re-parse it as a verdict expression.
|
||||
if imm, isImmediate := e.(*Immediate); isImmediate && imm.Register == unix.NFT_REG_VERDICT && len(imm.Data) == 0 {
|
||||
e = &Verdict{}
|
||||
if err := Unmarshal(fam, b, e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
exprs = append(exprs, e)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
return ad.Err()
|
||||
})
|
||||
return exprs, ad.Err()
|
||||
}
|
||||
|
||||
func exprFromName(name string) Any {
|
||||
var e Any
|
||||
switch name {
|
||||
case "ct":
|
||||
|
@ -137,38 +183,12 @@ func exprsFromBytes(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]Any, er
|
|||
case "hash":
|
||||
e = &Hash{}
|
||||
}
|
||||
if e == nil {
|
||||
// TODO: introduce an opaque expression type so that users know
|
||||
// something is here.
|
||||
continue // unsupported expression type
|
||||
}
|
||||
|
||||
ad.Do(func(b []byte) error {
|
||||
if err := Unmarshal(fam, b, e); err != nil {
|
||||
return err
|
||||
}
|
||||
// Verdict expressions are a special-case of immediate expressions, so
|
||||
// if the expression is an immediate writing nothing into the verdict
|
||||
// register (invalid), re-parse it as a verdict expression.
|
||||
if imm, isImmediate := e.(*Immediate); isImmediate && imm.Register == unix.NFT_REG_VERDICT && len(imm.Data) == 0 {
|
||||
e = &Verdict{}
|
||||
if err := Unmarshal(fam, b, e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
exprs = append(exprs, e)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
return ad.Err()
|
||||
})
|
||||
return exprs, ad.Err()
|
||||
return e
|
||||
}
|
||||
|
||||
// Any is an interface implemented by any expression type.
|
||||
type Any interface {
|
||||
marshal(fam byte) ([]byte, error)
|
||||
marshal(fam byte, dataOnly bool) ([]byte, error)
|
||||
unmarshal(fam byte, data []byte) error
|
||||
}
|
||||
|
||||
|
@ -213,8 +233,8 @@ type Meta struct {
|
|||
Register uint32
|
||||
}
|
||||
|
||||
func (e *Meta) marshal(fam byte) ([]byte, error) {
|
||||
regData := []byte{}
|
||||
func (e *Meta) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
var regData []byte
|
||||
exprData, err := netlink.MarshalAttributes(
|
||||
[]netlink.Attribute{
|
||||
{Type: unix.NFTA_META_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
||||
|
@ -240,6 +260,9 @@ func (e *Meta) marshal(fam byte) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
exprData = append(exprData, regData...)
|
||||
if dataOnly {
|
||||
return exprData, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("meta\x00")},
|
||||
|
@ -290,7 +313,7 @@ const (
|
|||
NF_NAT_RANGE_PREFIX = unix.NF_NAT_RANGE_NETMAP
|
||||
)
|
||||
|
||||
func (e *Masq) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Masq) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
msgData := []byte{}
|
||||
if !e.ToPorts {
|
||||
flags := uint32(0)
|
||||
|
@ -327,6 +350,9 @@ func (e *Masq) marshal(fam byte) ([]byte, error) {
|
|||
msgData = append(msgData, regsData...)
|
||||
}
|
||||
}
|
||||
if dataOnly {
|
||||
return msgData, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("masq\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: msgData},
|
||||
|
@ -376,7 +402,7 @@ type Cmp struct {
|
|||
Data []byte
|
||||
}
|
||||
|
||||
func (e *Cmp) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Cmp) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
cmpData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_DATA_VALUE, Data: e.Data},
|
||||
})
|
||||
|
@ -391,6 +417,9 @@ func (e *Cmp) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return cmpData, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("cmp\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: exprData},
|
||||
|
|
|
@ -39,7 +39,7 @@ type Exthdr struct {
|
|||
SourceRegister uint32
|
||||
}
|
||||
|
||||
func (e *Exthdr) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Exthdr) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
var attr []netlink.Attribute
|
||||
|
||||
// Operations are differentiated by the Op and whether the SourceRegister
|
||||
|
@ -68,6 +68,9 @@ func (e *Exthdr) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("exthdr\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -44,7 +44,7 @@ func TestExthdr(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
neh := Exthdr{}
|
||||
data, err := tt.eh.marshal(0 /* don't care in this test */)
|
||||
data, err := tt.eh.marshal(0 /* don't care in this test */, false)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal error: %+v", err)
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ type Fib struct {
|
|||
FlagPRESENT bool
|
||||
}
|
||||
|
||||
func (e *Fib) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Fib) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data := []byte{}
|
||||
reg, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_FIB_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||
|
@ -92,7 +92,9 @@ func (e *Fib) marshal(fam byte) ([]byte, error) {
|
|||
}
|
||||
data = append(data, rslt...)
|
||||
}
|
||||
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("fib\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -27,13 +27,16 @@ type FlowOffload struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
func (e *FlowOffload) marshal(fam byte) ([]byte, error) {
|
||||
func (e *FlowOffload) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: NFTNL_EXPR_FLOW_TABLE_NAME, Data: []byte(e.Name)},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("flow_offload\x00")},
|
||||
|
|
|
@ -40,7 +40,7 @@ type Hash struct {
|
|||
Type HashType
|
||||
}
|
||||
|
||||
func (e *Hash) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Hash) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
hashAttrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_HASH_SREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.SourceRegister))},
|
||||
{Type: unix.NFTA_HASH_DREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.DestRegister))},
|
||||
|
@ -60,6 +60,9 @@ func (e *Hash) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("hash\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -28,7 +28,7 @@ type Immediate struct {
|
|||
Data []byte
|
||||
}
|
||||
|
||||
func (e *Immediate) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Immediate) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
immData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_DATA_VALUE, Data: e.Data},
|
||||
})
|
||||
|
@ -43,6 +43,9 @@ func (e *Immediate) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("immediate\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -71,7 +71,7 @@ type Limit struct {
|
|||
Burst uint32
|
||||
}
|
||||
|
||||
func (l *Limit) marshal(fam byte) ([]byte, error) {
|
||||
func (l *Limit) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
var flags uint32
|
||||
if l.Over {
|
||||
flags = unix.NFT_LIMIT_F_INV
|
||||
|
@ -88,6 +88,9 @@ func (l *Limit) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("limit\x00")},
|
||||
|
|
|
@ -68,7 +68,7 @@ type Log struct {
|
|||
Data []byte
|
||||
}
|
||||
|
||||
func (e *Log) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Log) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// Per https://git.netfilter.org/libnftnl/tree/src/expr/log.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n129
|
||||
attrs := make([]netlink.Attribute, 0)
|
||||
if e.Key&(1<<unix.NFTA_LOG_GROUP) != 0 {
|
||||
|
@ -113,6 +113,9 @@ func (e *Log) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("log\x00")},
|
||||
|
|
|
@ -33,7 +33,7 @@ type Lookup struct {
|
|||
Invert bool
|
||||
}
|
||||
|
||||
func (e *Lookup) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Lookup) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// See: https://git.netfilter.org/libnftnl/tree/src/expr/lookup.c?id=6dc1c3d8bb64077da7f3f28c7368fb087d10a492#n115
|
||||
var opAttrs []netlink.Attribute
|
||||
if e.SourceRegister != 0 {
|
||||
|
@ -53,6 +53,9 @@ func (e *Lookup) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return opData, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("lookup\x00")},
|
||||
|
|
|
@ -17,7 +17,7 @@ type Match struct {
|
|||
Info xt.InfoAny
|
||||
}
|
||||
|
||||
func (e *Match) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Match) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// Per https://git.netfilter.org/libnftnl/tree/src/expr/match.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n38
|
||||
name := e.Name
|
||||
// limit the extension name as (some) user-space tools do and leave room for
|
||||
|
@ -40,7 +40,9 @@ func (e *Match) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("match\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestMatch(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ntgt := Match{}
|
||||
data, err := tt.mtch.marshal(0 /* don't care in this test */)
|
||||
data, err := tt.mtch.marshal(0 /* don't care in this test */, false)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal error: %+v", err)
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ func TestMeta(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
nMeta := Meta{}
|
||||
data, err := tt.meta.marshal(0 /* don't care in this test */)
|
||||
data, err := tt.meta.marshal(0 /* don't care in this test */, false)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal error: %+v", err)
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ type NAT struct {
|
|||
// |00008|--|00005| |len |flags| type| NFTA_NAT_REG_PROTO_MIN
|
||||
// | 00 00 00 02 | | data | reg 2
|
||||
|
||||
func (e *NAT) marshal(fam byte) ([]byte, error) {
|
||||
func (e *NAT) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_NAT_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
|
||||
{Type: unix.NFTA_NAT_FAMILY, Data: binaryutil.BigEndian.PutUint32(e.Family)},
|
||||
|
@ -94,6 +94,9 @@ func (e *NAT) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("nat\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
|
||||
type Notrack struct{}
|
||||
|
||||
func (e *Notrack) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Notrack) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("notrack\x00")},
|
||||
})
|
||||
|
|
|
@ -31,7 +31,7 @@ type Numgen struct {
|
|||
Offset uint32
|
||||
}
|
||||
|
||||
func (e *Numgen) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Numgen) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// Currently only two types are supported, failing if Type is not of two known types
|
||||
switch e.Type {
|
||||
case unix.NFT_NG_INCREMENTAL:
|
||||
|
@ -49,6 +49,9 @@ func (e *Numgen) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("numgen\x00")},
|
||||
|
|
|
@ -27,7 +27,7 @@ type Objref struct {
|
|||
Name string
|
||||
}
|
||||
|
||||
func (e *Objref) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Objref) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_OBJREF_IMM_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
|
||||
{Type: unix.NFTA_OBJREF_IMM_NAME, Data: []byte(e.Name)}, // NOT \x00-terminated?!
|
||||
|
@ -35,6 +35,9 @@ func (e *Objref) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("objref\x00")},
|
||||
|
|
|
@ -57,7 +57,7 @@ type Payload struct {
|
|||
CsumFlags uint32
|
||||
}
|
||||
|
||||
func (e *Payload) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Payload) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
|
||||
var attrs []netlink.Attribute
|
||||
|
||||
|
@ -90,10 +90,13 @@ func (e *Payload) marshal(fam byte) ([]byte, error) {
|
|||
}
|
||||
|
||||
data, err := netlink.MarshalAttributes(attrs)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("payload\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -43,7 +43,7 @@ type Queue struct {
|
|||
Flag QueueFlag
|
||||
}
|
||||
|
||||
func (e *Queue) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Queue) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
if e.Total == 0 {
|
||||
e.Total = 1 // The total default value is 1
|
||||
}
|
||||
|
@ -55,6 +55,9 @@ func (e *Queue) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("queue\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -29,7 +29,7 @@ type Quota struct {
|
|||
Over bool
|
||||
}
|
||||
|
||||
func (q *Quota) marshal(fam byte) ([]byte, error) {
|
||||
func (q *Quota) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_QUOTA_BYTES, Data: binaryutil.BigEndian.PutUint64(q.Bytes)},
|
||||
{Type: unix.NFTA_QUOTA_CONSUMED, Data: binaryutil.BigEndian.PutUint64(q.Consumed)},
|
||||
|
@ -48,6 +48,9 @@ func (q *Quota) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("quota\x00")},
|
||||
|
|
|
@ -30,7 +30,7 @@ type Range struct {
|
|||
ToData []byte
|
||||
}
|
||||
|
||||
func (e *Range) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Range) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
var attrs []netlink.Attribute
|
||||
var err error
|
||||
var rangeFromData, rangeToData []byte
|
||||
|
@ -57,7 +57,9 @@ func (e *Range) marshal(fam byte) ([]byte, error) {
|
|||
}
|
||||
data = append(data, rangeFromData...)
|
||||
data = append(data, rangeToData...)
|
||||
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("range\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -28,7 +28,7 @@ type Redir struct {
|
|||
Flags uint32
|
||||
}
|
||||
|
||||
func (e *Redir) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Redir) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
var attrs []netlink.Attribute
|
||||
if e.RegisterProtoMin > 0 {
|
||||
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_REDIR_REG_PROTO_MIN, Data: binaryutil.BigEndian.PutUint32(e.RegisterProtoMin)})
|
||||
|
@ -44,6 +44,9 @@ func (e *Redir) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("redir\x00")},
|
||||
|
|
|
@ -27,7 +27,7 @@ type Reject struct {
|
|||
Code uint8
|
||||
}
|
||||
|
||||
func (e *Reject) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Reject) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_REJECT_TYPE, Data: binaryutil.BigEndian.PutUint32(e.Type)},
|
||||
{Type: unix.NFTA_REJECT_ICMP_CODE, Data: []byte{e.Code}},
|
||||
|
@ -35,6 +35,9 @@ func (e *Reject) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("reject\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -36,7 +36,7 @@ type Rt struct {
|
|||
Key RtKey
|
||||
}
|
||||
|
||||
func (e *Rt) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Rt) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_RT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
||||
{Type: unix.NFTA_RT_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||
|
@ -44,6 +44,9 @@ func (e *Rt) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("rt\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -48,7 +48,7 @@ const (
|
|||
SocketKeyCgroupv2 SocketKey = NFT_SOCKET_CGROUPV2
|
||||
)
|
||||
|
||||
func (e *Socket) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Socket) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// NOTE: Socket.Level is only used when Socket.Key == SocketKeyCgroupv2. But `nft` always encoding it. Check link below:
|
||||
// http://git.netfilter.org/nftables/tree/src/netlink_linearize.c?id=0583bac241ea18c9d7f61cb20ca04faa1e043b78#n319
|
||||
exprData, err := netlink.MarshalAttributes(
|
||||
|
@ -62,6 +62,9 @@ func (e *Socket) marshal(fam byte) ([]byte, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if dataOnly {
|
||||
return exprData, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("socket\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: exprData},
|
||||
|
|
|
@ -74,7 +74,7 @@ func TestSocket(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
nSocket := Socket{}
|
||||
data, err := tt.socket.marshal(0 /* don't care in this test */)
|
||||
data, err := tt.socket.marshal(0 /* don't care in this test */, false)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal error: %+v", err)
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ type Target struct {
|
|||
Info xt.InfoAny
|
||||
}
|
||||
|
||||
func (e *Target) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Target) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// Per https://git.netfilter.org/libnftnl/tree/src/expr/target.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n38
|
||||
name := e.Name
|
||||
// limit the extension name as (some) user-space tools do and leave room for
|
||||
|
@ -44,7 +44,9 @@ func (e *Target) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("target\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -30,7 +30,7 @@ func TestTarget(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ntgt := Target{}
|
||||
data, err := tt.tgt.marshal(0 /* don't care in this test */)
|
||||
data, err := tt.tgt.marshal(0 /* don't care in this test */, false)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal error: %+v", err)
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ type TProxy struct {
|
|||
RegPort uint32
|
||||
}
|
||||
|
||||
func (e *TProxy) marshal(fam byte) ([]byte, error) {
|
||||
func (e *TProxy) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: NFTA_TPROXY_FAMILY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Family))},
|
||||
{Type: NFTA_TPROXY_REG_PORT, Data: binaryutil.BigEndian.PutUint32(e.RegPort)},
|
||||
|
@ -56,6 +56,9 @@ func (e *TProxy) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("tproxy\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -53,7 +53,7 @@ const (
|
|||
VerdictStop
|
||||
)
|
||||
|
||||
func (e *Verdict) marshal(fam byte) ([]byte, error) {
|
||||
func (e *Verdict) marshal(fam byte, dataOnly bool) ([]byte, error) {
|
||||
// A verdict is a tree of netlink attributes structured as follows:
|
||||
// NFTA_LIST_ELEM | NLA_F_NESTED {
|
||||
// NFTA_EXPR_NAME { "immediate\x00" }
|
||||
|
@ -90,6 +90,9 @@ func (e *Verdict) marshal(fam byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dataOnly {
|
||||
return data, nil
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("immediate\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
|
|
|
@ -219,7 +219,7 @@ func (cc *Conn) getFlowtables(t *Table) ([]netlink.Message, error) {
|
|||
|
||||
reply, err := receiveAckAware(conn, message.Header.Flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Receive: %v", err)
|
||||
return nil, fmt.Errorf("receiveAckAware: %v", err)
|
||||
}
|
||||
|
||||
return reply, nil
|
||||
|
|
|
@ -5,6 +5,6 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ParseExprBytesFunc func(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]interface{}, error)
|
||||
ParseExprMsgFunc func(fam byte, b []byte) ([]interface{}, error)
|
||||
ParseExprBytesFunc func(fam byte, ad *netlink.AttributeDecoder, args ...string) ([]interface{}, error)
|
||||
ParseExprMsgFunc func(fam byte, b []byte, args ...string) ([]interface{}, error)
|
||||
)
|
||||
|
|
137
nftables_test.go
137
nftables_test.go
|
@ -1783,7 +1783,7 @@ func TestListChainByName(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestListChainByNameUsingLasting(t *testing.T) {
|
||||
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||
_, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||
conn, err := nftables.New(nftables.WithNetNSFd(int(newNS)), nftables.AsLasting())
|
||||
if err != nil {
|
||||
t.Fatalf("nftables.New() failed: %v", err)
|
||||
|
@ -1882,8 +1882,7 @@ func TestListTableByName(t *testing.T) {
|
|||
}
|
||||
|
||||
// not specifying correct family should return err since no table in ipv4
|
||||
tr, err = conn.ListTable(table2.Name)
|
||||
if err == nil {
|
||||
if _, err = conn.ListTable(table2.Name); err == nil {
|
||||
t.Fatalf("conn.ListTable() should have failed")
|
||||
}
|
||||
|
||||
|
@ -2114,9 +2113,9 @@ func TestGetObjReset(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
co, ok := obj.(*nftables.CounterObj)
|
||||
co, ok := obj.(*nftables.ObjAttr)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *nftables.CounterObj", obj)
|
||||
t.Fatalf("unexpected type: got %T, want *nftables.ObjAttr", obj)
|
||||
}
|
||||
if got, want := co.Table.Name, filter.Name; got != want {
|
||||
t.Errorf("unexpected table name: got %q, want %q", got, want)
|
||||
|
@ -2124,10 +2123,14 @@ func TestGetObjReset(t *testing.T) {
|
|||
if got, want := co.Table.Family, filter.Family; got != want {
|
||||
t.Errorf("unexpected table family: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := co.Packets, uint64(9); got != want {
|
||||
o, ok := co.Obj.(*expr.Counter)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *expr.Counter", o)
|
||||
}
|
||||
if got, want := o.Packets, uint64(9); got != want {
|
||||
t.Errorf("unexpected number of packets: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := co.Bytes, uint64(1121); got != want {
|
||||
if got, want := o.Bytes, uint64(1121); got != want {
|
||||
t.Errorf("unexpected number of bytes: got %d, want %d", got, want)
|
||||
}
|
||||
}
|
||||
|
@ -2223,10 +2226,9 @@ func TestObjAPI(t *testing.T) {
|
|||
t.Errorf("c.GetObject(counter1) failed: %v failed", err)
|
||||
}
|
||||
|
||||
rcounter1, ok := obj1.(*nftables.CounterObj)
|
||||
|
||||
rcounter1, ok := obj1.(*nftables.ObjAttr)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *nftables.CounterObj", rcounter1)
|
||||
t.Fatalf("unexpected type: got %T, want *nftables.CounterObj", obj1)
|
||||
}
|
||||
|
||||
if rcounter1.Name != "fwded1" {
|
||||
|
@ -2238,10 +2240,9 @@ func TestObjAPI(t *testing.T) {
|
|||
t.Errorf("c.GetObject(counter2) failed: %v failed", err)
|
||||
}
|
||||
|
||||
rcounter2, ok := obj2.(*nftables.CounterObj)
|
||||
|
||||
rcounter2, ok := obj2.(*nftables.ObjAttr)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *nftables.CounterObj", rcounter2)
|
||||
t.Fatalf("unexpected type: got %T, want *nftables.CounterObj", obj2)
|
||||
}
|
||||
|
||||
if rcounter2.Name != "fwded2" {
|
||||
|
@ -2260,7 +2261,7 @@ func TestObjAPI(t *testing.T) {
|
|||
t.Errorf("c.GetObject(counter1) failed: %v failed", err)
|
||||
}
|
||||
|
||||
if counter1 := obj1.(*nftables.CounterObj); counter1.Packets > 0 {
|
||||
if counter1 := obj1.(*nftables.ObjAttr).Obj.(*expr.Counter); counter1.Packets > 0 {
|
||||
t.Errorf("unexpected packets number: got %d, want %d", counter1.Packets, 0)
|
||||
}
|
||||
|
||||
|
@ -2270,7 +2271,7 @@ func TestObjAPI(t *testing.T) {
|
|||
t.Errorf("c.GetObject(counter2) failed: %v failed", err)
|
||||
}
|
||||
|
||||
if counter2 := obj2.(*nftables.CounterObj); counter2.Packets != 1 {
|
||||
if counter2 := obj2.(*nftables.ObjAttr).Obj.(*expr.Counter); counter2.Packets != 1 {
|
||||
t.Errorf("unexpected packets number: got %d, want %d", counter2.Packets, 1)
|
||||
}
|
||||
|
||||
|
@ -2767,7 +2768,7 @@ func TestCreateUseAnonymousSet(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCappedErrMsgOnSets(t *testing.T) {
|
||||
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||
_, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||
c, err := nftables.New(nftables.WithNetNSFd(int(newNS)), nftables.AsLasting())
|
||||
if err != nil {
|
||||
t.Fatalf("nftables.New() failed: %v", err)
|
||||
|
@ -6285,6 +6286,84 @@ func TestGetRulesObjref(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAddLimitObj(t *testing.T) {
|
||||
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||
defer nftest.CleanupSystemConn(t, newNS)
|
||||
conn.FlushRuleset()
|
||||
defer conn.FlushRuleset()
|
||||
|
||||
table := &nftables.Table{
|
||||
Name: "limit_demo",
|
||||
Family: nftables.TableFamilyIPv4,
|
||||
}
|
||||
tr := conn.AddTable(table)
|
||||
|
||||
c := &nftables.Chain{
|
||||
Name: "filter",
|
||||
Table: table,
|
||||
}
|
||||
conn.AddChain(c)
|
||||
|
||||
l := &expr.Limit{
|
||||
Type: expr.LimitTypePkts,
|
||||
Rate: 400,
|
||||
Unit: expr.LimitTimeMinute,
|
||||
Burst: 5,
|
||||
Over: false,
|
||||
}
|
||||
o := &nftables.ObjAttr{
|
||||
Table: tr,
|
||||
Name: "limit_test",
|
||||
Type: nftables.ObjTypeLimit,
|
||||
Obj: l,
|
||||
}
|
||||
conn.AddObj(o)
|
||||
|
||||
if err := conn.Flush(); err != nil {
|
||||
t.Errorf("conn.Flush() failed: %v", err)
|
||||
}
|
||||
|
||||
obj, err := conn.GetObj(&nftables.ObjAttr{
|
||||
Table: table,
|
||||
Name: "limit_test",
|
||||
Type: nftables.ObjTypeLimit,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("conn.GetObj() failed: %v", err)
|
||||
}
|
||||
|
||||
if got, want := len(obj), 1; got != want {
|
||||
t.Fatalf("unexpected object list length: got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
o1, ok := obj[0].(*nftables.ObjAttr)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *ObjAttr", obj[0])
|
||||
}
|
||||
if got, want := o1.Name, o.Name; got != want {
|
||||
t.Fatalf("limit name mismatch: got %s, want %s", got, want)
|
||||
}
|
||||
q, ok := o1.Obj.(*expr.Limit)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *expr.Quota", o1.Obj)
|
||||
}
|
||||
if got, want := q.Burst, l.Burst; got != want {
|
||||
t.Fatalf("limit burst mismatch: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := q.Unit, l.Unit; got != want {
|
||||
t.Fatalf("limit unit mismatch: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := q.Rate, l.Rate; got != want {
|
||||
t.Fatalf("limit rate mismatch: got %v, want %v", got, want)
|
||||
}
|
||||
if got, want := q.Over, l.Over; got != want {
|
||||
t.Fatalf("limit over mismatch: got %v, want %v", got, want)
|
||||
}
|
||||
if got, want := q.Type, l.Type; got != want {
|
||||
t.Fatalf("limit type mismatch: got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddQuotaObj(t *testing.T) {
|
||||
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||
defer nftest.CleanupSystemConn(t, newNS)
|
||||
|
@ -6328,20 +6407,24 @@ func TestAddQuotaObj(t *testing.T) {
|
|||
t.Fatalf("unexpected object list length: got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
o1, ok := obj[0].(*nftables.QuotaObj)
|
||||
o1, ok := obj[0].(*nftables.ObjAttr)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *QuotaObj", obj[0])
|
||||
t.Fatalf("unexpected type: got %T, want *ObjAttr", obj[0])
|
||||
}
|
||||
if got, want := o1.Name, o.Name; got != want {
|
||||
t.Fatalf("quota name mismatch: got %s, want %s", got, want)
|
||||
}
|
||||
if got, want := o1.Bytes, o.Bytes; got != want {
|
||||
q, ok := o1.Obj.(*expr.Quota)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected type: got %T, want *expr.Quota", o1.Obj)
|
||||
}
|
||||
if got, want := q.Bytes, o.Bytes; got != want {
|
||||
t.Fatalf("quota bytes mismatch: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := o1.Consumed, o.Consumed; got != want {
|
||||
if got, want := q.Consumed, o.Consumed; got != want {
|
||||
t.Fatalf("quota consumed mismatch: got %d, want %d", got, want)
|
||||
}
|
||||
if got, want := o1.Over, o.Over; got != want {
|
||||
if got, want := q.Over, o.Over; got != want {
|
||||
t.Fatalf("quota over mismatch: got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
@ -6452,7 +6535,17 @@ func TestDeleteQuotaObj(t *testing.T) {
|
|||
t.Fatalf("unexpected number of objects: got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
if got, want := obj[0], o; !reflect.DeepEqual(got, want) {
|
||||
want := &nftables.ObjAttr{
|
||||
Table: tr,
|
||||
Name: "q_test",
|
||||
Type: nftables.ObjTypeQuota,
|
||||
Obj: &expr.Quota{
|
||||
Bytes: o.Bytes,
|
||||
Consumed: o.Consumed,
|
||||
Over: o.Over,
|
||||
},
|
||||
}
|
||||
if got, want := obj[0], want; !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("got = %+v, want = %+v", got, want)
|
||||
}
|
||||
|
||||
|
|
130
obj.go
130
obj.go
|
@ -18,6 +18,9 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/nftables/binaryutil"
|
||||
"github.com/google/nftables/expr"
|
||||
"github.com/google/nftables/internal/parseexprfunc"
|
||||
"github.com/mdlayher/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
@ -27,13 +30,70 @@ var (
|
|||
delObjHeaderType = netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_DELOBJ)
|
||||
)
|
||||
|
||||
type ObjType uint32
|
||||
|
||||
// https://git.netfilter.org/libnftnl/tree/include/linux/netfilter/nf_tables.h?id=be0bae0ad31b0adb506f96de083f52a2bd0d4fbf#n1612
|
||||
const (
|
||||
ObjTypeCounter ObjType = unix.NFT_OBJECT_COUNTER
|
||||
ObjTypeQuota ObjType = unix.NFT_OBJECT_QUOTA
|
||||
ObjTypeCtHelper ObjType = unix.NFT_OBJECT_CT_HELPER
|
||||
ObjTypeLimit ObjType = unix.NFT_OBJECT_LIMIT
|
||||
ObjTypeConnLimit ObjType = unix.NFT_OBJECT_CONNLIMIT
|
||||
ObjTypeTunnel ObjType = unix.NFT_OBJECT_TUNNEL
|
||||
ObjTypeCtTimeout ObjType = unix.NFT_OBJECT_CT_TIMEOUT
|
||||
ObjTypeSecMark ObjType = unix.NFT_OBJECT_SECMARK
|
||||
ObjTypeCtExpect ObjType = unix.NFT_OBJECT_CT_EXPECT
|
||||
ObjTypeSynProxy ObjType = unix.NFT_OBJECT_SYNPROXY
|
||||
)
|
||||
|
||||
var objByObjTypeMagic = map[ObjType]string{
|
||||
ObjTypeCounter: "counter",
|
||||
ObjTypeQuota: "quota",
|
||||
ObjTypeLimit: "limit",
|
||||
ObjTypeConnLimit: "connlimit",
|
||||
ObjTypeCtHelper: "cthelper", // not implemented in expr
|
||||
ObjTypeTunnel: "tunnel", // not implemented in expr
|
||||
ObjTypeCtTimeout: "cttimeout", // not implemented in expr
|
||||
ObjTypeSecMark: "secmark", // not implemented in expr
|
||||
ObjTypeCtExpect: "ctexpect", // not implemented in expr
|
||||
ObjTypeSynProxy: "synproxy", // not implemented in expr
|
||||
}
|
||||
|
||||
// Obj represents a netfilter stateful object. See also
|
||||
// https://wiki.nftables.org/wiki-nftables/index.php/Stateful_objects
|
||||
type Obj interface {
|
||||
table() *Table
|
||||
family() TableFamily
|
||||
unmarshal(*netlink.AttributeDecoder) error
|
||||
marshal(data bool) ([]byte, error)
|
||||
data() expr.Any
|
||||
name() string
|
||||
objType() ObjType
|
||||
}
|
||||
|
||||
type ObjAttr struct {
|
||||
Table *Table
|
||||
Name string
|
||||
Type ObjType
|
||||
Obj expr.Any
|
||||
}
|
||||
|
||||
func (o *ObjAttr) table() *Table {
|
||||
return o.Table
|
||||
}
|
||||
|
||||
func (o *ObjAttr) family() TableFamily {
|
||||
return o.Table.Family
|
||||
}
|
||||
|
||||
func (o *ObjAttr) data() expr.Any {
|
||||
return o.Obj
|
||||
}
|
||||
|
||||
func (o *ObjAttr) name() string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
func (o *ObjAttr) objType() ObjType {
|
||||
return o.Type
|
||||
}
|
||||
|
||||
// AddObject adds the specified Obj. Alias of AddObj.
|
||||
|
@ -46,18 +106,27 @@ func (cc *Conn) AddObject(o Obj) Obj {
|
|||
func (cc *Conn) AddObj(o Obj) Obj {
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
data, err := o.marshal(true)
|
||||
data, err := expr.MarshalExprData(byte(o.family()), o.data())
|
||||
if err != nil {
|
||||
cc.setErr(err)
|
||||
return nil
|
||||
}
|
||||
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(o.table().Name + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_NAME, Data: []byte(o.name() + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(o.objType()))},
|
||||
}
|
||||
if len(data) > 0 {
|
||||
attrs = append(attrs, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA, Data: data})
|
||||
}
|
||||
|
||||
cc.messages = append(cc.messages, netlink.Message{
|
||||
Header: netlink.Header{
|
||||
Type: netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_NEWOBJ),
|
||||
Flags: netlink.Request | netlink.Acknowledge | netlink.Create,
|
||||
},
|
||||
Data: append(extraHeader(uint8(o.family()), 0), data...),
|
||||
Data: append(extraHeader(uint8(o.family()), 0), cc.marshalAttr(attrs)...),
|
||||
})
|
||||
return o
|
||||
}
|
||||
|
@ -66,12 +135,12 @@ func (cc *Conn) AddObj(o Obj) Obj {
|
|||
func (cc *Conn) DeleteObject(o Obj) {
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
data, err := o.marshal(false)
|
||||
if err != nil {
|
||||
cc.setErr(err)
|
||||
return
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(o.table().Name + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_NAME, Data: []byte(o.name() + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(o.objType()))},
|
||||
}
|
||||
|
||||
data := cc.marshalAttr(attrs)
|
||||
data = append(data, cc.marshalAttr([]netlink.Attribute{{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA}})...)
|
||||
|
||||
cc.messages = append(cc.messages, netlink.Message{
|
||||
|
@ -150,40 +219,28 @@ func objFromMsg(msg netlink.Message) (Obj, error) {
|
|||
case unix.NFTA_OBJ_TYPE:
|
||||
objectType = ad.Uint32()
|
||||
case unix.NFTA_OBJ_DATA:
|
||||
switch objectType {
|
||||
case unix.NFT_OBJECT_COUNTER:
|
||||
o := CounterObj{
|
||||
o := ObjAttr{
|
||||
Table: table,
|
||||
Name: name,
|
||||
Type: ObjType(objectType),
|
||||
}
|
||||
|
||||
ad.Do(func(b []byte) error {
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
objs, err := parseexprfunc.ParseExprBytesFunc(byte(o.family()), ad, objByObjTypeMagic[o.Type])
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
ad.ByteOrder = binary.BigEndian
|
||||
return o.unmarshal(ad)
|
||||
})
|
||||
return &o, ad.Err()
|
||||
case NFT_OBJECT_QUOTA:
|
||||
o := QuotaObj{
|
||||
Table: table,
|
||||
Name: name,
|
||||
exprs := make([]expr.Any, len(objs))
|
||||
for i := range exprs {
|
||||
exprs[i] = objs[i].(expr.Any)
|
||||
}
|
||||
if len(exprs) == 0 {
|
||||
return nil, fmt.Errorf("objFromMsg: exprs is empty for obj %v", o)
|
||||
}
|
||||
|
||||
ad.Do(func(b []byte) error {
|
||||
ad, err := netlink.NewAttributeDecoder(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ad.ByteOrder = binary.BigEndian
|
||||
return o.unmarshal(ad)
|
||||
})
|
||||
o.Obj = exprs[0]
|
||||
return &o, ad.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := ad.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -201,7 +258,12 @@ func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
|||
var flags netlink.HeaderFlags
|
||||
|
||||
if o != nil {
|
||||
data, err = o.marshal(false)
|
||||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(o.table().Name + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_NAME, Data: []byte(o.name() + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(o.objType()))},
|
||||
}
|
||||
data = cc.marshalAttr(attrs)
|
||||
} else {
|
||||
flags = netlink.Dump
|
||||
data, err = netlink.MarshalAttributes([]netlink.Attribute{
|
||||
|
@ -226,7 +288,7 @@ func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
|||
|
||||
reply, err := receiveAckAware(conn, message.Header.Flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Receive: %v", err)
|
||||
return nil, fmt.Errorf("receiveAckAware: %v", err)
|
||||
}
|
||||
var objs []Obj
|
||||
for _, msg := range reply {
|
||||
|
|
25
quota.go
25
quota.go
|
@ -16,15 +16,12 @@ package nftables
|
|||
|
||||
import (
|
||||
"github.com/google/nftables/binaryutil"
|
||||
"github.com/google/nftables/expr"
|
||||
"github.com/mdlayher/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
NFTA_OBJ_USERDATA = 8
|
||||
NFT_OBJECT_QUOTA = 2
|
||||
)
|
||||
|
||||
// Deprecated: Use ObjAttr instead
|
||||
type QuotaObj struct {
|
||||
Table *Table
|
||||
Name string
|
||||
|
@ -63,7 +60,7 @@ func (q *QuotaObj) marshal(data bool) ([]byte, error) {
|
|||
attrs := []netlink.Attribute{
|
||||
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(q.Table.Name + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_NAME, Data: []byte(q.Name + "\x00")},
|
||||
{Type: unix.NFTA_OBJ_TYPE, Data: binaryutil.BigEndian.PutUint32(NFT_OBJECT_QUOTA)},
|
||||
{Type: unix.NFTA_OBJ_TYPE, Data: binaryutil.BigEndian.PutUint32(unix.NFT_OBJECT_QUOTA)},
|
||||
}
|
||||
if data {
|
||||
attrs = append(attrs, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA, Data: obj})
|
||||
|
@ -78,3 +75,19 @@ func (q *QuotaObj) table() *Table {
|
|||
func (q *QuotaObj) family() TableFamily {
|
||||
return q.Table.Family
|
||||
}
|
||||
|
||||
func (q *QuotaObj) data() expr.Any {
|
||||
return &expr.Quota{
|
||||
Bytes: q.Bytes,
|
||||
Consumed: q.Consumed,
|
||||
Over: q.Over,
|
||||
}
|
||||
}
|
||||
|
||||
func (q *QuotaObj) name() string {
|
||||
return q.Name
|
||||
}
|
||||
|
||||
func (q *QuotaObj) objType() ObjType {
|
||||
return ObjTypeQuota
|
||||
}
|
||||
|
|
2
rule.go
2
rule.go
|
@ -92,7 +92,7 @@ func (cc *Conn) GetRules(t *Table, c *Chain) ([]*Rule, error) {
|
|||
|
||||
reply, err := receiveAckAware(conn, message.Header.Flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Receive: %v", err)
|
||||
return nil, fmt.Errorf("receiveAckAware: %v", err)
|
||||
}
|
||||
var rules []*Rule
|
||||
for _, msg := range reply {
|
||||
|
|
10
set.go
10
set.go
|
@ -321,7 +321,7 @@ func (s *SetElement) decode(fam byte) func(b []byte) error {
|
|||
case unix.NFTA_SET_ELEM_EXPIRATION:
|
||||
s.Expires = time.Millisecond * time.Duration(ad.Uint64())
|
||||
case unix.NFTA_SET_ELEM_EXPR:
|
||||
elems, err := parseexprfunc.ParseExprBytesFunc(fam, ad, ad.Bytes())
|
||||
elems, err := parseexprfunc.ParseExprBytesFunc(fam, ad)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -832,7 +832,7 @@ func (cc *Conn) GetSets(t *Table) ([]*Set, error) {
|
|||
|
||||
reply, err := receiveAckAware(conn, message.Header.Flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Receive: %v", err)
|
||||
return nil, fmt.Errorf("receiveAckAware: %v", err)
|
||||
}
|
||||
var sets []*Set
|
||||
for _, msg := range reply {
|
||||
|
@ -877,11 +877,11 @@ func (cc *Conn) GetSetByName(t *Table, name string) (*Set, error) {
|
|||
|
||||
reply, err := receiveAckAware(conn, message.Header.Flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Receive: %w", err)
|
||||
return nil, fmt.Errorf("receiveAckAware: %w", err)
|
||||
}
|
||||
|
||||
if len(reply) != 1 {
|
||||
return nil, fmt.Errorf("Receive: expected to receive 1 message but got %d", len(reply))
|
||||
return nil, fmt.Errorf("receiveAckAware: expected to receive 1 message but got %d", len(reply))
|
||||
}
|
||||
rs, err := setsFromMsg(reply[0])
|
||||
if err != nil {
|
||||
|
@ -922,7 +922,7 @@ func (cc *Conn) GetSetElements(s *Set) ([]SetElement, error) {
|
|||
|
||||
reply, err := receiveAckAware(conn, message.Header.Flags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Receive: %v", err)
|
||||
return nil, fmt.Errorf("receiveAckAware: %v", err)
|
||||
}
|
||||
var elems []SetElement
|
||||
for _, msg := range reply {
|
||||
|
|
Loading…
Reference in New Issue