github.com/mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/utils/iplink_parser.go (about) 1 /* 2 Copyright 2018 Mirantis 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package utils 18 19 import ( 20 "bufio" 21 "bytes" 22 "fmt" 23 "regexp" 24 "strconv" 25 ) 26 27 // VFInfo contains information about particular VF 28 type VFInfo struct { 29 // ID contains VF number 30 ID int 31 // Mac contains hardware mac address 32 Mac string 33 // VLanID contains vlan id 34 VLanID int 35 // SpoofChecking holds status of spoof checking 36 SpoofChecking bool 37 // LinkState holds state of link (nil means auto) 38 LinkState *bool 39 } 40 41 // helper func to create pointer to boolean value 42 func newBool(value bool) *bool { 43 tmp := value 44 return &tmp 45 } 46 47 // ParseIPLinkOutput takes output of `ip link show somelink` and parses 48 // it to list of VFInfo structures 49 func ParseIPLinkOutput(data []byte) ([]VFInfo, error) { 50 scanner := bufio.NewScanner(bytes.NewReader(data)) 51 lineRx := regexp.MustCompile( 52 `vf (\d+) MAC ([^,]+), vlan (\d+), spoof checking (on|off), link-state (auto|enable|disable)`) 53 54 var vfinfos []VFInfo 55 for scanner.Scan() { 56 s := scanner.Text() 57 parts := lineRx.FindStringSubmatch(s) 58 if parts == nil { 59 continue 60 } 61 62 id, err := strconv.Atoi(parts[1]) 63 if err != nil { 64 return nil, fmt.Errorf("cannot parse %q as int: %v", parts[1], err) 65 } 66 vlanid, err := strconv.Atoi(parts[3]) 67 if err != nil { 68 return nil, fmt.Errorf("cannot parse %q as int: %v", parts[3], err) 69 } 70 spfc := false 71 if parts[4] == "on" { 72 spfc = true 73 } 74 var state *bool 75 switch parts[5] { 76 case "enable": 77 state = newBool(true) 78 case "disable": 79 state = newBool(false) 80 } 81 vfinfos = append(vfinfos, VFInfo{ 82 ID: id, 83 Mac: parts[2], 84 VLanID: vlanid, 85 SpoofChecking: spfc, 86 LinkState: state, 87 }) 88 } 89 90 return vfinfos, nil 91 }