geneve.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Copyright 2016 Google, Inc. All rights reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the LICENSE file in the root of the source
  5. // tree.
  6. package layers
  7. import (
  8. "encoding/binary"
  9. "errors"
  10. "github.com/google/gopacket"
  11. )
  12. // Geneve is specifed here https://tools.ietf.org/html/draft-ietf-nvo3-geneve-03
  13. // Geneve Header:
  14. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  15. // |Ver| Opt Len |O|C| Rsvd. | Protocol Type |
  16. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  17. // | Virtual Network Identifier (VNI) | Reserved |
  18. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  19. // | Variable Length Options |
  20. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  21. type Geneve struct {
  22. BaseLayer
  23. Version uint8 // 2 bits
  24. OptionsLength uint8 // 6 bits
  25. OAMPacket bool // 1 bits
  26. CriticalOption bool // 1 bits
  27. Protocol EthernetType // 16 bits
  28. VNI uint32 // 24bits
  29. Options []*GeneveOption
  30. }
  31. // Geneve Tunnel Options
  32. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  33. // | Option Class | Type |R|R|R| Length |
  34. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  35. // | Variable Option Data |
  36. // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  37. type GeneveOption struct {
  38. Class uint16 // 16 bits
  39. Type uint8 // 8 bits
  40. Flags uint8 // 3 bits
  41. Length uint8 // 5 bits
  42. Data []byte
  43. }
  44. // LayerType returns LayerTypeGeneve
  45. func (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve }
  46. func decodeGeneveOption(data []byte, gn *Geneve, df gopacket.DecodeFeedback) (*GeneveOption, uint8, error) {
  47. if len(data) < 3 {
  48. df.SetTruncated()
  49. return nil, 0, errors.New("geneve option too small")
  50. }
  51. opt := &GeneveOption{}
  52. opt.Class = binary.BigEndian.Uint16(data[0:2])
  53. opt.Type = data[2]
  54. opt.Flags = data[3] >> 4
  55. opt.Length = (data[3]&0xf)*4 + 4
  56. if len(data) < int(opt.Length) {
  57. df.SetTruncated()
  58. return nil, 0, errors.New("geneve option too small")
  59. }
  60. opt.Data = make([]byte, opt.Length-4)
  61. copy(opt.Data, data[4:opt.Length])
  62. return opt, opt.Length, nil
  63. }
  64. func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
  65. if len(data) < 7 {
  66. df.SetTruncated()
  67. return errors.New("geneve packet too short")
  68. }
  69. gn.Version = data[0] >> 7
  70. gn.OptionsLength = (data[0] & 0x3f) * 4
  71. gn.OAMPacket = data[1]&0x80 > 0
  72. gn.CriticalOption = data[1]&0x40 > 0
  73. gn.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
  74. var buf [4]byte
  75. copy(buf[1:], data[4:7])
  76. gn.VNI = binary.BigEndian.Uint32(buf[:])
  77. offset, length := uint8(8), int32(gn.OptionsLength)
  78. if len(data) < int(length+7) {
  79. df.SetTruncated()
  80. return errors.New("geneve packet too short")
  81. }
  82. for length > 0 {
  83. opt, len, err := decodeGeneveOption(data[offset:], gn, df)
  84. if err != nil {
  85. return err
  86. }
  87. gn.Options = append(gn.Options, opt)
  88. length -= int32(len)
  89. offset += len
  90. }
  91. gn.BaseLayer = BaseLayer{data[:offset], data[offset:]}
  92. return nil
  93. }
  94. func (gn *Geneve) NextLayerType() gopacket.LayerType {
  95. return gn.Protocol.LayerType()
  96. }
  97. func decodeGeneve(data []byte, p gopacket.PacketBuilder) error {
  98. gn := &Geneve{}
  99. return decodingLayerDecoder(gn, data, p)
  100. }