1package netlink
2
3import (
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.
13type Link interface {
14	Attrs() *LinkAttrs
15	Type() string
16}
17
18type (
19	NsPid int
20	NsFd  int
21)
22
23// LinkAttrs represents data shared by most link types
24type 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	Xdp          *LinkXdp
39	EncapType    string
40	Protinfo     *Protinfo
41	OperState    LinkOperState
42	NetNsID      int
43	NumTxQueues  int
44	NumRxQueues  int
45	GSOMaxSize   uint32
46	GSOMaxSegs   uint32
47	Vfs          []VfInfo // virtual functions available on link
48	Group        uint32
49	Slave        LinkSlave
50}
51
52// LinkSlave represents a slave device.
53type LinkSlave interface {
54	SlaveType() string
55}
56
57// VfInfo represents configuration of virtual function
58type VfInfo struct {
59	ID        int
60	Mac       net.HardwareAddr
61	Vlan      int
62	Qos       int
63	TxRate    int // IFLA_VF_TX_RATE  Max TxRate
64	Spoofchk  bool
65	LinkState uint32
66	MaxTxRate uint32 // IFLA_VF_RATE Max TxRate
67	MinTxRate uint32 // IFLA_VF_RATE Min TxRate
68}
69
70// LinkOperState represents the values of the IFLA_OPERSTATE link
71// attribute, which contains the RFC2863 state of the interface.
72type LinkOperState uint8
73
74const (
75	OperUnknown        = iota // Status can't be determined.
76	OperNotPresent            // Some component is missing.
77	OperDown                  // Down.
78	OperLowerLayerDown        // Down due to state of lower layer.
79	OperTesting               // In some test mode.
80	OperDormant               // Not up but pending an external event.
81	OperUp                    // Up, ready to send packets.
82)
83
84func (s LinkOperState) String() string {
85	switch s {
86	case OperNotPresent:
87		return "not-present"
88	case OperDown:
89		return "down"
90	case OperLowerLayerDown:
91		return "lower-layer-down"
92	case OperTesting:
93		return "testing"
94	case OperDormant:
95		return "dormant"
96	case OperUp:
97		return "up"
98	default:
99		return "unknown"
100	}
101}
102
103// NewLinkAttrs returns LinkAttrs structure filled with default values
104func NewLinkAttrs() LinkAttrs {
105	return LinkAttrs{
106		TxQLen: -1,
107	}
108}
109
110type LinkStatistics LinkStatistics64
111
112/*
113Ref: struct rtnl_link_stats {...}
114*/
115type LinkStatistics32 struct {
116	RxPackets         uint32
117	TxPackets         uint32
118	RxBytes           uint32
119	TxBytes           uint32
120	RxErrors          uint32
121	TxErrors          uint32
122	RxDropped         uint32
123	TxDropped         uint32
124	Multicast         uint32
125	Collisions        uint32
126	RxLengthErrors    uint32
127	RxOverErrors      uint32
128	RxCrcErrors       uint32
129	RxFrameErrors     uint32
130	RxFifoErrors      uint32
131	RxMissedErrors    uint32
132	TxAbortedErrors   uint32
133	TxCarrierErrors   uint32
134	TxFifoErrors      uint32
135	TxHeartbeatErrors uint32
136	TxWindowErrors    uint32
137	RxCompressed      uint32
138	TxCompressed      uint32
139}
140
141func (s32 LinkStatistics32) to64() *LinkStatistics64 {
142	return &LinkStatistics64{
143		RxPackets:         uint64(s32.RxPackets),
144		TxPackets:         uint64(s32.TxPackets),
145		RxBytes:           uint64(s32.RxBytes),
146		TxBytes:           uint64(s32.TxBytes),
147		RxErrors:          uint64(s32.RxErrors),
148		TxErrors:          uint64(s32.TxErrors),
149		RxDropped:         uint64(s32.RxDropped),
150		TxDropped:         uint64(s32.TxDropped),
151		Multicast:         uint64(s32.Multicast),
152		Collisions:        uint64(s32.Collisions),
153		RxLengthErrors:    uint64(s32.RxLengthErrors),
154		RxOverErrors:      uint64(s32.RxOverErrors),
155		RxCrcErrors:       uint64(s32.RxCrcErrors),
156		RxFrameErrors:     uint64(s32.RxFrameErrors),
157		RxFifoErrors:      uint64(s32.RxFifoErrors),
158		RxMissedErrors:    uint64(s32.RxMissedErrors),
159		TxAbortedErrors:   uint64(s32.TxAbortedErrors),
160		TxCarrierErrors:   uint64(s32.TxCarrierErrors),
161		TxFifoErrors:      uint64(s32.TxFifoErrors),
162		TxHeartbeatErrors: uint64(s32.TxHeartbeatErrors),
163		TxWindowErrors:    uint64(s32.TxWindowErrors),
164		RxCompressed:      uint64(s32.RxCompressed),
165		TxCompressed:      uint64(s32.TxCompressed),
166	}
167}
168
169/*
170Ref: struct rtnl_link_stats64 {...}
171*/
172type LinkStatistics64 struct {
173	RxPackets         uint64
174	TxPackets         uint64
175	RxBytes           uint64
176	TxBytes           uint64
177	RxErrors          uint64
178	TxErrors          uint64
179	RxDropped         uint64
180	TxDropped         uint64
181	Multicast         uint64
182	Collisions        uint64
183	RxLengthErrors    uint64
184	RxOverErrors      uint64
185	RxCrcErrors       uint64
186	RxFrameErrors     uint64
187	RxFifoErrors      uint64
188	RxMissedErrors    uint64
189	TxAbortedErrors   uint64
190	TxCarrierErrors   uint64
191	TxFifoErrors      uint64
192	TxHeartbeatErrors uint64
193	TxWindowErrors    uint64
194	RxCompressed      uint64
195	TxCompressed      uint64
196}
197
198type LinkXdp struct {
199	Fd       int
200	Attached bool
201	Flags    uint32
202	ProgId   uint32
203}
204
205// Device links cannot be created via netlink. These links
206// are links created by udev like 'lo' and 'etho0'
207type Device struct {
208	LinkAttrs
209}
210
211func (device *Device) Attrs() *LinkAttrs {
212	return &device.LinkAttrs
213}
214
215func (device *Device) Type() string {
216	return "device"
217}
218
219// Dummy links are dummy ethernet devices
220type Dummy struct {
221	LinkAttrs
222}
223
224func (dummy *Dummy) Attrs() *LinkAttrs {
225	return &dummy.LinkAttrs
226}
227
228func (dummy *Dummy) Type() string {
229	return "dummy"
230}
231
232// Ifb links are advanced dummy devices for packet filtering
233type Ifb struct {
234	LinkAttrs
235}
236
237func (ifb *Ifb) Attrs() *LinkAttrs {
238	return &ifb.LinkAttrs
239}
240
241func (ifb *Ifb) Type() string {
242	return "ifb"
243}
244
245// Bridge links are simple linux bridges
246type Bridge struct {
247	LinkAttrs
248	MulticastSnooping *bool
249	HelloTime         *uint32
250	VlanFiltering     *bool
251}
252
253func (bridge *Bridge) Attrs() *LinkAttrs {
254	return &bridge.LinkAttrs
255}
256
257func (bridge *Bridge) Type() string {
258	return "bridge"
259}
260
261// Vlan links have ParentIndex set in their Attrs()
262type Vlan struct {
263	LinkAttrs
264	VlanId       int
265	VlanProtocol VlanProtocol
266}
267
268func (vlan *Vlan) Attrs() *LinkAttrs {
269	return &vlan.LinkAttrs
270}
271
272func (vlan *Vlan) Type() string {
273	return "vlan"
274}
275
276type MacvlanMode uint16
277
278const (
279	MACVLAN_MODE_DEFAULT MacvlanMode = iota
280	MACVLAN_MODE_PRIVATE
281	MACVLAN_MODE_VEPA
282	MACVLAN_MODE_BRIDGE
283	MACVLAN_MODE_PASSTHRU
284	MACVLAN_MODE_SOURCE
285)
286
287// Macvlan links have ParentIndex set in their Attrs()
288type Macvlan struct {
289	LinkAttrs
290	Mode MacvlanMode
291
292	// MACAddrs is only populated for Macvlan SOURCE links
293	MACAddrs []net.HardwareAddr
294}
295
296func (macvlan *Macvlan) Attrs() *LinkAttrs {
297	return &macvlan.LinkAttrs
298}
299
300func (macvlan *Macvlan) Type() string {
301	return "macvlan"
302}
303
304// Macvtap - macvtap is a virtual interfaces based on macvlan
305type Macvtap struct {
306	Macvlan
307}
308
309func (macvtap Macvtap) Type() string {
310	return "macvtap"
311}
312
313type TuntapMode uint16
314type TuntapFlag uint16
315
316// Tuntap links created via /dev/tun/tap, but can be destroyed via netlink
317type Tuntap struct {
318	LinkAttrs
319	Mode       TuntapMode
320	Flags      TuntapFlag
321	NonPersist bool
322	Queues     int
323	Fds        []*os.File
324	Owner      uint32
325	Group      uint32
326}
327
328func (tuntap *Tuntap) Attrs() *LinkAttrs {
329	return &tuntap.LinkAttrs
330}
331
332func (tuntap *Tuntap) Type() string {
333	return "tuntap"
334}
335
336// Veth devices must specify PeerName on create
337type Veth struct {
338	LinkAttrs
339	PeerName         string // veth on create only
340	PeerHardwareAddr net.HardwareAddr
341}
342
343func (veth *Veth) Attrs() *LinkAttrs {
344	return &veth.LinkAttrs
345}
346
347func (veth *Veth) Type() string {
348	return "veth"
349}
350
351// GenericLink links represent types that are not currently understood
352// by this netlink library.
353type GenericLink struct {
354	LinkAttrs
355	LinkType string
356}
357
358func (generic *GenericLink) Attrs() *LinkAttrs {
359	return &generic.LinkAttrs
360}
361
362func (generic *GenericLink) Type() string {
363	return generic.LinkType
364}
365
366type Vxlan struct {
367	LinkAttrs
368	VxlanId        int
369	VtepDevIndex   int
370	SrcAddr        net.IP
371	Group          net.IP
372	TTL            int
373	TOS            int
374	Learning       bool
375	Proxy          bool
376	RSC            bool
377	L2miss         bool
378	L3miss         bool
379	UDPCSum        bool
380	UDP6ZeroCSumTx bool
381	UDP6ZeroCSumRx bool
382	NoAge          bool
383	GBP            bool
384	FlowBased      bool
385	Age            int
386	Limit          int
387	Port           int
388	PortLow        int
389	PortHigh       int
390}
391
392func (vxlan *Vxlan) Attrs() *LinkAttrs {
393	return &vxlan.LinkAttrs
394}
395
396func (vxlan *Vxlan) Type() string {
397	return "vxlan"
398}
399
400type IPVlanMode uint16
401
402const (
403	IPVLAN_MODE_L2 IPVlanMode = iota
404	IPVLAN_MODE_L3
405	IPVLAN_MODE_L3S
406	IPVLAN_MODE_MAX
407)
408
409type IPVlanFlag uint16
410
411const (
412	IPVLAN_FLAG_BRIDGE IPVlanFlag = iota
413	IPVLAN_FLAG_PRIVATE
414	IPVLAN_FLAG_VEPA
415)
416
417type IPVlan struct {
418	LinkAttrs
419	Mode IPVlanMode
420	Flag IPVlanFlag
421}
422
423func (ipvlan *IPVlan) Attrs() *LinkAttrs {
424	return &ipvlan.LinkAttrs
425}
426
427func (ipvlan *IPVlan) Type() string {
428	return "ipvlan"
429}
430
431// VlanProtocol type
432type VlanProtocol int
433
434func (p VlanProtocol) String() string {
435	s, ok := VlanProtocolToString[p]
436	if !ok {
437		return fmt.Sprintf("VlanProtocol(%d)", p)
438	}
439	return s
440}
441
442// StringToVlanProtocol returns vlan protocol, or unknown is the s is invalid.
443func StringToVlanProtocol(s string) VlanProtocol {
444	mode, ok := StringToVlanProtocolMap[s]
445	if !ok {
446		return VLAN_PROTOCOL_UNKNOWN
447	}
448	return mode
449}
450
451// VlanProtocol possible values
452const (
453	VLAN_PROTOCOL_UNKNOWN VlanProtocol = 0
454	VLAN_PROTOCOL_8021Q   VlanProtocol = 0x8100
455	VLAN_PROTOCOL_8021AD  VlanProtocol = 0x88A8
456)
457
458var VlanProtocolToString = map[VlanProtocol]string{
459	VLAN_PROTOCOL_8021Q:  "802.1q",
460	VLAN_PROTOCOL_8021AD: "802.1ad",
461}
462
463var StringToVlanProtocolMap = map[string]VlanProtocol{
464	"802.1q":  VLAN_PROTOCOL_8021Q,
465	"802.1ad": VLAN_PROTOCOL_8021AD,
466}
467
468// BondMode type
469type BondMode int
470
471func (b BondMode) String() string {
472	s, ok := bondModeToString[b]
473	if !ok {
474		return fmt.Sprintf("BondMode(%d)", b)
475	}
476	return s
477}
478
479// StringToBondMode returns bond mode, or unknown is the s is invalid.
480func StringToBondMode(s string) BondMode {
481	mode, ok := StringToBondModeMap[s]
482	if !ok {
483		return BOND_MODE_UNKNOWN
484	}
485	return mode
486}
487
488// Possible BondMode
489const (
490	BOND_MODE_BALANCE_RR BondMode = iota
491	BOND_MODE_ACTIVE_BACKUP
492	BOND_MODE_BALANCE_XOR
493	BOND_MODE_BROADCAST
494	BOND_MODE_802_3AD
495	BOND_MODE_BALANCE_TLB
496	BOND_MODE_BALANCE_ALB
497	BOND_MODE_UNKNOWN
498)
499
500var bondModeToString = map[BondMode]string{
501	BOND_MODE_BALANCE_RR:    "balance-rr",
502	BOND_MODE_ACTIVE_BACKUP: "active-backup",
503	BOND_MODE_BALANCE_XOR:   "balance-xor",
504	BOND_MODE_BROADCAST:     "broadcast",
505	BOND_MODE_802_3AD:       "802.3ad",
506	BOND_MODE_BALANCE_TLB:   "balance-tlb",
507	BOND_MODE_BALANCE_ALB:   "balance-alb",
508}
509var StringToBondModeMap = map[string]BondMode{
510	"balance-rr":    BOND_MODE_BALANCE_RR,
511	"active-backup": BOND_MODE_ACTIVE_BACKUP,
512	"balance-xor":   BOND_MODE_BALANCE_XOR,
513	"broadcast":     BOND_MODE_BROADCAST,
514	"802.3ad":       BOND_MODE_802_3AD,
515	"balance-tlb":   BOND_MODE_BALANCE_TLB,
516	"balance-alb":   BOND_MODE_BALANCE_ALB,
517}
518
519// BondArpValidate type
520type BondArpValidate int
521
522// Possible BondArpValidate value
523const (
524	BOND_ARP_VALIDATE_NONE BondArpValidate = iota
525	BOND_ARP_VALIDATE_ACTIVE
526	BOND_ARP_VALIDATE_BACKUP
527	BOND_ARP_VALIDATE_ALL
528)
529
530// BondPrimaryReselect type
531type BondPrimaryReselect int
532
533// Possible BondPrimaryReselect value
534const (
535	BOND_PRIMARY_RESELECT_ALWAYS BondPrimaryReselect = iota
536	BOND_PRIMARY_RESELECT_BETTER
537	BOND_PRIMARY_RESELECT_FAILURE
538)
539
540// BondArpAllTargets type
541type BondArpAllTargets int
542
543// Possible BondArpAllTargets value
544const (
545	BOND_ARP_ALL_TARGETS_ANY BondArpAllTargets = iota
546	BOND_ARP_ALL_TARGETS_ALL
547)
548
549// BondFailOverMac type
550type BondFailOverMac int
551
552// Possible BondFailOverMac value
553const (
554	BOND_FAIL_OVER_MAC_NONE BondFailOverMac = iota
555	BOND_FAIL_OVER_MAC_ACTIVE
556	BOND_FAIL_OVER_MAC_FOLLOW
557)
558
559// BondXmitHashPolicy type
560type BondXmitHashPolicy int
561
562func (b BondXmitHashPolicy) String() string {
563	s, ok := bondXmitHashPolicyToString[b]
564	if !ok {
565		return fmt.Sprintf("XmitHashPolicy(%d)", b)
566	}
567	return s
568}
569
570// StringToBondXmitHashPolicy returns bond lacp arte, or unknown is the s is invalid.
571func StringToBondXmitHashPolicy(s string) BondXmitHashPolicy {
572	lacp, ok := StringToBondXmitHashPolicyMap[s]
573	if !ok {
574		return BOND_XMIT_HASH_POLICY_UNKNOWN
575	}
576	return lacp
577}
578
579// Possible BondXmitHashPolicy value
580const (
581	BOND_XMIT_HASH_POLICY_LAYER2 BondXmitHashPolicy = iota
582	BOND_XMIT_HASH_POLICY_LAYER3_4
583	BOND_XMIT_HASH_POLICY_LAYER2_3
584	BOND_XMIT_HASH_POLICY_ENCAP2_3
585	BOND_XMIT_HASH_POLICY_ENCAP3_4
586	BOND_XMIT_HASH_POLICY_UNKNOWN
587)
588
589var bondXmitHashPolicyToString = map[BondXmitHashPolicy]string{
590	BOND_XMIT_HASH_POLICY_LAYER2:   "layer2",
591	BOND_XMIT_HASH_POLICY_LAYER3_4: "layer3+4",
592	BOND_XMIT_HASH_POLICY_LAYER2_3: "layer2+3",
593	BOND_XMIT_HASH_POLICY_ENCAP2_3: "encap2+3",
594	BOND_XMIT_HASH_POLICY_ENCAP3_4: "encap3+4",
595}
596var StringToBondXmitHashPolicyMap = map[string]BondXmitHashPolicy{
597	"layer2":   BOND_XMIT_HASH_POLICY_LAYER2,
598	"layer3+4": BOND_XMIT_HASH_POLICY_LAYER3_4,
599	"layer2+3": BOND_XMIT_HASH_POLICY_LAYER2_3,
600	"encap2+3": BOND_XMIT_HASH_POLICY_ENCAP2_3,
601	"encap3+4": BOND_XMIT_HASH_POLICY_ENCAP3_4,
602}
603
604// BondLacpRate type
605type BondLacpRate int
606
607func (b BondLacpRate) String() string {
608	s, ok := bondLacpRateToString[b]
609	if !ok {
610		return fmt.Sprintf("LacpRate(%d)", b)
611	}
612	return s
613}
614
615// StringToBondLacpRate returns bond lacp arte, or unknown is the s is invalid.
616func StringToBondLacpRate(s string) BondLacpRate {
617	lacp, ok := StringToBondLacpRateMap[s]
618	if !ok {
619		return BOND_LACP_RATE_UNKNOWN
620	}
621	return lacp
622}
623
624// Possible BondLacpRate value
625const (
626	BOND_LACP_RATE_SLOW BondLacpRate = iota
627	BOND_LACP_RATE_FAST
628	BOND_LACP_RATE_UNKNOWN
629)
630
631var bondLacpRateToString = map[BondLacpRate]string{
632	BOND_LACP_RATE_SLOW: "slow",
633	BOND_LACP_RATE_FAST: "fast",
634}
635var StringToBondLacpRateMap = map[string]BondLacpRate{
636	"slow": BOND_LACP_RATE_SLOW,
637	"fast": BOND_LACP_RATE_FAST,
638}
639
640// BondAdSelect type
641type BondAdSelect int
642
643// Possible BondAdSelect value
644const (
645	BOND_AD_SELECT_STABLE BondAdSelect = iota
646	BOND_AD_SELECT_BANDWIDTH
647	BOND_AD_SELECT_COUNT
648)
649
650// BondAdInfo represents ad info for bond
651type BondAdInfo struct {
652	AggregatorId int
653	NumPorts     int
654	ActorKey     int
655	PartnerKey   int
656	PartnerMac   net.HardwareAddr
657}
658
659// Bond representation
660type Bond struct {
661	LinkAttrs
662	Mode            BondMode
663	ActiveSlave     int
664	Miimon          int
665	UpDelay         int
666	DownDelay       int
667	UseCarrier      int
668	ArpInterval     int
669	ArpIpTargets    []net.IP
670	ArpValidate     BondArpValidate
671	ArpAllTargets   BondArpAllTargets
672	Primary         int
673	PrimaryReselect BondPrimaryReselect
674	FailOverMac     BondFailOverMac
675	XmitHashPolicy  BondXmitHashPolicy
676	ResendIgmp      int
677	NumPeerNotif    int
678	AllSlavesActive int
679	MinLinks        int
680	LpInterval      int
681	PackersPerSlave int
682	LacpRate        BondLacpRate
683	AdSelect        BondAdSelect
684	// looking at iproute tool AdInfo can only be retrived. It can't be set.
685	AdInfo         *BondAdInfo
686	AdActorSysPrio int
687	AdUserPortKey  int
688	AdActorSystem  net.HardwareAddr
689	TlbDynamicLb   int
690}
691
692func NewLinkBond(atr LinkAttrs) *Bond {
693	return &Bond{
694		LinkAttrs:       atr,
695		Mode:            -1,
696		ActiveSlave:     -1,
697		Miimon:          -1,
698		UpDelay:         -1,
699		DownDelay:       -1,
700		UseCarrier:      -1,
701		ArpInterval:     -1,
702		ArpIpTargets:    nil,
703		ArpValidate:     -1,
704		ArpAllTargets:   -1,
705		Primary:         -1,
706		PrimaryReselect: -1,
707		FailOverMac:     -1,
708		XmitHashPolicy:  -1,
709		ResendIgmp:      -1,
710		NumPeerNotif:    -1,
711		AllSlavesActive: -1,
712		MinLinks:        -1,
713		LpInterval:      -1,
714		PackersPerSlave: -1,
715		LacpRate:        -1,
716		AdSelect:        -1,
717		AdActorSysPrio:  -1,
718		AdUserPortKey:   -1,
719		AdActorSystem:   nil,
720		TlbDynamicLb:    -1,
721	}
722}
723
724// Flag mask for bond options. Bond.Flagmask must be set to on for option to work.
725const (
726	BOND_MODE_MASK uint64 = 1 << (1 + iota)
727	BOND_ACTIVE_SLAVE_MASK
728	BOND_MIIMON_MASK
729	BOND_UPDELAY_MASK
730	BOND_DOWNDELAY_MASK
731	BOND_USE_CARRIER_MASK
732	BOND_ARP_INTERVAL_MASK
733	BOND_ARP_VALIDATE_MASK
734	BOND_ARP_ALL_TARGETS_MASK
735	BOND_PRIMARY_MASK
736	BOND_PRIMARY_RESELECT_MASK
737	BOND_FAIL_OVER_MAC_MASK
738	BOND_XMIT_HASH_POLICY_MASK
739	BOND_RESEND_IGMP_MASK
740	BOND_NUM_PEER_NOTIF_MASK
741	BOND_ALL_SLAVES_ACTIVE_MASK
742	BOND_MIN_LINKS_MASK
743	BOND_LP_INTERVAL_MASK
744	BOND_PACKETS_PER_SLAVE_MASK
745	BOND_LACP_RATE_MASK
746	BOND_AD_SELECT_MASK
747)
748
749// Attrs implementation.
750func (bond *Bond) Attrs() *LinkAttrs {
751	return &bond.LinkAttrs
752}
753
754// Type implementation fro Vxlan.
755func (bond *Bond) Type() string {
756	return "bond"
757}
758
759// BondSlaveState represents the values of the IFLA_BOND_SLAVE_STATE bond slave
760// attribute, which contains the state of the bond slave.
761type BondSlaveState uint8
762
763const (
764	BondStateActive = iota // Link is active.
765	BondStateBackup        // Link is backup.
766)
767
768func (s BondSlaveState) String() string {
769	switch s {
770	case BondStateActive:
771		return "ACTIVE"
772	case BondStateBackup:
773		return "BACKUP"
774	default:
775		return strconv.Itoa(int(s))
776	}
777}
778
779// BondSlaveState represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
780// attribute, which contains the status of MII link monitoring
781type BondSlaveMiiStatus uint8
782
783const (
784	BondLinkUp   = iota // link is up and running.
785	BondLinkFail        // link has just gone down.
786	BondLinkDown        // link has been down for too long time.
787	BondLinkBack        // link is going back.
788)
789
790func (s BondSlaveMiiStatus) String() string {
791	switch s {
792	case BondLinkUp:
793		return "UP"
794	case BondLinkFail:
795		return "GOING_DOWN"
796	case BondLinkDown:
797		return "DOWN"
798	case BondLinkBack:
799		return "GOING_BACK"
800	default:
801		return strconv.Itoa(int(s))
802	}
803}
804
805type BondSlave struct {
806	State                  BondSlaveState
807	MiiStatus              BondSlaveMiiStatus
808	LinkFailureCount       uint32
809	PermHardwareAddr       net.HardwareAddr
810	QueueId                uint16
811	AggregatorId           uint16
812	AdActorOperPortState   uint8
813	AdPartnerOperPortState uint16
814}
815
816func (b *BondSlave) SlaveType() string {
817	return "bond"
818}
819
820// Gretap devices must specify LocalIP and RemoteIP on create
821type Gretap struct {
822	LinkAttrs
823	IKey       uint32
824	OKey       uint32
825	EncapSport uint16
826	EncapDport uint16
827	Local      net.IP
828	Remote     net.IP
829	IFlags     uint16
830	OFlags     uint16
831	PMtuDisc   uint8
832	Ttl        uint8
833	Tos        uint8
834	EncapType  uint16
835	EncapFlags uint16
836	Link       uint32
837	FlowBased  bool
838}
839
840func (gretap *Gretap) Attrs() *LinkAttrs {
841	return &gretap.LinkAttrs
842}
843
844func (gretap *Gretap) Type() string {
845	if gretap.Local.To4() == nil {
846		return "ip6gretap"
847	}
848	return "gretap"
849}
850
851type Iptun struct {
852	LinkAttrs
853	Ttl        uint8
854	Tos        uint8
855	PMtuDisc   uint8
856	Link       uint32
857	Local      net.IP
858	Remote     net.IP
859	EncapSport uint16
860	EncapDport uint16
861	EncapType  uint16
862	EncapFlags uint16
863	FlowBased  bool
864}
865
866func (iptun *Iptun) Attrs() *LinkAttrs {
867	return &iptun.LinkAttrs
868}
869
870func (iptun *Iptun) Type() string {
871	return "ipip"
872}
873
874type Ip6tnl struct {
875	LinkAttrs
876	Link       uint32
877	Local      net.IP
878	Remote     net.IP
879	Ttl        uint8
880	Tos        uint8
881	EncapLimit uint8
882	Flags      uint32
883	Proto      uint8
884	FlowInfo   uint32
885}
886
887func (ip6tnl *Ip6tnl) Attrs() *LinkAttrs {
888	return &ip6tnl.LinkAttrs
889}
890
891func (ip6tnl *Ip6tnl) Type() string {
892	return "ip6tnl"
893}
894
895type Sittun struct {
896	LinkAttrs
897	Link       uint32
898	Local      net.IP
899	Remote     net.IP
900	Ttl        uint8
901	Tos        uint8
902	PMtuDisc   uint8
903	EncapType  uint16
904	EncapFlags uint16
905	EncapSport uint16
906	EncapDport uint16
907}
908
909func (sittun *Sittun) Attrs() *LinkAttrs {
910	return &sittun.LinkAttrs
911}
912
913func (sittun *Sittun) Type() string {
914	return "sit"
915}
916
917type Vti struct {
918	LinkAttrs
919	IKey   uint32
920	OKey   uint32
921	Link   uint32
922	Local  net.IP
923	Remote net.IP
924}
925
926func (vti *Vti) Attrs() *LinkAttrs {
927	return &vti.LinkAttrs
928}
929
930func (vti *Vti) Type() string {
931	if vti.Local.To4() == nil {
932		return "vti6"
933	}
934	return "vti"
935}
936
937type Gretun struct {
938	LinkAttrs
939	Link       uint32
940	IFlags     uint16
941	OFlags     uint16
942	IKey       uint32
943	OKey       uint32
944	Local      net.IP
945	Remote     net.IP
946	Ttl        uint8
947	Tos        uint8
948	PMtuDisc   uint8
949	EncapType  uint16
950	EncapFlags uint16
951	EncapSport uint16
952	EncapDport uint16
953}
954
955func (gretun *Gretun) Attrs() *LinkAttrs {
956	return &gretun.LinkAttrs
957}
958
959func (gretun *Gretun) Type() string {
960	if gretun.Local.To4() == nil {
961		return "ip6gre"
962	}
963	return "gre"
964}
965
966type Vrf struct {
967	LinkAttrs
968	Table uint32
969}
970
971func (vrf *Vrf) Attrs() *LinkAttrs {
972	return &vrf.LinkAttrs
973}
974
975func (vrf *Vrf) Type() string {
976	return "vrf"
977}
978
979type GTP struct {
980	LinkAttrs
981	FD0         int
982	FD1         int
983	Role        int
984	PDPHashsize int
985}
986
987func (gtp *GTP) Attrs() *LinkAttrs {
988	return &gtp.LinkAttrs
989}
990
991func (gtp *GTP) Type() string {
992	return "gtp"
993}
994
995// Virtual XFRM Interfaces
996//	Named "xfrmi" to prevent confusion with XFRM objects
997type Xfrmi struct {
998	LinkAttrs
999	Ifid uint32
1000}
1001
1002func (xfrm *Xfrmi) Attrs() *LinkAttrs {
1003	return &xfrm.LinkAttrs
1004}
1005
1006func (xfrm *Xfrmi) Type() string {
1007	return "xfrm"
1008}
1009
1010// IPoIB interface
1011
1012type IPoIBMode uint16
1013
1014func (m *IPoIBMode) String() string {
1015	str, ok := iPoIBModeToString[*m]
1016	if !ok {
1017		return fmt.Sprintf("mode(%d)", *m)
1018	}
1019	return str
1020}
1021
1022const (
1023	IPOIB_MODE_DATAGRAM = iota
1024	IPOIB_MODE_CONNECTED
1025)
1026
1027var iPoIBModeToString = map[IPoIBMode]string{
1028	IPOIB_MODE_DATAGRAM:  "datagram",
1029	IPOIB_MODE_CONNECTED: "connected",
1030}
1031
1032var StringToIPoIBMode = map[string]IPoIBMode{
1033	"datagram":  IPOIB_MODE_DATAGRAM,
1034	"connected": IPOIB_MODE_CONNECTED,
1035}
1036
1037type IPoIB struct {
1038	LinkAttrs
1039	Pkey   uint16
1040	Mode   IPoIBMode
1041	Umcast uint16
1042}
1043
1044func (ipoib *IPoIB) Attrs() *LinkAttrs {
1045	return &ipoib.LinkAttrs
1046}
1047
1048func (ipoib *IPoIB) Type() string {
1049	return "ipoib"
1050}
1051
1052// iproute2 supported devices;
1053// vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
1054// bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |
1055// gre | gretap | ip6gre | ip6gretap | vti | vti6 | nlmon |
1056// bond_slave | ipvlan | xfrm
1057
1058// LinkNotFoundError wraps the various not found errors when
1059// getting/reading links. This is intended for better error
1060// handling by dependent code so that "not found error" can
1061// be distinguished from other errors
1062type LinkNotFoundError struct {
1063	error
1064}
1065