...

Source file src/edge-infra.dev/pkg/lib/kernel/netlink/link/link.go

Documentation: edge-infra.dev/pkg/lib/kernel/netlink/link

     1  package link
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/vishvananda/netlink"
     9  
    10  	"slices"
    11  )
    12  
    13  var (
    14  	defaultTqLength           = 1000
    15  	backboneInterfacePrefixes = []string{"eno", "ens", "enp", "enx", "eth", "enX"}
    16  )
    17  
    18  type NetLinker interface {
    19  	GetFromHardwareAddr(hardwareAddr string) (netlink.Link, error)
    20  	GetAllNetworkDeviceLinks() ([]netlink.Link, error)
    21  	GetByName(name string) (netlink.Link, error)
    22  	Ensure(link netlink.Link) (netlink.Link, error)
    23  	Delete(name string) error
    24  	NewIfb(name string, mtu int) netlink.Link
    25  }
    26  
    27  type NetLink struct{}
    28  
    29  // retrieves link from hardware address (mac address)
    30  func (n *NetLink) GetFromHardwareAddr(hardwareAddr string) (netlink.Link, error) {
    31  	allLinks, err := n.GetAllNetworkDeviceLinks()
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	for _, link := range allLinks {
    36  		if link.Attrs().HardwareAddr.String() == hardwareAddr {
    37  			return link, nil
    38  		}
    39  	}
    40  	return nil, fmt.Errorf("interface not found with hardware address: %s", hardwareAddr)
    41  }
    42  
    43  // retrieves all network device links associated on node
    44  func (n *NetLink) GetAllNetworkDeviceLinks() ([]netlink.Link, error) {
    45  	var links []netlink.Link
    46  	allLinks, err := netlink.LinkList()
    47  	if err != nil {
    48  		return nil, fmt.Errorf("error listing links: %w", err)
    49  	}
    50  	for _, link := range allLinks {
    51  		if slices.ContainsFunc(backboneInterfacePrefixes, func(prefix string) bool {
    52  			return strings.HasPrefix(link.Attrs().Name, prefix)
    53  		}) {
    54  			links = append(links, link)
    55  		}
    56  	}
    57  	return links, nil
    58  }
    59  
    60  func (n *NetLink) GetByName(name string) (netlink.Link, error) {
    61  	link, err := netlink.LinkByName(name)
    62  	if err != nil {
    63  		return nil, fmt.Errorf("error getting link %s: %w", name, err)
    64  	}
    65  	return link, nil
    66  }
    67  
    68  // Ensures a link exists and is up and returns the updated link with new link index
    69  // If the link already exists, we ensure it is up and return the up-to-date link
    70  func (n *NetLink) Ensure(link netlink.Link) (netlink.Link, error) {
    71  	name := link.Attrs().Name
    72  	if err := netlink.LinkAdd(link); err != nil && !strings.Contains(err.Error(), "file exists") {
    73  		return nil, fmt.Errorf("error creating link %s: %w", name, err)
    74  	}
    75  	link, err := netlink.LinkByName(name)
    76  	if err != nil {
    77  		return nil, fmt.Errorf("error retrieving new link %s: %w", name, err)
    78  	}
    79  	if err := netlink.LinkSetUp(link); err != nil {
    80  		return nil, fmt.Errorf("error setting link %s up: %w", name, err)
    81  	}
    82  	return link, nil
    83  }
    84  
    85  // Deletes a link if it exists
    86  func (n *NetLink) Delete(name string) error {
    87  	link, err := n.GetByName(name)
    88  	if err != nil {
    89  		if errors.As(err, &netlink.LinkNotFoundError{}) {
    90  			return nil
    91  		}
    92  		return fmt.Errorf("error retrieving link %s: %w", name, err)
    93  	}
    94  	if err := netlink.LinkDel(link); err != nil {
    95  		return fmt.Errorf("error deleting link %s: %w", name, err)
    96  	}
    97  	return nil
    98  }
    99  
   100  // Creates a new blank ifb link
   101  func (n *NetLink) NewIfb(name string, mtu int) netlink.Link {
   102  	ifbLinkAttrs := netlink.NewLinkAttrs()
   103  	ifbLinkAttrs.Name = name
   104  	defaultIfbLink := &netlink.Ifb{
   105  		LinkAttrs: ifbLinkAttrs,
   106  	}
   107  	defaultIfbLink.TxQLen = defaultTqLength
   108  	defaultIfbLink.MTU = mtu
   109  	return defaultIfbLink
   110  }
   111  

View as plain text