Skip to content

Commit

Permalink
try to reduce syscalls for netlink
Browse files Browse the repository at this point in the history
  • Loading branch information
Cellebyte committed Apr 23, 2024
1 parent bdd9ac8 commit 6473bb4
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 55 deletions.
2 changes: 1 addition & 1 deletion pkg/monitoring/nl.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (c *netlinkCollector) updateRoutes(ch chan<- prometheus.Metric, routeSummar
func (c *netlinkCollector) getNeighbors() []nl.NeighborInformation {
neighbors, err := c.netlink.ListNeighborInformation()
if err != nil {
c.logger.Error(err, "Cannot get neighbors from netlink")
c.logger.Error(err, "cannot get neighbors from netlink")
}
return neighbors
}
Expand Down
63 changes: 31 additions & 32 deletions pkg/nl/layer2.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"net"
"os"
"strings"
"time"

schiff_unix "github.com/telekom/das-schiff-network-operator/pkg/unix"
Expand Down Expand Up @@ -453,47 +452,47 @@ func (n *NetlinkManager) ListNeighborInformation() ([]NeighborInformation, error
if err != nil {
return nil, err
}
neighborLinks, err := n.ListNeighborInterfaces()
if err != nil {
return nil, err
}
netlinkNeighbors = append(netlinkNeighbors, fdbTable...)
neighbors := map[NeighborKey]NeighborInformation{}
for index := range netlinkNeighbors {
linkInfo, err := netlink.LinkByIndex(netlinkNeighbors[index].LinkIndex)
if err != nil {
linkInfo, ok := (*neighborLinks)[netlinkNeighbors[index].LinkIndex]
if !ok {
// we don't care if a link is not available
// as it could be removed between our LinkByIndex and arp lookup
continue
}
interfaceName := linkInfo.Attrs().Name
// This ensures that only neighbors of secondary interfaces are imported
// or hardware interfaces which support VFs
if strings.HasPrefix(interfaceName, vethL2Prefix) ||
strings.HasPrefix(interfaceName, macvlanPrefix) ||
strings.HasPrefix(interfaceName, layer2Prefix) ||
linkInfo.Attrs().Vfs != nil {
neighborKey := NeighborKey{InterfaceIndex: netlinkNeighbors[index].LinkIndex, State: netlinkNeighbors[index].State, Flags: netlinkNeighbors[index].Flags, Family: netlinkNeighbors[index].Family}
neighborInformation, ok := neighbors[neighborKey]
if ok {
neighborInformation.Quantity++
neighbors[neighborKey] = neighborInformation
} else {
family, err := GetAddressFamily(netlinkNeighbors[index].Family)
if err != nil {
return nil, fmt.Errorf("error converting addressFamily: %w", err)
}
state, err := getNeighborState(netlinkNeighbors[index].State)
if err != nil {
return nil, fmt.Errorf("error converting neighborState: %w", err)
}
flag, err := getFlags(netlinkNeighbors[index].Flags)
if err != nil {
return nil, fmt.Errorf("error converting flag: %w", err)
}
neighbors[neighborKey] = NeighborInformation{
Family: family,
State: state,
Interface: interfaceName,
Flag: flag,
Quantity: 1,
}

neighborKey := NeighborKey{InterfaceIndex: netlinkNeighbors[index].LinkIndex, State: netlinkNeighbors[index].State, Flags: netlinkNeighbors[index].Flags, Family: netlinkNeighbors[index].Family}
neighborInformation, ok := neighbors[neighborKey]
if ok {
neighborInformation.Quantity++
neighbors[neighborKey] = neighborInformation
} else {
family, err := GetAddressFamily(netlinkNeighbors[index].Family)
if err != nil {
return nil, fmt.Errorf("error converting addressFamily: %w", err)
}
state, err := getNeighborState(netlinkNeighbors[index].State)
if err != nil {
return nil, fmt.Errorf("error converting neighborState: %w", err)
}
flag, err := getFlags(netlinkNeighbors[index].Flags)
if err != nil {
return nil, fmt.Errorf("error converting flag: %w", err)
}
neighbors[neighborKey] = NeighborInformation{
Family: family,
State: state,
Interface: interfaceName,
Flag: flag,
Quantity: 1,
}
}
}
Expand Down
28 changes: 23 additions & 5 deletions pkg/nl/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ func (*NetlinkManager) listNeighbors() ([]netlink.Neigh, error) {
return neighbors, nil
}

func (*NetlinkManager) ListVRFInterfaces() ([]VRFInformation, error) {
infos := []VRFInformation{}

func (*NetlinkManager) ListVRFInterfaces() (*map[int]VRFInformation, error) {
// TODO: find a way to merge this with ListL3
infos := map[int]VRFInformation{}
links, err := netlink.LinkList()
if err != nil {
return nil, fmt.Errorf("error listing links: %w", err)
Expand All @@ -56,10 +56,28 @@ func (*NetlinkManager) ListVRFInterfaces() ([]VRFInformation, error) {
info.table = int(vrf.Table)
info.Name = link.Attrs().Name
info.vrfID = vrf.Attrs().Index
infos = append(infos, info)
infos[info.table] = info
}

return infos, nil
return &infos, nil
}

func (*NetlinkManager) ListNeighborInterfaces() (*map[int]netlink.Link, error) {
links, err := netlink.LinkList()
neighborLinks := map[int]netlink.Link{}
if err != nil {
return nil, fmt.Errorf("error listing links: %w", err)
}

for _, link := range links {
if strings.HasPrefix(link.Attrs().Name, vethL2Prefix) ||
strings.HasPrefix(link.Attrs().Name, macvlanPrefix) ||
strings.HasPrefix(link.Attrs().Name, layer2Prefix) ||
link.Attrs().Vfs != nil {
neighborLinks[link.Attrs().Index] = link
}
}
return &neighborLinks, nil
}

func (n *NetlinkManager) ListL3() ([]VRFInformation, error) {
Expand Down
28 changes: 11 additions & 17 deletions pkg/nl/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,7 @@ func GetAddressFamily(addressFamily int) (string, error) {
}
}

func (n *NetlinkManager) getVRFNameByInterface(tableID int) (string, error) {
links, err := n.ListVRFInterfaces()
if err != nil {
return "", fmt.Errorf("error getting vrf interfaces: %w", err)
}
for _, link := range links {
if tableID == link.table {
return link.Name, nil
}
}
return "", nil
}

func (n *NetlinkManager) getVRFName(tableID int) (string, error) {
func (n *NetlinkManager) getVRFName(tableID int, vrfInterfaces *map[int]VRFInformation) (string, error) {
if tableID < 0 || tableID > 255 {
return "", fmt.Errorf("table id %d out of range [0-255]", tableID)
}
Expand All @@ -165,7 +152,11 @@ func (n *NetlinkManager) getVRFName(tableID int) (string, error) {
case unspecifiedTableID:
return "unspecified", nil
default:
return n.getVRFNameByInterface(tableID)
link, ok := (*vrfInterfaces)[tableID]
if !ok {
return "", nil
}
return link.Name, nil
}
}

Expand All @@ -174,8 +165,11 @@ func (n *NetlinkManager) ListRouteInformation() ([]route.Information, error) {
if err != nil {
return nil, fmt.Errorf("error listing routes: %w", err)
}
vrfInterfaces, err := n.ListVRFInterfaces()
if err != nil {
return nil, fmt.Errorf("error getting vrf interfaces: %w", err)
}
routes := map[route.Key]route.Information{}

for index := range netlinkRoutes {
routeKey := route.Key{TableID: netlinkRoutes[index].Table, RouteProtocol: int(netlinkRoutes[index].Protocol), AddressFamily: netlinkRoutes[index].Family}
routeInformation, ok := routes[routeKey]
Expand All @@ -190,7 +184,7 @@ func (n *NetlinkManager) ListRouteInformation() ([]route.Information, error) {
if err != nil {
return nil, fmt.Errorf("error converting addressFamily [%d]: %w", netlinkRoutes[index].Family, err)
}
vrfName, err := n.getVRFName(netlinkRoutes[index].Table)
vrfName, err := n.getVRFName(netlinkRoutes[index].Table, vrfInterfaces)
if err != nil {
return nil, fmt.Errorf("error getting vrfName for table id %d: %w", netlinkRoutes[index].Table, err)
}
Expand Down

0 comments on commit 6473bb4

Please sign in to comment.