Added Other expression type to support types that are not explicitly supported.
This replaces the previous behaviour of silently ignoring unkown types when decoding
This commit is contained in:
parent
a285acebca
commit
79e321dfab
|
@ -0,0 +1,50 @@
|
|||
package expr
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/mdlayher/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Other is a nft expression that this library don't know
|
||||
// It can unmarshal/marshal it as list of attributes
|
||||
type Other struct {
|
||||
Type string // the type (name) of the expression
|
||||
Attributes []OtherAttribute
|
||||
}
|
||||
|
||||
// OtherAttribute is one of the attributes in an Other
|
||||
type OtherAttribute struct {
|
||||
Type uint16
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func (e *Other) marshal() ([]byte, error) {
|
||||
attrs := make([]netlink.Attribute, len(e.Attributes))
|
||||
for i, a := range e.Attributes {
|
||||
attrs[i].Type = a.Type
|
||||
attrs[i].Data = a.Data
|
||||
}
|
||||
|
||||
data, err := netlink.MarshalAttributes(attrs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return netlink.MarshalAttributes([]netlink.Attribute{
|
||||
{Type: unix.NFTA_EXPR_NAME, Data: []byte(e.Type + "\x00")},
|
||||
{Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
|
||||
})
|
||||
}
|
||||
|
||||
func (e *Other) unmarshal(data []byte) error {
|
||||
ad, err := netlink.NewAttributeDecoder(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ad.ByteOrder = binary.BigEndian
|
||||
for ad.Next() {
|
||||
e.Attributes = append(e.Attributes, OtherAttribute{Type: ad.Type(), Data: ad.Bytes()})
|
||||
}
|
||||
return ad.Err()
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package expr
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/mdlayher/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func TestOther(t *testing.T) {
|
||||
orig := &Other{
|
||||
Type: "testing",
|
||||
Attributes: []OtherAttribute{
|
||||
{1, []byte{66, 5}},
|
||||
{5, []byte("test")},
|
||||
},
|
||||
}
|
||||
|
||||
data, err := Marshal(orig)
|
||||
if err != nil {
|
||||
t.Fatal("Error marshalling other: ", err)
|
||||
}
|
||||
|
||||
ad, err := netlink.NewAttributeDecoder(data)
|
||||
if err != nil {
|
||||
t.Fatalf("NewAttributeDecoder() error: %+v", err)
|
||||
}
|
||||
ad.ByteOrder = binary.BigEndian
|
||||
if !ad.Next() {
|
||||
t.Fatal("too short")
|
||||
}
|
||||
if ad.Type() != unix.NFTA_EXPR_NAME || ad.String() != orig.Type {
|
||||
t.Fatalf("wrong name %d:%q", ad.Type(), ad.String())
|
||||
}
|
||||
|
||||
if !ad.Next() {
|
||||
t.Fatal("too short")
|
||||
}
|
||||
decoded := &Other{Type: "testing"}
|
||||
if ad.Type() != unix.NFTA_EXPR_DATA {
|
||||
t.Fatal("Wrong type for data:", ad.Type())
|
||||
}
|
||||
if err := Unmarshal(ad.Bytes(), decoded); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(orig, decoded) {
|
||||
t.Errorf("Wrong structure decoded: %+v vs %+v", decoded, orig)
|
||||
}
|
||||
if ad.Next() {
|
||||
t.Error("Got extra attribute: ", ad.Type())
|
||||
}
|
||||
}
|
7
rule.go
7
rule.go
|
@ -248,11 +248,8 @@ func exprsFromMsg(b []byte) ([]expr.Any, error) {
|
|||
e = &expr.Limit{}
|
||||
case "dynset":
|
||||
e = &expr.Dynset{}
|
||||
}
|
||||
if e == nil {
|
||||
// TODO: introduce an opaque expression type so that users know
|
||||
// something is here.
|
||||
continue // unsupported expression type
|
||||
default:
|
||||
e = &expr.Other{Type: name}
|
||||
}
|
||||
|
||||
ad.Do(func(b []byte) error {
|
||||
|
|
Loading…
Reference in New Issue