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  }