mirror of
https://github.com/prometheus/node_exporter.git
synced 2025-01-20 07:19:01 +01:00
arp: optimize netlink interface name resolution (#3133)
Some checks failed
golangci-lint / lint (push) Has been cancelled
Some checks failed
golangci-lint / lint (push) Has been cancelled
github.com/jsimonetti/rtnetlink provides a high level rtnl wrapper around the lower level rtnetlink functions, which essentially does all that we need. The rtnl.Conn.Neighbors uses an internal cache for resolving interface indexes to names, so it makes at most one rtnetlink call per interface to resolve the name. Using this high level wrapper hugely simplifies our code and makes it easier to understand and maintain. Fixes: #3075 Signed-off-by: Daniel Swarbrick <daniel.swarbrick@gmail.com>
This commit is contained in:
parent
8f9a914bee
commit
acdd9b813d
@ -17,13 +17,11 @@
|
||||
package collector
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
|
||||
"github.com/alecthomas/kingpin/v2"
|
||||
"github.com/jsimonetti/rtnetlink/v2"
|
||||
"github.com/jsimonetti/rtnetlink/v2/rtnl"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/procfs"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -76,44 +74,30 @@ func getTotalArpEntries(deviceEntries []procfs.ARPEntry) map[string]uint32 {
|
||||
}
|
||||
|
||||
func getTotalArpEntriesRTNL() (map[string]uint32, error) {
|
||||
conn, err := rtnetlink.Dial(nil)
|
||||
conn, err := rtnl.Dial(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
neighbors, err := conn.Neigh.List()
|
||||
// Neighbors will also contain IPv6 neighbors, but since this is purely an ARP collector,
|
||||
// restrict to AF_INET.
|
||||
neighbors, err := conn.Neighbours(nil, unix.AF_INET)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ifIndexEntries := make(map[uint32]uint32)
|
||||
// Map of interface name to ARP neighbor count.
|
||||
entries := make(map[string]uint32)
|
||||
|
||||
for _, n := range neighbors {
|
||||
// Neighbors will also contain IPv6 neighbors, but since this is purely an ARP collector,
|
||||
// restrict to AF_INET. Also skip entries which have state NUD_NOARP to conform to output
|
||||
// of /proc/net/arp.
|
||||
if n.Family == unix.AF_INET && n.State&unix.NUD_NOARP == 0 {
|
||||
ifIndexEntries[n.Index]++
|
||||
// Skip entries which have state NUD_NOARP to conform to output of /proc/net/arp.
|
||||
if n.State&unix.NUD_NOARP == 0 {
|
||||
entries[n.Interface.Name]++
|
||||
}
|
||||
}
|
||||
|
||||
enumEntries := make(map[string]uint32)
|
||||
|
||||
// Convert interface indexes to names.
|
||||
for ifIndex, entryCount := range ifIndexEntries {
|
||||
iface, err := net.InterfaceByIndex(int(ifIndex))
|
||||
if err != nil {
|
||||
if errors.Unwrap(err).Error() == "no such network interface" {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
enumEntries[iface.Name] = entryCount
|
||||
}
|
||||
|
||||
return enumEntries, nil
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
|
||||
|
Loading…
Reference in New Issue
Block a user