Skip to content

Commit

Permalink
network, sriov: Map sriov devices to pci addresses
Browse files Browse the repository at this point in the history
Create a map between SRIOV networks and their appropriate
PCI-Address, using the multus network-status annotation.

Signed-off-by: Ram Lavi <[email protected]>
  • Loading branch information
RamLavi committed Sep 4, 2022
1 parent 89ea477 commit 0c9015f
Show file tree
Hide file tree
Showing 5 changed files with 439 additions and 1 deletion.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ lint:
hack/dockerized "golangci-lint run --timeout 20m --verbose \
pkg/network/namescheme/... \
pkg/network/domainspec/... \
pkg/network/sriov/... \
tests/console/... \
tests/libnet/... \
tests/libvmi/... \
Expand Down
24 changes: 23 additions & 1 deletion pkg/network/sriov/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

go_library(
name = "go_default_library",
srcs = ["sriov.go"],
importpath = "kubevirt.io/kubevirt/pkg/network/sriov",
visibility = ["//visibility:public"],
deps = [
"//pkg/network/namescheme:go_default_library",
"//pkg/network/vmispec:go_default_library",
"//staging/src/kubevirt.io/api/core/v1:go_default_library",
"//staging/src/kubevirt.io/client-go/log:go_default_library",
"//vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1:go_default_library",
],
)

go_test(
name = "go_default_test",
srcs = [
"sriov_suite_test.go",
"sriov_test.go",
],
deps = [
":go_default_library",
"//staging/src/kubevirt.io/api/core/v1:go_default_library",
"//staging/src/kubevirt.io/client-go/testutils:go_default_library",
"//vendor/github.com/onsi/ginkgo/v2:go_default_library",
"//vendor/github.com/onsi/gomega:go_default_library",
],
)
73 changes: 73 additions & 0 deletions pkg/network/sriov/sriov.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,77 @@

package sriov

import (
"encoding/json"
"fmt"

networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
v1 "kubevirt.io/api/core/v1"
"kubevirt.io/client-go/log"

"kubevirt.io/kubevirt/pkg/network/namescheme"
"kubevirt.io/kubevirt/pkg/network/vmispec"
)

const AliasPrefix = "sriov-"

func CreateNetworkPCIAnnotationValue(networks []v1.Network, interfaces []v1.Interface, networkStatusAnnotationValue string) string {
networkPCIMap, err := mapNetworkNameToPCIAddress(networks, interfaces, networkStatusAnnotationValue)
if err != nil {
log.Log.Warningf("failed to create network-pci-map: %v", err)
networkPCIMap = map[string]string{}
}

networkPCIMapBytes, err := json.Marshal(networkPCIMap)
if err != nil {
log.Log.Warningf("failed to marshal network-pci-map: %v", err)
return ""
}

return string(networkPCIMapBytes)
}

func mapNetworkNameToPCIAddress(networks []v1.Network, interfaces []v1.Interface,
networkStatusAnnotationValue string) (map[string]string, error) {
multusInterfaceNameToNetworkStatusMap, err := mapMultusInterfaceNameToNetworkStatus(networkStatusAnnotationValue)
if err != nil {
return nil, err
}
networkNameScheme := namescheme.CreateNetworkNameScheme(networks)

networkPCIMap := map[string]string{}
for _, sriovIface := range vmispec.FilterSRIOVInterfaces(interfaces) {
multusInterfaceName := networkNameScheme[sriovIface.Name]
networkStatusEntry, exist := multusInterfaceNameToNetworkStatusMap[multusInterfaceName]
if !exist {
return nil, fmt.Errorf("failed to find network-status entry with interface %q", multusInterfaceName)
}
if networkStatusEntry.DeviceInfo == nil || networkStatusEntry.DeviceInfo.Pci == nil {
return nil, fmt.Errorf("failed to find device-info/pci-address in network-status annotation for SR-IOV interface %q", sriovIface.Name)
}

pciAddress := networkStatusEntry.DeviceInfo.Pci.PciAddress
if pciAddress == "" {
return nil, fmt.Errorf("failed to associate pci-address to SR-IOV interface %q", sriovIface.Name)
}
networkPCIMap[sriovIface.Name] = pciAddress
}
return networkPCIMap, nil
}

func mapMultusInterfaceNameToNetworkStatus(networkStatusAnnotationValue string) (map[string]networkv1.NetworkStatus, error) {
if networkStatusAnnotationValue == "" {
return nil, fmt.Errorf("network-status annotation is not present")
}
var networkStatusList []networkv1.NetworkStatus
if err := json.Unmarshal([]byte(networkStatusAnnotationValue), &networkStatusList); err != nil {
return nil, fmt.Errorf("failed to unmarshal network-status annotation: %v", err)
}

multusInterfaceNameToNetworkStatusMap := map[string]networkv1.NetworkStatus{}
for _, networkStatus := range networkStatusList {
multusInterfaceNameToNetworkStatusMap[networkStatus.Interface] = networkStatus
}

return multusInterfaceNameToNetworkStatusMap, nil
}
30 changes: 30 additions & 0 deletions pkg/network/sriov/sriov_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* This file is part of the KubeVirt project
*
* 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.
*
* Copyright 2022 Red Hat, Inc.
*
*/

package sriov_test

import (
"testing"

"kubevirt.io/client-go/testutils"
)

func TestSRIOV(t *testing.T) {
testutils.KubeVirtTestSuiteSetup(t)
}
Loading

0 comments on commit 0c9015f

Please sign in to comment.