Compare commits
2 Commits
e82ba6dbb9
...
1cef3a6218
Author | SHA1 | Date |
---|---|---|
|
1cef3a6218 | |
|
a8e056d949 |
139
obj.go
139
obj.go
|
@ -69,6 +69,9 @@ type Obj interface {
|
||||||
objType() ObjType
|
objType() ObjType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ObjAttr represents nftables stateful object attributes
|
||||||
|
// Corresponds to netfilter nft_object_attributes as per
|
||||||
|
// https://git.netfilter.org/libnftnl/tree/include/linux/netfilter/nf_tables.h?id=116e95aa7b6358c917de8c69f6f173874030b46b#n1626
|
||||||
type ObjAttr struct {
|
type ObjAttr struct {
|
||||||
Table *Table
|
Table *Table
|
||||||
Name string
|
Name string
|
||||||
|
@ -154,17 +157,32 @@ 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
|
||||||
|
// This function will determine whether returned object will be
|
||||||
|
// one of legacy types QuotaObj/CounterObj or the new ObjAttr
|
||||||
|
// type struct based passed o parameter type
|
||||||
|
// If o is of type ObjAttr, the implementation will work with
|
||||||
|
// the new ObjAttr type, otherwise falls back to legacy QuotaObj/CounterObj
|
||||||
func (cc *Conn) GetObj(o Obj) ([]Obj, error) {
|
func (cc *Conn) GetObj(o Obj) ([]Obj, error) {
|
||||||
return cc.getObjWithLegacyType(nil, o.table(), unix.NFT_MSG_GETOBJ, cc.useLegacyObjType(o))
|
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
|
||||||
|
// This function will determine whether returned object will be
|
||||||
|
// one of legacy types QuotaObj/CounterObj or the new ObjAttr
|
||||||
|
// type struct based passed o parameter type
|
||||||
|
// If o is of type ObjAttr, the implementation will work with
|
||||||
|
// the new ObjAttr type, otherwise falls back to legacy QuotaObj/CounterObj
|
||||||
func (cc *Conn) GetObjReset(o Obj) ([]Obj, error) {
|
func (cc *Conn) GetObjReset(o Obj) ([]Obj, error) {
|
||||||
return cc.getObjWithLegacyType(nil, o.table(), unix.NFT_MSG_GETOBJ_RESET, cc.useLegacyObjType(o))
|
return cc.getObjWithLegacyType(nil, o.table(), unix.NFT_MSG_GETOBJ_RESET, cc.useLegacyObjType(o))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObject gets the specified Object
|
// GetObject gets the specified Object
|
||||||
|
// This function will determine whether returned object will be
|
||||||
|
// one of legacy types QuotaObj/CounterObj or the new ObjAttr
|
||||||
|
// type struct based passed o parameter type
|
||||||
|
// If o is of type ObjAttr, the implementation will work with
|
||||||
|
// the new ObjAttr type, otherwise falls back to legacy QuotaObj/CounterObj
|
||||||
func (cc *Conn) GetObject(o Obj) (Obj, error) {
|
func (cc *Conn) GetObject(o Obj) (Obj, error) {
|
||||||
objs, err := cc.getObj(o, o.table(), unix.NFT_MSG_GETOBJ)
|
objs, err := cc.getObj(o, o.table(), unix.NFT_MSG_GETOBJ)
|
||||||
|
|
||||||
|
@ -176,11 +194,18 @@ func (cc *Conn) GetObject(o Obj) (Obj, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetObjects get all the Obj that belongs to the given table
|
// GetObjects get all the Obj that belongs to the given table
|
||||||
|
// This function will always return legacy QuotaObj/CounterObj
|
||||||
|
// types for backwards compatibility
|
||||||
func (cc *Conn) GetObjects(t *Table) ([]Obj, error) {
|
func (cc *Conn) GetObjects(t *Table) ([]Obj, error) {
|
||||||
return cc.getObj(nil, t, unix.NFT_MSG_GETOBJ)
|
return cc.getObj(nil, t, unix.NFT_MSG_GETOBJ)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetObject reset the given Obj
|
// ResetObject reset the given Obj
|
||||||
|
// This function will determine whether returned object will be
|
||||||
|
// one of legacy types QuotaObj/CounterObj or the new ObjAttr
|
||||||
|
// type struct based passed o parameter type
|
||||||
|
// If o is of type ObjAttr, the implementation will work with
|
||||||
|
// the new ObjAttr type, otherwise falls back to legacy QuotaObj/CounterObj
|
||||||
func (cc *Conn) ResetObject(o Obj) (Obj, error) {
|
func (cc *Conn) ResetObject(o Obj) (Obj, error) {
|
||||||
objs, err := cc.getObj(o, o.table(), unix.NFT_MSG_GETOBJ_RESET)
|
objs, err := cc.getObj(o, o.table(), unix.NFT_MSG_GETOBJ_RESET)
|
||||||
|
|
||||||
|
@ -192,6 +217,8 @@ func (cc *Conn) ResetObject(o Obj) (Obj, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetObjects reset all the Obj that belongs to the given table
|
// ResetObjects reset all the Obj that belongs to the given table
|
||||||
|
// This function will always return legacy QuotaObj/CounterObj
|
||||||
|
// types for backwards compatibility
|
||||||
func (cc *Conn) ResetObjects(t *Table) ([]Obj, error) {
|
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)
|
||||||
}
|
}
|
||||||
|
@ -219,61 +246,30 @@ func objFromMsg(msg netlink.Message, returnLegacyType bool) (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 {
|
if returnLegacyType {
|
||||||
o := ObjAttr{
|
return objDataFromMsgLegacy(ad, table, name, objectType)
|
||||||
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 {
|
o := ObjAttr{
|
||||||
case unix.NFT_OBJECT_COUNTER:
|
Table: table,
|
||||||
o := CounterObj{
|
Name: name,
|
||||||
Table: table,
|
Type: ObjType(objectType),
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
|
|
||||||
ad.Do(func(b []byte) error {
|
|
||||||
ad, err := netlink.NewAttributeDecoder(b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ad.ByteOrder = binary.BigEndian
|
|
||||||
return o.unmarshal(ad)
|
|
||||||
})
|
|
||||||
return &o, ad.Err()
|
|
||||||
case unix.NFT_OBJECT_QUOTA:
|
|
||||||
o := QuotaObj{
|
|
||||||
Table: table,
|
|
||||||
Name: name,
|
|
||||||
}
|
|
||||||
|
|
||||||
ad.Do(func(b []byte) error {
|
|
||||||
ad, err := netlink.NewAttributeDecoder(b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ad.ByteOrder = binary.BigEndian
|
|
||||||
return o.unmarshal(ad)
|
|
||||||
})
|
|
||||||
return &o, ad.Err()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := ad.Err(); err != nil {
|
if err := ad.Err(); err != nil {
|
||||||
|
@ -282,6 +278,45 @@ func objFromMsg(msg netlink.Message, returnLegacyType bool) (Obj, error) {
|
||||||
return nil, fmt.Errorf("malformed stateful object")
|
return nil, fmt.Errorf("malformed stateful object")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func objDataFromMsgLegacy(ad *netlink.AttributeDecoder, table *Table, name string, objectType uint32) (Obj, error) {
|
||||||
|
switch objectType {
|
||||||
|
case unix.NFT_OBJECT_COUNTER:
|
||||||
|
o := CounterObj{
|
||||||
|
Table: table,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
ad.Do(func(b []byte) error {
|
||||||
|
ad, err := netlink.NewAttributeDecoder(b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ad.ByteOrder = binary.BigEndian
|
||||||
|
return o.unmarshal(ad)
|
||||||
|
})
|
||||||
|
return &o, ad.Err()
|
||||||
|
case unix.NFT_OBJECT_QUOTA:
|
||||||
|
o := QuotaObj{
|
||||||
|
Table: table,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
|
||||||
|
ad.Do(func(b []byte) error {
|
||||||
|
ad, err := netlink.NewAttributeDecoder(b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ad.ByteOrder = binary.BigEndian
|
||||||
|
return o.unmarshal(ad)
|
||||||
|
})
|
||||||
|
return &o, ad.Err()
|
||||||
|
}
|
||||||
|
if err := ad.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("malformed stateful object")
|
||||||
|
}
|
||||||
|
|
||||||
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))
|
return cc.getObjWithLegacyType(o, t, msgType, cc.useLegacyObjType(o))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue