Browse Source

Vendor netlink @ebdfb74

Signed-off-by: Alessandro Boch <aboch@docker.com>
Alessandro Boch 8 years ago
parent
commit
ed758b604a

+ 1 - 1
vendor.conf

@@ -32,7 +32,7 @@ github.com/hashicorp/go-multierror fcdddc395df1ddf4247c69bd436e84cfa0733f7e
 github.com/hashicorp/serf 598c54895cc5a7b1a24a398d635e8c0ea0959870
 github.com/docker/libkv 1d8431073ae03cdaedb198a89722f3aab6d418ef
 github.com/vishvananda/netns 604eaf189ee867d8c147fafc28def2394e878d25
-github.com/vishvananda/netlink 482f7a52b758233521878cb6c5904b6bd63f3457
+github.com/vishvananda/netlink ebdfb7402004b397e6573c71132160d8e23cc12a
 github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060
 github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
 github.com/deckarep/golang-set ef32fa3046d9f249d399f98ebaf9be944430fd1d

+ 8 - 0
vendor/github.com/vishvananda/netlink/addr.go

@@ -13,6 +13,7 @@ type Addr struct {
 	Label string
 	Flags int
 	Scope int
+	Peer  *net.IPNet
 }
 
 // String returns $ip/$netmask $label
@@ -43,3 +44,10 @@ func (a Addr) Equal(x Addr) bool {
 	// ignore label for comparison
 	return a.IP.Equal(x.IP) && sizea == sizeb
 }
+
+func (a Addr) PeerEqual(x Addr) bool {
+	sizea, _ := a.Peer.Mask.Size()
+	sizeb, _ := x.Peer.Mask.Size()
+	// ignore label for comparison
+	return a.Peer.IP.Equal(x.Peer.IP) && sizea == sizeb
+}

+ 17 - 5
vendor/github.com/vishvananda/netlink/addr_linux.go

@@ -56,17 +56,27 @@ func (h *Handle) addrHandle(link Link, addr *Addr, req *nl.NetlinkRequest) error
 	msg.Prefixlen = uint8(prefixlen)
 	req.AddData(msg)
 
-	var addrData []byte
+	var localAddrData []byte
 	if family == FAMILY_V4 {
-		addrData = addr.IP.To4()
+		localAddrData = addr.IP.To4()
 	} else {
-		addrData = addr.IP.To16()
+		localAddrData = addr.IP.To16()
 	}
 
-	localData := nl.NewRtAttr(syscall.IFA_LOCAL, addrData)
+	localData := nl.NewRtAttr(syscall.IFA_LOCAL, localAddrData)
 	req.AddData(localData)
+	var peerAddrData []byte
+	if addr.Peer != nil {
+		if family == FAMILY_V4 {
+			peerAddrData = addr.Peer.IP.To4()
+		} else {
+			peerAddrData = addr.Peer.IP.To16()
+		}
+	} else {
+		peerAddrData = localAddrData
+	}
 
-	addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, addrData)
+	addressData := nl.NewRtAttr(syscall.IFA_ADDRESS, peerAddrData)
 	req.AddData(addressData)
 
 	if addr.Flags != 0 {
@@ -161,11 +171,13 @@ func parseAddr(m []byte) (addr Addr, family, index int, err error) {
 				IP:   attr.Value,
 				Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
 			}
+			addr.Peer = dst
 		case syscall.IFA_LOCAL:
 			local = &net.IPNet{
 				IP:   attr.Value,
 				Mask: net.CIDRMask(int(msg.Prefixlen), 8*len(attr.Value)),
 			}
+			addr.IPNet = local
 		case syscall.IFA_LABEL:
 			addr.Label = string(attr.Value[:len(attr.Value)-1])
 		case IFA_FLAGS:

+ 218 - 0
vendor/github.com/vishvananda/netlink/handle_unspecified.go

@@ -0,0 +1,218 @@
+// +build !linux
+
+package netlink
+
+import (
+	"net"
+	"time"
+
+	"github.com/vishvananda/netns"
+)
+
+type Handle struct{}
+
+func NewHandle(nlFamilies ...int) (*Handle, error) {
+	return nil, ErrNotImplemented
+}
+
+func NewHandleAt(ns netns.NsHandle, nlFamilies ...int) (*Handle, error) {
+	return nil, ErrNotImplemented
+}
+
+func NewHandleAtFrom(newNs, curNs netns.NsHandle) (*Handle, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) Delete() {}
+
+func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
+	return false
+}
+
+func (h *Handle) SetSocketTimeout(to time.Duration) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) SetPromiscOn(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) SetPromiscOff(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetUp(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetDown(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetMTU(link Link, mtu int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetName(link Link, name string) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetAlias(link Link, name string) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetVfVlan(link Link, vf, vlan int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetVfTxRate(link Link, vf, rate int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetMaster(link Link, master *Bridge) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetNoMaster(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetMasterByIndex(link Link, masterIndex int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetNsPid(link Link, nspid int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetNsFd(link Link, fd int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkAdd(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkDel(link Link) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkByName(name string) (Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) LinkByAlias(alias string) (Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) LinkByIndex(index int) (Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) LinkList() ([]Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) LinkSetHairpin(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetGuard(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetFastLeave(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetLearning(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetRootBlock(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) LinkSetFlood(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) setProtinfoAttr(link Link, mode bool, attr int) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) AddrAdd(link Link, addr *Addr) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) AddrDel(link Link, addr *Addr) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) AddrList(link Link, family int) ([]Addr, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) ClassDel(class Class) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) ClassChange(class Class) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) ClassReplace(class Class) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) ClassAdd(class Class) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) ClassList(link Link, parent uint32) ([]Class, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) FilterDel(filter Filter) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) FilterAdd(filter Filter) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) FilterList(link Link, parent uint32) ([]Filter, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) NeighAdd(neigh *Neigh) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) NeighSet(neigh *Neigh) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) NeighAppend(neigh *Neigh) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) NeighDel(neigh *Neigh) error {
+	return ErrNotImplemented
+}
+
+func (h *Handle) NeighList(linkIndex, family int) ([]Neigh, error) {
+	return nil, ErrNotImplemented
+}
+
+func (h *Handle) NeighProxyList(linkIndex, family int) ([]Neigh, error) {
+	return nil, ErrNotImplemented
+}

+ 147 - 5
vendor/github.com/vishvananda/netlink/link.go

@@ -35,6 +35,41 @@ type LinkAttrs struct {
 	Promisc      int
 	Xdp          *LinkXdp
 	EncapType    string
+	Protinfo     *Protinfo
+	OperState    LinkOperState
+}
+
+// LinkOperState represents the values of the IFLA_OPERSTATE link
+// attribute, which contains the RFC2863 state of the interface.
+type LinkOperState uint8
+
+const (
+	OperUnknown        = iota // Status can't be determined.
+	OperNotPresent            // Some component is missing.
+	OperDown                  // Down.
+	OperLowerLayerDown        // Down due to state of lower layer.
+	OperTesting               // In some test mode.
+	OperDormant               // Not up but pending an external event.
+	OperUp                    // Up, ready to send packets.
+)
+
+func (s LinkOperState) String() string {
+	switch s {
+	case OperNotPresent:
+		return "not-present"
+	case OperDown:
+		return "down"
+	case OperLowerLayerDown:
+		return "lower-layer-down"
+	case OperTesting:
+		return "testing"
+	case OperDormant:
+		return "dormant"
+	case OperUp:
+		return "up"
+	default:
+		return "unknown"
+	}
 }
 
 // NewLinkAttrs returns LinkAttrs structure filled with default values
@@ -44,10 +79,12 @@ func NewLinkAttrs() LinkAttrs {
 	}
 }
 
+type LinkStatistics LinkStatistics64
+
 /*
 Ref: struct rtnl_link_stats {...}
 */
-type LinkStatistics struct {
+type LinkStatistics32 struct {
 	RxPackets         uint32
 	TxPackets         uint32
 	RxBytes           uint32
@@ -73,6 +110,63 @@ type LinkStatistics struct {
 	TxCompressed      uint32
 }
 
+func (s32 LinkStatistics32) to64() *LinkStatistics64 {
+	return &LinkStatistics64{
+		RxPackets:         uint64(s32.RxPackets),
+		TxPackets:         uint64(s32.TxPackets),
+		RxBytes:           uint64(s32.RxBytes),
+		TxBytes:           uint64(s32.TxBytes),
+		RxErrors:          uint64(s32.RxErrors),
+		TxErrors:          uint64(s32.TxErrors),
+		RxDropped:         uint64(s32.RxDropped),
+		TxDropped:         uint64(s32.TxDropped),
+		Multicast:         uint64(s32.Multicast),
+		Collisions:        uint64(s32.Collisions),
+		RxLengthErrors:    uint64(s32.RxLengthErrors),
+		RxOverErrors:      uint64(s32.RxOverErrors),
+		RxCrcErrors:       uint64(s32.RxCrcErrors),
+		RxFrameErrors:     uint64(s32.RxFrameErrors),
+		RxFifoErrors:      uint64(s32.RxFifoErrors),
+		RxMissedErrors:    uint64(s32.RxMissedErrors),
+		TxAbortedErrors:   uint64(s32.TxAbortedErrors),
+		TxCarrierErrors:   uint64(s32.TxCarrierErrors),
+		TxFifoErrors:      uint64(s32.TxFifoErrors),
+		TxHeartbeatErrors: uint64(s32.TxHeartbeatErrors),
+		TxWindowErrors:    uint64(s32.TxWindowErrors),
+		RxCompressed:      uint64(s32.RxCompressed),
+		TxCompressed:      uint64(s32.TxCompressed),
+	}
+}
+
+/*
+Ref: struct rtnl_link_stats64 {...}
+*/
+type LinkStatistics64 struct {
+	RxPackets         uint64
+	TxPackets         uint64
+	RxBytes           uint64
+	TxBytes           uint64
+	RxErrors          uint64
+	TxErrors          uint64
+	RxDropped         uint64
+	TxDropped         uint64
+	Multicast         uint64
+	Collisions        uint64
+	RxLengthErrors    uint64
+	RxOverErrors      uint64
+	RxCrcErrors       uint64
+	RxFrameErrors     uint64
+	RxFifoErrors      uint64
+	RxMissedErrors    uint64
+	TxAbortedErrors   uint64
+	TxCarrierErrors   uint64
+	TxFifoErrors      uint64
+	TxHeartbeatErrors uint64
+	TxWindowErrors    uint64
+	RxCompressed      uint64
+	TxCompressed      uint64
+}
+
 type LinkXdp struct {
 	Fd       int
 	Attached bool
@@ -301,31 +395,31 @@ func StringToBondMode(s string) BondMode {
 
 // Possible BondMode
 const (
-	BOND_MODE_802_3AD BondMode = iota
-	BOND_MODE_BALANCE_RR
+	BOND_MODE_BALANCE_RR BondMode = iota
 	BOND_MODE_ACTIVE_BACKUP
 	BOND_MODE_BALANCE_XOR
 	BOND_MODE_BROADCAST
+	BOND_MODE_802_3AD
 	BOND_MODE_BALANCE_TLB
 	BOND_MODE_BALANCE_ALB
 	BOND_MODE_UNKNOWN
 )
 
 var bondModeToString = map[BondMode]string{
-	BOND_MODE_802_3AD:       "802.3ad",
 	BOND_MODE_BALANCE_RR:    "balance-rr",
 	BOND_MODE_ACTIVE_BACKUP: "active-backup",
 	BOND_MODE_BALANCE_XOR:   "balance-xor",
 	BOND_MODE_BROADCAST:     "broadcast",
+	BOND_MODE_802_3AD:       "802.3ad",
 	BOND_MODE_BALANCE_TLB:   "balance-tlb",
 	BOND_MODE_BALANCE_ALB:   "balance-alb",
 }
 var StringToBondModeMap = map[string]BondMode{
-	"802.3ad":       BOND_MODE_802_3AD,
 	"balance-rr":    BOND_MODE_BALANCE_RR,
 	"active-backup": BOND_MODE_ACTIVE_BACKUP,
 	"balance-xor":   BOND_MODE_BALANCE_XOR,
 	"broadcast":     BOND_MODE_BROADCAST,
+	"802.3ad":       BOND_MODE_802_3AD,
 	"balance-tlb":   BOND_MODE_BALANCE_TLB,
 	"balance-alb":   BOND_MODE_BALANCE_ALB,
 }
@@ -589,6 +683,54 @@ func (gretap *Gretap) Type() string {
 	return "gretap"
 }
 
+type Iptun struct {
+	LinkAttrs
+	Ttl      uint8
+	Tos      uint8
+	PMtuDisc uint8
+	Link     uint32
+	Local    net.IP
+	Remote   net.IP
+}
+
+func (iptun *Iptun) Attrs() *LinkAttrs {
+	return &iptun.LinkAttrs
+}
+
+func (iptun *Iptun) Type() string {
+	return "ipip"
+}
+
+type Vti struct {
+	LinkAttrs
+	IKey   uint32
+	OKey   uint32
+	Link   uint32
+	Local  net.IP
+	Remote net.IP
+}
+
+func (vti *Vti) Attrs() *LinkAttrs {
+	return &vti.LinkAttrs
+}
+
+func (iptun *Vti) Type() string {
+	return "vti"
+}
+
+type Vrf struct {
+	LinkAttrs
+	Table uint32
+}
+
+func (vrf *Vrf) Attrs() *LinkAttrs {
+	return &vrf.LinkAttrs
+}
+
+func (vrf *Vrf) Type() string {
+	return "vrf"
+}
+
 // iproute2 supported devices;
 // vlan | veth | vcan | dummy | ifb | macvlan | macvtap |
 // bridge | bond | ipoib | ip6tnl | ipip | sit | vxlan |

+ 153 - 10
vendor/github.com/vishvananda/netlink/link_linux.go

@@ -13,7 +13,11 @@ import (
 	"github.com/vishvananda/netns"
 )
 
-const SizeofLinkStats = 0x5c
+const (
+	SizeofLinkStats32 = 0x5c
+	SizeofLinkStats64 = 0xd8
+	IFLA_STATS64      = 0x17 // syscall pkg does not contain this one
+)
 
 const (
 	TUNTAP_MODE_TUN  TuntapMode = syscall.IFF_TUN
@@ -783,6 +787,12 @@ func (h *Handle) LinkAdd(link Link) error {
 		}
 	} else if gretap, ok := link.(*Gretap); ok {
 		addGretapAttrs(gretap, linkInfo)
+	} else if iptun, ok := link.(*Iptun); ok {
+		addIptunAttrs(iptun, linkInfo)
+	} else if vti, ok := link.(*Vti); ok {
+		addVtiAttrs(vti, linkInfo)
+	} else if vrf, ok := link.(*Vrf); ok {
+		addVrfAttrs(vrf, linkInfo)
 	}
 
 	req.AddData(linkInfo)
@@ -949,7 +959,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
 		return nil, fmt.Errorf("Link not found")
 
 	case len(msgs) == 1:
-		return linkDeserialize(msgs[0])
+		return LinkDeserialize(nil, msgs[0])
 
 	default:
 		return nil, fmt.Errorf("More than one link found")
@@ -958,7 +968,7 @@ func execGetLink(req *nl.NetlinkRequest) (Link, error) {
 
 // linkDeserialize deserializes a raw message received from netlink into
 // a link object.
-func linkDeserialize(m []byte) (Link, error) {
+func LinkDeserialize(hdr *syscall.NlMsghdr, m []byte) (Link, error) {
 	msg := nl.DeserializeIfInfomsg(m)
 
 	attrs, err := nl.ParseRouteAttr(m[msg.Len():])
@@ -970,8 +980,12 @@ func linkDeserialize(m []byte) (Link, error) {
 	if msg.Flags&syscall.IFF_PROMISC != 0 {
 		base.Promisc = 1
 	}
-	var link Link
-	linkType := ""
+	var (
+		link     Link
+		stats32  []byte
+		stats64  []byte
+		linkType string
+	)
 	for _, attr := range attrs {
 		switch attr.Attr.Type {
 		case syscall.IFLA_LINKINFO:
@@ -1006,6 +1020,12 @@ func linkDeserialize(m []byte) (Link, error) {
 						link = &Macvtap{}
 					case "gretap":
 						link = &Gretap{}
+					case "ipip":
+						link = &Iptun{}
+					case "vti":
+						link = &Vti{}
+					case "vrf":
+						link = &Vrf{}
 					default:
 						link = &GenericLink{LinkType: linkType}
 					}
@@ -1029,6 +1049,12 @@ func linkDeserialize(m []byte) (Link, error) {
 						parseMacvtapData(link, data)
 					case "gretap":
 						parseGretapData(link, data)
+					case "ipip":
+						parseIptunData(link, data)
+					case "vti":
+						parseVtiData(link, data)
+					case "vrf":
+						parseVrfData(link, data)
 					}
 				}
 			}
@@ -1055,15 +1081,35 @@ func linkDeserialize(m []byte) (Link, error) {
 		case syscall.IFLA_IFALIAS:
 			base.Alias = string(attr.Value[:len(attr.Value)-1])
 		case syscall.IFLA_STATS:
-			base.Statistics = parseLinkStats(attr.Value[:])
+			stats32 = attr.Value[:]
+		case IFLA_STATS64:
+			stats64 = attr.Value[:]
 		case nl.IFLA_XDP:
 			xdp, err := parseLinkXdp(attr.Value[:])
 			if err != nil {
 				return nil, err
 			}
 			base.Xdp = xdp
+		case syscall.IFLA_PROTINFO | syscall.NLA_F_NESTED:
+			if hdr != nil && hdr.Type == syscall.RTM_NEWLINK &&
+				msg.Family == syscall.AF_BRIDGE {
+				attrs, err := nl.ParseRouteAttr(attr.Value[:])
+				if err != nil {
+					return nil, err
+				}
+				base.Protinfo = parseProtinfo(attrs)
+			}
+		case syscall.IFLA_OPERSTATE:
+			base.OperState = LinkOperState(uint8(attr.Value[0]))
 		}
 	}
+
+	if stats64 != nil {
+		base.Statistics = parseLinkStats64(stats64)
+	} else if stats32 != nil {
+		base.Statistics = parseLinkStats32(stats32)
+	}
+
 	// Links that don't have IFLA_INFO_KIND are hardware devices
 	if link == nil {
 		link = &Device{}
@@ -1096,7 +1142,7 @@ func (h *Handle) LinkList() ([]Link, error) {
 
 	var res []Link
 	for _, m := range msgs {
-		link, err := linkDeserialize(m)
+		link, err := LinkDeserialize(nil, m)
 		if err != nil {
 			return nil, err
 		}
@@ -1145,7 +1191,7 @@ func linkSubscribe(newNs, curNs netns.NsHandle, ch chan<- LinkUpdate, done <-cha
 			}
 			for _, m := range msgs {
 				ifmsg := nl.DeserializeIfInfomsg(m.Data)
-				link, err := linkDeserialize(m.Data)
+				link, err := LinkDeserialize(&m.Header, m.Data)
 				if err != nil {
 					return
 				}
@@ -1490,8 +1536,12 @@ func parseGretapData(link Link, data []syscall.NetlinkRouteAttr) {
 	}
 }
 
-func parseLinkStats(data []byte) *LinkStatistics {
-	return (*LinkStatistics)(unsafe.Pointer(&data[0:SizeofLinkStats][0]))
+func parseLinkStats32(data []byte) *LinkStatistics {
+	return (*LinkStatistics)((*LinkStatistics32)(unsafe.Pointer(&data[0:SizeofLinkStats32][0])).to64())
+}
+
+func parseLinkStats64(data []byte) *LinkStatistics {
+	return (*LinkStatistics)((*LinkStatistics64)(unsafe.Pointer(&data[0:SizeofLinkStats64][0])))
 }
 
 func addXdpAttrs(xdp *LinkXdp, req *nl.NetlinkRequest) {
@@ -1518,3 +1568,96 @@ func parseLinkXdp(data []byte) (*LinkXdp, error) {
 	}
 	return xdp, nil
 }
+
+func addIptunAttrs(iptun *Iptun, linkInfo *nl.RtAttr) {
+	data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
+
+	ip := iptun.Local.To4()
+	if ip != nil {
+		nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LOCAL, []byte(ip))
+	}
+
+	ip = iptun.Remote.To4()
+	if ip != nil {
+		nl.NewRtAttrChild(data, nl.IFLA_IPTUN_REMOTE, []byte(ip))
+	}
+
+	if iptun.Link != 0 {
+		nl.NewRtAttrChild(data, nl.IFLA_IPTUN_LINK, nl.Uint32Attr(iptun.Link))
+	}
+	nl.NewRtAttrChild(data, nl.IFLA_IPTUN_PMTUDISC, nl.Uint8Attr(iptun.PMtuDisc))
+	nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TTL, nl.Uint8Attr(iptun.Ttl))
+	nl.NewRtAttrChild(data, nl.IFLA_IPTUN_TOS, nl.Uint8Attr(iptun.Tos))
+}
+
+func parseIptunData(link Link, data []syscall.NetlinkRouteAttr) {
+	iptun := link.(*Iptun)
+	for _, datum := range data {
+		switch datum.Attr.Type {
+		case nl.IFLA_IPTUN_LOCAL:
+			iptun.Local = net.IP(datum.Value[0:4])
+		case nl.IFLA_IPTUN_REMOTE:
+			iptun.Remote = net.IP(datum.Value[0:4])
+		case nl.IFLA_IPTUN_TTL:
+			iptun.Ttl = uint8(datum.Value[0])
+		case nl.IFLA_IPTUN_TOS:
+			iptun.Tos = uint8(datum.Value[0])
+		case nl.IFLA_IPTUN_PMTUDISC:
+			iptun.PMtuDisc = uint8(datum.Value[0])
+		}
+	}
+}
+
+func addVtiAttrs(vti *Vti, linkInfo *nl.RtAttr) {
+	data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
+
+	ip := vti.Local.To4()
+	if ip != nil {
+		nl.NewRtAttrChild(data, nl.IFLA_VTI_LOCAL, []byte(ip))
+	}
+
+	ip = vti.Remote.To4()
+	if ip != nil {
+		nl.NewRtAttrChild(data, nl.IFLA_VTI_REMOTE, []byte(ip))
+	}
+
+	if vti.Link != 0 {
+		nl.NewRtAttrChild(data, nl.IFLA_VTI_LINK, nl.Uint32Attr(vti.Link))
+	}
+
+	nl.NewRtAttrChild(data, nl.IFLA_VTI_IKEY, htonl(vti.IKey))
+	nl.NewRtAttrChild(data, nl.IFLA_VTI_OKEY, htonl(vti.OKey))
+}
+
+func parseVtiData(link Link, data []syscall.NetlinkRouteAttr) {
+	vti := link.(*Vti)
+	for _, datum := range data {
+		switch datum.Attr.Type {
+		case nl.IFLA_VTI_LOCAL:
+			vti.Local = net.IP(datum.Value[0:4])
+		case nl.IFLA_VTI_REMOTE:
+			vti.Remote = net.IP(datum.Value[0:4])
+		case nl.IFLA_VTI_IKEY:
+			vti.IKey = ntohl(datum.Value[0:4])
+		case nl.IFLA_VTI_OKEY:
+			vti.OKey = ntohl(datum.Value[0:4])
+		}
+	}
+}
+
+func addVrfAttrs(vrf *Vrf, linkInfo *nl.RtAttr) {
+	data := nl.NewRtAttrChild(linkInfo, nl.IFLA_INFO_DATA, nil)
+	b := make([]byte, 4)
+	native.PutUint32(b, uint32(vrf.Table))
+	nl.NewRtAttrChild(data, nl.IFLA_VRF_TABLE, b)
+}
+
+func parseVrfData(link Link, data []syscall.NetlinkRouteAttr) {
+	vrf := link.(*Vrf)
+	for _, datum := range data {
+		switch datum.Attr.Type {
+		case nl.IFLA_VRF_TABLE:
+			vrf.Table = native.Uint32(datum.Value[0:4])
+		}
+	}
+}

+ 84 - 11
vendor/github.com/vishvananda/netlink/netlink_unspecified.go

@@ -4,41 +4,114 @@ package netlink
 
 import (
 	"errors"
+	"net"
 )
 
 var (
 	ErrNotImplemented = errors.New("not implemented")
 )
 
-func LinkSetUp(link *Link) error {
+func LinkSetUp(link Link) error {
 	return ErrNotImplemented
 }
 
-func LinkSetDown(link *Link) error {
+func LinkSetDown(link Link) error {
 	return ErrNotImplemented
 }
 
-func LinkSetMTU(link *Link, mtu int) error {
+func LinkSetMTU(link Link, mtu int) error {
 	return ErrNotImplemented
 }
 
-func LinkSetMaster(link *Link, master *Link) error {
+func LinkSetMaster(link Link, master *Link) error {
 	return ErrNotImplemented
 }
 
-func LinkSetNsPid(link *Link, nspid int) error {
+func LinkSetNsPid(link Link, nspid int) error {
 	return ErrNotImplemented
 }
 
-func LinkSetNsFd(link *Link, fd int) error {
+func LinkSetNsFd(link Link, fd int) error {
 	return ErrNotImplemented
 }
 
-func LinkAdd(link *Link) error {
+func LinkSetName(link Link, name string) error {
 	return ErrNotImplemented
 }
 
-func LinkDel(link *Link) error {
+func LinkSetAlias(link Link, name string) error {
+	return ErrNotImplemented
+}
+
+func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
+	return ErrNotImplemented
+}
+
+func LinkSetVfHardwareAddr(link Link, vf int, hwaddr net.HardwareAddr) error {
+	return ErrNotImplemented
+}
+
+func LinkSetVfVlan(link Link, vf, vlan int) error {
+	return ErrNotImplemented
+}
+
+func LinkSetVfTxRate(link Link, vf, rate int) error {
+	return ErrNotImplemented
+}
+
+func LinkSetNoMaster(link Link) error {
+	return ErrNotImplemented
+}
+
+func LinkSetMasterByIndex(link Link, masterIndex int) error {
+	return ErrNotImplemented
+}
+
+func LinkSetXdpFd(link Link, fd int) error {
+	return ErrNotImplemented
+}
+
+func LinkByName(name string) (Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func LinkByAlias(alias string) (Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func LinkByIndex(index int) (Link, error) {
+	return nil, ErrNotImplemented
+}
+
+func LinkSetHairpin(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func LinkSetGuard(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func LinkSetFastLeave(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func LinkSetLearning(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func LinkSetRootBlock(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func LinkSetFlood(link Link, mode bool) error {
+	return ErrNotImplemented
+}
+
+func LinkAdd(link Link) error {
+	return ErrNotImplemented
+}
+
+func LinkDel(link Link) error {
 	return ErrNotImplemented
 }
 
@@ -70,11 +143,11 @@ func LinkList() ([]Link, error) {
 	return nil, ErrNotImplemented
 }
 
-func AddrAdd(link *Link, addr *Addr) error {
+func AddrAdd(link Link, addr *Addr) error {
 	return ErrNotImplemented
 }
 
-func AddrDel(link *Link, addr *Addr) error {
+func AddrDel(link Link, addr *Addr) error {
 	return ErrNotImplemented
 }
 
@@ -90,7 +163,7 @@ func RouteDel(route *Route) error {
 	return ErrNotImplemented
 }
 
-func RouteList(link *Link, family int) ([]Route, error) {
+func RouteList(link Link, family int) ([]Route, error) {
 	return nil, ErrNotImplemented
 }
 

+ 34 - 0
vendor/github.com/vishvananda/netlink/nl/link_linux.go

@@ -418,3 +418,37 @@ const (
 	IFLA_XDP_ATTACHED /* read-only bool indicating if prog is attached */
 	IFLA_XDP_MAX      = IFLA_XDP_ATTACHED
 )
+
+const (
+	IFLA_IPTUN_UNSPEC = iota
+	IFLA_IPTUN_LINK
+	IFLA_IPTUN_LOCAL
+	IFLA_IPTUN_REMOTE
+	IFLA_IPTUN_TTL
+	IFLA_IPTUN_TOS
+	IFLA_IPTUN_ENCAP_LIMIT
+	IFLA_IPTUN_FLOWINFO
+	IFLA_IPTUN_FLAGS
+	IFLA_IPTUN_PROTO
+	IFLA_IPTUN_PMTUDISC
+	IFLA_IPTUN_6RD_PREFIX
+	IFLA_IPTUN_6RD_RELAY_PREFIX
+	IFLA_IPTUN_6RD_PREFIXLEN
+	IFLA_IPTUN_6RD_RELAY_PREFIXLEN
+	IFLA_IPTUN_MAX = IFLA_IPTUN_6RD_RELAY_PREFIXLEN
+)
+
+const (
+	IFLA_VTI_UNSPEC = iota
+	IFLA_VTI_LINK
+	IFLA_VTI_IKEY
+	IFLA_VTI_OKEY
+	IFLA_VTI_LOCAL
+	IFLA_VTI_REMOTE
+	IFLA_VTI_MAX = IFLA_VTI_REMOTE
+)
+
+const (
+	IFLA_VRF_UNSPEC = iota
+	IFLA_VRF_TABLE
+)

+ 7 - 0
vendor/github.com/vishvananda/netlink/nl/nl_linux.go

@@ -656,6 +656,13 @@ func Uint32Attr(v uint32) []byte {
 	return bytes
 }
 
+func Uint64Attr(v uint64) []byte {
+	native := NativeEndian()
+	bytes := make([]byte, 8)
+	native.PutUint64(bytes, v)
+	return bytes
+}
+
 func ParseRouteAttr(b []byte) ([]syscall.NetlinkRouteAttr, error) {
 	var attrs []syscall.NetlinkRouteAttr
 	for len(b) >= syscall.SizeofRtAttr {

+ 1 - 4
vendor/github.com/vishvananda/netlink/protinfo.go

@@ -46,8 +46,5 @@ func boolToByte(x bool) []byte {
 }
 
 func byteToBool(x byte) bool {
-	if uint8(x) != 0 {
-		return true
-	}
-	return false
+	return uint8(x) != 0
 }

+ 23 - 17
vendor/github.com/vishvananda/netlink/protinfo_linux.go

@@ -40,25 +40,31 @@ func (h *Handle) LinkGetProtinfo(link Link) (Protinfo, error) {
 			if err != nil {
 				return pi, err
 			}
-			var pi Protinfo
-			for _, info := range infos {
-				switch info.Attr.Type {
-				case nl.IFLA_BRPORT_MODE:
-					pi.Hairpin = byteToBool(info.Value[0])
-				case nl.IFLA_BRPORT_GUARD:
-					pi.Guard = byteToBool(info.Value[0])
-				case nl.IFLA_BRPORT_FAST_LEAVE:
-					pi.FastLeave = byteToBool(info.Value[0])
-				case nl.IFLA_BRPORT_PROTECT:
-					pi.RootBlock = byteToBool(info.Value[0])
-				case nl.IFLA_BRPORT_LEARNING:
-					pi.Learning = byteToBool(info.Value[0])
-				case nl.IFLA_BRPORT_UNICAST_FLOOD:
-					pi.Flood = byteToBool(info.Value[0])
-				}
-			}
+			pi = *parseProtinfo(infos)
+
 			return pi, nil
 		}
 	}
 	return pi, fmt.Errorf("Device with index %d not found", base.Index)
 }
+
+func parseProtinfo(infos []syscall.NetlinkRouteAttr) *Protinfo {
+	var pi Protinfo
+	for _, info := range infos {
+		switch info.Attr.Type {
+		case nl.IFLA_BRPORT_MODE:
+			pi.Hairpin = byteToBool(info.Value[0])
+		case nl.IFLA_BRPORT_GUARD:
+			pi.Guard = byteToBool(info.Value[0])
+		case nl.IFLA_BRPORT_FAST_LEAVE:
+			pi.FastLeave = byteToBool(info.Value[0])
+		case nl.IFLA_BRPORT_PROTECT:
+			pi.RootBlock = byteToBool(info.Value[0])
+		case nl.IFLA_BRPORT_LEARNING:
+			pi.Learning = byteToBool(info.Value[0])
+		case nl.IFLA_BRPORT_UNICAST_FLOOD:
+			pi.Flood = byteToBool(info.Value[0])
+		}
+	}
+	return &pi
+}

+ 4 - 2
vendor/github.com/vishvananda/netlink/qdisc_linux.go

@@ -168,11 +168,13 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
 		options = nl.NewRtAttr(nl.TCA_OPTIONS, tcmap.Serialize())
 	} else if tbf, ok := qdisc.(*Tbf); ok {
 		opt := nl.TcTbfQopt{}
-		// TODO: handle rate > uint32
 		opt.Rate.Rate = uint32(tbf.Rate)
 		opt.Limit = tbf.Limit
 		opt.Buffer = tbf.Buffer
 		nl.NewRtAttrChild(options, nl.TCA_TBF_PARMS, opt.Serialize())
+		if tbf.Rate >= uint64(1<<32) {
+			nl.NewRtAttrChild(options, nl.TCA_TBF_RATE64, nl.Uint64Attr(tbf.Rate))
+		}
 	} else if htb, ok := qdisc.(*Htb); ok {
 		opt := nl.TcHtbGlob{}
 		opt.Version = htb.Version
@@ -421,7 +423,7 @@ func parseTbfData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
 			tbf.Limit = opt.Limit
 			tbf.Buffer = opt.Buffer
 		case nl.TCA_TBF_RATE64:
-			tbf.Rate = native.Uint64(datum.Value[0:4])
+			tbf.Rate = native.Uint64(datum.Value[0:8])
 		}
 	}
 	return nil

+ 14 - 8
vendor/github.com/vishvananda/netlink/route_linux.go

@@ -283,14 +283,20 @@ func (h *Handle) RouteListFiltered(family int, filter *Route, filterMask uint64)
 				continue
 			case filterMask&RT_FILTER_SRC != 0 && !route.Src.Equal(filter.Src):
 				continue
-			case filterMask&RT_FILTER_DST != 0 && filter.Dst != nil:
-				if route.Dst == nil {
-					continue
-				}
-				aMaskLen, aMaskBits := route.Dst.Mask.Size()
-				bMaskLen, bMaskBits := filter.Dst.Mask.Size()
-				if !(route.Dst.IP.Equal(filter.Dst.IP) && aMaskLen == bMaskLen && aMaskBits == bMaskBits) {
-					continue
+			case filterMask&RT_FILTER_DST != 0:
+				if filter.Dst == nil {
+					if route.Dst != nil {
+						continue
+					}
+				} else {
+					if route.Dst == nil {
+						continue
+					}
+					aMaskLen, aMaskBits := route.Dst.Mask.Size()
+					bMaskLen, bMaskBits := filter.Dst.Mask.Size()
+					if !(route.Dst.IP.Equal(filter.Dst.IP) && aMaskLen == bMaskLen && aMaskBits == bMaskBits) {
+						continue
+					}
 				}
 			}
 		}