Additional change to Element to support set intervals (#44)

This commit is contained in:
Serguei Bezverkhi 2019-08-09 13:36:23 -04:00 committed by Michael Stapelberg
parent 26de8f0eaa
commit 2f48b7d8d8
1 changed files with 20 additions and 7 deletions

27
set.go
View File

@ -71,8 +71,9 @@ type Set struct {
// SetElement represents a data point within a set. // SetElement represents a data point within a set.
type SetElement struct { type SetElement struct {
Key []byte Key []byte
Val []byte Val []byte
IntervalEnd bool
} }
// SetAddElements applies data points to an nftables set. // SetAddElements applies data points to an nftables set.
@ -98,15 +99,23 @@ func (cc *Conn) SetAddElements(s *Set, vals []SetElement) error {
func (s *Set) makeElemList(vals []SetElement) ([]netlink.Attribute, error) { func (s *Set) makeElemList(vals []SetElement) ([]netlink.Attribute, error) {
var elements []netlink.Attribute var elements []netlink.Attribute
for i, v := range vals { for i, v := range vals {
encodedKey, err := netlink.MarshalAttributes([]netlink.Attribute{{Type: unix.NFTA_DATA_VALUE, Data: v.Key}}) item := make([]netlink.Attribute, 0)
var flags uint32
if v.IntervalEnd {
flags |= unix.NFT_SET_ELEM_INTERVAL_END
item = append(item, netlink.Attribute{Type: unix.NFTA_SET_ELEM_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)})
}
encodedKey, err := netlink.MarshalAttributes([]netlink.Attribute{{Type: unix.NFTA_SET_ELEM_KEY, Data: v.Key}})
if err != nil { if err != nil {
return nil, fmt.Errorf("marshal key %d: %v", i, err) return nil, fmt.Errorf("marshal key %d: %v", i, err)
} }
item := []netlink.Attribute{{Type: unix.NFTA_SET_ELEM_KEY | unix.NLA_F_NESTED, Data: encodedKey}} item = append(item, netlink.Attribute{Type: unix.NFTA_SET_ELEM_KEY | unix.NLA_F_NESTED, Data: encodedKey})
if len(v.Val) > 0 { if len(v.Val) > 0 {
encodedVal, err := netlink.MarshalAttributes([]netlink.Attribute{{Type: unix.NFTA_DATA_VALUE, Data: v.Val}}) encodedVal, err := netlink.MarshalAttributes([]netlink.Attribute{{Type: unix.NFTA_SET_ELEM_DATA, Data: v.Val}})
if err != nil { if err != nil {
return nil, fmt.Errorf("marshal item %d: %v", i, err) return nil, fmt.Errorf("marshal item %d: %v", i, err)
} }
@ -172,7 +181,7 @@ func (cc *Conn) AddSet(s *Set, vals []SetElement) error {
tableInfo := []netlink.Attribute{ tableInfo := []netlink.Attribute{
{Type: unix.NFTA_SET_TABLE, Data: []byte(s.Table.Name + "\x00")}, {Type: unix.NFTA_SET_TABLE, Data: []byte(s.Table.Name + "\x00")},
{Type: unix.NFTA_SET_NAME, Data: []byte(s.Name + "\x00")}, {Type: unix.NFTA_SET_NAME, Data: []byte(s.Name + "\x00")},
{Type: unix.NFTA_SET_ELEM_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)}, {Type: unix.NFTA_SET_FLAGS, Data: binaryutil.BigEndian.PutUint32(flags)},
{Type: unix.NFTA_SET_KEY_TYPE, Data: binaryutil.BigEndian.PutUint32(s.KeyType.nftMagic)}, {Type: unix.NFTA_SET_KEY_TYPE, Data: binaryutil.BigEndian.PutUint32(s.KeyType.nftMagic)},
{Type: unix.NFTA_SET_KEY_LEN, Data: binaryutil.BigEndian.PutUint32(s.KeyType.Bytes)}, {Type: unix.NFTA_SET_KEY_LEN, Data: binaryutil.BigEndian.PutUint32(s.KeyType.Bytes)},
{Type: unix.NFTA_SET_ID, Data: binaryutil.BigEndian.PutUint32(s.ID)}, {Type: unix.NFTA_SET_ID, Data: binaryutil.BigEndian.PutUint32(s.ID)},
@ -181,7 +190,7 @@ func (cc *Conn) AddSet(s *Set, vals []SetElement) error {
tableInfo = append(tableInfo, netlink.Attribute{Type: unix.NFTA_SET_DATA_TYPE, Data: binaryutil.BigEndian.PutUint32(unix.NFT_DATA_VALUE)}, tableInfo = append(tableInfo, netlink.Attribute{Type: unix.NFTA_SET_DATA_TYPE, Data: binaryutil.BigEndian.PutUint32(unix.NFT_DATA_VALUE)},
netlink.Attribute{Type: unix.NFTA_SET_DATA_LEN, Data: binaryutil.BigEndian.PutUint32(uint32(s.DataLen))}) netlink.Attribute{Type: unix.NFTA_SET_DATA_LEN, Data: binaryutil.BigEndian.PutUint32(uint32(s.DataLen))})
} }
if s.Anonymous || s.Constant { if s.Anonymous || s.Constant || s.Interval {
tableInfo = append(tableInfo, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_SET_DESC, Data: setData}, tableInfo = append(tableInfo, netlink.Attribute{Type: unix.NLA_F_NESTED | unix.NFTA_SET_DESC, Data: setData},
// Semantically useless - kept for binary compatability with nft // Semantically useless - kept for binary compatability with nft
netlink.Attribute{Type: unix.NFTA_SET_USERDATA, Data: []byte("\x00\x04\x02\x00\x00\x00")}) netlink.Attribute{Type: unix.NFTA_SET_USERDATA, Data: []byte("\x00\x04\x02\x00\x00\x00")})
@ -277,6 +286,7 @@ func setsFromMsg(msg netlink.Message) (*Set, error) {
flags := ad.Uint32() flags := ad.Uint32()
set.Constant = (flags & unix.NFT_SET_CONSTANT) != 0 set.Constant = (flags & unix.NFT_SET_CONSTANT) != 0
set.Anonymous = (flags & unix.NFT_SET_ANONYMOUS) != 0 set.Anonymous = (flags & unix.NFT_SET_ANONYMOUS) != 0
set.Interval = (flags & unix.NFT_SET_INTERVAL) != 0
case unix.NFTA_SET_KEY_TYPE: case unix.NFTA_SET_KEY_TYPE:
nftMagic := ad.Uint32() nftMagic := ad.Uint32()
for _, dt := range nftDatatypes { for _, dt := range nftDatatypes {
@ -322,6 +332,9 @@ func elementsFromMsg(msg netlink.Message) ([]SetElement, error) {
elem.Key = ad.Bytes() elem.Key = ad.Bytes()
case unix.NFTA_SET_ELEM_DATA: case unix.NFTA_SET_ELEM_DATA:
elem.Val = ad.Bytes() elem.Val = ad.Bytes()
case unix.NFTA_SET_ELEM_FLAGS:
flags := ad.Uint32()
elem.IntervalEnd = (flags & unix.NFT_SET_ELEM_INTERVAL_END) != 0
} }
} }
elements = append(elements, elem) elements = append(elements, elem)