First Commit of Voltha-Go-Controller from Radisys
Change-Id: I8e2e908e7ab09a4fe3d86849da18b6d69dcf4ab0
diff --git a/vendor/github.com/google/gopacket/layers/stp.go b/vendor/github.com/google/gopacket/layers/stp.go
new file mode 100644
index 0000000..31c2a6e
--- /dev/null
+++ b/vendor/github.com/google/gopacket/layers/stp.go
@@ -0,0 +1,150 @@
+// Copyright 2017 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "net"
+
+ "github.com/google/gopacket"
+)
+
+type STPSwitchID struct {
+ Priority uint16 // Bridge priority
+ SysID uint16 // VLAN ID
+ HwAddr net.HardwareAddr
+}
+
+// STP decode spanning tree protocol packets to transport BPDU (bridge protocol data unit) message.
+type STP struct {
+ BaseLayer
+ ProtocolID uint16
+ Version uint8
+ Type uint8
+ TC, TCA bool // TC: Topologie change ; TCA: Topologie change ack
+ RouteID, BridgeID STPSwitchID
+ Cost uint32
+ PortID uint16
+ MessageAge uint16
+ MaxAge uint16
+ HelloTime uint16
+ FDelay uint16
+}
+
+// LayerType returns gopacket.LayerTypeSTP.
+func (s *STP) LayerType() gopacket.LayerType { return LayerTypeSTP }
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (s *STP) CanDecode() gopacket.LayerClass {
+ return LayerTypeSTP
+}
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (stp *STP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+ stpLength := 35
+ if len(data) < stpLength {
+ df.SetTruncated()
+ return fmt.Errorf("STP length %d too short", len(data))
+ }
+
+ stp.ProtocolID = binary.BigEndian.Uint16(data[:2])
+ stp.Version = uint8(data[2])
+ stp.Type = uint8(data[3])
+ stp.TC = data[4]&0x01 != 0
+ stp.TCA = data[4]&0x80 != 0
+ stp.RouteID.Priority = binary.BigEndian.Uint16(data[5:7]) & 0xf000
+ stp.RouteID.SysID = binary.BigEndian.Uint16(data[5:7]) & 0x0fff
+ stp.RouteID.HwAddr = net.HardwareAddr(data[7:13])
+ stp.Cost = binary.BigEndian.Uint32(data[13:17])
+ stp.BridgeID.Priority = binary.BigEndian.Uint16(data[17:19]) & 0xf000
+ stp.BridgeID.SysID = binary.BigEndian.Uint16(data[17:19]) & 0x0fff
+ stp.BridgeID.HwAddr = net.HardwareAddr(data[19:25])
+ stp.PortID = binary.BigEndian.Uint16(data[25:27])
+ stp.MessageAge = binary.BigEndian.Uint16(data[27:29])
+ stp.MaxAge = binary.BigEndian.Uint16(data[29:31])
+ stp.HelloTime = binary.BigEndian.Uint16(data[31:33])
+ stp.FDelay = binary.BigEndian.Uint16(data[33:35])
+ stp.Contents = data[:stpLength]
+ stp.Payload = data[stpLength:]
+
+ return nil
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (stp *STP) NextLayerType() gopacket.LayerType {
+ return gopacket.LayerTypePayload
+}
+
+// Check if the priority value is correct.
+func checkPriority(prio uint16) (uint16, error) {
+ if prio == 0 {
+ return prio, errors.New("Invalid Priority value must be in the rage <4096-61440> with an increment of 4096")
+ }
+ if prio%4096 == 0 {
+ return prio, nil
+ } else {
+ return prio, errors.New("Invalid Priority value must be in the rage <4096-61440> with an increment of 4096")
+ }
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (s *STP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+ var flags uint8 = 0x00
+ bytes, err := b.PrependBytes(35)
+ if err != nil {
+ return err
+ }
+ binary.BigEndian.PutUint16(bytes, s.ProtocolID)
+ bytes[2] = s.Version
+ bytes[3] = s.Type
+ if s.TC {
+ flags |= 0x01
+ }
+ if s.TCA {
+ flags |= 0x80
+ }
+ bytes[4] = flags
+
+ prioRoot, err := checkPriority(s.RouteID.Priority)
+ if err != nil {
+ panic(err)
+ }
+ if s.RouteID.SysID >= 4096 {
+ panic("Invalid VlanID value ..!")
+ }
+ binary.BigEndian.PutUint16(bytes[5:7], prioRoot|s.RouteID.SysID)
+ copy(bytes[7:13], s.RouteID.HwAddr)
+
+ binary.BigEndian.PutUint32(bytes[13:17], s.Cost)
+
+ prioBridge, err := checkPriority(s.BridgeID.Priority)
+ if err != nil {
+ panic(err)
+ }
+ if s.BridgeID.SysID >= 4096 {
+ panic("Invalid VlanID value ..!")
+ }
+ binary.BigEndian.PutUint16(bytes[17:19], prioBridge|s.BridgeID.SysID)
+ copy(bytes[19:25], s.BridgeID.HwAddr)
+
+ binary.BigEndian.PutUint16(bytes[25:27], s.PortID)
+ binary.BigEndian.PutUint16(bytes[27:29], s.MessageAge)
+ binary.BigEndian.PutUint16(bytes[29:31], s.MaxAge)
+ binary.BigEndian.PutUint16(bytes[31:33], s.HelloTime)
+ binary.BigEndian.PutUint16(bytes[33:35], s.FDelay)
+
+ return nil
+}
+
+func decodeSTP(data []byte, p gopacket.PacketBuilder) error {
+ stp := &STP{}
+ return decodingLayerDecoder(stp, data, p)
+}