ODPM 266: Go-libmemif + 2 examples.
[govpp.git] / vendor / github.com / google / gopacket / layers / vxlan.go
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
7 package layers
8
9 import (
10         "encoding/binary"
11         "fmt"
12         "github.com/google/gopacket"
13 )
14
15 //  VXLAN is specifed in RFC 7348 https://tools.ietf.org/html/rfc7348
16 //  G, D, A, Group Policy ID from https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00
17 //  0                   1                   2                   3
18 //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
19 //  0             8               16              24              32
20 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
21 // |G|R|R|R|I|R|R|R|R|D|R|R|A|R|R|R|       Group Policy ID         |
22 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
23 // |     24 bit VXLAN Network Identifier           |   Reserved    |
24 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
25
26 // VXLAN is a VXLAN packet header
27 type VXLAN struct {
28         BaseLayer
29         ValidIDFlag      bool   // 'I' bit per RFC 7348
30         VNI              uint32 // 'VXLAN Network Identifier' 24 bits per RFC 7348
31         GBPExtension     bool   // 'G' bit per Group Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00
32         GBPDontLearn     bool   // 'D' bit per Group Policy
33         GBPApplied       bool   // 'A' bit per Group Policy
34         GBPGroupPolicyID uint16 // 'Group Policy ID' 16 bits per Group Policy
35 }
36
37 // LayerType returns LayerTypeVXLAN
38 func (vx *VXLAN) LayerType() gopacket.LayerType { return LayerTypeVXLAN }
39
40 func decodeVXLAN(data []byte, p gopacket.PacketBuilder) error {
41         vx := &VXLAN{}
42
43         // VNI is a 24bit number, Uint32 requires 32 bits
44         var buf [4]byte
45         copy(buf[1:], data[4:7])
46
47         // RFC 7348 https://tools.ietf.org/html/rfc7348
48         vx.ValidIDFlag = data[0]&0x08 > 0        // 'I' bit per RFC7348
49         vx.VNI = binary.BigEndian.Uint32(buf[:]) // VXLAN Network Identifier per RFC7348
50
51         // Group Based Policy https://tools.ietf.org/html/draft-smith-vxlan-group-policy-00
52         vx.GBPExtension = data[0]&0x80 > 0                       // 'G' bit per the group policy draft
53         vx.GBPDontLearn = data[1]&0x40 > 0                       // 'D' bit - the egress VTEP MUST NOT learn the source address of the encapsulated frame.
54         vx.GBPApplied = data[1]&0x80 > 0                         // 'A' bit - indicates that the group policy has already been applied to this packet.
55         vx.GBPGroupPolicyID = binary.BigEndian.Uint16(data[2:4]) // Policy ID as per the group policy draft
56
57         // Layer information
58         const vxlanLength = 8
59         vx.Contents = data[:vxlanLength]
60         vx.Payload = data[vxlanLength:]
61
62         p.AddLayer(vx)
63         return p.NextDecoder(LinkTypeEthernet)
64 }
65
66 // SerializeTo writes the serialized form of this layer into the
67 // SerializationBuffer, implementing gopacket.SerializableLayer.
68 // See the docs for gopacket.SerializableLayer for more info.
69 func (vx *VXLAN) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
70         bytes, err := b.PrependBytes(8)
71         if err != nil {
72                 return err
73         }
74
75         if vx.ValidIDFlag {
76                 bytes[0] |= 0x08
77         }
78         if vx.GBPExtension {
79                 bytes[0] |= 0x80
80         }
81         if vx.GBPDontLearn {
82                 bytes[1] |= 0x40
83         }
84         if vx.GBPApplied {
85                 bytes[1] |= 0x80
86         }
87
88         binary.BigEndian.PutUint16(bytes[2:4], vx.GBPGroupPolicyID)
89         if vx.VNI >= 1<<24 {
90                 return fmt.Errorf("Virtual Network Identifier = %x exceeds max for 24-bit uint", vx.VNI)
91         }
92         binary.BigEndian.PutUint32(bytes[4:8], vx.VNI<<8)
93         return nil
94 }