blob: 36aab0be62c36b9ae06824791b7c905fd8efb609 [file] [log] [blame]
/*
* Copyright 2022-present Open Networking Foundation
* 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 util
import (
"encoding/binary"
"net"
"strconv"
"strings"
"voltha-go-controller/internal/pkg/of"
)
// RemoveFromSlice to remove particular value from given slice.
func RemoveFromSlice(s []string, value string) []string {
i := 0
for i = 0; i < len(s); i++ {
if s[i] == value {
break
}
}
if i != len(s) {
//It means value is found in the slice
s[len(s)-1], s[i] = s[i], s[len(s)-1]
return s[:len(s)-1]
}
return s
}
// IsSliceSame - check and return true if the two slices are identical
func IsSliceSame(ref, rcvd []uint32) bool {
var found bool
if len(ref) != len(rcvd) {
return false
}
for _, refEntry := range ref {
found = false
for _, rcvdEntry := range rcvd {
if refEntry == rcvdEntry {
found = true
break
}
}
if !found {
return false
}
}
return true
}
// IsPbitSliceSame - check and return true if the two slices are identical
func IsPbitSliceSame(ref, rcvd []of.PbitType) bool {
var found bool
if len(ref) != len(rcvd) {
return false
}
for _, refEntry := range ref {
found = false
for _, rcvdEntry := range rcvd {
if refEntry == rcvdEntry {
found = true
break
}
}
if !found {
return false
}
}
return true
}
// IsNniPort is to check if given port is Nni Port.
func IsNniPort(id uint32) bool {
return (id >= 0x1000000)
}
// Uint32ToByte to convert uint32 to byte
func Uint32ToByte(value uint32) []byte {
byteValue := make([]byte, 4)
binary.BigEndian.PutUint32(byteValue[0:4], value)
return byteValue
}
// IP2LongConv convert ip address to integer value.
func IP2LongConv(ip net.IP) uint32 {
if len(ip) == 16 {
return binary.BigEndian.Uint32(ip[12:16])
}
return binary.BigEndian.Uint32(ip)
}
// Long2ipConv convert integer to ip address.
func Long2ipConv(nn uint32) net.IP {
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, nn)
return ip
}
// GetExpIPList converts list or range of IPs to expanded IP list
func GetExpIPList(ips []string) []net.IP {
ipList := []net.IP{}
for _, ipOrRange := range ips {
if strings.Contains(ipOrRange, "-") {
var splits = strings.Split(ipOrRange, "-")
ipStart := IP2LongConv(net.ParseIP(splits[0]))
ipEnd := IP2LongConv(net.ParseIP(splits[1]))
for i := ipStart; i <= ipEnd; i++ {
ipList = append(ipList, Long2ipConv(i))
}
} else {
ipList = append(ipList, net.ParseIP(ipOrRange))
}
}
return ipList
}
// GetUniFromMetadata returns uni port from write metadata of DS flows.
func GetUniFromMetadata(metadata uint64) uint32 {
return uint32(metadata & 0xFFFFFFFF)
}
// GetUniFromDSDhcpFlow returns uni port from the flow cookie
func GetUniFromDSDhcpFlow(cookie uint64) uint32 {
uniport := uint32(cookie >> 16)
uniport = uniport & 0xFFFFFFFF
return uniport
}
// GetUniPortFromFlow returns uni port from the flow data
func GetUniPortFromFlow(nniPort string, flow *of.VoltSubFlow) uint32 {
var portNo uint32
if nniPort == strconv.Itoa(int(flow.Match.InPort)) {
if of.IPProtocolUDP == flow.Match.L4Protocol {
// For DHCP DS flow, uniport is not part of metadata. Hence retrieve it from cookie
portNo = GetUniFromDSDhcpFlow(flow.Cookie)
} else {
portNo = GetUniFromMetadata(flow.Action.Metadata)
}
} else {
portNo = flow.Match.InPort
}
return portNo
}
// MacAddrsMatch for comparison of MAC addresses and return true if MAC addresses matches
func MacAddrsMatch(addr1 net.HardwareAddr, addr2 net.HardwareAddr) bool {
if len(addr1) != len(addr2) {
return false
}
for i := 0; i < len(addr1); i++ {
if addr1[i] != addr2[i] {
return false
}
}
return true
}