diff options
author | Rastislav Szabo <raszabo@cisco.com> | 2017-05-04 11:09:03 +0200 |
---|---|---|
committer | Rastislav Szabo <raszabo@cisco.com> | 2017-05-04 11:12:35 +0200 |
commit | a101d966133a70b8a76526be25070436d14fcf9f (patch) | |
tree | 75e2dbf20de615e58252b780b2ba5baae8fdcf82 /api/ifcounters/ifcounters.go | |
parent | a968ead74525125dff9ae90b1c9a9102e4327900 (diff) |
initial commit
Signed-off-by: Rastislav Szabo <raszabo@cisco.com>
Diffstat (limited to 'api/ifcounters/ifcounters.go')
-rw-r--r-- | api/ifcounters/ifcounters.go | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/api/ifcounters/ifcounters.go b/api/ifcounters/ifcounters.go new file mode 100644 index 0000000..202fe6e --- /dev/null +++ b/api/ifcounters/ifcounters.go @@ -0,0 +1,147 @@ +// Copyright (c) 2017 Cisco and/or its affiliates. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ifcounters + +import ( + "bytes" + "errors" + "fmt" + + "github.com/lunixbochs/struc" +) + +// VnetInterfaceCounters is the input data type defined in the 'interface.api', with binary encoded Data field, +// that can be decoded into the InterfaceCounter or CombinedInterfaceCounter struct using this package. +type VnetInterfaceCounters struct { + VnetCounterType uint8 + IsCombined uint8 + FirstSwIfIndex uint32 + Count uint32 `struc:"sizeof=Data"` + Data []byte +} + +// CounterType is the basic counter type - contains only packet statistics. +type CounterType int + +// constants as defined in the vnet_interface_counter_type_t enum in 'vnet/interface.h' +const ( + Drop CounterType = 0 + Punt = 1 + IPv4 = 2 + IPv6 = 3 + RxNoBuf = 4 + RxMiss = 5 + RxError = 6 + TxError = 7 + MPLS = 8 +) + +// CombinedCounterType is the extended counter type - contains both packet and byte statistics. +type CombinedCounterType int + +// constants as defined in the vnet_interface_counter_type_t enum in 'vnet/interface.h' +const ( + Rx CombinedCounterType = 0 + Tx = 1 +) + +// InterfaceCounter contains basic counter data (contains only packet statistics). +type InterfaceCounter struct { + Type CounterType + SwIfIndex uint32 + Packets uint64 +} + +// CombinedInterfaceCounter contains extended counter data (contains both packet and byte statistics). +type CombinedInterfaceCounter struct { + Type CombinedCounterType + SwIfIndex uint32 + Packets uint64 + Bytes uint64 +} + +type counterData struct { + Packets uint64 +} + +type counter struct { + Count uint32 `struc:"sizeof=Data"` + Data []counterData +} + +type combinedCounterData struct { + Packets uint64 + Bytes uint64 +} + +type combinedCounter struct { + Count uint32 `struc:"sizeof=Data"` + Data []combinedCounterData +} + +// DecodeCounters decodes VnetInterfaceCounters struct content into the slice of InterfaceCounter structs. +func DecodeCounters(vnetCounters VnetInterfaceCounters) ([]InterfaceCounter, error) { + if vnetCounters.IsCombined == 1 { + return nil, errors.New("invalid argument - combined counter passed in") + } + + // decode into internal struct + var c counter + buf := bytes.NewReader(vnetCounters.Data) + err := struc.Unpack(buf, &c) + if err != nil { + return nil, fmt.Errorf("unable to decode counter data: %v", err) + } + + // prepare the slice + res := make([]InterfaceCounter, c.Count) + + // fill in the slice + for i := uint32(0); i < c.Count; i++ { + res[i].Type = CounterType(vnetCounters.VnetCounterType) + res[i].SwIfIndex = vnetCounters.FirstSwIfIndex + i + res[i].Packets = c.Data[i].Packets + } + + return res, nil +} + +// DecodeCombinedCounters decodes VnetInterfaceCounters struct content into the slice of CombinedInterfaceCounter structs. +func DecodeCombinedCounters(vnetCounters VnetInterfaceCounters) ([]CombinedInterfaceCounter, error) { + if vnetCounters.IsCombined != 1 { + return nil, errors.New("invalid argument - simple counter passed in") + } + + // decode into internal struct + var c combinedCounter + buf := bytes.NewReader(vnetCounters.Data) + err := struc.Unpack(buf, &c) + if err != nil { + return nil, fmt.Errorf("unable to decode counter data: %v", err) + } + + // prepare the slice + res := make([]CombinedInterfaceCounter, c.Count) + + // fill in the slice + for i := uint32(0); i < c.Count; i++ { + res[i].Type = CombinedCounterType(vnetCounters.VnetCounterType) + res[i].SwIfIndex = vnetCounters.FirstSwIfIndex + i + res[i].Packets = c.Data[i].Packets + res[i].Bytes = c.Data[i].Bytes + } + + return res, nil +} |