refactor: pass table family when un/marshalling expr

This commit is contained in:
thediveo 2022-05-14 16:45:18 +00:00 committed by Michael Stapelberg
parent aeea153026
commit 3e042f75d7
35 changed files with 90 additions and 87 deletions

View File

@ -227,8 +227,8 @@ func (cc *Conn) marshalAttr(attrs []netlink.Attribute) []byte {
return b return b
} }
func (cc *Conn) marshalExpr(e expr.Any) []byte { func (cc *Conn) marshalExpr(fam byte, e expr.Any) []byte {
b, err := expr.Marshal(e) b, err := expr.Marshal(fam, e)
if err != nil { if err != nil {
cc.setErr(err) cc.setErr(err)
return nil return nil

View File

@ -30,7 +30,7 @@ type Bitwise struct {
Xor []byte Xor []byte
} }
func (e *Bitwise) marshal() ([]byte, error) { func (e *Bitwise) marshal(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},
}) })
@ -60,7 +60,7 @@ func (e *Bitwise) marshal() ([]byte, error) {
}) })
} }
func (e *Bitwise) unmarshal(data []byte) error { func (e *Bitwise) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -32,7 +32,7 @@ func TestBitwise(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
nbw := Bitwise{} nbw := Bitwise{}
data, err := tt.bw.marshal() data, err := tt.bw.marshal(0 /* don't care in this test */)
if err != nil { if err != nil {
t.Fatalf("marshal error: %+v", err) t.Fatalf("marshal error: %+v", err)
@ -44,7 +44,7 @@ func TestBitwise(t *testing.T) {
ad.ByteOrder = binary.BigEndian ad.ByteOrder = binary.BigEndian
for ad.Next() { for ad.Next() {
if ad.Type() == unix.NFTA_EXPR_DATA { if ad.Type() == unix.NFTA_EXPR_DATA {
if err := nbw.unmarshal(ad.Bytes()); err != nil { if err := nbw.unmarshal(0, ad.Bytes()); err != nil {
t.Errorf("unmarshal error: %+v", err) t.Errorf("unmarshal error: %+v", err)
break break
} }

View File

@ -37,7 +37,7 @@ type Byteorder struct {
Size uint32 Size uint32
} }
func (e *Byteorder) marshal() ([]byte, error) { func (e *Byteorder) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_BYTEORDER_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)}, {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_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)},
@ -54,6 +54,6 @@ func (e *Byteorder) marshal() ([]byte, error) {
}) })
} }
func (e *Byteorder) unmarshal(data []byte) error { func (e *Byteorder) unmarshal(fam byte, data []byte) error {
return fmt.Errorf("not yet implemented") return fmt.Errorf("not yet implemented")
} }

View File

@ -27,7 +27,7 @@ type Counter struct {
Packets uint64 Packets uint64
} }
func (e *Counter) marshal() ([]byte, error) { func (e *Counter) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_COUNTER_BYTES, Data: binaryutil.BigEndian.PutUint64(e.Bytes)}, {Type: unix.NFTA_COUNTER_BYTES, Data: binaryutil.BigEndian.PutUint64(e.Bytes)},
{Type: unix.NFTA_COUNTER_PACKETS, Data: binaryutil.BigEndian.PutUint64(e.Packets)}, {Type: unix.NFTA_COUNTER_PACKETS, Data: binaryutil.BigEndian.PutUint64(e.Packets)},
@ -42,7 +42,7 @@ func (e *Counter) marshal() ([]byte, error) {
}) })
} }
func (e *Counter) unmarshal(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 {
return err return err

View File

@ -63,7 +63,7 @@ type Ct struct {
Key CtKey Key CtKey
} }
func (e *Ct) marshal() ([]byte, error) { func (e *Ct) marshal(fam byte) ([]byte, error) {
regData := []byte{} regData := []byte{}
exprData, err := netlink.MarshalAttributes( exprData, err := netlink.MarshalAttributes(
[]netlink.Attribute{ []netlink.Attribute{
@ -97,7 +97,7 @@ func (e *Ct) marshal() ([]byte, error) {
}) })
} }
func (e *Ct) unmarshal(data []byte) error { func (e *Ct) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -28,7 +28,7 @@ type Dup struct {
IsRegDevSet bool IsRegDevSet bool
} }
func (e *Dup) marshal() ([]byte, error) { func (e *Dup) marshal(fam byte) ([]byte, error) {
attrs := []netlink.Attribute{ attrs := []netlink.Attribute{
{Type: unix.NFTA_DUP_SREG_ADDR, Data: binaryutil.BigEndian.PutUint32(e.RegAddr)}, {Type: unix.NFTA_DUP_SREG_ADDR, Data: binaryutil.BigEndian.PutUint32(e.RegAddr)},
} }
@ -49,7 +49,7 @@ func (e *Dup) marshal() ([]byte, error) {
}) })
} }
func (e *Dup) unmarshal(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 {
return err return err

View File

@ -34,7 +34,7 @@ type Dynset struct {
Invert bool Invert bool
} }
func (e *Dynset) marshal() ([]byte, error) { func (e *Dynset) marshal(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)})
@ -62,7 +62,7 @@ func (e *Dynset) marshal() ([]byte, error) {
}) })
} }
func (e *Dynset) unmarshal(data []byte) error { func (e *Dynset) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -24,19 +24,19 @@ import (
) )
// Marshal serializes the specified expression into a byte slice. // Marshal serializes the specified expression into a byte slice.
func Marshal(e Any) ([]byte, error) { func Marshal(fam byte, e Any) ([]byte, error) {
return e.marshal() return e.marshal(fam)
} }
// Unmarshal fills an expression from the specified byte slice. // Unmarshal fills an expression from the specified byte slice.
func Unmarshal(data []byte, e Any) error { func Unmarshal(fam byte, data []byte, e Any) error {
return e.unmarshal(data) return e.unmarshal(fam, data)
} }
// 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() ([]byte, error) marshal(fam byte) ([]byte, error)
unmarshal([]byte) error unmarshal(fam byte, data []byte) error
} }
// MetaKey specifies which piece of meta information should be loaded. See also // MetaKey specifies which piece of meta information should be loaded. See also
@ -80,7 +80,7 @@ type Meta struct {
Register uint32 Register uint32
} }
func (e *Meta) marshal() ([]byte, error) { func (e *Meta) marshal(fam byte) ([]byte, error) {
regData := []byte{} regData := []byte{}
exprData, err := netlink.MarshalAttributes( exprData, err := netlink.MarshalAttributes(
[]netlink.Attribute{ []netlink.Attribute{
@ -114,7 +114,7 @@ func (e *Meta) marshal() ([]byte, error) {
}) })
} }
func (e *Meta) unmarshal(data []byte) error { func (e *Meta) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err
@ -153,7 +153,7 @@ const (
NF_NAT_RANGE_PERSISTENT = 0x8 NF_NAT_RANGE_PERSISTENT = 0x8
) )
func (e *Masq) marshal() ([]byte, error) { func (e *Masq) marshal(fam byte) ([]byte, error) {
msgData := []byte{} msgData := []byte{}
if !e.ToPorts { if !e.ToPorts {
flags := uint32(0) flags := uint32(0)
@ -196,7 +196,7 @@ func (e *Masq) marshal() ([]byte, error) {
}) })
} }
func (e *Masq) unmarshal(data []byte) error { func (e *Masq) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err
@ -238,7 +238,7 @@ type Cmp struct {
Data []byte Data []byte
} }
func (e *Cmp) marshal() ([]byte, error) { func (e *Cmp) marshal(fam byte) ([]byte, error) {
cmpData, err := netlink.MarshalAttributes([]netlink.Attribute{ cmpData, err := netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_DATA_VALUE, Data: e.Data}, {Type: unix.NFTA_DATA_VALUE, Data: e.Data},
}) })
@ -259,7 +259,7 @@ func (e *Cmp) marshal() ([]byte, error) {
}) })
} }
func (e *Cmp) unmarshal(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 {
return err return err

View File

@ -39,7 +39,7 @@ type Exthdr struct {
SourceRegister uint32 SourceRegister uint32
} }
func (e *Exthdr) marshal() ([]byte, error) { func (e *Exthdr) marshal(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
@ -49,7 +49,7 @@ func (e *Exthdr) marshal() ([]byte, error) {
{Type: unix.NFTA_EXTHDR_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)}} {Type: unix.NFTA_EXTHDR_SREG, Data: binaryutil.BigEndian.PutUint32(e.SourceRegister)}}
} else { } else {
attr = []netlink.Attribute{ attr = []netlink.Attribute{
netlink.Attribute{Type: unix.NFTA_EXTHDR_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)}} {Type: unix.NFTA_EXTHDR_DREG, Data: binaryutil.BigEndian.PutUint32(e.DestRegister)}}
} }
attr = append(attr, attr = append(attr,
@ -74,7 +74,7 @@ func (e *Exthdr) marshal() ([]byte, error) {
}) })
} }
func (e *Exthdr) unmarshal(data []byte) error { func (e *Exthdr) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -44,7 +44,7 @@ func TestExthdr(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
neh := Exthdr{} neh := Exthdr{}
data, err := tt.eh.marshal() data, err := tt.eh.marshal(0 /* don't care in this test */)
if err != nil { if err != nil {
t.Fatalf("marshal error: %+v", err) t.Fatalf("marshal error: %+v", err)
@ -56,7 +56,7 @@ func TestExthdr(t *testing.T) {
ad.ByteOrder = binary.BigEndian ad.ByteOrder = binary.BigEndian
for ad.Next() { for ad.Next() {
if ad.Type() == unix.NFTA_EXPR_DATA { if ad.Type() == unix.NFTA_EXPR_DATA {
if err := neh.unmarshal(ad.Bytes()); err != nil { if err := neh.unmarshal(0, ad.Bytes()); err != nil {
t.Errorf("unmarshal error: %+v", err) t.Errorf("unmarshal error: %+v", err)
break break
} }

View File

@ -36,7 +36,7 @@ type Fib struct {
FlagPRESENT bool FlagPRESENT bool
} }
func (e *Fib) marshal() ([]byte, error) { func (e *Fib) marshal(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)},
@ -99,7 +99,7 @@ func (e *Fib) marshal() ([]byte, error) {
}) })
} }
func (e *Fib) unmarshal(data []byte) error { func (e *Fib) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -40,7 +40,7 @@ type Hash struct {
Type HashType Type HashType
} }
func (e *Hash) marshal() ([]byte, error) { func (e *Hash) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]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))},
@ -59,7 +59,7 @@ func (e *Hash) marshal() ([]byte, error) {
}) })
} }
func (e *Hash) unmarshal(data []byte) error { func (e *Hash) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -28,7 +28,7 @@ type Immediate struct {
Data []byte Data []byte
} }
func (e *Immediate) marshal() ([]byte, error) { func (e *Immediate) marshal(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},
}) })
@ -49,7 +49,7 @@ func (e *Immediate) marshal() ([]byte, error) {
}) })
} }
func (e *Immediate) unmarshal(data []byte) error { func (e *Immediate) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -71,7 +71,7 @@ type Limit struct {
Burst uint32 Burst uint32
} }
func (l *Limit) marshal() ([]byte, error) { func (l *Limit) marshal(fam byte) ([]byte, error) {
attrs := []netlink.Attribute{ attrs := []netlink.Attribute{
{Type: unix.NFTA_LIMIT_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(l.Type))}, {Type: unix.NFTA_LIMIT_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(l.Type))},
{Type: unix.NFTA_LIMIT_RATE, Data: binaryutil.BigEndian.PutUint64(l.Rate)}, {Type: unix.NFTA_LIMIT_RATE, Data: binaryutil.BigEndian.PutUint64(l.Rate)},
@ -103,7 +103,7 @@ func (l *Limit) marshal() ([]byte, error) {
}) })
} }
func (l *Limit) unmarshal(data []byte) error { func (l *Limit) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -68,7 +68,7 @@ type Log struct {
Data []byte Data []byte
} }
func (e *Log) marshal() ([]byte, error) { func (e *Log) marshal(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 {
@ -120,7 +120,7 @@ func (e *Log) marshal() ([]byte, error) {
}) })
} }
func (e *Log) unmarshal(data []byte) error { func (e *Log) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -33,7 +33,7 @@ type Lookup struct {
Invert bool Invert bool
} }
func (e *Lookup) marshal() ([]byte, error) { func (e *Lookup) marshal(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 {
@ -60,7 +60,7 @@ func (e *Lookup) marshal() ([]byte, error) {
}) })
} }
func (e *Lookup) unmarshal(data []byte) error { func (e *Lookup) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -16,7 +16,7 @@ type Match struct {
Info []byte Info []byte
} }
func (e *Match) marshal() ([]byte, error) { func (e *Match) marshal(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
@ -40,7 +40,7 @@ func (e *Match) marshal() ([]byte, error) {
}) })
} }
func (e *Match) unmarshal(data []byte) error { func (e *Match) unmarshal(fam byte, data []byte) error {
// Per https://git.netfilter.org/libnftnl/tree/src/expr/match.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n65 // Per https://git.netfilter.org/libnftnl/tree/src/expr/match.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n65
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {

View File

@ -28,7 +28,7 @@ func TestMatch(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ntgt := Match{} ntgt := Match{}
data, err := tt.mtch.marshal() data, err := tt.mtch.marshal(0 /* don't care in this test */)
if err != nil { if err != nil {
t.Fatalf("marshal error: %+v", err) t.Fatalf("marshal error: %+v", err)
@ -40,7 +40,7 @@ func TestMatch(t *testing.T) {
ad.ByteOrder = binary.BigEndian ad.ByteOrder = binary.BigEndian
for ad.Next() { for ad.Next() {
if ad.Type() == unix.NFTA_EXPR_DATA { if ad.Type() == unix.NFTA_EXPR_DATA {
if err := ntgt.unmarshal(ad.Bytes()); err != nil { if err := ntgt.unmarshal(0 /* don't care in this test */, ad.Bytes()); err != nil {
t.Errorf("unmarshal error: %+v", err) t.Errorf("unmarshal error: %+v", err)
break break
} }

View File

@ -55,7 +55,7 @@ type NAT struct {
// |00008|--|00005| |len |flags| type| NFTA_NAT_REG_PROTO_MIN // |00008|--|00005| |len |flags| type| NFTA_NAT_REG_PROTO_MIN
// | 00 00 00 02 | | data | reg 2 // | 00 00 00 02 | | data | reg 2
func (e *NAT) marshal() ([]byte, error) { func (e *NAT) marshal(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)},
@ -96,7 +96,7 @@ func (e *NAT) marshal() ([]byte, error) {
}) })
} }
func (e *NAT) unmarshal(data []byte) error { func (e *NAT) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -21,13 +21,13 @@ import (
type Notrack struct{} type Notrack struct{}
func (e *Notrack) marshal() ([]byte, error) { func (e *Notrack) marshal(fam byte) ([]byte, error) {
return netlink.MarshalAttributes([]netlink.Attribute{ return netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_EXPR_NAME, Data: []byte("notrack\x00")}, {Type: unix.NFTA_EXPR_NAME, Data: []byte("notrack\x00")},
}) })
} }
func (e *Notrack) unmarshal(data []byte) error { func (e *Notrack) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {

View File

@ -31,7 +31,7 @@ type Numgen struct {
Offset uint32 Offset uint32
} }
func (e *Numgen) marshal() ([]byte, error) { func (e *Numgen) marshal(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:
@ -56,7 +56,7 @@ func (e *Numgen) marshal() ([]byte, error) {
}) })
} }
func (e *Numgen) unmarshal(data []byte) error { func (e *Numgen) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -27,7 +27,7 @@ type Objref struct {
Name string Name string
} }
func (e *Objref) marshal() ([]byte, error) { func (e *Objref) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_OBJREF_IMM_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))}, {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?! {Type: unix.NFTA_OBJREF_IMM_NAME, Data: []byte(e.Name)}, // NOT \x00-terminated?!
@ -42,7 +42,7 @@ func (e *Objref) marshal() ([]byte, error) {
}) })
} }
func (e *Objref) unmarshal(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 {
return err return err

View File

@ -57,7 +57,7 @@ type Payload struct {
CsumFlags uint32 CsumFlags uint32
} }
func (e *Payload) marshal() ([]byte, error) { func (e *Payload) marshal(fam byte) ([]byte, error) {
var attrs []netlink.Attribute var attrs []netlink.Attribute
@ -100,7 +100,7 @@ func (e *Payload) marshal() ([]byte, error) {
}) })
} }
func (e *Payload) unmarshal(data []byte) error { func (e *Payload) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -44,7 +44,7 @@ type Queue struct {
Flag QueueFlag Flag QueueFlag
} }
func (e *Queue) marshal() ([]byte, error) { func (e *Queue) marshal(fam byte) ([]byte, error) {
if e.Total == 0 { if e.Total == 0 {
e.Total = 1 // The total default value is 1 e.Total = 1 // The total default value is 1
} }
@ -62,7 +62,7 @@ func (e *Queue) marshal() ([]byte, error) {
}) })
} }
func (e *Queue) unmarshal(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 {
return err return err

View File

@ -29,7 +29,7 @@ type Quota struct {
Over bool Over bool
} }
func (q *Quota) marshal() ([]byte, error) { func (q *Quota) marshal(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)},
@ -55,7 +55,7 @@ func (q *Quota) marshal() ([]byte, error) {
}) })
} }
func (q *Quota) unmarshal(data []byte) error { func (q *Quota) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -30,7 +30,7 @@ type Range struct {
ToData []byte ToData []byte
} }
func (e *Range) marshal() ([]byte, error) { func (e *Range) marshal(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
@ -64,7 +64,7 @@ func (e *Range) marshal() ([]byte, error) {
}) })
} }
func (e *Range) unmarshal(data []byte) error { func (e *Range) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -28,7 +28,7 @@ type Redir struct {
Flags uint32 Flags uint32
} }
func (e *Redir) marshal() ([]byte, error) { func (e *Redir) marshal(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)})
@ -51,7 +51,7 @@ func (e *Redir) marshal() ([]byte, error) {
}) })
} }
func (e *Redir) unmarshal(data []byte) error { func (e *Redir) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -27,7 +27,7 @@ type Reject struct {
Code uint8 Code uint8
} }
func (e *Reject) marshal() ([]byte, error) { func (e *Reject) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_REJECT_TYPE, Data: binaryutil.BigEndian.PutUint32(e.Type)}, {Type: unix.NFTA_REJECT_TYPE, Data: binaryutil.BigEndian.PutUint32(e.Type)},
{Type: unix.NFTA_REJECT_ICMP_CODE, Data: []byte{e.Code}}, {Type: unix.NFTA_REJECT_ICMP_CODE, Data: []byte{e.Code}},
@ -41,7 +41,7 @@ func (e *Reject) marshal() ([]byte, error) {
}) })
} }
func (e *Reject) unmarshal(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 {
return err return err

View File

@ -36,7 +36,7 @@ type Rt struct {
Key RtKey Key RtKey
} }
func (e *Rt) marshal() ([]byte, error) { func (e *Rt) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]netlink.Attribute{
{Type: unix.NFTA_RT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))}, {Type: unix.NFTA_RT_KEY, Data: binaryutil.BigEndian.PutUint32(uint32(e.Key))},
{Type: unix.NFTA_RT_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)}, {Type: unix.NFTA_RT_DREG, Data: binaryutil.BigEndian.PutUint32(e.Register)},
@ -50,6 +50,6 @@ func (e *Rt) marshal() ([]byte, error) {
}) })
} }
func (e *Rt) unmarshal(data []byte) error { func (e *Rt) unmarshal(fam byte, data []byte) error {
return fmt.Errorf("not yet implemented") return fmt.Errorf("not yet implemented")
} }

