Objects implementation refactor
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
This commit is contained in:
parent
aa8348f790
commit
533a9343c8
16
counter.go
16
counter.go
|
@ -16,11 +16,11 @@ package nftables
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/nftables/binaryutil"
|
"github.com/google/nftables/binaryutil"
|
||||||
|
"github.com/google/nftables/expr"
|
||||||
"github.com/mdlayher/netlink"
|
"github.com/mdlayher/netlink"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CounterObj implements Obj.
|
|
||||||
type CounterObj struct {
|
type CounterObj struct {
|
||||||
Table *Table
|
Table *Table
|
||||||
Name string // e.g. “fwded”
|
Name string // e.g. “fwded”
|
||||||
|
@ -41,6 +41,20 @@ func (c *CounterObj) unmarshal(ad *netlink.AttributeDecoder) error {
|
||||||
return ad.Err()
|
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 {
|
func (c *CounterObj) table() *Table {
|
||||||
return c.Table
|
return c.Table
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,17 @@ type Bitwise struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Bitwise) marshal(fam byte) ([]byte, error) {
|
func (e *Bitwise) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Bitwise) marshalData(fam byte) ([]byte, error) {
|
||||||
mask, err := netlink.MarshalAttributes([]netlink.Attribute{
|
mask, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_DATA_VALUE, Data: e.Mask},
|
{Type: unix.NFTA_DATA_VALUE, Data: e.Mask},
|
||||||
})
|
})
|
||||||
|
@ -44,20 +55,13 @@ func (e *Bitwise) marshal(fam byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_BITWISE_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)},
|
{Type: unix.NFTA_BITWISE_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)},
|
||||||
{Type: unix.NFTA_BITWISE_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)},
|
{Type: unix.NFTA_BITWISE_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)},
|
||||||
{Type: unix.NFTA_BITWISE_LEN, Data: binaryutil.BigEndian.PutUint32(e.Len)},
|
{Type: unix.NFTA_BITWISE_LEN, Data: binaryutil.BigEndian.PutUint32(e.Len)},
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_BITWISE_MASK, Data: mask},
|
{Type: unix.NLA_F_NESTED | unix.NFTA_BITWISE_MASK, Data: mask},
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_BITWISE_XOR, Data: xor},
|
{Type: unix.NLA_F_NESTED | unix.NFTA_BITWISE_XOR, Data: xor},
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Bitwise) unmarshal(fam byte, data []byte) error {
|
func (e *Bitwise) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -38,13 +38,7 @@ type Byteorder struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Byteorder) marshal(fam byte) ([]byte, error) {
|
func (e *Byteorder) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: unix.NFTA_BYTEORDER_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)},
|
|
||||||
{Type: unix.NFTA_BYTEORDER_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)},
|
|
||||||
{Type: unix.NFTA_BYTEORDER_OP, Data: binaryutil.BigEndian.PutUint32(uint32(e.Op))},
|
|
||||||
{Type: unix.NFTA_BYTEORDER_LEN, Data: binaryutil.BigEndian.PutUint32(e.Len)},
|
|
||||||
{Type: unix.NFTA_BYTEORDER_SIZE, Data: binaryutil.BigEndian.PutUint32(e.Size)},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -54,6 +48,16 @@ func (e *Byteorder) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Byteorder) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return 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)},
|
||||||
|
{Type: unix.NFTA_BYTEORDER_OP, Data: binaryutil.BigEndian.PutUint32(uint32(e.Op))},
|
||||||
|
{Type: unix.NFTA_BYTEORDER_LEN, Data: binaryutil.BigEndian.PutUint32(e.Len)},
|
||||||
|
{Type: unix.NFTA_BYTEORDER_SIZE, Data: binaryutil.BigEndian.PutUint32(e.Size)},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Byteorder) unmarshal(fam byte, data []byte) error {
|
func (e *Byteorder) unmarshal(fam byte, data []byte) error {
|
||||||
return fmt.Errorf("not yet implemented")
|
return fmt.Errorf("not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,10 +37,7 @@ type Connlimit struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Connlimit) marshal(fam byte) ([]byte, error) {
|
func (e *Connlimit) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: NFTA_CONNLIMIT_COUNT, Data: binaryutil.BigEndian.PutUint32(e.Count)},
|
|
||||||
{Type: NFTA_CONNLIMIT_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -51,6 +48,13 @@ func (e *Connlimit) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Connlimit) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: NFTA_CONNLIMIT_COUNT, Data: binaryutil.BigEndian.PutUint32(e.Count)},
|
||||||
|
{Type: NFTA_CONNLIMIT_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Connlimit) unmarshal(fam byte, data []byte) error {
|
func (e *Connlimit) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -28,10 +28,7 @@ type Counter struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Counter) marshal(fam byte) ([]byte, error) {
|
func (e *Counter) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: unix.NFTA_COUNTER_BYTES, Data: binaryutil.BigEndian.PutUint64(e.Bytes)},
|
|
||||||
{Type: unix.NFTA_COUNTER_PACKETS, Data: binaryutil.BigEndian.PutUint64(e.Packets)},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -42,6 +39,13 @@ func (e *Counter) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Counter) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return 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)},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Counter) unmarshal(fam byte, data []byte) error {
|
func (e *Counter) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
20
expr/ct.go
20
expr/ct.go
|
@ -64,7 +64,19 @@ type Ct struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Ct) marshal(fam byte) ([]byte, error) {
|
func (e *Ct) marshal(fam byte) ([]byte, error) {
|
||||||
regData := []byte{}
|
exprData, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("ct\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: exprData},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Ct) marshalData(fam byte) ([]byte, error) {
|
||||||
|
var regData []byte
|
||||||
exprData, err := netlink.MarshalAttributes(
|
exprData, err := netlink.MarshalAttributes(
|
||||||
[]netlink.Attribute{
|
[]netlink.Attribute{
|
||||||
{Type: unix.NFTA_CT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
{Type: unix.NFTA_CT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
||||||
|
@ -90,11 +102,7 @@ func (e *Ct) marshal(fam byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
exprData = append(exprData, regData...)
|
exprData = append(exprData, regData...)
|
||||||
|
return exprData, nil
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("ct\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: exprData},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Ct) unmarshal(fam byte, data []byte) error {
|
func (e *Ct) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
23
expr/dup.go
23
expr/dup.go
|
@ -29,16 +29,7 @@ type Dup struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Dup) marshal(fam byte) ([]byte, error) {
|
func (e *Dup) marshal(fam byte) ([]byte, error) {
|
||||||
attrs := []netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: unix.NFTA_DUP_SREG_ADDR, Data: binaryutil.BigEndian.PutUint32(e.RegAddr)},
|
|
||||||
}
|
|
||||||
|
|
||||||
if e.IsRegDevSet {
|
|
||||||
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_DUP_SREG_DEV, Data: binaryutil.BigEndian.PutUint32(e.RegDev)})
|
|
||||||
}
|
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -49,6 +40,18 @@ func (e *Dup) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Dup) marshalData(fam byte) ([]byte, error) {
|
||||||
|
attrs := []netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_DUP_SREG_ADDR, Data: binaryutil.BigEndian.PutUint32(e.RegAddr)},
|
||||||
|
}
|
||||||
|
|
||||||
|
if e.IsRegDevSet {
|
||||||
|
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_DUP_SREG_DEV, Data: binaryutil.BigEndian.PutUint32(e.RegDev)})
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes(attrs)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Dup) unmarshal(fam byte, data []byte) error {
|
func (e *Dup) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -44,6 +44,18 @@ type Dynset struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Dynset) marshal(fam byte) ([]byte, error) {
|
func (e *Dynset) marshal(fam byte) ([]byte, error) {
|
||||||
|
opData, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("dynset\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: opData},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Dynset) marshalData(fam byte) ([]byte, error) {
|
||||||
// See: https://git.netfilter.org/libnftnl/tree/src/expr/dynset.c
|
// See: https://git.netfilter.org/libnftnl/tree/src/expr/dynset.c
|
||||||
var opAttrs []netlink.Attribute
|
var opAttrs []netlink.Attribute
|
||||||
opAttrs = append(opAttrs, netlink.Attribute{Type: unix.NFTA_DYNSET_SREG_KEY, Data: binaryutil.BigEndian.PutUint32(e.SrcRegKey)})
|
opAttrs = append(opAttrs, netlink.Attribute{Type: unix.NFTA_DYNSET_SREG_KEY, Data: binaryutil.BigEndian.PutUint32(e.SrcRegKey)})
|
||||||
|
@ -89,17 +101,9 @@ func (e *Dynset) marshal(fam byte) ([]byte, error) {
|
||||||
opAttrs = append(opAttrs, netlink.Attribute{Type: NFTA_DYNSET_EXPRESSIONS, Data: elemData})
|
opAttrs = append(opAttrs, netlink.Attribute{Type: NFTA_DYNSET_EXPRESSIONS, Data: elemData})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opAttrs = append(opAttrs, netlink.Attribute{Type: unix.NFTA_DYNSET_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)})
|
opAttrs = append(opAttrs, netlink.Attribute{Type: unix.NFTA_DYNSET_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)})
|
||||||
|
return netlink.MarshalAttributes(opAttrs)
|
||||||
opData, err := netlink.MarshalAttributes(opAttrs)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("dynset\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: opData},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Dynset) unmarshal(fam byte, data []byte) error {
|
func (e *Dynset) unmarshal(fam byte, data []byte) error {
|
||||||
|
@ -125,7 +129,7 @@ func (e *Dynset) unmarshal(fam byte, data []byte) error {
|
||||||
case unix.NFTA_DYNSET_FLAGS:
|
case unix.NFTA_DYNSET_FLAGS:
|
||||||
e.Invert = (ad.Uint32() & unix.NFT_DYNSET_F_INV) != 0
|
e.Invert = (ad.Uint32() & unix.NFT_DYNSET_F_INV) != 0
|
||||||
case unix.NFTA_DYNSET_EXPR:
|
case unix.NFTA_DYNSET_EXPR:
|
||||||
exprs, err := parseexprfunc.ParseExprBytesFunc(fam, ad, ad.Bytes())
|
exprs, err := parseexprfunc.ParseExprBytesFunc(fam, ad)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
201
expr/expr.go
201
expr/expr.go
|
@ -25,8 +25,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
parseexprfunc.ParseExprBytesFunc = func(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]interface{}, error) {
|
parseexprfunc.ParseExprBytesFunc = func(fam byte, ad *netlink.AttributeDecoder, args ...string) ([]interface{}, error) {
|
||||||
exprs, err := exprsFromBytes(fam, ad, b)
|
exprs, err := exprsFromBytes(fam, ad, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ func init() {
|
||||||
}
|
}
|
||||||
return result, nil
|
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)
|
ad, err := netlink.NewAttributeDecoder(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -44,7 +44,7 @@ func init() {
|
||||||
ad.ByteOrder = binary.BigEndian
|
ad.ByteOrder = binary.BigEndian
|
||||||
var exprs []interface{}
|
var exprs []interface{}
|
||||||
for ad.Next() {
|
for ad.Next() {
|
||||||
e, err := parseexprfunc.ParseExprBytesFunc(fam, ad, b)
|
e, err := parseexprfunc.ParseExprBytesFunc(fam, ad, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return e, err
|
return e, err
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,10 @@ func Marshal(fam byte, e Any) ([]byte, error) {
|
||||||
return e.marshal(fam)
|
return e.marshal(fam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func MarshalExprData(fam byte, e Any) ([]byte, error) {
|
||||||
|
return e.marshalData(fam)
|
||||||
|
}
|
||||||
|
|
||||||
// Unmarshal fills an expression from the specified byte slice.
|
// Unmarshal fills an expression from the specified byte slice.
|
||||||
func Unmarshal(fam byte, data []byte, e Any) error {
|
func Unmarshal(fam byte, data []byte, e Any) error {
|
||||||
return e.unmarshal(fam, data)
|
return e.unmarshal(fam, data)
|
||||||
|
@ -66,8 +70,20 @@ func Unmarshal(fam byte, data []byte, e Any) error {
|
||||||
|
|
||||||
// exprsFromBytes parses nested raw expressions bytes
|
// exprsFromBytes parses nested raw expressions bytes
|
||||||
// to construct nftables expressions
|
// 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
|
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.Do(func(b []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(b)
|
ad, err := netlink.NewAttributeDecoder(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -84,65 +100,12 @@ func exprsFromBytes(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]Any, er
|
||||||
exprs = append(exprs, e)
|
exprs = append(exprs, e)
|
||||||
}
|
}
|
||||||
case unix.NFTA_EXPR_DATA:
|
case unix.NFTA_EXPR_DATA:
|
||||||
var e Any
|
e := exprFromName(name)
|
||||||
switch name {
|
|
||||||
case "ct":
|
|
||||||
e = &Ct{}
|
|
||||||
case "range":
|
|
||||||
e = &Range{}
|
|
||||||
case "meta":
|
|
||||||
e = &Meta{}
|
|
||||||
case "cmp":
|
|
||||||
e = &Cmp{}
|
|
||||||
case "counter":
|
|
||||||
e = &Counter{}
|
|
||||||
case "objref":
|
|
||||||
e = &Objref{}
|
|
||||||
case "payload":
|
|
||||||
e = &Payload{}
|
|
||||||
case "lookup":
|
|
||||||
e = &Lookup{}
|
|
||||||
case "immediate":
|
|
||||||
e = &Immediate{}
|
|
||||||
case "bitwise":
|
|
||||||
e = &Bitwise{}
|
|
||||||
case "redir":
|
|
||||||
e = &Redir{}
|
|
||||||
case "nat":
|
|
||||||
e = &NAT{}
|
|
||||||
case "limit":
|
|
||||||
e = &Limit{}
|
|
||||||
case "quota":
|
|
||||||
e = &Quota{}
|
|
||||||
case "dynset":
|
|
||||||
e = &Dynset{}
|
|
||||||
case "log":
|
|
||||||
e = &Log{}
|
|
||||||
case "exthdr":
|
|
||||||
e = &Exthdr{}
|
|
||||||
case "match":
|
|
||||||
e = &Match{}
|
|
||||||
case "target":
|
|
||||||
e = &Target{}
|
|
||||||
case "connlimit":
|
|
||||||
e = &Connlimit{}
|
|
||||||
case "queue":
|
|
||||||
e = &Queue{}
|
|
||||||
case "flow_offload":
|
|
||||||
e = &FlowOffload{}
|
|
||||||
case "reject":
|
|
||||||
e = &Reject{}
|
|
||||||
case "masq":
|
|
||||||
e = &Masq{}
|
|
||||||
case "hash":
|
|
||||||
e = &Hash{}
|
|
||||||
}
|
|
||||||
if e == nil {
|
if e == nil {
|
||||||
// TODO: introduce an opaque expression type so that users know
|
// TODO: introduce an opaque expression type so that users know
|
||||||
// something is here.
|
// something is here.
|
||||||
continue // unsupported expression type
|
continue // unsupported expression type
|
||||||
}
|
}
|
||||||
|
|
||||||
ad.Do(func(b []byte) error {
|
ad.Do(func(b []byte) error {
|
||||||
if err := Unmarshal(fam, b, e); err != nil {
|
if err := Unmarshal(fam, b, e); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -166,9 +129,67 @@ func exprsFromBytes(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]Any, er
|
||||||
return exprs, ad.Err()
|
return exprs, ad.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func exprFromName(name string) Any {
|
||||||
|
var e Any
|
||||||
|
switch name {
|
||||||
|
case "ct":
|
||||||
|
e = &Ct{}
|
||||||
|
case "range":
|
||||||
|
e = &Range{}
|
||||||
|
case "meta":
|
||||||
|
e = &Meta{}
|
||||||
|
case "cmp":
|
||||||
|
e = &Cmp{}
|
||||||
|
case "counter":
|
||||||
|
e = &Counter{}
|
||||||
|
case "objref":
|
||||||
|
e = &Objref{}
|
||||||
|
case "payload":
|
||||||
|
e = &Payload{}
|
||||||
|
case "lookup":
|
||||||
|
e = &Lookup{}
|
||||||
|
case "immediate":
|
||||||
|
e = &Immediate{}
|
||||||
|
case "bitwise":
|
||||||
|
e = &Bitwise{}
|
||||||
|
case "redir":
|
||||||
|
e = &Redir{}
|
||||||
|
case "nat":
|
||||||
|
e = &NAT{}
|
||||||
|
case "limit":
|
||||||
|
e = &Limit{}
|
||||||
|
case "quota":
|
||||||
|
e = &Quota{}
|
||||||
|
case "dynset":
|
||||||
|
e = &Dynset{}
|
||||||
|
case "log":
|
||||||
|
e = &Log{}
|
||||||
|
case "exthdr":
|
||||||
|
e = &Exthdr{}
|
||||||
|
case "match":
|
||||||
|
e = &Match{}
|
||||||
|
case "target":
|
||||||
|
e = &Target{}
|
||||||
|
case "connlimit":
|
||||||
|
e = &Connlimit{}
|
||||||
|
case "queue":
|
||||||
|
e = &Queue{}
|
||||||
|
case "flow_offload":
|
||||||
|
e = &FlowOffload{}
|
||||||
|
case "reject":
|
||||||
|
e = &Reject{}
|
||||||
|
case "masq":
|
||||||
|
e = &Masq{}
|
||||||
|
case "hash":
|
||||||
|
e = &Hash{}
|
||||||
|
}
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
// Any is an interface implemented by any expression type.
|
// Any is an interface implemented by any expression type.
|
||||||
type Any interface {
|
type Any interface {
|
||||||
marshal(fam byte) ([]byte, error)
|
marshal(fam byte) ([]byte, error)
|
||||||
|
marshalData(fam byte) ([]byte, error)
|
||||||
unmarshal(fam byte, data []byte) error
|
unmarshal(fam byte, data []byte) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +235,19 @@ type Meta struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Meta) marshal(fam byte) ([]byte, error) {
|
func (e *Meta) marshal(fam byte) ([]byte, error) {
|
||||||
regData := []byte{}
|
exprData, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("meta\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: exprData},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Meta) marshalData(fam byte) ([]byte, error) {
|
||||||
|
var regData []byte
|
||||||
exprData, err := netlink.MarshalAttributes(
|
exprData, err := netlink.MarshalAttributes(
|
||||||
[]netlink.Attribute{
|
[]netlink.Attribute{
|
||||||
{Type: unix.NFTA_META_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
{Type: unix.NFTA_META_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
||||||
|
@ -240,11 +273,7 @@ func (e *Meta) marshal(fam byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
exprData = append(exprData, regData...)
|
exprData = append(exprData, regData...)
|
||||||
|
return exprData, nil
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("meta\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: exprData},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Meta) unmarshal(fam byte, data []byte) error {
|
func (e *Meta) unmarshal(fam byte, data []byte) error {
|
||||||
|
@ -291,6 +320,17 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *Masq) marshal(fam byte) ([]byte, error) {
|
func (e *Masq) marshal(fam byte) ([]byte, error) {
|
||||||
|
msgData, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Masq) marshalData(fam byte) ([]byte, error) {
|
||||||
msgData := []byte{}
|
msgData := []byte{}
|
||||||
if !e.ToPorts {
|
if !e.ToPorts {
|
||||||
flags := uint32(0)
|
flags := uint32(0)
|
||||||
|
@ -327,10 +367,7 @@ func (e *Masq) marshal(fam byte) ([]byte, error) {
|
||||||
msgData = append(msgData, regsData...)
|
msgData = append(msgData, regsData...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
return msgData, nil
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("masq\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: msgData},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Masq) unmarshal(fam byte, data []byte) error {
|
func (e *Masq) unmarshal(fam byte, data []byte) error {
|
||||||
|
@ -377,17 +414,7 @@ type Cmp struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Cmp) marshal(fam byte) ([]byte, error) {
|
func (e *Cmp) marshal(fam byte) ([]byte, error) {
|
||||||
cmpData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
exprData, err := e.marshalData(fam)
|
||||||
{Type: unix.NFTA_DATA_VALUE, Data: e.Data},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
exprData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_CMP_SREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
|
||||||
{Type: unix.NFTA_CMP_OP, Data: binaryutil.BigEndian.PutUint32(uint32(e.Op))},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_CMP_DATA, Data: cmpData},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -397,6 +424,20 @@ func (e *Cmp) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Cmp) marshalData(fam byte) ([]byte, error) {
|
||||||
|
cmpData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_DATA_VALUE, Data: e.Data},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_CMP_SREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||||
|
{Type: unix.NFTA_CMP_OP, Data: binaryutil.BigEndian.PutUint32(uint32(e.Op))},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_CMP_DATA, Data: cmpData},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Cmp) unmarshal(fam byte, data []byte) error {
|
func (e *Cmp) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -40,6 +40,17 @@ type Exthdr struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exthdr) marshal(fam byte) ([]byte, error) {
|
func (e *Exthdr) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Exthdr) marshalData(fam byte) ([]byte, error) {
|
||||||
var attr []netlink.Attribute
|
var attr []netlink.Attribute
|
||||||
|
|
||||||
// Operations are differentiated by the Op and whether the SourceRegister
|
// Operations are differentiated by the Op and whether the SourceRegister
|
||||||
|
@ -64,14 +75,7 @@ func (e *Exthdr) marshal(fam byte) ([]byte, error) {
|
||||||
netlink.Attribute{Type: unix.NFTA_EXTHDR_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)})
|
netlink.Attribute{Type: unix.NFTA_EXTHDR_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)})
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attr)
|
return netlink.MarshalAttributes(attr)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Exthdr) unmarshal(fam byte, data []byte) error {
|
func (e *Exthdr) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
17
expr/fib.go
17
expr/fib.go
|
@ -37,6 +37,17 @@ type Fib struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Fib) marshal(fam byte) ([]byte, error) {
|
func (e *Fib) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Fib) marshalData(fam byte) ([]byte, error) {
|
||||||
data := []byte{}
|
data := []byte{}
|
||||||
reg, err := netlink.MarshalAttributes([]netlink.Attribute{
|
reg, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_FIB_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
{Type: unix.NFTA_FIB_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||||
|
@ -92,11 +103,7 @@ func (e *Fib) marshal(fam byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
data = append(data, rslt...)
|
data = append(data, rslt...)
|
||||||
}
|
}
|
||||||
|
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Fib) unmarshal(fam byte, data []byte) error {
|
func (e *Fib) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -28,9 +28,7 @@ type FlowOffload struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *FlowOffload) marshal(fam byte) ([]byte, error) {
|
func (e *FlowOffload) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: NFTNL_EXPR_FLOW_TABLE_NAME, Data: []byte(e.Name)},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -41,6 +39,12 @@ func (e *FlowOffload) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *FlowOffload) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: NFTNL_EXPR_FLOW_TABLE_NAME, Data: []byte(e.Name)},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *FlowOffload) unmarshal(fam byte, data []byte) error {
|
func (e *FlowOffload) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
20
expr/hash.go
20
expr/hash.go
|
@ -41,6 +41,17 @@ type Hash struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Hash) marshal(fam byte) ([]byte, error) {
|
func (e *Hash) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Hash) marshalData(fam byte) ([]byte, error) {
|
||||||
hashAttrs := []netlink.Attribute{
|
hashAttrs := []netlink.Attribute{
|
||||||
{Type: unix.NFTA_HASH_SREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.SourceRegister))},
|
{Type: unix.NFTA_HASH_SREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.SourceRegister))},
|
||||||
{Type: unix.NFTA_HASH_DREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.DestRegister))},
|
{Type: unix.NFTA_HASH_DREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.DestRegister))},
|
||||||
|
@ -56,14 +67,7 @@ func (e *Hash) marshal(fam byte) ([]byte, error) {
|
||||||
{Type: unix.NFTA_HASH_OFFSET, Data: binaryutil.BigEndian.PutUint32(uint32(e.Offset))},
|
{Type: unix.NFTA_HASH_OFFSET, Data: binaryutil.BigEndian.PutUint32(uint32(e.Offset))},
|
||||||
{Type: unix.NFTA_HASH_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
|
{Type: unix.NFTA_HASH_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
|
||||||
}...)
|
}...)
|
||||||
data, err := netlink.MarshalAttributes(hashAttrs)
|
return netlink.MarshalAttributes(hashAttrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Hash) unmarshal(fam byte, data []byte) error {
|
func (e *Hash) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -29,6 +29,17 @@ type Immediate struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Immediate) marshal(fam byte) ([]byte, error) {
|
func (e *Immediate) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Immediate) marshalData(fam byte) ([]byte, error) {
|
||||||
immData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
immData, err := netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_DATA_VALUE, Data: e.Data},
|
{Type: unix.NFTA_DATA_VALUE, Data: e.Data},
|
||||||
})
|
})
|
||||||
|
@ -36,17 +47,10 @@ func (e *Immediate) marshal(fam byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_IMMEDIATE_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
{Type: unix.NFTA_IMMEDIATE_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_IMMEDIATE_DATA, Data: immData},
|
{Type: unix.NLA_F_NESTED | unix.NFTA_IMMEDIATE_DATA, Data: immData},
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Immediate) unmarshal(fam byte, data []byte) error {
|
func (e *Immediate) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -72,6 +72,18 @@ type Limit struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Limit) marshal(fam byte) ([]byte, error) {
|
func (l *Limit) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := l.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("limit\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Limit) marshalData(fam byte) ([]byte, error) {
|
||||||
var flags uint32
|
var flags uint32
|
||||||
if l.Over {
|
if l.Over {
|
||||||
flags = unix.NFT_LIMIT_F_INV
|
flags = unix.NFT_LIMIT_F_INV
|
||||||
|
@ -84,15 +96,7 @@ func (l *Limit) marshal(fam byte) ([]byte, error) {
|
||||||
{Type: unix.NFTA_LIMIT_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)},
|
{Type: unix.NFTA_LIMIT_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)},
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("limit\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Limit) unmarshal(fam byte, data []byte) error {
|
func (l *Limit) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
22
expr/log.go
22
expr/log.go
|
@ -69,6 +69,18 @@ type Log struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Log) marshal(fam byte) ([]byte, error) {
|
func (e *Log) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("log\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Log) marshalData(fam byte) ([]byte, error) {
|
||||||
// Per https://git.netfilter.org/libnftnl/tree/src/expr/log.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n129
|
// Per https://git.netfilter.org/libnftnl/tree/src/expr/log.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n129
|
||||||
attrs := make([]netlink.Attribute, 0)
|
attrs := make([]netlink.Attribute, 0)
|
||||||
if e.Key&(1<<unix.NFTA_LOG_GROUP) != 0 {
|
if e.Key&(1<<unix.NFTA_LOG_GROUP) != 0 {
|
||||||
|
@ -109,15 +121,7 @@ func (e *Log) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("log\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Log) unmarshal(fam byte, data []byte) error {
|
func (e *Log) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -34,6 +34,18 @@ type Lookup struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Lookup) marshal(fam byte) ([]byte, error) {
|
func (e *Lookup) marshal(fam byte) ([]byte, error) {
|
||||||
|
opData, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("lookup\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: opData},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Lookup) marshalData(fam byte) ([]byte, error) {
|
||||||
// See: https://git.netfilter.org/libnftnl/tree/src/expr/lookup.c?id=6dc1c3d8bb64077da7f3f28c7368fb087d10a492#n115
|
// See: https://git.netfilter.org/libnftnl/tree/src/expr/lookup.c?id=6dc1c3d8bb64077da7f3f28c7368fb087d10a492#n115
|
||||||
var opAttrs []netlink.Attribute
|
var opAttrs []netlink.Attribute
|
||||||
if e.SourceRegister != 0 {
|
if e.SourceRegister != 0 {
|
||||||
|
@ -49,15 +61,7 @@ func (e *Lookup) marshal(fam byte) ([]byte, error) {
|
||||||
netlink.Attribute{Type: unix.NFTA_LOOKUP_SET, Data: []byte(e.SetName + "\x00")},
|
netlink.Attribute{Type: unix.NFTA_LOOKUP_SET, Data: []byte(e.SetName + "\x00")},
|
||||||
netlink.Attribute{Type: unix.NFTA_LOOKUP_SET_ID, Data: binaryutil.BigEndian.PutUint32(e.SetID)},
|
netlink.Attribute{Type: unix.NFTA_LOOKUP_SET_ID, Data: binaryutil.BigEndian.PutUint32(e.SetID)},
|
||||||
)
|
)
|
||||||
opData, err := netlink.MarshalAttributes(opAttrs)
|
return netlink.MarshalAttributes(opAttrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("lookup\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: opData},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Lookup) unmarshal(fam byte, data []byte) error {
|
func (e *Lookup) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -18,6 +18,17 @@ type Match struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Match) marshal(fam byte) ([]byte, error) {
|
func (e *Match) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Match) marshalData(fam byte) ([]byte, error) {
|
||||||
// Per https://git.netfilter.org/libnftnl/tree/src/expr/match.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n38
|
// Per https://git.netfilter.org/libnftnl/tree/src/expr/match.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n38
|
||||||
name := e.Name
|
name := e.Name
|
||||||
// limit the extension name as (some) user-space tools do and leave room for
|
// limit the extension name as (some) user-space tools do and leave room for
|
||||||
|
@ -36,15 +47,7 @@ func (e *Match) marshal(fam byte) ([]byte, error) {
|
||||||
{Type: unix.NFTA_MATCH_REV, Data: binaryutil.BigEndian.PutUint32(e.Rev)},
|
{Type: unix.NFTA_MATCH_REV, Data: binaryutil.BigEndian.PutUint32(e.Rev)},
|
||||||
{Type: unix.NFTA_MATCH_INFO, Data: info},
|
{Type: unix.NFTA_MATCH_INFO, Data: info},
|
||||||
}
|
}
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Match) unmarshal(fam byte, data []byte) error {
|
func (e *Match) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
20
expr/nat.go
20
expr/nat.go
|
@ -57,6 +57,17 @@ type NAT struct {
|
||||||
// | 00 00 00 02 | | data | reg 2
|
// | 00 00 00 02 | | data | reg 2
|
||||||
|
|
||||||
func (e *NAT) marshal(fam byte) ([]byte, error) {
|
func (e *NAT) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *NAT) marshalData(fam byte) ([]byte, error) {
|
||||||
attrs := []netlink.Attribute{
|
attrs := []netlink.Attribute{
|
||||||
{Type: unix.NFTA_NAT_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
|
{Type: unix.NFTA_NAT_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
|
||||||
{Type: unix.NFTA_NAT_FAMILY, Data: binaryutil.BigEndian.PutUint32(e.Family)},
|
{Type: unix.NFTA_NAT_FAMILY, Data: binaryutil.BigEndian.PutUint32(e.Family)},
|
||||||
|
@ -90,14 +101,7 @@ func (e *NAT) marshal(fam byte) ([]byte, error) {
|
||||||
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_NAT_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)})
|
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_NAT_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)})
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NAT) unmarshal(fam byte, data []byte) error {
|
func (e *NAT) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -27,6 +27,10 @@ func (e *Notrack) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Notrack) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return []byte("notrack\x00"), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Notrack) unmarshal(fam byte, data []byte) error {
|
func (e *Notrack) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,18 @@ type Numgen struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Numgen) marshal(fam byte) ([]byte, error) {
|
func (e *Numgen) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("numgen\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Numgen) marshalData(fam byte) ([]byte, error) {
|
||||||
// Currently only two types are supported, failing if Type is not of two known types
|
// Currently only two types are supported, failing if Type is not of two known types
|
||||||
switch e.Type {
|
switch e.Type {
|
||||||
case unix.NFT_NG_INCREMENTAL:
|
case unix.NFT_NG_INCREMENTAL:
|
||||||
|
@ -40,20 +52,12 @@ func (e *Numgen) marshal(fam byte) ([]byte, error) {
|
||||||
return nil, fmt.Errorf("unsupported numgen type %d", e.Type)
|
return nil, fmt.Errorf("unsupported numgen type %d", e.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_NG_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
{Type: unix.NFTA_NG_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||||
{Type: unix.NFTA_NG_MODULUS, Data: binaryutil.BigEndian.PutUint32(e.Modulus)},
|
{Type: unix.NFTA_NG_MODULUS, Data: binaryutil.BigEndian.PutUint32(e.Modulus)},
|
||||||
{Type: unix.NFTA_NG_TYPE, Data: binaryutil.BigEndian.PutUint32(e.Type)},
|
{Type: unix.NFTA_NG_TYPE, Data: binaryutil.BigEndian.PutUint32(e.Type)},
|
||||||
{Type: unix.NFTA_NG_OFFSET, Data: binaryutil.BigEndian.PutUint32(e.Offset)},
|
{Type: unix.NFTA_NG_OFFSET, Data: binaryutil.BigEndian.PutUint32(e.Offset)},
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("numgen\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Numgen) unmarshal(fam byte, data []byte) error {
|
func (e *Numgen) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -28,10 +28,7 @@ type Objref struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Objref) marshal(fam byte) ([]byte, error) {
|
func (e *Objref) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{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?!
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -42,6 +39,13 @@ func (e *Objref) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Objref) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return 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?!
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Objref) unmarshal(fam byte, data []byte) error {
|
func (e *Objref) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -58,7 +58,18 @@ type Payload struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Payload) marshal(fam byte) ([]byte, error) {
|
func (e *Payload) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Payload) marshalData(fam byte) ([]byte, error) {
|
||||||
var attrs []netlink.Attribute
|
var attrs []netlink.Attribute
|
||||||
|
|
||||||
if e.OperationType == PayloadWrite {
|
if e.OperationType == PayloadWrite {
|
||||||
|
@ -89,15 +100,7 @@ func (e *Payload) marshal(fam byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Payload) unmarshal(fam byte, data []byte) error {
|
func (e *Payload) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -44,14 +44,7 @@ type Queue struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Queue) marshal(fam byte) ([]byte, error) {
|
func (e *Queue) marshal(fam byte) ([]byte, error) {
|
||||||
if e.Total == 0 {
|
data, err := e.marshalData(fam)
|
||||||
e.Total = 1 // The total default value is 1
|
|
||||||
}
|
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_QUEUE_NUM, Data: binaryutil.BigEndian.PutUint16(e.Num)},
|
|
||||||
{Type: unix.NFTA_QUEUE_TOTAL, Data: binaryutil.BigEndian.PutUint16(e.Total)},
|
|
||||||
{Type: unix.NFTA_QUEUE_FLAGS, Data: binaryutil.BigEndian.PutUint16(uint16(e.Flag))},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -61,6 +54,17 @@ func (e *Queue) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Queue) marshalData(fam byte) ([]byte, error) {
|
||||||
|
if e.Total == 0 {
|
||||||
|
e.Total = 1 // The total default value is 1
|
||||||
|
}
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_QUEUE_NUM, Data: binaryutil.BigEndian.PutUint16(e.Num)},
|
||||||
|
{Type: unix.NFTA_QUEUE_TOTAL, Data: binaryutil.BigEndian.PutUint16(e.Total)},
|
||||||
|
{Type: unix.NFTA_QUEUE_FLAGS, Data: binaryutil.BigEndian.PutUint16(uint16(e.Flag))},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Queue) unmarshal(fam byte, data []byte) error {
|
func (e *Queue) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -30,6 +30,18 @@ type Quota struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Quota) marshal(fam byte) ([]byte, error) {
|
func (q *Quota) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := q.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("quota\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Quota) marshalData(fam byte) ([]byte, error) {
|
||||||
attrs := []netlink.Attribute{
|
attrs := []netlink.Attribute{
|
||||||
{Type: unix.NFTA_QUOTA_BYTES, Data: binaryutil.BigEndian.PutUint64(q.Bytes)},
|
{Type: unix.NFTA_QUOTA_BYTES, Data: binaryutil.BigEndian.PutUint64(q.Bytes)},
|
||||||
{Type: unix.NFTA_QUOTA_CONSUMED, Data: binaryutil.BigEndian.PutUint64(q.Consumed)},
|
{Type: unix.NFTA_QUOTA_CONSUMED, Data: binaryutil.BigEndian.PutUint64(q.Consumed)},
|
||||||
|
@ -44,15 +56,7 @@ func (q *Quota) marshal(fam byte) ([]byte, error) {
|
||||||
Data: binaryutil.BigEndian.PutUint32(flags),
|
Data: binaryutil.BigEndian.PutUint32(flags),
|
||||||
})
|
})
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("quota\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *Quota) unmarshal(fam byte, data []byte) error {
|
func (q *Quota) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -31,6 +31,18 @@ type Range struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Range) marshal(fam byte) ([]byte, error) {
|
func (e *Range) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Range) marshalData(fam byte) ([]byte, error) {
|
||||||
var attrs []netlink.Attribute
|
var attrs []netlink.Attribute
|
||||||
var err error
|
var err error
|
||||||
var rangeFromData, rangeToData []byte
|
var rangeFromData, rangeToData []byte
|
||||||
|
@ -57,11 +69,7 @@ func (e *Range) marshal(fam byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
data = append(data, rangeFromData...)
|
data = append(data, rangeFromData...)
|
||||||
data = append(data, rangeToData...)
|
data = append(data, rangeToData...)
|
||||||
|
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Range) unmarshal(fam byte, data []byte) error {
|
func (e *Range) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -29,6 +29,18 @@ type Redir struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Redir) marshal(fam byte) ([]byte, error) {
|
func (e *Redir) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
{Type: unix.NFTA_EXPR_NAME, Data: []byte("redir\x00")},
|
||||||
|
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Redir) marshalData(fam byte) ([]byte, error) {
|
||||||
var attrs []netlink.Attribute
|
var attrs []netlink.Attribute
|
||||||
if e.RegisterProtoMin > 0 {
|
if e.RegisterProtoMin > 0 {
|
||||||
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_REDIR_REG_PROTO_MIN, Data: binaryutil.BigEndian.PutUint32(e.RegisterProtoMin)})
|
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_REDIR_REG_PROTO_MIN, Data: binaryutil.BigEndian.PutUint32(e.RegisterProtoMin)})
|
||||||
|
@ -40,15 +52,7 @@ func (e *Redir) marshal(fam byte) ([]byte, error) {
|
||||||
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_REDIR_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)})
|
attrs = append(attrs, netlink.Attribute{Type: unix.NFTA_REDIR_FLAGS, Data: binaryutil.BigEndian.PutUint32(e.Flags)})
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
|
||||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte("redir\x00")},
|
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Redir) unmarshal(fam byte, data []byte) error {
|
func (e *Redir) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -28,10 +28,7 @@ type Reject struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Reject) marshal(fam byte) ([]byte, error) {
|
func (e *Reject) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: unix.NFTA_REJECT_TYPE, Data: binaryutil.BigEndian.PutUint32(e.Type)},
|
|
||||||
{Type: unix.NFTA_REJECT_ICMP_CODE, Data: []byte{e.Code}},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -41,6 +38,13 @@ func (e *Reject) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Reject) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return 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}},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Reject) unmarshal(fam byte, data []byte) error {
|
func (e *Reject) unmarshal(fam byte, data []byte) error {
|
||||||
ad, err := netlink.NewAttributeDecoder(data)
|
ad, err := netlink.NewAttributeDecoder(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
12
expr/rt.go
12
expr/rt.go
|
@ -37,10 +37,7 @@ type Rt struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Rt) marshal(fam byte) ([]byte, error) {
|
func (e *Rt) marshal(fam byte) ([]byte, error) {
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
data, err := e.marshalData(fam)
|
||||||
{Type: unix.NFTA_RT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
|
||||||
{Type: unix.NFTA_RT_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -50,6 +47,13 @@ func (e *Rt) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Rt) marshalData(fam byte) ([]byte, error) {
|
||||||
|
return 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)},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Rt) unmarshal(fam byte, data []byte) error {
|
func (e *Rt) unmarshal(fam byte, data []byte) error {
|
||||||
return fmt.Errorf("not yet implemented")
|
return fmt.Errorf("not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,23 +49,26 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *Socket) marshal(fam byte) ([]byte, error) {
|
func (e *Socket) marshal(fam byte) ([]byte, error) {
|
||||||
|
exprData, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Socket) marshalData(fam byte) ([]byte, error) {
|
||||||
// NOTE: Socket.Level is only used when Socket.Key == SocketKeyCgroupv2. But `nft` always encoding it. Check link below:
|
// 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
|
// http://git.netfilter.org/nftables/tree/src/netlink_linearize.c?id=0583bac241ea18c9d7f61cb20ca04faa1e043b78#n319
|
||||||
exprData, err := netlink.MarshalAttributes(
|
return netlink.MarshalAttributes(
|
||||||
[]netlink.Attribute{
|
[]netlink.Attribute{
|
||||||
{Type: NFTA_SOCKET_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
{Type: NFTA_SOCKET_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
|
||||||
{Type: NFTA_SOCKET_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
{Type: NFTA_SOCKET_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
|
||||||
{Type: NFTA_SOCKET_LEVEL, Data: binaryutil.BigEndian.PutUint32(uint32(e.Level))},
|
{Type: NFTA_SOCKET_LEVEL, Data: binaryutil.BigEndian.PutUint32(uint32(e.Level))},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Socket) unmarshal(fam byte, data []byte) error {
|
func (e *Socket) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -21,6 +21,17 @@ type Target struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Target) marshal(fam byte) ([]byte, error) {
|
func (e *Target) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Target) marshalData(fam byte) ([]byte, error) {
|
||||||
// Per https://git.netfilter.org/libnftnl/tree/src/expr/target.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n38
|
// Per https://git.netfilter.org/libnftnl/tree/src/expr/target.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n38
|
||||||
name := e.Name
|
name := e.Name
|
||||||
// limit the extension name as (some) user-space tools do and leave room for
|
// limit the extension name as (some) user-space tools do and leave room for
|
||||||
|
@ -40,15 +51,7 @@ func (e *Target) marshal(fam byte) ([]byte, error) {
|
||||||
{Type: unix.NFTA_TARGET_INFO, Data: info},
|
{Type: unix.NFTA_TARGET_INFO, Data: info},
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Target) unmarshal(fam byte, data []byte) error {
|
func (e *Target) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -40,6 +40,17 @@ type TProxy struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *TProxy) marshal(fam byte) ([]byte, error) {
|
func (e *TProxy) marshal(fam byte) ([]byte, error) {
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *TProxy) marshalData(fam byte) ([]byte, error) {
|
||||||
attrs := []netlink.Attribute{
|
attrs := []netlink.Attribute{
|
||||||
{Type: NFTA_TPROXY_FAMILY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Family))},
|
{Type: NFTA_TPROXY_FAMILY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Family))},
|
||||||
{Type: NFTA_TPROXY_REG_PORT, Data: binaryutil.BigEndian.PutUint32(e.RegPort)},
|
{Type: NFTA_TPROXY_REG_PORT, Data: binaryutil.BigEndian.PutUint32(e.RegPort)},
|
||||||
|
@ -52,14 +63,7 @@ func (e *TProxy) marshal(fam byte) ([]byte, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes(attrs)
|
return netlink.MarshalAttributes(attrs)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *TProxy) unmarshal(fam byte, data []byte) error {
|
func (e *TProxy) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -64,7 +64,17 @@ func (e *Verdict) marshal(fam byte) ([]byte, error) {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
data, err := e.marshalData(fam)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Verdict) marshalData(fam byte) ([]byte, error) {
|
||||||
attrs := []netlink.Attribute{
|
attrs := []netlink.Attribute{
|
||||||
{Type: unix.NFTA_VERDICT_CODE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Kind))},
|
{Type: unix.NFTA_VERDICT_CODE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Kind))},
|
||||||
}
|
}
|
||||||
|
@ -83,17 +93,10 @@ func (e *Verdict) marshal(fam byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := netlink.MarshalAttributes([]netlink.Attribute{
|
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
{Type: unix.NFTA_IMMEDIATE_DREG, Data: binaryutil.BigEndian.PutUint32(unix.NFT_REG_VERDICT)},
|
{Type: unix.NFTA_IMMEDIATE_DREG, Data: binaryutil.BigEndian.PutUint32(unix.NFT_REG_VERDICT)},
|
||||||
{Type: unix.NLA_F_NESTED | unix.NFTA_IMMEDIATE_DATA, Data: immData},
|
{Type: unix.NLA_F_NESTED | unix.NFTA_IMMEDIATE_DATA, Data: immData},
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
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},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Verdict) unmarshal(fam byte, data []byte) error {
|
func (e *Verdict) unmarshal(fam byte, data []byte) error {
|
||||||
|
|
|
@ -5,6 +5,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ParseExprBytesFunc func(fam byte, ad *netlink.AttributeDecoder, b []byte) ([]interface{}, error)
|
ParseExprBytesFunc func(fam byte, ad *netlink.AttributeDecoder, args ...string) ([]interface{}, error)
|
||||||
ParseExprMsgFunc func(fam byte, b []byte) ([]interface{}, error)
|
ParseExprMsgFunc func(fam byte, b []byte, args ...string) ([]interface{}, error)
|
||||||
)
|
)
|
||||||
|
|
|
@ -259,7 +259,7 @@ func (monitor *Monitor) monitor() {
|
||||||
}
|
}
|
||||||
monitor.eventCh <- event
|
monitor.eventCh <- event
|
||||||
case unix.NFT_MSG_NEWOBJ, unix.NFT_MSG_DELOBJ:
|
case unix.NFT_MSG_NEWOBJ, unix.NFT_MSG_DELOBJ:
|
||||||
obj, err := objFromMsg(msg)
|
obj, err := objFromMsg(msg, true)
|
||||||
event := &MonitorEvent{
|
event := &MonitorEvent{
|
||||||
Type: MonitorEventType(msgType),
|
Type: MonitorEventType(msgType),
|
||||||
Data: obj,
|
Data: obj,
|
||||||
|
|
530
nftables_test.go
530
nftables_test.go
|
@ -1783,7 +1783,7 @@ func TestListChainByName(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListChainByNameUsingLasting(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())
|
conn, err := nftables.New(nftables.WithNetNSFd(int(newNS)), nftables.AsLasting())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("nftables.New() failed: %v", err)
|
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
|
// not specifying correct family should return err since no table in ipv4
|
||||||
tr, err = conn.ListTable(table2.Name)
|
if _, err = conn.ListTable(table2.Name); err == nil {
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("conn.ListTable() should have failed")
|
t.Fatalf("conn.ListTable() should have failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2106,17 +2105,18 @@ func TestGetObjReset(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := &nftables.Table{Name: "filter", Family: nftables.TableFamilyIPv4}
|
filter := &nftables.Table{Name: "filter", Family: nftables.TableFamilyIPv4}
|
||||||
obj, err := c.ResetObject(&nftables.CounterObj{
|
obj, err := c.ResetObject(&nftables.ObjAttr{
|
||||||
Table: filter,
|
Table: filter,
|
||||||
Name: "fwded",
|
Name: "fwded",
|
||||||
|
Type: nftables.ObjTypeCounter,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
co, ok := obj.(*nftables.CounterObj)
|
co, ok := obj.(*nftables.ObjAttr)
|
||||||
if !ok {
|
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 {
|
if got, want := co.Table.Name, filter.Name; got != want {
|
||||||
t.Errorf("unexpected table name: got %q, want %q", got, want)
|
t.Errorf("unexpected table name: got %q, want %q", got, want)
|
||||||
|
@ -2124,10 +2124,14 @@ func TestGetObjReset(t *testing.T) {
|
||||||
if got, want := co.Table.Family, filter.Family; got != want {
|
if got, want := co.Table.Family, filter.Family; got != want {
|
||||||
t.Errorf("unexpected table family: got %d, want %d", 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)
|
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)
|
t.Errorf("unexpected number of bytes: got %d, want %d", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2164,6 +2168,366 @@ func TestObjAPI(t *testing.T) {
|
||||||
Priority: nftables.ChainPriorityFilter,
|
Priority: nftables.ChainPriorityFilter,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
counter1 := c.AddObj(&nftables.ObjAttr{
|
||||||
|
Table: table,
|
||||||
|
Name: "fwded1",
|
||||||
|
Type: nftables.ObjTypeCounter,
|
||||||
|
Obj: &expr.Counter{
|
||||||
|
Bytes: 1,
|
||||||
|
Packets: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
counter2 := c.AddObj(&nftables.ObjAttr{
|
||||||
|
Table: table,
|
||||||
|
Name: "fwded2",
|
||||||
|
Type: nftables.ObjTypeCounter,
|
||||||
|
Obj: &expr.Counter{
|
||||||
|
Bytes: 1,
|
||||||
|
Packets: 1,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
c.AddObj(&nftables.ObjAttr{
|
||||||
|
Table: tableOther,
|
||||||
|
Name: "fwdedOther",
|
||||||
|
Type: nftables.ObjTypeCounter,
|
||||||
|
Obj: &expr.Counter{
|
||||||
|
Bytes: 0,
|
||||||
|
Packets: 0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
c.AddRule(&nftables.Rule{
|
||||||
|
Table: table,
|
||||||
|
Chain: chain,
|
||||||
|
Exprs: []expr.Any{
|
||||||
|
&expr.Objref{
|
||||||
|
Type: 1,
|
||||||
|
Name: "fwded1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := c.Flush(); err != nil {
|
||||||
|
t.Fatalf(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
objs, err := c.GetObjects(table)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObjects(table) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := len(objs); got != 2 {
|
||||||
|
t.Fatalf("unexpected number of objects: got %d, want %d", got, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
objsOther, err := c.GetObjects(tableOther)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObjects(tableOther) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := len(objsOther); got != 1 {
|
||||||
|
t.Fatalf("unexpected number of objects: got %d, want %d", got, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj1, err := c.GetObject(counter1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObject(counter1) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rcounter1, ok := obj1.(*nftables.ObjAttr)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("unexpected type: got %T, want *nftables.ObjAttr", obj1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rcounter1.Name != "fwded1" {
|
||||||
|
t.Fatalf("unexpected counter name: got %s, want %s", rcounter1.Name, "fwded1")
|
||||||
|
}
|
||||||
|
|
||||||
|
obj2, err := c.GetObject(counter2)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObject(counter2) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rcounter2, ok := obj2.(*nftables.ObjAttr)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("unexpected type: got %T, want *nftables.CounterObj", obj2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rcounter2.Name != "fwded2" {
|
||||||
|
t.Fatalf("unexpected counter name: got %s, want %s", rcounter2.Name, "fwded2")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.ResetObject(counter1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.ResetObjects(table) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj1, err = c.GetObject(counter1)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObject(counter1) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if counter1 := obj1.(*nftables.ObjAttr).Obj.(*expr.Counter); counter1.Packets > 0 {
|
||||||
|
t.Errorf("unexpected packets number: got %d, want %d", counter1.Packets, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj2, err = c.GetObject(counter2)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObject(counter2) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if counter2 := obj2.(*nftables.ObjAttr).Obj.(*expr.Counter); counter2.Packets != 1 {
|
||||||
|
t.Errorf("unexpected packets number: got %d, want %d", counter2.Packets, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
legacy, err := c.GetObj(counter1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObj(counter1) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(legacy) != 2 {
|
||||||
|
t.Errorf("unexpected number of objects: got %d, want %d", len(legacy), 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
legacyReset, err := c.GetObjReset(counter1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("c.GetObjReset(counter1) failed: %v failed", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(legacyReset) != 2 {
|
||||||
|
t.Errorf("unexpected number of objects: got %d, want %d", len(legacyReset), 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteLegacyQuotaObj(t *testing.T) {
|
||||||
|
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||||
|
defer nftest.CleanupSystemConn(t, newNS)
|
||||||
|
conn.FlushRuleset()
|
||||||
|
defer conn.FlushRuleset()
|
||||||
|
|
||||||
|
table := &nftables.Table{
|
||||||
|
Name: "quota_demo",
|
||||||
|
Family: nftables.TableFamilyIPv4,
|
||||||
|
}
|
||||||
|
tr := conn.AddTable(table)
|
||||||
|
|
||||||
|
c := &nftables.Chain{
|
||||||
|
Name: "filter",
|
||||||
|
Table: table,
|
||||||
|
}
|
||||||
|
conn.AddChain(c)
|
||||||
|
|
||||||
|
o := &nftables.QuotaObj{
|
||||||
|
Table: tr,
|
||||||
|
Name: "q_test",
|
||||||
|
Bytes: 0x06400000,
|
||||||
|
Consumed: 0,
|
||||||
|
Over: true,
|
||||||
|
}
|
||||||
|
conn.AddObj(o)
|
||||||
|
|
||||||
|
if err := conn.Flush(); err != nil {
|
||||||
|
t.Fatalf("conn.Flush() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj, err := conn.GetObj(&nftables.QuotaObj{
|
||||||
|
Table: table,
|
||||||
|
Name: "q_test",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("conn.GetObj() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := len(obj), 1; got != want {
|
||||||
|
t.Fatalf("unexpected number of objects: got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := obj[0], o; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("got = %+v, want = %+v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.DeleteObject(&nftables.QuotaObj{
|
||||||
|
Table: tr,
|
||||||
|
Name: "q_test",
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := conn.Flush(); err != nil {
|
||||||
|
t.Fatalf("conn.Flush() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj, err = conn.GetObj(&nftables.QuotaObj{
|
||||||
|
Table: table,
|
||||||
|
Name: "q_test",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("conn.GetObj() failed: %v", err)
|
||||||
|
}
|
||||||
|
if got, want := len(obj), 0; got != want {
|
||||||
|
t.Fatalf("unexpected object list length: got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddLegacyQuotaObj(t *testing.T) {
|
||||||
|
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||||
|
defer nftest.CleanupSystemConn(t, newNS)
|
||||||
|
conn.FlushRuleset()
|
||||||
|
defer conn.FlushRuleset()
|
||||||
|
|
||||||
|
table := &nftables.Table{
|
||||||
|
Name: "quota_demo",
|
||||||
|
Family: nftables.TableFamilyIPv4,
|
||||||
|
}
|
||||||
|
tr := conn.AddTable(table)
|
||||||
|
|
||||||
|
c := &nftables.Chain{
|
||||||
|
Name: "filter",
|
||||||
|
Table: table,
|
||||||
|
}
|
||||||
|
conn.AddChain(c)
|
||||||
|
|
||||||
|
o := &nftables.QuotaObj{
|
||||||
|
Table: tr,
|
||||||
|
Name: "q_test",
|
||||||
|
Bytes: 0x06400000,
|
||||||
|
Consumed: 0,
|
||||||
|
Over: true,
|
||||||
|
}
|
||||||
|
conn.AddObj(o)
|
||||||
|
|
||||||
|
if err := conn.Flush(); err != nil {
|
||||||
|
t.Errorf("conn.Flush() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj, err := conn.GetObj(&nftables.QuotaObj{
|
||||||
|
Table: table,
|
||||||
|
Name: "q_test",
|
||||||
|
})
|
||||||
|
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.QuotaObj)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("unexpected type: got %T, want *QuotaObj", 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 {
|
||||||
|
t.Fatalf("quota bytes mismatch: got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
if got, want := o1.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 {
|
||||||
|
t.Fatalf("quota over mismatch: got %v, want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddLegacyQuotaObjRef(t *testing.T) {
|
||||||
|
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||||
|
defer nftest.CleanupSystemConn(t, newNS)
|
||||||
|
conn.FlushRuleset()
|
||||||
|
defer conn.FlushRuleset()
|
||||||
|
|
||||||
|
table := &nftables.Table{
|
||||||
|
Name: "quota_demo",
|
||||||
|
Family: nftables.TableFamilyIPv4,
|
||||||
|
}
|
||||||
|
tr := conn.AddTable(table)
|
||||||
|
|
||||||
|
c := &nftables.Chain{
|
||||||
|
Name: "filter",
|
||||||
|
Table: table,
|
||||||
|
}
|
||||||
|
conn.AddChain(c)
|
||||||
|
|
||||||
|
o := &nftables.QuotaObj{
|
||||||
|
Table: tr,
|
||||||
|
Name: "q_test",
|
||||||
|
Bytes: 0x06400000,
|
||||||
|
Consumed: 0,
|
||||||
|
Over: true,
|
||||||
|
}
|
||||||
|
conn.AddObj(o)
|
||||||
|
|
||||||
|
r := &nftables.Rule{
|
||||||
|
Table: table,
|
||||||
|
Chain: c,
|
||||||
|
Exprs: []expr.Any{
|
||||||
|
&expr.Objref{
|
||||||
|
Type: 2,
|
||||||
|
Name: "q_test",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
conn.AddRule(r)
|
||||||
|
if err := conn.Flush(); err != nil {
|
||||||
|
t.Fatalf("failed to flush: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rules, err := conn.GetRules(table, c)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get rules: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got, want := len(rules), 1; got != want {
|
||||||
|
t.Fatalf("unexpected number of rules: got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
if got, want := len(rules[0].Exprs), 1; got != want {
|
||||||
|
t.Fatalf("unexpected number of exprs: got %d, want %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
objref, ok := rules[0].Exprs[0].(*expr.Objref)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("Exprs[0] is type %T, want *expr.Objref", rules[0].Exprs[0])
|
||||||
|
}
|
||||||
|
if want := r.Exprs[0]; !reflect.DeepEqual(objref, want) {
|
||||||
|
t.Errorf("objref expr = %+v, wanted %+v", objref, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestObjAPICounterLegacyType(t *testing.T) {
|
||||||
|
if os.Getenv("TRAVIS") == "true" {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new network namespace to test these operations,
|
||||||
|
// and tear down the namespace at test completion.
|
||||||
|
c, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||||
|
defer nftest.CleanupSystemConn(t, newNS)
|
||||||
|
|
||||||
|
// Clear all rules at the beginning + end of the test.
|
||||||
|
c.FlushRuleset()
|
||||||
|
defer c.FlushRuleset()
|
||||||
|
|
||||||
|
table := c.AddTable(&nftables.Table{
|
||||||
|
Family: nftables.TableFamilyIPv4,
|
||||||
|
Name: "filter",
|
||||||
|
})
|
||||||
|
|
||||||
|
tableOther := c.AddTable(&nftables.Table{
|
||||||
|
Family: nftables.TableFamilyIPv4,
|
||||||
|
Name: "foo",
|
||||||
|
})
|
||||||
|
|
||||||
|
chain := c.AddChain(&nftables.Chain{
|
||||||
|
Name: "chain",
|
||||||
|
Table: table,
|
||||||
|
Type: nftables.ChainTypeFilter,
|
||||||
|
Hooknum: nftables.ChainHookPostrouting,
|
||||||
|
Priority: nftables.ChainPriorityFilter,
|
||||||
|
})
|
||||||
|
|
||||||
counter1 := c.AddObj(&nftables.CounterObj{
|
counter1 := c.AddObj(&nftables.CounterObj{
|
||||||
Table: table,
|
Table: table,
|
||||||
Name: "fwded1",
|
Name: "fwded1",
|
||||||
|
@ -2767,7 +3131,7 @@ func TestCreateUseAnonymousSet(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCappedErrMsgOnSets(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())
|
c, err := nftables.New(nftables.WithNetNSFd(int(newNS)), nftables.AsLasting())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("nftables.New() failed: %v", err)
|
t.Fatalf("nftables.New() failed: %v", err)
|
||||||
|
@ -6285,6 +6649,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) {
|
func TestAddQuotaObj(t *testing.T) {
|
||||||
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer nftest.CleanupSystemConn(t, newNS)
|
||||||
|
@ -6303,22 +6745,26 @@ func TestAddQuotaObj(t *testing.T) {
|
||||||
}
|
}
|
||||||
conn.AddChain(c)
|
conn.AddChain(c)
|
||||||
|
|
||||||
o := &nftables.QuotaObj{
|
o := &nftables.ObjAttr{
|
||||||
Table: tr,
|
Table: tr,
|
||||||
Name: "q_test",
|
Name: "q_test",
|
||||||
Bytes: 0x06400000,
|
Type: nftables.ObjTypeQuota,
|
||||||
Consumed: 0,
|
Obj: &expr.Quota{
|
||||||
Over: true,
|
Bytes: 0x06400000,
|
||||||
|
Consumed: 0,
|
||||||
|
Over: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
conn.AddObj(o)
|
conn.AddObj(o)
|
||||||
|
|
||||||
if err := conn.Flush(); err != nil {
|
if err := conn.Flush(); err != nil {
|
||||||
t.Errorf("conn.Flush() failed: %v", err)
|
t.Fatalf("conn.Flush() failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := conn.GetObj(&nftables.QuotaObj{
|
obj, err := conn.GetObj(&nftables.ObjAttr{
|
||||||
Table: table,
|
Table: table,
|
||||||
Name: "q_test",
|
Name: "q_test",
|
||||||
|
Type: nftables.ObjTypeQuota,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("conn.GetObj() failed: %v", err)
|
t.Fatalf("conn.GetObj() failed: %v", err)
|
||||||
|
@ -6328,20 +6774,25 @@ func TestAddQuotaObj(t *testing.T) {
|
||||||
t.Fatalf("unexpected object list length: got %d, want %d", got, want)
|
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 {
|
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 {
|
if got, want := o1.Name, o.Name; got != want {
|
||||||
t.Fatalf("quota name mismatch: got %s, want %s", 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)
|
||||||
|
}
|
||||||
|
o2, _ := o.Obj.(*expr.Quota)
|
||||||
|
if got, want := q.Bytes, o2.Bytes; got != want {
|
||||||
t.Fatalf("quota bytes mismatch: got %d, want %d", 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, o2.Consumed; got != want {
|
||||||
t.Fatalf("quota consumed mismatch: got %d, want %d", 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, o2.Over; got != want {
|
||||||
t.Fatalf("quota over mismatch: got %v, want %v", got, want)
|
t.Fatalf("quota over mismatch: got %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6409,7 +6860,7 @@ func TestAddQuotaObjRef(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteQuotaObj(t *testing.T) {
|
func TestDeleteQuotaObjMixedTypes(t *testing.T) {
|
||||||
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
conn, newNS := nftest.OpenSystemConn(t, *enableSysTests)
|
||||||
defer nftest.CleanupSystemConn(t, newNS)
|
defer nftest.CleanupSystemConn(t, newNS)
|
||||||
conn.FlushRuleset()
|
conn.FlushRuleset()
|
||||||
|
@ -6427,12 +6878,15 @@ func TestDeleteQuotaObj(t *testing.T) {
|
||||||
}
|
}
|
||||||
conn.AddChain(c)
|
conn.AddChain(c)
|
||||||
|
|
||||||
o := &nftables.QuotaObj{
|
o := &nftables.ObjAttr{
|
||||||
Table: tr,
|
Table: tr,
|
||||||
Name: "q_test",
|
Name: "q_test",
|
||||||
Bytes: 0x06400000,
|
Type: nftables.ObjTypeQuota,
|
||||||
Consumed: 0,
|
Obj: &expr.Quota{
|
||||||
Over: true,
|
Bytes: 0x06400000,
|
||||||
|
Consumed: 0,
|
||||||
|
Over: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
conn.AddObj(o)
|
conn.AddObj(o)
|
||||||
|
|
||||||
|
@ -6440,9 +6894,10 @@ func TestDeleteQuotaObj(t *testing.T) {
|
||||||
t.Fatalf("conn.Flush() failed: %v", err)
|
t.Fatalf("conn.Flush() failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := conn.GetObj(&nftables.QuotaObj{
|
obj, err := conn.GetObj(&nftables.ObjAttr{
|
||||||
Table: table,
|
Table: tr,
|
||||||
Name: "q_test",
|
Name: "q_test",
|
||||||
|
Type: nftables.ObjTypeQuota,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("conn.GetObj() failed: %v", err)
|
t.Fatalf("conn.GetObj() failed: %v", err)
|
||||||
|
@ -6452,7 +6907,18 @@ func TestDeleteQuotaObj(t *testing.T) {
|
||||||
t.Fatalf("unexpected number of objects: got %d, want %d", got, want)
|
t.Fatalf("unexpected number of objects: got %d, want %d", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
if got, want := obj[0], o; !reflect.DeepEqual(got, want) {
|
o2, _ := o.Obj.(*expr.Quota)
|
||||||
|
want := &nftables.ObjAttr{
|
||||||
|
Table: tr,
|
||||||
|
Name: "q_test",
|
||||||
|
Type: nftables.ObjTypeQuota,
|
||||||
|
Obj: &expr.Quota{
|
||||||
|
Bytes: o2.Bytes,
|
||||||
|
Consumed: o2.Consumed,
|
||||||
|
Over: o2.Over,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if got, want := obj[0], want; !reflect.DeepEqual(got, want) {
|
||||||
t.Errorf("got = %+v, want = %+v", got, want)
|
t.Errorf("got = %+v, want = %+v", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
142
obj.go
142
obj.go
|
@ -18,6 +18,9 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/nftables/binaryutil"
|
||||||
|
"github.com/google/nftables/expr"
|
||||||
|
"github.com/google/nftables/internal/parseexprfunc"
|
||||||
"github.com/mdlayher/netlink"
|
"github.com/mdlayher/netlink"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
@ -27,13 +30,70 @@ var (
|
||||||
delObjHeaderType = netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_DELOBJ)
|
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
|
// Obj represents a netfilter stateful object. See also
|
||||||
// https://wiki.nftables.org/wiki-nftables/index.php/Stateful_objects
|
// https://wiki.nftables.org/wiki-nftables/index.php/Stateful_objects
|
||||||
type Obj interface {
|
type Obj interface {
|
||||||
table() *Table
|
table() *Table
|
||||||
family() TableFamily
|
family() TableFamily
|
||||||
unmarshal(*netlink.AttributeDecoder) error
|
data() expr.Any
|
||||||
marshal(data bool) ([]byte, error)
|
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.
|
// 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 {
|
func (cc *Conn) AddObj(o Obj) Obj {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
defer cc.mu.Unlock()
|
defer cc.mu.Unlock()
|
||||||
data, err := o.marshal(true)
|
data, err := expr.MarshalExprData(byte(o.family()), o.data())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cc.setErr(err)
|
cc.setErr(err)
|
||||||
return nil
|
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{
|
cc.messages = append(cc.messages, netlink.Message{
|
||||||
Header: netlink.Header{
|
Header: netlink.Header{
|
||||||
Type: netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_NEWOBJ),
|
Type: netlink.HeaderType((unix.NFNL_SUBSYS_NFTABLES << 8) | unix.NFT_MSG_NEWOBJ),
|
||||||
Flags: netlink.Request | netlink.Acknowledge | netlink.Create,
|
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
|
return o
|
||||||
}
|
}
|
||||||
|
@ -66,12 +135,12 @@ func (cc *Conn) AddObj(o Obj) Obj {
|
||||||
func (cc *Conn) DeleteObject(o Obj) {
|
func (cc *Conn) DeleteObject(o Obj) {
|
||||||
cc.mu.Lock()
|
cc.mu.Lock()
|
||||||
defer cc.mu.Unlock()
|
defer cc.mu.Unlock()
|
||||||
data, err := o.marshal(false)
|
attrs := []netlink.Attribute{
|
||||||
if err != nil {
|
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(o.table().Name + "\x00")},
|
||||||
cc.setErr(err)
|
{Type: unix.NFTA_OBJ_NAME, Data: []byte(o.name() + "\x00")},
|
||||||
return
|
{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}})...)
|
data = append(data, cc.marshalAttr([]netlink.Attribute{{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA}})...)
|
||||||
|
|
||||||
cc.messages = append(cc.messages, netlink.Message{
|
cc.messages = append(cc.messages, netlink.Message{
|
||||||
|
@ -86,13 +155,13 @@ func (cc *Conn) DeleteObject(o Obj) {
|
||||||
// GetObj is a legacy method that return all Obj that belongs
|
// GetObj is a legacy method that return all Obj that belongs
|
||||||
// to the same table as the given one
|
// to the same table as the given one
|
||||||
func (cc *Conn) GetObj(o Obj) ([]Obj, error) {
|
func (cc *Conn) GetObj(o Obj) ([]Obj, error) {
|
||||||
return cc.getObj(nil, o.table(), unix.NFT_MSG_GETOBJ)
|
return cc.getObjWithLegacyType(nil, o.table(), unix.NFT_MSG_GETOBJ, cc.useLegacyObjType(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjReset is a legacy method that reset all Obj that belongs
|
// GetObjReset is a legacy method that reset all Obj that belongs
|
||||||
// the same table as the given one
|
// the same table as the given one
|
||||||
func (cc *Conn) GetObjReset(o Obj) ([]Obj, error) {
|
func (cc *Conn) GetObjReset(o Obj) ([]Obj, error) {
|
||||||
return cc.getObj(nil, o.table(), unix.NFT_MSG_GETOBJ_RESET)
|
return cc.getObjWithLegacyType(nil, o.table(), unix.NFT_MSG_GETOBJ_RESET, cc.useLegacyObjType(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObject gets the specified Object
|
// GetObject gets the specified Object
|
||||||
|
@ -127,7 +196,7 @@ func (cc *Conn) ResetObjects(t *Table) ([]Obj, error) {
|
||||||
return cc.getObj(nil, t, unix.NFT_MSG_GETOBJ_RESET)
|
return cc.getObj(nil, t, unix.NFT_MSG_GETOBJ_RESET)
|
||||||
}
|
}
|
||||||
|
|
||||||
func objFromMsg(msg netlink.Message) (Obj, error) {
|
func objFromMsg(msg netlink.Message, returnLegacyType bool) (Obj, error) {
|
||||||
if got, want1, want2 := msg.Header.Type, newObjHeaderType, delObjHeaderType; got != want1 && got != want2 {
|
if got, want1, want2 := msg.Header.Type, newObjHeaderType, delObjHeaderType; got != want1 && got != want2 {
|
||||||
return nil, fmt.Errorf("unexpected header type: got %v, want %v or %v", got, want1, want2)
|
return nil, fmt.Errorf("unexpected header type: got %v, want %v or %v", got, want1, want2)
|
||||||
}
|
}
|
||||||
|
@ -150,6 +219,29 @@ func objFromMsg(msg netlink.Message) (Obj, error) {
|
||||||
case unix.NFTA_OBJ_TYPE:
|
case unix.NFTA_OBJ_TYPE:
|
||||||
objectType = ad.Uint32()
|
objectType = ad.Uint32()
|
||||||
case unix.NFTA_OBJ_DATA:
|
case unix.NFTA_OBJ_DATA:
|
||||||
|
if !returnLegacyType {
|
||||||
|
o := ObjAttr{
|
||||||
|
Table: table,
|
||||||
|
Name: name,
|
||||||
|
Type: ObjType(objectType),
|
||||||
|
}
|
||||||
|
|
||||||
|
objs, err := parseexprfunc.ParseExprBytesFunc(byte(o.family()), ad, objByObjTypeMagic[o.Type])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
o.Obj = exprs[0]
|
||||||
|
return &o, ad.Err()
|
||||||
|
}
|
||||||
|
|
||||||
switch objectType {
|
switch objectType {
|
||||||
case unix.NFT_OBJECT_COUNTER:
|
case unix.NFT_OBJECT_COUNTER:
|
||||||
o := CounterObj{
|
o := CounterObj{
|
||||||
|
@ -166,7 +258,7 @@ func objFromMsg(msg netlink.Message) (Obj, error) {
|
||||||
return o.unmarshal(ad)
|
return o.unmarshal(ad)
|
||||||
})
|
})
|
||||||
return &o, ad.Err()
|
return &o, ad.Err()
|
||||||
case NFT_OBJECT_QUOTA:
|
case unix.NFT_OBJECT_QUOTA:
|
||||||
o := QuotaObj{
|
o := QuotaObj{
|
||||||
Table: table,
|
Table: table,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -191,6 +283,10 @@ func objFromMsg(msg netlink.Message) (Obj, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
||||||
|
return cc.getObjWithLegacyType(o, t, msgType, cc.useLegacyObjType(o))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cc *Conn) getObjWithLegacyType(o Obj, t *Table, msgType uint16, returnLegacyObjType bool) ([]Obj, error) {
|
||||||
conn, closer, err := cc.netlinkConn()
|
conn, closer, err := cc.netlinkConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -201,7 +297,12 @@ func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
||||||
var flags netlink.HeaderFlags
|
var flags netlink.HeaderFlags
|
||||||
|
|
||||||
if o != nil {
|
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 {
|
} else {
|
||||||
flags = netlink.Dump
|
flags = netlink.Dump
|
||||||
data, err = netlink.MarshalAttributes([]netlink.Attribute{
|
data, err = netlink.MarshalAttributes([]netlink.Attribute{
|
||||||
|
@ -230,7 +331,7 @@ func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
||||||
}
|
}
|
||||||
var objs []Obj
|
var objs []Obj
|
||||||
for _, msg := range reply {
|
for _, msg := range reply {
|
||||||
o, err := objFromMsg(msg)
|
o, err := objFromMsg(msg, returnLegacyObjType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -239,3 +340,14 @@ func (cc *Conn) getObj(o Obj, t *Table, msgType uint16) ([]Obj, error) {
|
||||||
|
|
||||||
return objs, nil
|
return objs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cc *Conn) useLegacyObjType(o Obj) bool {
|
||||||
|
useLegacyType := true
|
||||||
|
if o != nil {
|
||||||
|
switch o.(type) {
|
||||||
|
case *ObjAttr:
|
||||||
|
useLegacyType = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return useLegacyType
|
||||||
|
}
|
||||||
|
|
24
quota.go
24
quota.go
|
@ -16,15 +16,11 @@ package nftables
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/nftables/binaryutil"
|
"github.com/google/nftables/binaryutil"
|
||||||
|
"github.com/google/nftables/expr"
|
||||||
"github.com/mdlayher/netlink"
|
"github.com/mdlayher/netlink"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
NFTA_OBJ_USERDATA = 8
|
|
||||||
NFT_OBJECT_QUOTA = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
type QuotaObj struct {
|
type QuotaObj struct {
|
||||||
Table *Table
|
Table *Table
|
||||||
Name string
|
Name string
|
||||||
|
@ -63,7 +59,7 @@ func (q *QuotaObj) marshal(data bool) ([]byte, error) {
|
||||||
attrs := []netlink.Attribute{
|
attrs := []netlink.Attribute{
|
||||||
{Type: unix.NFTA_OBJ_TABLE, Data: []byte(q.Table.Name + "\x00")},
|
{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_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 {
|
if data {
|
||||||
attrs = append(attrs, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA, Data: obj})
|
attrs = append(attrs, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_OBJ_DATA, Data: obj})
|
||||||
|
@ -78,3 +74,19 @@ func (q *QuotaObj) table() *Table {
|
||||||
func (q *QuotaObj) family() TableFamily {
|
func (q *QuotaObj) family() TableFamily {
|
||||||
return q.Table.Family
|
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
set.go
2
set.go
|
@ -321,7 +321,7 @@ func (s *SetElement) decode(fam byte) func(b []byte) error {
|
||||||
case unix.NFTA_SET_ELEM_EXPIRATION:
|
case unix.NFTA_SET_ELEM_EXPIRATION:
|
||||||
s.Expires = time.Millisecond * time.Duration(ad.Uint64())
|
s.Expires = time.Millisecond * time.Duration(ad.Uint64())
|
||||||
case unix.NFTA_SET_ELEM_EXPR:
|
case unix.NFTA_SET_ELEM_EXPR:
|
||||||
elems, err := parseexprfunc.ParseExprBytesFunc(fam, ad, ad.Bytes())
|
elems, err := parseexprfunc.ParseExprBytesFunc(fam, ad)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue