mirror of
https://github.com/vishvananda/netlink.git
synced 2025-09-27 04:05:59 +08:00
Fallback to LinkList on LinkByName when needed
Older kernels (e.g. one shipped with RHEL 6.5) don't support RTM_GETLINK with IFLA_IFNAME. In these cases fallback to dumping all interfaces and filtering in userspace.
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var native = nl.NativeEndian()
|
var native = nl.NativeEndian()
|
||||||
|
var lookupByDump = false
|
||||||
|
|
||||||
func ensureIndex(link *LinkAttrs) {
|
func ensureIndex(link *LinkAttrs) {
|
||||||
if link != nil && link.Index == 0 {
|
if link != nil && link.Index == 0 {
|
||||||
@@ -314,8 +315,26 @@ func LinkDel(link Link) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func linkByNameDump(name string) (Link, error) {
|
||||||
|
links, err := LinkList()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, link := range links {
|
||||||
|
if link.Attrs().Name == name {
|
||||||
|
return link, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Link %s not found", name)
|
||||||
|
}
|
||||||
|
|
||||||
// LinkByName finds a link by name and returns a pointer to the object.
|
// LinkByName finds a link by name and returns a pointer to the object.
|
||||||
func LinkByName(name string) (Link, error) {
|
func LinkByName(name string) (Link, error) {
|
||||||
|
if lookupByDump {
|
||||||
|
return linkByNameDump(name)
|
||||||
|
}
|
||||||
|
|
||||||
req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
|
req := nl.NewNetlinkRequest(syscall.RTM_GETLINK, syscall.NLM_F_ACK)
|
||||||
|
|
||||||
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
|
||||||
@@ -324,7 +343,15 @@ func LinkByName(name string) (Link, error) {
|
|||||||
nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(name))
|
nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(name))
|
||||||
req.AddData(nameData)
|
req.AddData(nameData)
|
||||||
|
|
||||||
return execGetLink(req)
|
link, err := execGetLink(req)
|
||||||
|
if err == syscall.EINVAL {
|
||||||
|
// older kernels don't support looking up via IFLA_IFNAME
|
||||||
|
// so fall back to dumping all links
|
||||||
|
lookupByDump = true
|
||||||
|
return linkByNameDump(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return link, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// LinkByIndex finds a link by index and returns a pointer to the object.
|
// LinkByIndex finds a link by index and returns a pointer to the object.
|
||||||
|
Reference in New Issue
Block a user