github.com/cilium/cilium@v1.16.2/pkg/datapath/linux/netdevice/netdevice.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package netdevice
     5  
     6  import (
     7  	"fmt"
     8  	"net/netip"
     9  
    10  	"github.com/vishvananda/netlink"
    11  	"go4.org/netipx"
    12  )
    13  
    14  func GetIfaceFirstIPv4Address(ifaceName string) (netip.Addr, error) {
    15  	dev, err := netlink.LinkByName(ifaceName)
    16  	if err != nil {
    17  		return netip.Addr{}, err
    18  	}
    19  
    20  	addrs, err := netlink.AddrList(dev, netlink.FAMILY_V4)
    21  	if err != nil {
    22  		return netip.Addr{}, err
    23  	}
    24  
    25  	for _, addr := range addrs {
    26  		if addr.IP.To4() != nil {
    27  			a, ok := netipx.FromStdIP(addr.IP)
    28  			if !ok {
    29  				continue
    30  			}
    31  			return a, nil
    32  		}
    33  	}
    34  
    35  	return netip.Addr{}, fmt.Errorf("no IPv4 address assigned to interface")
    36  }
    37  
    38  func TestForIfaceWithIPv4Address(ip netip.Addr) error {
    39  	_, err := getIfaceWithIPv4Address(ip)
    40  	return err
    41  }
    42  
    43  func GetIfaceWithIPv4Address(ip netip.Addr) (string, error) {
    44  	return getIfaceWithIPv4Address(ip)
    45  }
    46  
    47  func getIfaceWithIPv4Address(ip netip.Addr) (string, error) {
    48  	links, err := netlink.LinkList()
    49  	if err != nil {
    50  		return "", err
    51  	}
    52  
    53  	for _, l := range links {
    54  		addrs, err := netlink.AddrList(l, netlink.FAMILY_V4)
    55  		if err != nil {
    56  			return "", err
    57  		}
    58  
    59  		for _, addr := range addrs {
    60  			a, ok := netipx.FromStdIP(addr.IP)
    61  			if !ok {
    62  				continue
    63  			}
    64  			if a == ip {
    65  				return l.Attrs().Name, nil
    66  			}
    67  		}
    68  	}
    69  
    70  	return "", fmt.Errorf("no interface with %s IPv4 assigned to", ip)
    71  }