Skip to content
This repository was archived by the owner on Dec 9, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cmd/dranet/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/ext"
"github.com/google/dranet/pkg/driver"
"github.com/google/dranet/pkg/pcidb"
"github.com/prometheus/client_golang/prometheus/promhttp"

resourcev1 "k8s.io/api/resource/v1"
Expand Down Expand Up @@ -58,7 +59,7 @@ func init() {
flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
flag.StringVar(&bindAddress, "bind-address", ":9177", "The IP address and port for the metrics and healthz server to serve on")
flag.StringVar(&hostnameOverride, "hostname-override", "", "If non-empty, will be used as the name of the Node that kube-network-policies is running on. If unset, the node name is assumed to be the same as the node's hostname.")
flag.StringVar(&celExpression, "filter", `attributes["dra.net/type"].StringValue != "veth"`, "CEL expression to filter network interface attributes (v1.DeviceAttribute).")
flag.StringVar(&celExpression, "filter", `!("dra.net/type" in attributes) || attributes["dra.net/type"].StringValue != "veth"`, "CEL expression to filter network interface attributes (v1.DeviceAttribute).")

flag.Usage = func() {
fmt.Fprint(os.Stderr, "Usage: dranet [options]\n\n")
Expand Down Expand Up @@ -90,6 +91,10 @@ func main() {
_ = http.ListenAndServe(bindAddress, mux)
}()

if err := pcidb.Setup(); err != nil {
klog.Fatalf("Failed to setup PCI DB: %v", err)
}

var config *rest.Config
var err error
if kubeconfig != "" {
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/google/cel-go v0.26.0
github.com/google/go-cmp v0.7.0
github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f
github.com/jaypipes/ghw v0.19.0
github.com/mdlayher/genetlink v1.3.2
github.com/mdlayher/netlink v1.7.2
github.com/prometheus/client_golang v1.23.0
Expand Down Expand Up @@ -49,6 +50,7 @@ require (
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
Expand All @@ -59,6 +61,7 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jaypipes/pcidb v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand All @@ -82,6 +85,7 @@ require (
github.com/tetratelabs/wazero v1.9.0 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
Expand All @@ -107,6 +111,7 @@ require (
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.2-0.20250314012144-ee69052608d9 // indirect
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
k8s.io/kubelet v0.34.0-rc.0 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
Expand Down Expand Up @@ -81,6 +83,11 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f h1:dd33oobuIv9PcBVqvbEiCXEbNTomOHyj3WFuC5YiPRU=
github.com/insomniacslk/dhcp v0.0.0-20250417080101-5f8cf70e8c5f/go.mod h1:zhFlBeJssZ1YBCMZ5Lzu1pX4vhftDvU10WUVb1uXKtM=
github.com/jaypipes/ghw v0.19.0 h1:Yf4Qy4Nb+U6W8CvTJ6lnVj2H6sG4mTz0c5QOnfwb0LE=
github.com/jaypipes/ghw v0.19.0/go.mod h1:UkqErkfrTUNgvABKyZVEzbz+wMNtvoT9RXGSloV8TUs=
github.com/jaypipes/pcidb v1.1.0 h1:f1Xh6LXRlYDw0aLyCwOEYaE0ifZBTdlCfLK8YW7A/so=
github.com/jaypipes/pcidb v1.1.0/go.mod h1:x27LT2krrUgjf875KxQXKB0Ha/YXLdZRVmw6hH0G7g8=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
Expand Down Expand Up @@ -179,6 +186,8 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0=
go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
Expand Down Expand Up @@ -232,6 +241,7 @@ golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand Down Expand Up @@ -278,6 +288,8 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v1.0.2-0.20250314012144-ee69052608d9 h1:eeH1AIcPvSc0Z25ThsYF+Xoqbn0CI/YnXVYoTLFdGQw=
howett.net/plist v1.0.2-0.20250314012144-ee69052608d9/go.mod h1:fyFX5Hj5tP1Mpk8obqA9MZgXT416Q5711SDT7dQLTLk=
k8s.io/api v0.34.0-rc.0 h1:0jrCG9TkH250E5wTqchpijMoMxmQ6FEl9xNum25FFSk=
k8s.io/api v0.34.0-rc.0/go.mod h1:H2VCZSAruVExfN0k+jj42LXFGQOvRhZDVbY1JlHGtHE=
k8s.io/apimachinery v0.34.0-rc.0 h1:PjXj9Fp/f53PN7JMtGnR7AldAbdztqNqT3SjABe99D8=
Expand Down
48 changes: 48 additions & 0 deletions pkg/apis/attributes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Copyright 2025 Google LLC

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

https://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 apis

const (
// TODO: Reconsider the domain being used when project becomes owned by some
// SIG. The issue with "dra.net" is that http://dra.net is an actual
// domain that is totally unrelated to this project and it can be a source
// of confusion and problems.
AttrPrefix = "dra.net"

// TODO: Document meaning of these attributes and re-evaluate if all are needed.
AttrInterfaceName = AttrPrefix + "/" + "ifName"
AttrPCIAddress = AttrPrefix + "/" + "pciAddress"
AttrMac = AttrPrefix + "/" + "mac"
AttrPCIVendor = AttrPrefix + "/" + "pciVendor"
AttrPCIDevice = AttrPrefix + "/" + "pciDevice"
AttrPCISubsystem = AttrPrefix + "/" + "pciSubsystem"
AttrNUMANode = AttrPrefix + "/" + "numaNode"
AttrMTU = AttrPrefix + "/" + "mtu"
AttrEncapsulation = AttrPrefix + "/" + "encapsulation"
AttrAlias = AttrPrefix + "/" + "alias"
AttrState = AttrPrefix + "/" + "state"
AttrType = AttrPrefix + "/" + "type"
AttrIPv4 = AttrPrefix + "/" + "ipv4"
AttrIPv6 = AttrPrefix + "/" + "ipv6"
AttrTCFilterNames = AttrPrefix + "/" + "tcFilterNames"
AttrTCXProgramNames = AttrPrefix + "/" + "tcxProgramNames"
AttrEBPF = AttrPrefix + "/" + "ebpf"
AttrSRIOV = AttrPrefix + "/" + "sriov"
AttrSRIOVVfs = AttrPrefix + "/" + "sriovVfs"
AttrVirtual = AttrPrefix + "/" + "virtual"
AttrRDMA = AttrPrefix + "/" + "rdma"
)
10 changes: 10 additions & 0 deletions pkg/cloudprovider/gce/gce.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ const (
GPUDirectRDMA GPUDirectSupport = "GPUDirect-RDMA"
)

const (
GCEAttrPrefix = "gce.dra.net"

AttrGCEBlock = GCEAttrPrefix + "/" + "block"
AttrGCESubblock = GCEAttrPrefix + "/" + "subblock"
AttrGCEHost = GCEAttrPrefix + "/" + "host"
AttrGCENetworkName = GCEAttrPrefix + "/" + "networkName"
AttrGCENetworkProjectNumber = GCEAttrPrefix + "/" + "networkProjectNumber"
)

var (
// https://cloud.google.com/compute/docs/accelerator-optimized-machines#network-protocol
// machine types have a one to one mapping to a network protocol in google cloud
Expand Down
47 changes: 24 additions & 23 deletions pkg/driver/dra_hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

"github.com/google/dranet/pkg/apis"
"github.com/google/dranet/pkg/filter"
"github.com/google/dranet/pkg/names"

"github.com/Mellanox/rdmamap"
"github.com/vishvananda/netlink"
Expand Down Expand Up @@ -163,34 +162,41 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
Namespace: claim.Namespace,
Name: claim.Name,
},
Network: netconf,
NetworkInterfaceConfigInPod: netconf,
}
ifName, err := np.netdb.GetNetInterfaceName(result.Device)
if err != nil {
errorList = append(errorList, fmt.Errorf("failed to get network interface name for device %s: %v", result.Device, err))
continue
}
ifName := names.GetOriginalName(result.Device)
// Get Network configuration and merge it
link, err := nlHandle.LinkByName(ifName)
if err != nil {
errorList = append(errorList, fmt.Errorf("fail to get network interface %s", ifName))
errorList = append(errorList, fmt.Errorf("failed to get netlink to interface %s: %v", ifName, err))
continue
}
podCfg.NetworkInterfaceConfigInHost.Interface.Name = ifName

if podCfg.Network.Interface.Name == "" {
podCfg.Network.Interface.Name = ifName
if podCfg.NetworkInterfaceConfigInPod.Interface.Name == "" {
// If the interface name was not explicitly overridden, use the same
// interface name within the pod's network namespace.
podCfg.NetworkInterfaceConfigInPod.Interface.Name = ifName
}

// If DHCP is requested, do a DHCP request to gather the network parameters (IPs and Routes)
// ... but we DO NOT apply them in the root namespace
if podCfg.Network.Interface.DHCP != nil && *podCfg.Network.Interface.DHCP {
if podCfg.NetworkInterfaceConfigInPod.Interface.DHCP != nil && *podCfg.NetworkInterfaceConfigInPod.Interface.DHCP {
klog.V(2).Infof("trying to get network configuration via DHCP")
contextCancel, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
ip, routes, err := getDHCP(contextCancel, ifName)
if err != nil {
errorList = append(errorList, fmt.Errorf("fail to get configuration via DHCP for %s: %w", ifName, err))
} else {
podCfg.Network.Interface.Addresses = []string{ip}
podCfg.Network.Routes = append(podCfg.Network.Routes, routes...)
podCfg.NetworkInterfaceConfigInPod.Interface.Addresses = []string{ip}
podCfg.NetworkInterfaceConfigInPod.Routes = append(podCfg.NetworkInterfaceConfigInPod.Routes, routes...)
}
} else if len(podCfg.Network.Interface.Addresses) == 0 {
} else if len(podCfg.NetworkInterfaceConfigInPod.Interface.Addresses) == 0 {
// If there is no custom addresses and no DHCP, then use the existing ones
// get the existing IP addresses
nlAddresses, err := nlHandle.AddrList(link, netlink.FAMILY_ALL)
Expand All @@ -204,13 +210,13 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
if address.Scope != unix.RT_SCOPE_UNIVERSE {
continue
}
podCfg.Network.Interface.Addresses = append(podCfg.Network.Interface.Addresses, address.IPNet.String())
podCfg.NetworkInterfaceConfigInPod.Interface.Addresses = append(podCfg.NetworkInterfaceConfigInPod.Interface.Addresses, address.IPNet.String())
}
}
}

// Obtain the existing supported ethtool features and validate the config
if podCfg.Network.Ethtool != nil {
if podCfg.NetworkInterfaceConfigInPod.Ethtool != nil {
client, err := newEthtoolClient(0)
if err != nil {
errorList = append(errorList, fmt.Errorf("fail to create ethtool client %v", err))
Expand All @@ -226,7 +232,7 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour

// translate features to the actual kernel names
ethtoolFeatures := map[string]bool{}
for feature, value := range podCfg.Network.Ethtool.Features {
for feature, value := range podCfg.NetworkInterfaceConfigInPod.Ethtool.Features {
aliases := ifFeatures.Get(feature)
if len(aliases) == 0 {
errorList = append(errorList, fmt.Errorf("feature %s not supported by interface", feature))
Expand All @@ -236,7 +242,7 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
ethtoolFeatures[alias] = value
}
}
podCfg.Network.Ethtool.Features = ethtoolFeatures
podCfg.NetworkInterfaceConfigInPod.Ethtool.Features = ethtoolFeatures
}

// Obtain the routes associated to the interface
Expand Down Expand Up @@ -267,7 +273,7 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
routeCfg.Source = route.Src.String()
}
routeCfg.Scope = uint8(route.Scope)
podCfg.Network.Routes = append(podCfg.Network.Routes, routeCfg)
podCfg.NetworkInterfaceConfigInPod.Routes = append(podCfg.NetworkInterfaceConfigInPod.Routes, routeCfg)
}

// Get RDMA configuration: link and char devices
Expand All @@ -290,23 +296,18 @@ func (np *NetworkDriver) prepareResourceClaim(ctx context.Context, claim *resour
// Remove the pinned programs before the NRI hooks since it
// has to walk the entire bpf virtual filesystem and is slow
// TODO: check if there is some other way to do this
if podCfg.Network.Interface.DisableEBPFPrograms != nil &&
*podCfg.Network.Interface.DisableEBPFPrograms {
if podCfg.NetworkInterfaceConfigInPod.Interface.DisableEBPFPrograms != nil &&
*podCfg.NetworkInterfaceConfigInPod.Interface.DisableEBPFPrograms {
err := unpinBPFPrograms(ifName)
if err != nil {
klog.Infof("error unpinning ebpf programs for %s : %v", ifName, err)
}
}

device := kubeletplugin.Device{
Requests: []string{result.Request},
PoolName: result.Pool,
DeviceName: result.Device,
}
// TODO: support for multiple pods sharing the same device
// we'll create the subinterface here
for _, uid := range podUIDs {
np.podConfigStore.Set(uid, device.DeviceName, podCfg)
np.podConfigStore.Set(uid, result.Device, podCfg)
}
klog.V(4).Infof("Claim Resources for pods %v : %#v", podUIDs, podCfg)
}
Expand Down
Loading
Loading