Skip to content
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
9 changes: 9 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ linters:
enable:
- contextcheck
- durationcheck
- forbidigo
- gci
- ginkgolinter
- gocritic
Expand All @@ -39,6 +40,14 @@ linters-settings:
- default
- prefix(github.com/containernetworking)

forbidigo:
forbid:
# Copied from https://github.com/moby/moby/pull/48407
- pkg: ^github.com/vishvananda/netlink$
p: ^netlink\.(Handle\.)?(AddrList|BridgeVlanList|ChainList|ClassList|ConntrackTableList|ConntrackDeleteFilter$|ConntrackDeleteFilters|DevLinkGetDeviceList|DevLinkGetAllPortList|DevlinkGetDeviceParams|FilterList|FouList|GenlFamilyList|GTPPDPList|LinkByName|LinkByAlias|LinkList|LinkSubscribeWithOptions|NeighList$|NeighProxyList|NeighListExecute|NeighSubscribeWithOptions|LinkGetProtinfo|QdiscList|RdmaLinkList|RdmaLinkByName|RdmaLinkDel|RouteList|RouteListFilteredIter|RuleListFiltered$|RouteSubscribeWithOptions|RuleList$|RuleListFiltered|SocketGet|SocketDiagTCPInfo|SocketDiagTCP|SocketDiagUDPInfo|SocketDiagUDP|UnixSocketDiagInfo|UnixSocketDiag|VDPAGetDevConfigList|VDPAGetDevList|VDPAGetMGMTDevList|XfrmPolicyList|XfrmStateList)
msg: Use internal netlinksafe package for EINTR handling.
analyze-types: true

run:
timeout: 5m
modules-download-mode: vendor
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ require (
github.com/onsi/ginkgo/v2 v2.22.2
github.com/onsi/gomega v1.36.2
github.com/opencontainers/selinux v1.11.1
github.com/pkg/errors v0.9.1
github.com/safchain/ethtool v0.5.10
github.com/vishvananda/netlink v1.3.0
github.com/vishvananda/netlink v1.3.1-0.20250303224720-0e7078ed04c8
Copy link
Contributor

@aojea aojea Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this contains the docker patch in the library that will alliviate the problem considerably, as it will not return early

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha, interesting -- do you have a link to the commit / patch?

github.com/vishvananda/netns v0.0.4
golang.org/x/sys v0.30.0
sigs.k8s.io/knftables v0.0.18
)
Expand All @@ -38,10 +40,8 @@ require (
github.com/mdlayher/packet v1.1.2 // indirect
github.com/mdlayher/socket v0.5.1 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/sync v0.10.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 h1:pyC9PaHYZFgEKFdlp3G8RaCKgVpHZnecvArXvPXcFkM=
github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701/go.mod h1:P3a5rG4X7tI17Nn3aOIAYr5HbIMukwXG0urG0WuL8OA=
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netlink v1.3.1-0.20250303224720-0e7078ed04c8 h1:Y4egeTrP7sccowz2GWTJVtHlwkZippgBTpUmMteFUWQ=
github.com/vishvananda/netlink v1.3.1-0.20250303224720-0e7078ed04c8/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
6 changes: 4 additions & 2 deletions pkg/ip/addr_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"time"

"github.com/vishvananda/netlink"

"github.com/containernetworking/plugins/pkg/netlinksafe"
)