View File

@ -19,7 +19,7 @@ type Target struct {
Info []byte Info []byte
} }
func (e *Target) marshal() ([]byte, error) { func (e *Target) marshal(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
@ -44,7 +44,7 @@ func (e *Target) marshal() ([]byte, error) {
}) })
} }
func (e *Target) unmarshal(data []byte) error { func (e *Target) unmarshal(fam byte, data []byte) error {
// Per https://git.netfilter.org/libnftnl/tree/src/expr/target.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n65 // Per https://git.netfilter.org/libnftnl/tree/src/expr/target.c?id=09456c720e9c00eecc08e41ac6b7c291b3821ee5#n65
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {

View File

@ -28,7 +28,7 @@ func TestTarget(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
ntgt := Target{} ntgt := Target{}
data, err := tt.tgt.marshal() data, err := tt.tgt.marshal(0 /* don't care in this test */)
if err != nil { if err != nil {
t.Fatalf("marshal error: %+v", err) t.Fatalf("marshal error: %+v", err)
@ -40,7 +40,7 @@ func TestTarget(t *testing.T) {
ad.ByteOrder = binary.BigEndian ad.ByteOrder = binary.BigEndian
for ad.Next() { for ad.Next() {
if ad.Type() == unix.NFTA_EXPR_DATA { if ad.Type() == unix.NFTA_EXPR_DATA {
if err := ntgt.unmarshal(ad.Bytes()); err != nil { if err := ntgt.unmarshal(0 /* don't care in this test */, ad.Bytes()); err != nil {
t.Errorf("unmarshal error: %+v", err) t.Errorf("unmarshal error: %+v", err)
break break
} }

View File

@ -36,7 +36,7 @@ type TProxy struct {
RegPort uint32 RegPort uint32
} }
func (e *TProxy) marshal() ([]byte, error) { func (e *TProxy) marshal(fam byte) ([]byte, error) {
data, err := netlink.MarshalAttributes([]netlink.Attribute{ data, err := netlink.MarshalAttributes([]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, Data: binaryutil.BigEndian.PutUint32(e.RegPort)}, {Type: NFTA_TPROXY_REG, Data: binaryutil.BigEndian.PutUint32(e.RegPort)},
@ -50,7 +50,7 @@ func (e *TProxy) marshal() ([]byte, error) {
}) })
} }
func (e *TProxy) unmarshal(data []byte) error { func (e *TProxy) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

View File

@ -53,7 +53,7 @@ const (
VerdictStop VerdictStop
) )
func (e *Verdict) marshal() ([]byte, error) { func (e *Verdict) marshal(fam byte) ([]byte, error) {
// A verdict is a tree of netlink attributes structured as follows: // A verdict is a tree of netlink attributes structured as follows:
// NFTA_LIST_ELEM | NLA_F_NESTED { // NFTA_LIST_ELEM | NLA_F_NESTED {
// NFTA_EXPR_NAME { "immediate\x00" } // NFTA_EXPR_NAME { "immediate\x00" }
@ -96,7 +96,7 @@ func (e *Verdict) marshal() ([]byte, error) {
}) })
} }
func (e *Verdict) unmarshal(data []byte) error { func (e *Verdict) unmarshal(fam byte, data []byte) error {
ad, err := netlink.NewAttributeDecoder(data) ad, err := netlink.NewAttributeDecoder(data)
if err != nil { if err != nil {
return err return err

19
rule.go
View File

@ -92,7 +92,7 @@ func (cc *Conn) GetRules(t *Table, c *Chain) ([]*Rule, error) {
} }
var rules []*Rule var rules []*Rule
for _, msg := range reply { for _, msg := range reply {
r, err := ruleFromMsg(msg) r, err := ruleFromMsg(t.Family, msg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -113,7 +113,7 @@ func (cc *Conn) newRule(r *Rule, op ruleOperation) *Rule {
for idx, expr := range r.Exprs { for idx, expr := range r.Exprs {
exprAttrs[idx] = netlink.Attribute{ exprAttrs[idx] = netlink.Attribute{
Type: unix.NLA_F_NESTED | unix.NFTA_LIST_ELEM, Type: unix.NLA_F_NESTED | unix.NFTA_LIST_ELEM,
Data: cc.marshalExpr(expr), Data: cc.marshalExpr(byte(r.Table.Family), expr),
} }
} }
@ -215,7 +215,7 @@ func (cc *Conn) DelRule(r *Rule) error {
return nil return nil
} }
func exprsFromMsg(b []byte) ([]expr.Any, error) { func exprsFromMsg(fam TableFamily, b []byte) ([]expr.Any, error) {
ad, err := netlink.NewAttributeDecoder(b) ad, err := netlink.NewAttributeDecoder(b)
if err != nil { if err != nil {
return nil, err return nil, err
@ -285,7 +285,7 @@ func exprsFromMsg(b []byte) ([]expr.Any, error) {
} }
ad.Do(func(b []byte) error { ad.Do(func(b []byte) error {
if err := expr.Unmarshal(b, e); err != nil { if err := expr.Unmarshal(byte(fam), b, e); err != nil {
return err return err
} }
// Verdict expressions are a special-case of immediate expressions, so // Verdict expressions are a special-case of immediate expressions, so
@ -293,7 +293,7 @@ func exprsFromMsg(b []byte) ([]expr.Any, error) {
// register (invalid), re-parse it as a verdict expression. // register (invalid), re-parse it as a verdict expression.
if imm, isImmediate := e.(*expr.Immediate); isImmediate && imm.Register == unix.NFT_REG_VERDICT && len(imm.Data) == 0 { if imm, isImmediate := e.(*expr.Immediate); isImmediate && imm.Register == unix.NFT_REG_VERDICT && len(imm.Data) == 0 {
e = &expr.Verdict{} e = &expr.Verdict{}
if err := expr.Unmarshal(b, e); err != nil { if err := expr.Unmarshal(byte(fam), b, e); err != nil {
return err return err
} }
} }
@ -308,7 +308,7 @@ func exprsFromMsg(b []byte) ([]expr.Any, error) {
return exprs, ad.Err() return exprs, ad.Err()
} }
func ruleFromMsg(msg netlink.Message) (*Rule, error) { func ruleFromMsg(fam TableFamily, msg netlink.Message) (*Rule, error) {
if got, want := msg.Header.Type, ruleHeaderType; got != want { if got, want := msg.Header.Type, ruleHeaderType; got != want {
return nil, fmt.Errorf("unexpected header type: got %v, want %v", got, want) return nil, fmt.Errorf("unexpected header type: got %v, want %v", got, want)
} }
@ -321,12 +321,15 @@ func ruleFromMsg(msg netlink.Message) (*Rule, error) {
for ad.Next() { for ad.Next() {
switch ad.Type() { switch ad.Type() {
case unix.NFTA_RULE_TABLE: case unix.NFTA_RULE_TABLE:
r.Table = &Table{Name: ad.String()} r.Table = &Table{
Name: ad.String(),
Family: fam,
}
case unix.NFTA_RULE_CHAIN: case unix.NFTA_RULE_CHAIN:
r.Chain = &Chain{Name: ad.String()} r.Chain = &Chain{Name: ad.String()}
case unix.NFTA_RULE_EXPRESSIONS: case unix.NFTA_RULE_EXPRESSIONS:
ad.Do(func(b []byte) error { ad.Do(func(b []byte) error {
r.Exprs, err = exprsFromMsg(b) r.Exprs, err = exprsFromMsg(fam, b)
return err return err
}) })
case unix.NFTA_RULE_POSITION: case unix.NFTA_RULE_POSITION: