github.com/sagernet/netlink@v0.0.0-20240612041022-b9a21c07ac6a/link.go (about)

     1  package netlink
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"os"
     7  	"strconv"
     8  )
     9  
    10  // Link represents a link device from netlink. Shared link attributes
    11  // like name may be retrieved using the Attrs() method. Unique data
    12  // can be retrieved by casting the object to the proper type.
    13  type Link interface {
    14  	Attrs() *LinkAttrs
    15  	Type() string
    16  }
    17  
    18  type (
    19  	NsPid int
    20  	NsFd  int
    21  )
    22  
    23  // LinkAttrs represents data shared by most link types
    24  type LinkAttrs struct {
    25  	Index        int
    26  	MTU          int
    27  	TxQLen       int // Transmit Queue Length
    28  	Name         string
    29  	HardwareAddr net.HardwareAddr
    30  	Flags        net.Flags
    31  	RawFlags     uint32
    32  	ParentIndex  int         // index of the parent link device
    33  	MasterIndex  int         // must be the index of a bridge
    34  	Namespace    interface{} // nil | NsPid | NsFd
    35  	Alias        string
    36  	Statistics   *LinkStatistics
    37  	Promisc      int
    38  	Allmulti     int
    39  	Multi        int
    40  	Xdp          *LinkXdp
    41  	EncapType    string
    42  	Protinfo     *Protinfo
    43  	OperState    LinkOperState
    44  	PhysSwitchID int
    45  	NetNsID      int
    46  	NumTxQueues  int
    47  	NumRxQueues  int
    48  	GSOMaxSize   uint32
    49  	GSOMaxSegs   uint32
    50  	GROMaxSize   uint32
    51  	Vfs          []VfInfo // virtual functions available on link
    52  	Group        uint32
    53  	Slave        LinkSlave
    54  }
    55  
    56  // LinkSlave represents a slave device.
    57  type LinkSlave interface {
    58  	SlaveType() string
    59  }
    60  
    61  // VfInfo represents configuration of virtual function
    62  type VfInfo struct {
    63  	ID        int
    64  	Mac       net.HardwareAddr
    65  	Vlan      int
    66  	Qos       int
    67  	TxRate    int // IFLA_VF_TX_RATE  Max TxRate
    68  	Spoofchk  bool
    69  	LinkState uint32
    70  	MaxTxRate uint32 // IFLA_VF_RATE Max TxRate
    71  	MinTxRate uint32 // IFLA_VF_RATE Min TxRate
    72  	RxPackets uint64
    73  	TxPackets uint64
    74  	RxBytes   uint64
    75  	TxBytes   uint64
    76  	Multicast uint64
    77  	Broadcast uint64
    78  	RxDropped uint64
    79  	TxDropped uint64
    80  
    81  	RssQuery uint32
    82  	Trust    uint32
    83  }
    84  
    85  // LinkOperState represents the values of the IFLA_OPERSTATE link
    86  // attribute, which contains the RFC2863 state of the interface.
    87  type LinkOperState uint8
    88  
    89  const (
    90  	OperUnknown        = iota // Status can't be determined.
    91  	OperNotPresent            // Some component is missing.
    92  	OperDown                  // Down.
    93  	OperLowerLayerDown        // Down due to state of lower layer.
    94  	OperTesting               // In some test mode.
    95  	OperDormant               // Not up but pending an external event.
    96  	OperUp                    // Up, ready to send packets.
    97  )
    98  
    99  func (s LinkOperState) String() string {
   100  	switch s {
   101  	case OperNotPresent:
   102  		return "not-present"
   103  	case OperDown:
   104  		return "down"
   105  	case OperLowerLayerDown:
   106  		return "lower-layer-down"
   107  	case OperTesting:
   108  		return "testing"
   109  	case OperDormant:
   110  		return "dormant"
   111  	case OperUp:
   112  		return "up"
   113  	default:
   114  		return "unknown"
   115  	}
   116  }
   117  
   118  // NewLinkAttrs returns LinkAttrs structure filled with default values
   119  func NewLinkAttrs() LinkAttrs {
   120  	return LinkAttrs{
   121  		NetNsID: -1,
   122  		TxQLen:  -1,
   123  	}
   124  }
   125  
   126  type LinkStatistics LinkStatistics64
   127  
   128  /*
   129  Ref: struct rtnl_link_stats {...}
   130  */
   131  type LinkStatistics32 struct {
   132  	RxPackets         uint32
   133  	TxPackets         uint32
   134  	RxBytes           uint32
   135  	TxBytes           uint32
   136  	RxErrors          uint32
   137  	TxErrors          uint32
   138  	RxDropped         uint32
   139  	TxDropped         uint32
   140  	Multicast         uint32
   141  	Collisions        uint32
   142  	RxLengthErrors    uint32
   143  	RxOverErrors      uint32
   144  	RxCrcErrors       uint32
   145  	RxFrameErrors     uint32
   146  	RxFifoErrors      uint32
   147  	RxMissedErrors    uint32
   148  	TxAbortedErrors   uint32
   149  	TxCarrierErrors   uint32
   150  	TxFifoErrors      uint32
   151  	TxHeartbeatErrors uint32
   152  	TxWindowErrors    uint32
   153  	RxCompressed      uint32
   154  	TxCompressed      uint32
   155  }
   156  
   157  func (s32 LinkStatistics32) to64() *LinkStatistics64 {
   158  	return &LinkStatistics64{
   159  		RxPackets:         uint64(s32.RxPackets),
   160  		TxPackets:         uint64(s32.TxPackets),
   161  		RxBytes:           uint64(s32.RxBytes),
   162  		TxBytes:           uint64(s32.TxBytes),
   163  		RxErrors:          uint64(s32.RxErrors),
   164  		TxErrors:          uint64(s32.TxErrors),
   165  		RxDropped:         uint64(s32.RxDropped),
   166  		TxDropped:         uint64(s32.TxDropped),
   167  		Multicast:         uint64(s32.Multicast),
   168  		Collisions:        uint64(s32.Collisions),
   169  		RxLengthErrors:    uint64(s32.RxLengthErrors),
   170  		RxOverErrors:      uint64(s32.RxOverErrors),
   171  		RxCrcErrors:       uint64(s32.RxCrcErrors),
   172  		RxFrameErrors:     uint64(s32.RxFrameErrors),
   173  		RxFifoErrors:      uint64(s32.RxFifoErrors),
   174  		RxMissedErrors:    uint64(s32.RxMissedErrors),
   175  		TxAbortedErrors:   uint64(s32.TxAbortedErrors),
   176  		TxCarrierErrors:   uint64(s32.TxCarrierErrors),
   177  		TxFifoErrors:      uint64(s32.TxFifoErrors),
   178  		TxHeartbeatErrors: uint64(s32.TxHeartbeatErrors),
   179  		TxWindowErrors:    uint64(s32.TxWindowErrors),
   180  		RxCompressed:      uint64(s32.RxCompressed),
   181  		TxCompressed:      uint64(s32.TxCompressed),
   182  	}
   183  }
   184  
   185  /*
   186  Ref: struct rtnl_link_stats64 {...}
   187  */
   188  type LinkStatistics64 struct {
   189  	RxPackets         uint64
   190  	TxPackets         uint64
   191  	RxBytes           uint64
   192  	TxBytes           uint64
   193  	RxErrors          uint64
   194  	TxErrors          uint64
   195  	RxDropped         uint64
   196  	TxDropped         uint64
   197  	Multicast         uint64
   198  	Collisions        uint64
   199  	RxLengthErrors    uint64
   200  	RxOverErrors      uint64
   201  	RxCrcErrors       uint64
   202  	RxFrameErrors     uint64
   203  	RxFifoErrors      uint64
   204  	RxMissedErrors    uint64
   205  	TxAbortedErrors   uint64
   206  	TxCarrierErrors   uint64
   207  	TxFifoErrors      uint64
   208  	TxHeartbeatErrors uint64
   209  	TxWindowErrors    uint64
   210  	RxCompressed      uint64
   211  	TxCompressed      uint64
   212  }
   213  
   214  type LinkXdp struct {
   215  	Fd         int
   216  	Attached   bool
   217  	AttachMode uint32
   218  	Flags      uint32
   219  	ProgId     uint32
   220  }
   221  
   222  // Device links cannot be created via netlink. These links
   223  // are links created by udev like 'lo' and 'etho0'
   224  type Device struct {
   225  	LinkAttrs
   226  }
   227  
   228  func (device *Device) Attrs() *LinkAttrs {
   229  	return &device.LinkAttrs
   230  }
   231  
   232  func (device *Device) Type() string {
   233  	return "device"
   234  }
   235  
   236  // Dummy links are dummy ethernet devices
   237  type Dummy struct {
   238  	LinkAttrs
   239  }
   240  
   241  func (dummy *Dummy) Attrs() *LinkAttrs {
   242  	return &dummy.LinkAttrs
   243  }
   244  
   245  func (dummy *Dummy) Type() string {
   246  	return "dummy"
   247  }
   248  
   249  // Ifb links are advanced dummy devices for packet filtering
   250  type Ifb struct {
   251  	LinkAttrs
   252  }
   253  
   254  func (ifb *Ifb) Attrs() *LinkAttrs {
   255  	return &ifb.LinkAttrs
   256  }
   257  
   258  func (ifb *Ifb) Type() string {
   259  	return "ifb"
   260  }
   261  
   262  // Bridge links are simple linux bridges
   263  type Bridge struct {
   264  	LinkAttrs
   265  	MulticastSnooping *bool
   266  	AgeingTime        *uint32
   267  	HelloTime         *uint32
   268  	VlanFiltering     *bool
   269  }
   270  
   271  func (bridge *Bridge) Attrs() *LinkAttrs {
   272  	return &bridge.LinkAttrs
   273  }
   274  
   275  func (bridge *Bridge) Type() string {
   276  	return "bridge"
   277  }
   278  
   279  // Vlan links have ParentIndex set in their Attrs()
   280  type Vlan struct {
   281  	LinkAttrs
   282  	VlanId       int
   283  	VlanProtocol VlanProtocol
   284  }
   285  
   286  func (vlan *Vlan) Attrs() *LinkAttrs {
   287  	return &vlan.LinkAttrs
   288  }
   289  
   290  func (vlan *Vlan) Type() string {
   291  	return "vlan"
   292  }
   293  
   294  type MacvlanMode uint16
   295  
   296  const (
   297  	MACVLAN_MODE_DEFAULT MacvlanMode = iota
   298  	MACVLAN_MODE_PRIVATE
   299  	MACVLAN_MODE_VEPA
   300  	MACVLAN_MODE_BRIDGE
   301  	MACVLAN_MODE_PASSTHRU
   302  	MACVLAN_MODE_SOURCE
   303  )
   304  
   305  // Macvlan links have ParentIndex set in their Attrs()
   306  type Macvlan struct {
   307  	LinkAttrs
   308  	Mode MacvlanMode
   309  
   310  	// MACAddrs is only populated for Macvlan SOURCE links
   311  	MACAddrs []net.HardwareAddr
   312  }
   313  
   314  func (macvlan *Macvlan) Attrs() *LinkAttrs {
   315  	return &macvlan.LinkAttrs
   316  }
   317  
   318  func (macvlan *Macvlan) Type() string {
   319  	return "macvlan"
   320  }
   321  
   322  // Macvtap - macvtap is a virtual interfaces based on macvlan
   323  type Macvtap struct {
   324  	Macvlan
   325  }
   326  
   327  func (macvtap Macvtap) Type() string {
   328  	return "macvtap"
   329  }
   330  
   331  type TuntapMode uint16
   332  type TuntapFlag uint16
   333  
   334  // Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
   335  type Tuntap struct {
   336  	LinkAttrs
   337  	Mode       TuntapMode
   338  	Flags      TuntapFlag
   339  	NonPersist bool
   340  	Queues     int
   341  	Fds        []*os.File
   342  	Owner      uint32
   343  	Group      uint32
   344  }
   345  
   346  func (tuntap *Tuntap) Attrs() *LinkAttrs {
   347  	return &tuntap.LinkAttrs
   348  }
   349  
   350  func (tuntap *Tuntap) Type() string {
   351  	return "tuntap"
   352  }
   353  
   354  // Veth devices must specify PeerName on create
   355  type Veth struct {
   356  	LinkAttrs
   357  	PeerName         string // veth on create only
   358  	PeerHardwareAddr net.HardwareAddr
   359  	PeerNamespace    interface{}
   360  }
   361  
   362  func (veth *Veth) Attrs() *LinkAttrs {
   363  	return &veth.LinkAttrs
   364  }
   365  
   366  func (veth *Veth) Type() string {
   367  	return "veth"
   368  }
   369  
   370  // Wireguard represent links of type "wireguard", see https://www.wireguard.com/
   371  type Wireguard struct {
   372  	LinkAttrs
   373  }
   374  
   375  func (wg *Wireguard) Attrs() *LinkAttrs {
   376  	return &wg.LinkAttrs
   377  }
   378  
   379  func (wg *Wireguard) Type() string {
   380  	return "wireguard"
   381  }
   382  
   383  // GenericLink links represent types that are not currently understood
   384  // by this netlink library.
   385  type GenericLink struct {
   386  	LinkAttrs
   387  	LinkType string
   388  }
   389  
   390  func (generic *GenericLink) Attrs() *LinkAttrs {
   391  	return &generic.LinkAttrs
   392  }
   393  
   394  func (generic *GenericLink) Type() string {
   395  	return generic.LinkType
   396  }
   397  
   398  type Vxlan struct {
   399  	LinkAttrs
   400  	VxlanId        int
   401  	VtepDevIndex   int
   402  	SrcAddr        net.IP
   403  	Group          net.IP
   404  	TTL            int
   405  	TOS            int
   406  	Learning       bool
   407  	Proxy          bool
   408  	RSC            bool
   409  	L2miss         bool
   410  	L3miss         bool
   411  	UDPCSum        bool
   412  	UDP6ZeroCSumTx bool
   413  	UDP6ZeroCSumRx bool
   414  	NoAge          bool
   415  	GBP            bool
   416  	FlowBased      bool
   417  	Age            int
   418  	Limit          int
   419  	Port           int
   420  	PortLow        int
   421  	PortHigh       int
   422  }
   423  
   424  func (vxlan *Vxlan) Attrs() *LinkAttrs {
   425  	return &vxlan.LinkAttrs
   426  }
   427  
   428  func (vxlan *Vxlan) Type() string {
   429  	return "vxlan"
   430  }
   431  
   432  type IPVlanMode uint16
   433  
   434  const (
   435  	IPVLAN_MODE_L2 IPVlanMode = iota
   436  	IPVLAN_MODE_L3
   437  	IPVLAN_MODE_L3S
   438  	IPVLAN_MODE_MAX
   439  )
   440  
   441  type IPVlanFlag uint16
   442  
   443  const (
   444  	IPVLAN_FLAG_BRIDGE IPVlanFlag = iota
   445  	IPVLAN_FLAG_PRIVATE
   446  	IPVLAN_FLAG_VEPA
   447  )
   448  
   449  type IPVlan struct {
   450  	LinkAttrs
   451  	Mode IPVlanMode
   452  	Flag IPVlanFlag
   453  }
   454  
   455  func (ipvlan *IPVlan) Attrs() *LinkAttrs {
   456  	return &ipvlan.LinkAttrs
   457  }
   458  
   459  func (ipvlan *IPVlan) Type() string {
   460  	return "ipvlan"
   461  }
   462  
   463  // IPVtap - IPVtap is a virtual interfaces based on ipvlan
   464  type IPVtap struct {
   465  	IPVlan
   466  }
   467  
   468  func (ipvtap *IPVtap) Attrs() *LinkAttrs {
   469  	return &ipvtap.LinkAttrs
   470  }
   471  
   472  func (ipvtap IPVtap) Type() string {
   473  	return "ipvtap"
   474  }
   475  
   476  // VlanProtocol type
   477  type VlanProtocol int
   478  
   479  func (p VlanProtocol) String() string {
   480  	s, ok := VlanProtocolToString[p]
   481  	if !ok {
   482  		return fmt.Sprintf("VlanProtocol(%d)", p)
   483  	}
   484  	return s
   485  }
   486  
   487  // StringToVlanProtocol returns vlan protocol, or unknown is the s is invalid.
   488  func StringToVlanProtocol(s string) VlanProtocol {
   489  	mode, ok := StringToVlanProtocolMap[s]
   490  	if !ok {
   491  		return VLAN_PROTOCOL_UNKNOWN
   492  	}
   493  	return mode
   494  }
   495  
   496  // VlanProtocol possible values
   497  const (
   498  	VLAN_PROTOCOL_UNKNOWN VlanProtocol = 0
   499  	VLAN_PROTOCOL_8021Q   VlanProtocol = 0x8100
   500  	VLAN_PROTOCOL_8021AD  VlanProtocol = 0x88A8
   501  )
   502  
   503  var VlanProtocolToString = map[VlanProtocol]string{
   504  	VLAN_PROTOCOL_8021Q:  "802.1q",
   505  	VLAN_PROTOCOL_8021AD: "802.1ad",
   506  }
   507  
   508  var StringToVlanProtocolMap = map[string]VlanProtocol{
   509  	"802.1q":  VLAN_PROTOCOL_8021Q,
   510  	"802.1ad": VLAN_PROTOCOL_8021AD,
   511  }
   512  
   513  // BondMode type
   514  type BondMode int
   515  
   516  func (b BondMode) String() string {
   517  	s, ok := bondModeToString[b]
   518  	if !ok {
   519  		return fmt.Sprintf("BondMode(%d)", b)
   520  	}
   521  	return s
   522  }
   523  
   524  // StringToBondMode returns bond mode, or unknown is the s is invalid.
   525  func StringToBondMode(s string) BondMode {
   526  	mode, ok := StringToBondModeMap[s]
   527  	if !ok {
   528  		return BOND_MODE_UNKNOWN
   529  	}
   530  	return mode
   531  }
   532  
   533  // Possible BondMode
   534  const (
   535  	BOND_MODE_BALANCE_RR BondMode = iota
   536  	BOND_MODE_ACTIVE_BACKUP
   537  	BOND_MODE_BALANCE_XOR
   538  	BOND_MODE_BROADCAST
   539  	BOND_MODE_802_3AD
   540  	BOND_MODE_BALANCE_TLB
   541  	BOND_MODE_BALANCE_ALB
   542  	BOND_MODE_UNKNOWN
   543  )
   544  
   545  var bondModeToString = map[BondMode]string{
   546  	BOND_MODE_BALANCE_RR:    "balance-rr",
   547  	BOND_MODE_ACTIVE_BACKUP: "active-backup",
   548  	BOND_MODE_BALANCE_XOR:   "balance-xor",
   549  	BOND_MODE_BROADCAST:     "broadcast",
   550  	BOND_MODE_802_3AD:       "802.3ad",
   551  	BOND_MODE_BALANCE_TLB:   "balance-tlb",
   552  	BOND_MODE_BALANCE_ALB:   "balance-alb",
   553  }
   554  var StringToBondModeMap = map[string]BondMode{
   555  	"balance-rr":    BOND_MODE_BALANCE_RR,
   556  	"active-backup": BOND_MODE_ACTIVE_BACKUP,
   557  	"balance-xor":   BOND_MODE_BALANCE_XOR,
   558  	"broadcast":     BOND_MODE_BROADCAST,
   559  	"802.3ad":       BOND_MODE_802_3AD,
   560  	"balance-tlb":   BOND_MODE_BALANCE_TLB,
   561  	"balance-alb":   BOND_MODE_BALANCE_ALB,
   562  }
   563  
   564  // BondArpValidate type
   565  type BondArpValidate int
   566  
   567  // Possible BondArpValidate value
   568  const (
   569  	BOND_ARP_VALIDATE_NONE BondArpValidate = iota
   570  	BOND_ARP_VALIDATE_ACTIVE
   571  	BOND_ARP_VALIDATE_BACKUP
   572  	BOND_ARP_VALIDATE_ALL
   573  )
   574  
   575  var bondArpValidateToString = map[BondArpValidate]string{
   576  	BOND_ARP_VALIDATE_NONE:   "none",
   577  	BOND_ARP_VALIDATE_ACTIVE: "active",
   578  	BOND_ARP_VALIDATE_BACKUP: "backup",
   579  	BOND_ARP_VALIDATE_ALL:    "none",
   580  }
   581  var StringToBondArpValidateMap = map[string]BondArpValidate{
   582  	"none":   BOND_ARP_VALIDATE_NONE,
   583  	"active": BOND_ARP_VALIDATE_ACTIVE,
   584  	"backup": BOND_ARP_VALIDATE_BACKUP,
   585  	"all":    BOND_ARP_VALIDATE_ALL,
   586  }
   587  
   588  func (b BondArpValidate) String() string {
   589  	s, ok := bondArpValidateToString[b]
   590  	if !ok {
   591  		return fmt.Sprintf("BondArpValidate(%d)", b)
   592  	}
   593  	return s
   594  }
   595  
   596  // BondPrimaryReselect type
   597  type BondPrimaryReselect int
   598  
   599  // Possible BondPrimaryReselect value
   600  const (
   601  	BOND_PRIMARY_RESELECT_ALWAYS BondPrimaryReselect = iota
   602  	BOND_PRIMARY_RESELECT_BETTER
   603  	BOND_PRIMARY_RESELECT_FAILURE
   604  )
   605  
   606  var bondPrimaryReselectToString = map[BondPrimaryReselect]string{
   607  	BOND_PRIMARY_RESELECT_ALWAYS:  "always",
   608  	BOND_PRIMARY_RESELECT_BETTER:  "better",
   609  	BOND_PRIMARY_RESELECT_FAILURE: "failure",
   610  }
   611  var StringToBondPrimaryReselectMap = map[string]BondPrimaryReselect{
   612  	"always":  BOND_PRIMARY_RESELECT_ALWAYS,
   613  	"better":  BOND_PRIMARY_RESELECT_BETTER,
   614  	"failure": BOND_PRIMARY_RESELECT_FAILURE,
   615  }
   616  
   617  func (b BondPrimaryReselect) String() string {
   618  	s, ok := bondPrimaryReselectToString[b]
   619  	if !ok {
   620  		return fmt.Sprintf("BondPrimaryReselect(%d)", b)
   621  	}
   622  	return s
   623  }
   624  
   625  // BondArpAllTargets type
   626  type BondArpAllTargets int
   627  
   628  // Possible BondArpAllTargets value
   629  const (
   630  	BOND_ARP_ALL_TARGETS_ANY BondArpAllTargets = iota
   631  	BOND_ARP_ALL_TARGETS_ALL
   632  )
   633  
   634  var bondArpAllTargetsToString = map[BondArpAllTargets]string{
   635  	BOND_ARP_ALL_TARGETS_ANY: "any",
   636  	BOND_ARP_ALL_TARGETS_ALL: "all",
   637  }
   638  var StringToBondArpAllTargetsMap = map[string]BondArpAllTargets{
   639  	"any": BOND_ARP_ALL_TARGETS_ANY,
   640  	"all": BOND_ARP_ALL_TARGETS_ALL,
   641  }
   642  
   643  func (b BondArpAllTargets) String() string {
   644  	s, ok := bondArpAllTargetsToString[b]
   645  	if !ok {
   646  		return fmt.Sprintf("BondArpAllTargets(%d)", b)
   647  	}
   648  	return s
   649  }
   650  
   651  // BondFailOverMac type
   652  type BondFailOverMac int
   653  
   654  // Possible BondFailOverMac value
   655  const (
   656  	BOND_FAIL_OVER_MAC_NONE BondFailOverMac = iota
   657  	BOND_FAIL_OVER_MAC_ACTIVE
   658  	BOND_FAIL_OVER_MAC_FOLLOW
   659  )
   660  
   661  var bondFailOverMacToString = map[BondFailOverMac]string{
   662  	BOND_FAIL_OVER_MAC_NONE:   "none",
   663  	BOND_FAIL_OVER_MAC_ACTIVE: "active",
   664  	BOND_FAIL_OVER_MAC_FOLLOW: "follow",
   665  }
   666  var StringToBondFailOverMacMap = map[string]BondFailOverMac{
   667  	"none":   BOND_FAIL_OVER_MAC_NONE,
   668  	"active": BOND_FAIL_OVER_MAC_ACTIVE,
   669  	"follow": BOND_FAIL_OVER_MAC_FOLLOW,
   670  }
   671  
   672  func (b BondFailOverMac) String() string {
   673  	s, ok := bondFailOverMacToString[b]
   674  	if !ok {
   675  		return fmt.Sprintf("BondFailOverMac(%d)", b)
   676  	}
   677  	return s
   678  }
   679  
   680  // BondXmitHashPolicy type
   681  type BondXmitHashPolicy int
   682  
   683  func (b BondXmitHashPolicy) String() string {
   684  	s, ok := bondXmitHashPolicyToString[b]
   685  	if !ok {
   686  		return fmt.Sprintf("XmitHashPolicy(%d)", b)
   687  	}
   688  	return s
   689  }
   690  
   691  // StringToBondXmitHashPolicy returns bond lacp arte, or unknown is the s is invalid.
   692  func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy {
   693  	lacp, ok := StringToBondXmitHashPolicyMap[s]
   694  	if !ok {
   695  		return BOND_XMIT_HASH_POLICY_UNKNOWN
   696  	}
   697  	return lacp
   698  }
   699  
   700  // Possible BondXmitHashPolicy value
   701  const (
   702  	BOND_XMIT_HASH_POLICY_LAYER2 BondXmitHashPolicy = iota
   703  	BOND_XMIT_HASH_POLICY_LAYER3_4
   704  	BOND_XMIT_HASH_POLICY_LAYER2_3
   705  	BOND_XMIT_HASH_POLICY_ENCAP2_3
   706  	BOND_XMIT_HASH_POLICY_ENCAP3_4
   707  	BOND_XMIT_HASH_POLICY_UNKNOWN
   708  )
   709  
   710  var bondXmitHashPolicyToString = map[BondXmitHashPolicy]string{
   711  	BOND_XMIT_HASH_POLICY_LAYER2:   "layer2",
   712  	BOND_XMIT_HASH_POLICY_LAYER3_4: "layer3+4",
   713  	BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3",
   714  	BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3",
   715  	BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4",
   716  }
   717  var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{
   718  	"layer2":   BOND_XMIT_HASH_POLICY_LAYER2,
   719  	"layer3+4": BOND_XMIT_HASH_POLICY_LAYER3_4,
   720  	"layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3,
   721  	"encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3,
   722  	"encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4,
   723  }
   724  
   725  // BondLacpRate type
   726  type BondLacpRate int
   727  
   728  func (b BondLacpRate) String() string {
   729  	s, ok := bondLacpRateToString[b]
   730  	if !ok {
   731  		return fmt.Sprintf("LacpRate(%d)", b)
   732  	}
   733  	return s
   734  }
   735  
   736  // StringToBondLacpRate returns bond lacp arte, or unknown is the s is invalid.
   737  func StringToBondLacpRate(s string) BondLacpRate {
   738  	lacp, ok := StringToBondLacpRateMap[s]
   739  	if !ok {
   740  		return BOND_LACP_RATE_UNKNOWN
   741  	}
   742  	return lacp
   743  }
   744  
   745  // Possible BondLacpRate value
   746  const (
   747  	BOND_LACP_RATE_SLOW BondLacpRate = iota
   748  	BOND_LACP_RATE_FAST
   749  	BOND_LACP_RATE_UNKNOWN
   750  )
   751  
   752  var bondLacpRateToString = map[BondLacpRate]string{
   753  	BOND_LACP_RATE_SLOW: "slow",
   754  	BOND_LACP_RATE_FAST: "fast",
   755  }
   756  var StringToBondLacpRateMap = map[string]BondLacpRate{
   757  	"slow": BOND_LACP_RATE_SLOW,
   758  	"fast": BOND_LACP_RATE_FAST,
   759  }
   760  
   761  // BondAdSelect type
   762  type BondAdSelect int
   763  
   764  // Possible BondAdSelect value
   765  const (
   766  	BOND_AD_SELECT_STABLE BondAdSelect = iota
   767  	BOND_AD_SELECT_BANDWIDTH
   768  	BOND_AD_SELECT_COUNT
   769  )
   770  
   771  var bondAdSelectToString = map[BondAdSelect]string{
   772  	BOND_AD_SELECT_STABLE:    "stable",
   773  	BOND_AD_SELECT_BANDWIDTH: "bandwidth",
   774  	BOND_AD_SELECT_COUNT:     "count",
   775  }
   776  var StringToBondAdSelectMap = map[string]BondAdSelect{
   777  	"stable":    BOND_AD_SELECT_STABLE,
   778  	"bandwidth": BOND_AD_SELECT_BANDWIDTH,
   779  	"count":     BOND_AD_SELECT_COUNT,
   780  }
   781  
   782  func (b BondAdSelect) String() string {
   783  	s, ok := bondAdSelectToString[b]
   784  	if !ok {
   785  		return fmt.Sprintf("BondAdSelect(%d)", b)
   786  	}
   787  	return s
   788  }
   789  
   790  // BondAdInfo represents ad info for bond
   791  type BondAdInfo struct {
   792  	AggregatorId int
   793  	NumPorts     int
   794  	ActorKey     int
   795  	PartnerKey   int
   796  	PartnerMac   net.HardwareAddr
   797  }
   798  
   799  // Bond representation
   800  type Bond struct {
   801  	LinkAttrs
   802  	Mode            BondMode
   803  	ActiveSlave     int
   804  	Miimon          int
   805  	UpDelay         int
   806  	DownDelay       int
   807  	UseCarrier      int
   808  	ArpInterval     int
   809  	ArpIpTargets    []net.IP
   810  	ArpValidate     BondArpValidate
   811  	ArpAllTargets   BondArpAllTargets
   812  	Primary         int
   813  	PrimaryReselect BondPrimaryReselect
   814  	FailOverMac     BondFailOverMac
   815  	XmitHashPolicy  BondXmitHashPolicy
   816  	ResendIgmp      int
   817  	NumPeerNotif    int
   818  	AllSlavesActive int
   819  	MinLinks        int
   820  	LpInterval      int
   821  	PacketsPerSlave int
   822  	LacpRate        BondLacpRate
   823  	AdSelect        BondAdSelect
   824  	// looking at iproute tool AdInfo can only be retrived. It can't be set.
   825  	AdInfo         *BondAdInfo
   826  	AdActorSysPrio int
   827  	AdUserPortKey  int
   828  	AdActorSystem  net.HardwareAddr
   829  	TlbDynamicLb   int
   830  }
   831  
   832  func NewLinkBond(atr LinkAttrs) *Bond {
   833  	return &Bond{
   834  		LinkAttrs:       atr,
   835  		Mode:            -1,
   836  		ActiveSlave:     -1,
   837  		Miimon:          -1,
   838  		UpDelay:         -1,
   839  		DownDelay:       -1,
   840  		UseCarrier:      -1,
   841  		ArpInterval:     -1,
   842  		ArpIpTargets:    nil,
   843  		ArpValidate:     -1,
   844  		ArpAllTargets:   -1,
   845  		Primary:         -1,
   846  		PrimaryReselect: -1,
   847  		FailOverMac:     -1,
   848  		XmitHashPolicy:  -1,
   849  		ResendIgmp:      -1,
   850  		NumPeerNotif:    -1,
   851  		AllSlavesActive: -1,
   852  		MinLinks:        -1,
   853  		LpInterval:      -1,
   854  		PacketsPerSlave: -1,
   855  		LacpRate:        -1,
   856  		AdSelect:        -1,
   857  		AdActorSysPrio:  -1,
   858  		AdUserPortKey:   -1,
   859  		AdActorSystem:   nil,
   860  		TlbDynamicLb:    -1,
   861  	}
   862  }
   863  
   864  // Flag mask for bond options. Bond.Flagmask must be set to on for option to work.
   865  const (
   866  	BOND_MODE_MASK uint64 = 1 << (1 + iota)
   867  	BOND_ACTIVE_SLAVE_MASK
   868  	BOND_MIIMON_MASK
   869  	BOND_UPDELAY_MASK
   870  	BOND_DOWNDELAY_MASK
   871  	BOND_USE_CARRIER_MASK
   872  	BOND_ARP_INTERVAL_MASK
   873  	BOND_ARP_VALIDATE_MASK
   874  	BOND_ARP_ALL_TARGETS_MASK
   875  	BOND_PRIMARY_MASK
   876  	BOND_PRIMARY_RESELECT_MASK
   877  	BOND_FAIL_OVER_MAC_MASK
   878  	BOND_XMIT_HASH_POLICY_MASK
   879  	BOND_RESEND_IGMP_MASK
   880  	BOND_NUM_PEER_NOTIF_MASK
   881  	BOND_ALL_SLAVES_ACTIVE_MASK
   882  	BOND_MIN_LINKS_MASK
   883  	BOND_LP_INTERVAL_MASK
   884  	BOND_PACKETS_PER_SLAVE_MASK
   885  	BOND_LACP_RATE_MASK
   886  	BOND_AD_SELECT_MASK
   887  )
   888  
   889  // Attrs implementation.
   890  func (bond *Bond) Attrs() *LinkAttrs {
   891  	return &bond.LinkAttrs
   892  }
   893  
   894  // Type implementation fro Vxlan.
   895  func (bond *Bond) Type() string {
   896  	return "bond"
   897  }
   898  
   899  // BondSlaveState represents the values of the IFLA_BOND_SLAVE_STATE bond slave
   900  // attribute, which contains the state of the bond slave.
   901  type BondSlaveState uint8
   902  
   903  const (
   904  	//BondStateActive Link is active.
   905  	BondStateActive BondSlaveState = iota
   906  	//BondStateBackup Link is backup.
   907  	BondStateBackup
   908  )
   909  
   910  func (s BondSlaveState) String() string {
   911  	switch s {
   912  	case BondStateActive:
   913  		return "ACTIVE"
   914  	case BondStateBackup:
   915  		return "BACKUP"
   916  	default:
   917  		return strconv.Itoa(int(s))
   918  	}
   919  }
   920  
   921  // BondSlaveMiiStatus represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
   922  // attribute, which contains the status of MII link monitoring
   923  type BondSlaveMiiStatus uint8
   924  
   925  const (
   926  	//BondLinkUp link is up and running.
   927  	BondLinkUp BondSlaveMiiStatus = iota
   928  	//BondLinkFail link has just gone down.
   929  	BondLinkFail
   930  	//BondLinkDown link has been down for too long time.
   931  	BondLinkDown
   932  	//BondLinkBack link is going back.
   933  	BondLinkBack
   934  )
   935  
   936  func (s BondSlaveMiiStatus) String() string {
   937  	switch s {
   938  	case BondLinkUp:
   939  		return "UP"
   940  	case BondLinkFail:
   941  		return "GOING_DOWN"
   942  	case BondLinkDown:
   943  		return "DOWN"
   944  	case BondLinkBack:
   945  		return "GOING_BACK"
   946  	default:
   947  		return strconv.Itoa(int(s))
   948  	}
   949  }
   950  
   951  type BondSlave struct {
   952  	State                  BondSlaveState
   953  	MiiStatus              BondSlaveMiiStatus
   954  	LinkFailureCount       uint32
   955  	PermHardwareAddr       net.HardwareAddr
   956  	QueueId                uint16
   957  	AggregatorId           uint16
   958  	AdActorOperPortState   uint8
   959  	AdPartnerOperPortState uint16
   960  }
   961  
   962  func (b *BondSlave) SlaveType() string {
   963  	return "bond"
   964  }
   965  
   966  type VrfSlave struct {
   967  	Table uint32
   968  }
   969  
   970  func (v *VrfSlave) SlaveType() string {
   971  	return "vrf"
   972  }
   973  
   974  // Geneve devices must specify RemoteIP and ID (VNI) on create
   975  // https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223
   976  type Geneve struct {
   977  	LinkAttrs
   978  	ID             uint32 // vni
   979  	Remote         net.IP
   980  	Ttl            uint8
   981  	Tos            uint8
   982  	Dport          uint16
   983  	UdpCsum        uint8
   984  	UdpZeroCsum6Tx uint8
   985  	UdpZeroCsum6Rx uint8
   986  	Link           uint32
   987  	FlowBased      bool
   988  }
   989  
   990  func (geneve *Geneve) Attrs() *LinkAttrs {
   991  	return &geneve.LinkAttrs
   992  }
   993  
   994  func (geneve *Geneve) Type() string {
   995  	return "geneve"
   996  }
   997  
   998  // Gretap devices must specify LocalIP and RemoteIP on create
   999  type Gretap struct {
  1000  	LinkAttrs
  1001  	IKey       uint32
  1002  	OKey       uint32
  1003  	EncapSport uint16
  1004  	EncapDport uint16
  1005  	Local      net.IP
  1006  	Remote     net.IP
  1007  	IFlags     uint16
  1008  	OFlags     uint16
  1009  	PMtuDisc   uint8
  1010  	Ttl        uint8
  1011  	Tos        uint8
  1012  	EncapType  uint16
  1013  	EncapFlags uint16
  1014  	Link       uint32
  1015  	FlowBased  bool
  1016  }
  1017  
  1018  func (gretap *Gretap) Attrs() *LinkAttrs {
  1019  	return &gretap.LinkAttrs
  1020  }
  1021  
  1022  func (gretap *Gretap) Type() string {
  1023  	if gretap.Local.To4() == nil {
  1024  		return "ip6gretap"
  1025  	}
  1026  	return "gretap"
  1027  }
  1028  
  1029  type Iptun struct {
  1030  	LinkAttrs
  1031  	Ttl        uint8
  1032  	Tos        uint8
  1033  	PMtuDisc   uint8
  1034  	Link       uint32
  1035  	Local      net.IP
  1036  	Remote     net.IP
  1037  	EncapSport uint16
  1038  	EncapDport uint16
  1039  	EncapType  uint16
  1040  	EncapFlags uint16
  1041  	FlowBased  bool
  1042  	Proto      uint8
  1043  }
  1044  
  1045  func (iptun *Iptun) Attrs() *LinkAttrs {
  1046  	return &iptun.LinkAttrs
  1047  }
  1048  
  1049  func (iptun *Iptun) Type() string {
  1050  	return "ipip"
  1051  }
  1052  
  1053  type Ip6tnl struct {
  1054  	LinkAttrs
  1055  	Link       uint32
  1056  	Local      net.IP
  1057  	Remote     net.IP
  1058  	Ttl        uint8
  1059  	Tos        uint8
  1060  	Flags      uint32
  1061  	Proto      uint8
  1062  	FlowInfo   uint32
  1063  	EncapLimit uint8
  1064  	EncapType  uint16
  1065  	EncapFlags uint16
  1066  	EncapSport uint16
  1067  	EncapDport uint16
  1068  }
  1069  
  1070  func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs {
  1071  	return &ip6tnl.LinkAttrs
  1072  }
  1073  
  1074  func (ip6tnl *Ip6tnl) Type() string {
  1075  	return "ip6tnl"
  1076  }
  1077  
  1078  // from https://elixir.bootlin.com/linux/v5.15.4/source/include/uapi/linux/if_tunnel.h#L84
  1079  type TunnelEncapType uint16
  1080  
  1081  const (
  1082  	None TunnelEncapType = iota
  1083  	FOU
  1084  	GUE
  1085  )
  1086  
  1087  // from https://elixir.bootlin.com/linux/v5.15.4/source/include/uapi/linux/if_tunnel.h#L91
  1088  type TunnelEncapFlag uint16
  1089  
  1090  const (
  1091  	CSum    TunnelEncapFlag = 1 << 0
  1092  	CSum6                   = 1 << 1
  1093  	RemCSum                 = 1 << 2
  1094  )
  1095  
  1096  // from https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/ip6_tunnel.h#L12
  1097  type IP6TunnelFlag uint16
  1098  
  1099  const (
  1100  	IP6_TNL_F_IGN_ENCAP_LIMIT    IP6TunnelFlag = 1  // don't add encapsulation limit if one isn't present in inner packet
  1101  	IP6_TNL_F_USE_ORIG_TCLASS                  = 2  // copy the traffic class field from the inner packet
  1102  	IP6_TNL_F_USE_ORIG_FLOWLABEL               = 4  // copy the flowlabel from the inner packet
  1103  	IP6_TNL_F_MIP6_DEV                         = 8  // being used for Mobile IPv6
  1104  	IP6_TNL_F_RCV_DSCP_COPY                    = 10 // copy DSCP from the outer packet
  1105  	IP6_TNL_F_USE_ORIG_FWMARK                  = 20 // copy fwmark from inner packet
  1106  	IP6_TNL_F_ALLOW_LOCAL_REMOTE               = 40 // allow remote endpoint on the local node
  1107  )
  1108  
  1109  type Sittun struct {
  1110  	LinkAttrs
  1111  	Link       uint32
  1112  	Ttl        uint8
  1113  	Tos        uint8
  1114  	PMtuDisc   uint8
  1115  	Proto      uint8
  1116  	Local      net.IP
  1117  	Remote     net.IP
  1118  	EncapLimit uint8
  1119  	EncapType  uint16
  1120  	EncapFlags uint16
  1121  	EncapSport uint16
  1122  	EncapDport uint16
  1123  }
  1124  
  1125  func (sittun *Sittun) Attrs() *LinkAttrs {
  1126  	return &sittun.LinkAttrs
  1127  }
  1128  
  1129  func (sittun *Sittun) Type() string {
  1130  	return "sit"
  1131  }
  1132  
  1133  type Vti struct {
  1134  	LinkAttrs
  1135  	IKey   uint32
  1136  	OKey   uint32
  1137  	Link   uint32
  1138  	Local  net.IP
  1139  	Remote net.IP
  1140  }
  1141  
  1142  func (vti *Vti) Attrs() *LinkAttrs {
  1143  	return &vti.LinkAttrs
  1144  }
  1145  
  1146  func (vti *Vti) Type() string {
  1147  	if vti.Local.To4() == nil {
  1148  		return "vti6"
  1149  	}
  1150  	return "vti"
  1151  }
  1152  
  1153  type Gretun struct {
  1154  	LinkAttrs
  1155  	Link       uint32
  1156  	IFlags     uint16
  1157  	OFlags     uint16
  1158  	IKey       uint32
  1159  	OKey       uint32
  1160  	Local      net.IP
  1161  	Remote     net.IP
  1162  	Ttl        uint8
  1163  	Tos        uint8
  1164  	PMtuDisc   uint8
  1165  	EncapType  uint16
  1166  	EncapFlags uint16
  1167  	EncapSport uint16
  1168  	EncapDport uint16
  1169  	FlowBased  bool
  1170  }
  1171  
  1172  func (gretun *Gretun) Attrs() *LinkAttrs {
  1173  	return &gretun.LinkAttrs
  1174  }
  1175  
  1176  func (gretun *Gretun) Type() string {
  1177  	if gretun.Local.To4() == nil {
  1178  		return "ip6gre"
  1179  	}
  1180  	return "gre"
  1181  }
  1182  
  1183  type Vrf struct {
  1184  	LinkAttrs
  1185  	Table uint32
  1186  }
  1187  
  1188  func (vrf *Vrf) Attrs() *LinkAttrs {
  1189  	return &vrf.LinkAttrs
  1190  }
  1191  
  1192  func (vrf *Vrf) Type() string {
  1193  	return "vrf"
  1194  }
  1195  
  1196  type GTP struct {
  1197  	LinkAttrs
  1198  	FD0         int
  1199  	FD1         int
  1200  	Role        int
  1201  	PDPHashsize int
  1202  }
  1203  
  1204  func (gtp *GTP) Attrs() *LinkAttrs {
  1205  	return &gtp.LinkAttrs
  1206  }
  1207  
  1208  func (gtp *GTP) Type() string {
  1209  	return "gtp"
  1210  }
  1211  
  1212  // Virtual XFRM Interfaces
  1213  //
  1214  //	Named "xfrmi" to prevent confusion with XFRM objects
  1215  type Xfrmi struct {
  1216  	LinkAttrs
  1217  	Ifid uint32
  1218  }
  1219  
  1220  func (xfrm *Xfrmi) Attrs() *LinkAttrs {
  1221  	return &xfrm.LinkAttrs
  1222  }
  1223  
  1224  func (xfrm *Xfrmi) Type() string {
  1225  	return "xfrm"
  1226  }
  1227  
  1228  // IPoIB interface
  1229  
  1230  type IPoIBMode uint16
  1231  
  1232  func (m *IPoIBMode) String() string {
  1233  	str, ok := iPoIBModeToString[*m]
  1234  	if !ok {
  1235  		return fmt.Sprintf("mode(%d)", *m)
  1236  	}
  1237  	return str
  1238  }
  1239  
  1240  const (
  1241  	IPOIB_MODE_DATAGRAM = iota
  1242  	IPOIB_MODE_CONNECTED
  1243  )
  1244  
  1245  var iPoIBModeToString = map[IPoIBMode]string{
  1246  	IPOIB_MODE_DATAGRAM:  "datagram",
  1247  	IPOIB_MODE_CONNECTED: "connected",
  1248  }
  1249  
  1250  var StringToIPoIBMode = map[string]IPoIBMode{
  1251  	"datagram":  IPOIB_MODE_DATAGRAM,
  1252  	"connected": IPOIB_MODE_CONNECTED,
  1253  }
  1254  
  1255  const (
  1256  	CAN_STATE_ERROR_ACTIVE = iota
  1257  	CAN_STATE_ERROR_WARNING
  1258  	CAN_STATE_ERROR_PASSIVE
  1259  	CAN_STATE_BUS_OFF
  1260  	CAN_STATE_STOPPED
  1261  	CAN_STATE_SLEEPING
  1262  )
  1263  
  1264  type Can struct {
  1265  	LinkAttrs
  1266  
  1267  	BitRate            uint32
  1268  	SamplePoint        uint32
  1269  	TimeQuanta         uint32
  1270  	PropagationSegment uint32
  1271  	PhaseSegment1      uint32
  1272  	PhaseSegment2      uint32
  1273  	SyncJumpWidth      uint32
  1274  	BitRatePreScaler   uint32
  1275  
  1276  	Name                string
  1277  	TimeSegment1Min     uint32
  1278  	TimeSegment1Max     uint32
  1279  	TimeSegment2Min     uint32
  1280  	TimeSegment2Max     uint32
  1281  	SyncJumpWidthMax    uint32
  1282  	BitRatePreScalerMin uint32
  1283  	BitRatePreScalerMax uint32
  1284  	BitRatePreScalerInc uint32
  1285  
  1286  	ClockFrequency uint32
  1287  
  1288  	State uint32
  1289  
  1290  	Mask  uint32
  1291  	Flags uint32
  1292  
  1293  	TxError uint16
  1294  	RxError uint16
  1295  
  1296  	RestartMs uint32
  1297  }
  1298  
  1299  func (can *Can) Attrs() *LinkAttrs {
  1300  	return &can.LinkAttrs
  1301  }
  1302  
  1303  func (can *Can) Type() string {
  1304  	return "can"
  1305  }
  1306  
  1307  type IPoIB struct {
  1308  	LinkAttrs
  1309  	Pkey   uint16
  1310  	Mode   IPoIBMode
  1311  	Umcast uint16
  1312  }
  1313  
  1314  func (ipoib *IPoIB) Attrs() *LinkAttrs {
  1315  	return &ipoib.LinkAttrs
  1316  }
  1317  
  1318  func (ipoib *IPoIB) Type() string {
  1319  	return "ipoib"
  1320  }
  1321  
  1322  type BareUDP struct {
  1323  	LinkAttrs
  1324  	Port       uint16
  1325  	EtherType  uint16
  1326  	SrcPortMin uint16
  1327  	MultiProto bool
  1328  }
  1329  
  1330  func (bareudp *BareUDP) Attrs() *LinkAttrs {
  1331  	return &bareudp.LinkAttrs
  1332  }
  1333  
  1334  func (bareudp *BareUDP) Type() string {
  1335  	return "bareudp"
  1336  }
  1337  
  1338  // iproute2 supported devices;
  1339  // vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
  1340  // bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
  1341  // gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
  1342  // bond_slave | ipvlan | xfrm | bareudp
  1343  
  1344  // LinkNotFoundError wraps the various not found errors when
  1345  // getting/reading links. This is intended for better error
  1346  // handling by dependent code so that "not found error" can
  1347  // be distinguished from other errors
  1348  type LinkNotFoundError struct {
  1349  	error
  1350  }