From d27cc52f157d296ed9e4275c232e96f008c0ad0b Mon Sep 17 00:00:00 2001 From: Rafael Campos Las Heras <157432+methril@users.noreply.github.com> Date: Thu, 3 Aug 2023 03:14:23 -0300 Subject: [PATCH] hash: Fix hash seed conditional (#234) Fix the marshall of the hash seed to be conditional, only if it is explicitly set, we need to add it to the kernel as stated on the libnftl and nftables projects. Refence: https://git.netfilter.org/nftables/tree/src/netlink_linearize.c?id=25e7b99cc450490c38becb03d8bddd0199cfd3f9#n174 Otherwise, having a hash expression similar to this: ``` ip daddr set jhash tcp sport mod 2 seed 0x0 map { 0 : 192.168.0.1, 1 : 192.168.2.2 } ``` end up setting only the first IP and ignoring the second one. Signed-off-by: Rafael Campos --- expr/hash.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/expr/hash.go b/expr/hash.go index 6849177..e8506b9 100644 --- a/expr/hash.go +++ b/expr/hash.go @@ -41,15 +41,22 @@ type Hash struct { } func (e *Hash) marshal(fam byte) ([]byte, error) { - data, err := netlink.MarshalAttributes([]netlink.Attribute{ + hashAttrs := []netlink.Attribute{ {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_LEN, Data: binaryutil.BigEndian.PutUint32(uint32(e.Length))}, {Type: unix.NFTA_HASH_MODULUS, Data: binaryutil.BigEndian.PutUint32(uint32(e.Modulus))}, - {Type: unix.NFTA_HASH_SEED, Data: binaryutil.BigEndian.PutUint32(uint32(e.Seed))}, + } + if e.Seed != 0 { + hashAttrs = append(hashAttrs, netlink.Attribute{ + Type: unix.NFTA_HASH_SEED, Data: binaryutil.BigEndian.PutUint32(uint32(e.Seed)), + }) + } + hashAttrs = append(hashAttrs, []netlink.Attribute{ {Type: unix.NFTA_HASH_OFFSET, Data: binaryutil.BigEndian.PutUint32(uint32(e.Offset))}, {Type: unix.NFTA_HASH_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))}, - }) + }...) + data, err := netlink.MarshalAttributes(hashAttrs) if err != nil { return nil, err }