hash.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2018 Google LLC. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package expr
  15. import (
  16. "encoding/binary"
  17. "github.com/google/nftables/binaryutil"
  18. "github.com/mdlayher/netlink"
  19. "golang.org/x/sys/unix"
  20. )
  21. type HashType uint32
  22. const (
  23. HashTypeJenkins HashType = unix.NFT_HASH_JENKINS
  24. HashTypeSym HashType = unix.NFT_HASH_SYM
  25. )
  26. // Hash defines type for nftables internal hashing functions
  27. type Hash struct {
  28. SourceRegister uint32
  29. DestRegister uint32
  30. Length uint32
  31. Modulus uint32
  32. Seed uint32
  33. Offset uint32
  34. Type HashType
  35. }
  36. func (e *Hash) marshal(fam byte) ([]byte, error) {
  37. data, err := netlink.MarshalAttributes([]netlink.Attribute{
  38. {Type: unix.NFTA_HASH_SREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.SourceRegister))},
  39. {Type: unix.NFTA_HASH_DREG, Data: binaryutil.BigEndian.PutUint32(uint32(e.DestRegister))},
  40. {Type: unix.NFTA_HASH_LEN, Data: binaryutil.BigEndian.PutUint32(uint32(e.Length))},
  41. {Type: unix.NFTA_HASH_MODULUS, Data: binaryutil.BigEndian.PutUint32(uint32(e.Modulus))},
  42. {Type: unix.NFTA_HASH_SEED, Data: binaryutil.BigEndian.PutUint32(uint32(e.Seed))},
  43. {Type: unix.NFTA_HASH_OFFSET, Data: binaryutil.BigEndian.PutUint32(uint32(e.Offset))},
  44. {Type: unix.NFTA_HASH_TYPE, Data: binaryutil.BigEndian.PutUint32(uint32(e.Type))},
  45. })
  46. if err != nil {
  47. return nil, err
  48. }
  49. return netlink.MarshalAttributes([]netlink.Attribute{
  50. {Type: unix.NFTA_EXPR_NAME, Data: []byte("hash\x00")},
  51. {Type: unix.NLA_F_NESTED | unix.NFTA_EXPR_DATA, Data: data},
  52. })
  53. }
  54. func (e *Hash) unmarshal(fam byte, data []byte) error {
  55. ad, err := netlink.NewAttributeDecoder(data)
  56. if err != nil {
  57. return err
  58. }
  59. ad.ByteOrder = binary.BigEndian
  60. for ad.Next() {
  61. switch ad.Type() {
  62. case unix.NFTA_HASH_SREG:
  63. e.SourceRegister = ad.Uint32()
  64. case unix.NFTA_HASH_DREG:
  65. e.DestRegister = ad.Uint32()
  66. case unix.NFTA_HASH_LEN:
  67. e.Length = ad.Uint32()
  68. case unix.NFTA_HASH_MODULUS:
  69. e.Modulus = ad.Uint32()
  70. case unix.NFTA_HASH_SEED:
  71. e.Seed = ad.Uint32()
  72. case unix.NFTA_HASH_OFFSET:
  73. e.Offset = ad.Uint32()
  74. case unix.NFTA_HASH_TYPE:
  75. e.Type = HashType(ad.Uint32())
  76. }
  77. }
  78. return ad.Err()
  79. }