func (c *client) LinkModes() ([]*LinkMode, error) {
	return c.linkMode(netlink.Dump, Interface{})
}
LinkModes fetches modes for all ethtool-supported links.
package ethtool
import (
	"errors"
	"fmt"
	"os"
	"github.com/mdlayher/genetlink"
	"github.com/mdlayher/netlink"
	"golang.org/x/sys/unix"
)
var errBadRequest = errors.New("ethtool: Request must have Index and/or Name set when calling Client methods")
type client struct {
	c         *genetlink.Conn
	family    uint16
	monitorID uint32
}
func newClient() (*client, error) {
	conn, err := genetlink.Dial(nil)
	if err != nil {
		return nil, err
	}
	if err := conn.SetOption(netlink.ExtendedAcknowledge, true); err != nil {
		return nil, err
	}
	c, err := initClient(conn)
	if err != nil {
		_ = conn.Close()
		return nil, err
	}
	return c, nil
}
func initClient(c *genetlink.Conn) (*client, error) {
	f, err := c.GetFamily(unix.ETHTOOL_GENL_NAME)
	if err != nil {
		return nil, err
	}
	var monitorID uint32
	for _, g := range f.Groups {
		if g.Name == unix.ETHTOOL_MCGRP_MONITOR_NAME {
			monitorID = g.ID
			break
		}
	}
	if monitorID == 0 {
		return nil, errors.New("ethtool: could not find monitor multicast group ID")
	}
	return &client{
		c:         c,
		family:    f.ID,
		monitorID: monitorID,
	}, nil
}
func (c *client) Close() error { return c.c.Close() }
func (c *client) LinkInfos() ([]*LinkInfo, error) {
	return c.linkInfo(netlink.Dump, Interface{})
}
func (c *client) LinkInfo(ifi Interface) (*LinkInfo, error) {
	lis, err := c.linkInfo(0, ifi)
	if err != nil {
		return nil, err
	}
	if l := len(lis); l != 1 {
		panicf("ethtool: unexpected number of LinkInfo messages for request index: %d, name: %q: %d",
			ifi.Index, ifi.Name, l)
	}
	return lis[0], nil
}
func (c *client) linkInfo(flags netlink.HeaderFlags, ifi Interface) ([]*LinkInfo, error) {
	msgs, err := c.get(
		unix.ETHTOOL_A_LINKINFO_HEADER,
		unix.ETHTOOL_MSG_LINKINFO_GET,
		flags,
		ifi,
		nil,
	)
	if err != nil {
		return nil, err
	}
	return parseLinkInfo(msgs)
}