1 // Copyright 2016 Google, Inc. All rights reserved.
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
12 "github.com/google/gopacket"
15 // Geneve is specifed here https://tools.ietf.org/html/draft-ietf-nvo3-geneve-03
17 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
18 // |Ver| Opt Len |O|C| Rsvd. | Protocol Type |
19 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
20 // | Virtual Network Identifier (VNI) | Reserved |
21 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
22 // | Variable Length Options |
23 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
26 Version uint8 // 2 bits
27 OptionsLength uint8 // 6 bits
28 OAMPacket bool // 1 bits
29 CriticalOption bool // 1 bits
30 Protocol EthernetType // 16 bits
32 Options []*GeneveOption
35 // Geneve Tunnel Options
36 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 // | Option Class | Type |R|R|R| Length |
38 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 // | Variable Option Data |
40 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 type GeneveOption struct {
42 Class uint16 // 16 bits
45 Length uint8 // 5 bits
49 // LayerType returns LayerTypeGeneve
50 func (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve }
52 func decodeGeneveOption(data []byte, gn *Geneve) (*GeneveOption, uint8) {
53 opt := &GeneveOption{}
55 opt.Class = binary.BigEndian.Uint16(data[0:1])
57 opt.Flags = data[3] >> 4
58 opt.Length = data[3] & 0xf
60 copy(opt.Data, data[4:opt.Length])
62 return opt, 4 + opt.Length
65 func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
66 gn.Version = data[0] >> 7
67 gn.OptionsLength = data[0] & 0x3f
69 gn.OAMPacket = data[1]&0x80 > 0
70 gn.CriticalOption = data[1]&0x40 > 0
71 gn.Protocol = EthernetType(binary.BigEndian.Uint16(data[2:4]))
74 copy(buf[1:], data[4:7])
75 gn.VNI = binary.BigEndian.Uint32(buf[:])
77 offset, length := uint8(8), gn.OptionsLength
79 opt, len := decodeGeneveOption(data[offset:], gn)
80 gn.Options = append(gn.Options, opt)
86 gn.BaseLayer = BaseLayer{data[:offset], data[offset:]}
91 func (gn *Geneve) NextLayerType() gopacket.LayerType {
92 return gn.Protocol.LayerType()
95 func decodeGeneve(data []byte, p gopacket.PacketBuilder) error {
97 return decodingLayerDecoder(gn, data, p)