const SETTLE_INTERVAL = 50 * time.Millisecond
Expand All @@ -30,14 +32,14 @@ const SETTLE_INTERVAL = 50 * time.Millisecond
// addresses are no longer tentative.
// If any addresses are still tentative after timeout seconds, then error.
func SettleAddresses(ifName string, timeout int) error {
link, err := netlink.LinkByName(ifName)
link, err := netlinksafe.LinkByName(ifName)
if err != nil {
return fmt.Errorf("failed to retrieve link: %v", err)
}

deadline := time.Now().Add(time.Duration(timeout) * time.Second)
for {
addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL)
addrs, err := netlinksafe.AddrList(link, netlink.FAMILY_ALL)
if err != nil {
return fmt.Errorf("could not list addresses: %v", err)
}
Expand Down
17 changes: 9 additions & 8 deletions pkg/ip/link_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/safchain/ethtool"
"github.com/vishvananda/netlink"

"github.com/containernetworking/plugins/pkg/netlinksafe"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
)
Expand Down Expand Up @@ -52,7 +53,7 @@ func makeVethPair(name, peer string, mtu int, mac string, hostNS ns.NetNS) (netl
return nil, err
}
// Re-fetch the container link to get its creation-time parameters, e.g. index and mac
veth2, err := netlink.LinkByName(name)
veth2, err := netlinksafe.LinkByName(name)
if err != nil {
netlink.LinkDel(veth) // try and clean up the link if possible.
return nil, err
Expand All @@ -62,7 +63,7 @@ func makeVethPair(name, peer string, mtu int, mac string, hostNS ns.NetNS) (netl
}

func peerExists(name string) bool {
if _, err := netlink.LinkByName(name); err != nil {
if _, err := netlinksafe.LinkByName(name); err != nil {
return false
}
return true
Expand Down Expand Up @@ -114,7 +115,7 @@ func RandomVethName() (string, error) {
}

func RenameLink(curName, newName string) error {
link, err := netlink.LinkByName(curName)
link, err := netlinksafe.LinkByName(curName)
if err == nil {
err = netlink.LinkSetName(link, newName)
}
Expand Down Expand Up @@ -145,7 +146,7 @@ func SetupVethWithName(contVethName, hostVethName string, mtu int, contVethMac s

var hostVeth netlink.Link
err = hostNS.Do(func(_ ns.NetNS) error {
hostVeth, err = netlink.LinkByName(hostVethName)
hostVeth, err = netlinksafe.LinkByName(hostVethName)
if err != nil {
return fmt.Errorf("failed to lookup %q in %q: %v", hostVethName, hostNS.Path(), err)
}
Expand Down Expand Up @@ -174,7 +175,7 @@ func SetupVeth(contVethName string, mtu int, contVethMac string, hostNS ns.NetNS

// DelLinkByName removes an interface link.
func DelLinkByName(ifName string) error {
iface, err := netlink.LinkByName(ifName)
iface, err := netlinksafe.LinkByName(ifName)
if err != nil {
if _, ok := err.(netlink.LinkNotFoundError); ok {
return ErrLinkNotFound
Expand All @@ -191,15 +192,15 @@ func DelLinkByName(ifName string) error {

// DelLinkByNameAddr remove an interface and returns its addresses
func DelLinkByNameAddr(ifName string) ([]*net.IPNet, error) {
iface, err := netlink.LinkByName(ifName)
iface, err := netlinksafe.LinkByName(ifName)
if err != nil {
if _, ok := err.(netlink.LinkNotFoundError); ok {
return nil, ErrLinkNotFound
}
return nil, fmt.Errorf("failed to lookup %q: %v", ifName, err)
}

addrs, err := netlink.AddrList(iface, netlink.FAMILY_ALL)
addrs, err := netlinksafe.AddrList(iface, netlink.FAMILY_ALL)
if err != nil {
return nil, fmt.Errorf("failed to get IP addresses for %q: %v", ifName, err)
}
Expand All @@ -222,7 +223,7 @@ func DelLinkByNameAddr(ifName string) ([]*net.IPNet, error) {
// veth, or an error. This peer ifindex will only be valid in the peer's
// network namespace.
func GetVethPeerIfindex(ifName string) (netlink.Link, int, error) {
link, err := netlink.LinkByName(ifName)
link, err := netlinksafe.LinkByName(ifName)
if err != nil {
return nil, -1, fmt.Errorf("could not look up %q: %v", ifName, err)
}
Expand Down
18 changes: 9 additions & 9 deletions pkg/ip/link_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import (

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/vishvananda/netlink"

"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/pkg/netlinksafe"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
)
Expand Down Expand Up @@ -127,7 +127,7 @@ var _ = Describe("Link", func() {
_ = containerNetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

containerVethFromName, err := netlink.LinkByName(containerVethName)
containerVethFromName, err := netlinksafe.LinkByName(containerVethName)
Expect(err).NotTo(HaveOccurred())
Expect(containerVethFromName.Attrs().Index).To(Equal(containerVeth.Index))

Expand All @@ -137,7 +137,7 @@ var _ = Describe("Link", func() {
_ = hostNetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

hostVethFromName, err := netlink.LinkByName(hostVethName)
hostVethFromName, err := netlinksafe.LinkByName(hostVethName)
Expect(err).NotTo(HaveOccurred())
Expect(hostVethFromName.Attrs().Index).To(Equal(hostVeth.Index))

Expand Down Expand Up @@ -207,7 +207,7 @@ var _ = Describe("Link", func() {
_ = containerNetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, err := netlink.LinkByName(containerVethName)
_, err := netlinksafe.LinkByName(containerVethName)
Expect(err).NotTo(HaveOccurred())

return nil
Expand All @@ -216,7 +216,7 @@ var _ = Describe("Link", func() {
_ = hostNetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, err := netlink.LinkByName(hostVethName)
_, err := netlinksafe.LinkByName(hostVethName)
Expect(err).NotTo(HaveOccurred())

return nil
Expand All @@ -232,7 +232,7 @@ var _ = Describe("Link", func() {
Expect(err).NotTo(HaveOccurred())
hostVethName = hostVeth.Name

link, err := netlink.LinkByName(containerVethName)
link, err := netlinksafe.LinkByName(containerVethName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr.String()).To(Equal(mac))

Expand All @@ -242,7 +242,7 @@ var _ = Describe("Link", func() {
_ = hostNetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

link, err := netlink.LinkByName(hostVethName)
link, err := netlinksafe.LinkByName(hostVethName)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().HardwareAddr.String()).NotTo(Equal(mac))

Expand All @@ -259,7 +259,7 @@ var _ = Describe("Link", func() {
err := ip.DelLinkByName(containerVethName)
Expect(err).NotTo(HaveOccurred())

_, err = netlink.LinkByName(containerVethName)
_, err = netlinksafe.LinkByName(containerVethName)
Expect(err).To(HaveOccurred())

return nil
Expand All @@ -268,7 +268,7 @@ var _ = Describe("Link", func() {
_ = hostNetNS.Do(func(ns.NetNS) error {
defer GinkgoRecover()

_, err := netlink.LinkByName(hostVethName)
_, err := netlinksafe.LinkByName(hostVethName)
Expect(err).To(HaveOccurred())

return nil
Expand Down
9 changes: 5 additions & 4 deletions pkg/ip/utils_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/containernetworking/cni/pkg/types"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/netlinksafe"
)

func ValidateExpectedInterfaceIPs(ifName string, resultIPs []*current.IPConfig) error {
Expand All @@ -33,12 +34,12 @@ func ValidateExpectedInterfaceIPs(ifName string, resultIPs []*current.IPConfig)
ourAddr := netlink.Addr{IPNet: &ips.Address}
match := false

link, err := netlink.LinkByName(ifName)
link, err := netlinksafe.LinkByName(ifName)
if err != nil {
return fmt.Errorf("Cannot find container link %v", ifName)
}

addrList, err := netlink.AddrList(link, netlink.FAMILY_ALL)
addrList, err := netlinksafe.AddrList(link, netlink.FAMILY_ALL)
if err != nil {
return fmt.Errorf("Cannot obtain List of IP Addresses")
}
Expand Down Expand Up @@ -67,7 +68,7 @@ func ValidateExpectedInterfaceIPs(ifName string, resultIPs []*current.IPConfig)
family = netlink.FAMILY_V4
}

gwy, err := netlink.RouteListFiltered(family, findGwy, routeFilter)
gwy, err := netlinksafe.RouteListFiltered(family, findGwy, routeFilter)
if err != nil {
return fmt.Errorf("Error %v trying to find Gateway %v for interface %v", err, ips.Gateway, ifName)
}
Expand Down Expand Up @@ -108,7 +109,7 @@ func ValidateExpectedRoute(resultRoutes []*types.Route) error {
return fmt.Errorf("Invalid static route found %v", route)
}

wasFound, err := netlink.RouteListFiltered(family, find, routeFilter)
wasFound, err := netlinksafe.RouteListFiltered(family, find, routeFilter)
if err != nil {
return fmt.Errorf("Expected Route %v not route table lookup error %v", route, err)
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/ipam/ipam_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/ip"
"github.com/containernetworking/plugins/pkg/netlinksafe"
"github.com/containernetworking/plugins/pkg/utils/sysctl"
)

Expand All @@ -38,7 +39,7 @@ func ConfigureIface(ifName string, res *current.Result) error {
return fmt.Errorf("no interfaces to configure")
}

link, err := netlink.LinkByName(ifName)
link, err := netlinksafe.LinkByName(ifName)
if err != nil {
return fmt.Errorf("failed to lookup %q: %v", ifName, err)
}
Expand Down
17 changes: 9 additions & 8 deletions pkg/ipam/ipam_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

"github.com/containernetworking/cni/pkg/types"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/plugins/pkg/netlinksafe"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
)
Expand Down Expand Up @@ -64,7 +65,7 @@ var _ = Describe("ConfigureIface", func() {
LinkAttrs: linkAttrs,
})
Expect(err).NotTo(HaveOccurred())
_, err = netlink.LinkByName(LINK_NAME)
_, err = netlinksafe.LinkByName(LINK_NAME)
Expect(err).NotTo(HaveOccurred())
return nil
})
Expand Down Expand Up @@ -148,16 +149,16 @@ var _ = Describe("ConfigureIface", func() {
err := ConfigureIface(LINK_NAME, result)
Expect(err).NotTo(HaveOccurred())

link, err := netlink.LinkByName(LINK_NAME)
link, err := netlinksafe.LinkByName(LINK_NAME)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Name).To(Equal(LINK_NAME))

v4addrs, err := netlink.AddrList(link, syscall.AF_INET)
v4addrs, err := netlinksafe.AddrList(link, syscall.AF_INET)
Expect(err).NotTo(HaveOccurred())
Expect(v4addrs).To(HaveLen(1))
Expect(ipNetEqual(v4addrs[0].IPNet, ipv4)).To(BeTrue())

v6addrs, err := netlink.AddrList(link, syscall.AF_INET6)
v6addrs, err := netlinksafe.AddrList(link, syscall.AF_INET6)
Expect(err).NotTo(HaveOccurred())
Expect(v6addrs).To(HaveLen(2))

Expand All @@ -171,7 +172,7 @@ var _ = Describe("ConfigureIface", func() {
Expect(found).To(BeTrue())

// Ensure the v4 route, v6 route, and subnet route
routes, err := netlink.RouteList(link, 0)
routes, err := netlinksafe.RouteList(link, 0)
Expect(err).NotTo(HaveOccurred())

var v4found, v6found, v4Scopefound bool
Expand Down Expand Up @@ -209,12 +210,12 @@ var _ = Describe("ConfigureIface", func() {
err := ConfigureIface(LINK_NAME, result)
Expect(err).NotTo(HaveOccurred())

link, err := netlink.LinkByName(LINK_NAME)
link, err := netlinksafe.LinkByName(LINK_NAME)
Expect(err).NotTo(HaveOccurred())
Expect(link.Attrs().Name).To(Equal(LINK_NAME))

// Ensure the v4 route, v6 route, and subnet route
routes, err := netlink.RouteList(link, 0)
routes, err := netlinksafe.RouteList(link, 0)
Expect(err).NotTo(HaveOccurred())

var v4found, v6found, v4Tablefound bool
Expand All @@ -239,7 +240,7 @@ var _ = Describe("ConfigureIface", func() {
Table: routeTable,
}

routes, err = netlink.RouteListFiltered(netlink.FAMILY_ALL,
routes, err = netlinksafe.RouteListFiltered(netlink.FAMILY_ALL,
routeFilter,
netlink.RT_FILTER_TABLE)
Expect(err).NotTo(HaveOccurred())
Expand Down
Loading